[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /** @license React v17.0.2 2 * react-dom.development.js 3 * 4 * Copyright (c) Facebook, Inc. and its affiliates. 5 * 6 * This source code is licensed under the MIT license found in the 7 * LICENSE file in the root directory of this source tree. 8 */ 9 (function (global, factory) { 10 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) : 11 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) : 12 (global = global || self, factory(global.ReactDOM = {}, global.React)); 13 }(this, (function (exports, React) { 'use strict'; 14 15 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 16 17 // by calls to these methods by a Babel plugin. 18 // 19 // In PROD (or in packages without access to React internals), 20 // they are left as they are instead. 21 22 function warn(format) { 23 { 24 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 25 args[_key - 1] = arguments[_key]; 26 } 27 28 printWarning('warn', format, args); 29 } 30 } 31 function error(format) { 32 { 33 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 34 args[_key2 - 1] = arguments[_key2]; 35 } 36 37 printWarning('error', format, args); 38 } 39 } 40 41 function printWarning(level, format, args) { 42 // When changing this logic, you might want to also 43 // update consoleWithStackDev.www.js as well. 44 { 45 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 46 var stack = ReactDebugCurrentFrame.getStackAddendum(); 47 48 if (stack !== '') { 49 format += '%s'; 50 args = args.concat([stack]); 51 } 52 53 var argsWithFormat = args.map(function (item) { 54 return '' + item; 55 }); // Careful: RN currently depends on this prefix 56 57 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it 58 // breaks IE9: https://github.com/facebook/react/issues/13610 59 // eslint-disable-next-line react-internal/no-production-logging 60 61 Function.prototype.apply.call(console[level], console, argsWithFormat); 62 } 63 } 64 65 if (!React) { 66 { 67 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." ); 68 } 69 } 70 71 var FunctionComponent = 0; 72 var ClassComponent = 1; 73 var IndeterminateComponent = 2; // Before we know whether it is function or class 74 75 var HostRoot = 3; // Root of a host tree. Could be nested inside another node. 76 77 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. 78 79 var HostComponent = 5; 80 var HostText = 6; 81 var Fragment = 7; 82 var Mode = 8; 83 var ContextConsumer = 9; 84 var ContextProvider = 10; 85 var ForwardRef = 11; 86 var Profiler = 12; 87 var SuspenseComponent = 13; 88 var MemoComponent = 14; 89 var SimpleMemoComponent = 15; 90 var LazyComponent = 16; 91 var IncompleteClassComponent = 17; 92 var DehydratedFragment = 18; 93 var SuspenseListComponent = 19; 94 var FundamentalComponent = 20; 95 var ScopeComponent = 21; 96 var Block = 22; 97 var OffscreenComponent = 23; 98 var LegacyHiddenComponent = 24; 99 100 // Filter certain DOM attributes (e.g. src, href) if their values are empty strings. 101 102 var enableProfilerTimer = true; // Record durations for commit and passive effects phases. 103 104 var enableFundamentalAPI = false; // Experimental Scope support. 105 var enableNewReconciler = false; // Errors that are thrown while unmounting (or after in the case of passive effects) 106 var warnAboutStringRefs = false; 107 108 var allNativeEvents = new Set(); 109 /** 110 * Mapping from registration name to event name 111 */ 112 113 114 var registrationNameDependencies = {}; 115 /** 116 * Mapping from lowercase registration names to the properly cased version, 117 * used to warn in the case of missing event handlers. Available 118 * only in true. 119 * @type {Object} 120 */ 121 122 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true 123 124 function registerTwoPhaseEvent(registrationName, dependencies) { 125 registerDirectEvent(registrationName, dependencies); 126 registerDirectEvent(registrationName + 'Capture', dependencies); 127 } 128 function registerDirectEvent(registrationName, dependencies) { 129 { 130 if (registrationNameDependencies[registrationName]) { 131 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName); 132 } 133 } 134 135 registrationNameDependencies[registrationName] = dependencies; 136 137 { 138 var lowerCasedName = registrationName.toLowerCase(); 139 possibleRegistrationNames[lowerCasedName] = registrationName; 140 141 if (registrationName === 'onDoubleClick') { 142 possibleRegistrationNames.ondblclick = registrationName; 143 } 144 } 145 146 for (var i = 0; i < dependencies.length; i++) { 147 allNativeEvents.add(dependencies[i]); 148 } 149 } 150 151 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); 152 153 // A reserved attribute. 154 // It is handled by React separately and shouldn't be written to the DOM. 155 var RESERVED = 0; // A simple string attribute. 156 // Attributes that aren't in the filter are presumed to have this type. 157 158 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called 159 // "enumerated" attributes with "true" and "false" as possible values. 160 // When true, it should be set to a "true" string. 161 // When false, it should be set to a "false" string. 162 163 var BOOLEANISH_STRING = 2; // A real boolean attribute. 164 // When true, it should be present (set either to an empty string or its name). 165 // When false, it should be omitted. 166 167 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value. 168 // When true, it should be present (set either to an empty string or its name). 169 // When false, it should be omitted. 170 // For any other value, should be present with that value. 171 172 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric. 173 // When falsy, it should be removed. 174 175 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric. 176 // When falsy, it should be removed. 177 178 var POSITIVE_NUMERIC = 6; 179 180 /* eslint-disable max-len */ 181 var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; 182 /* eslint-enable max-len */ 183 184 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; 185 var ROOT_ATTRIBUTE_NAME = 'data-reactroot'; 186 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 187 var hasOwnProperty = Object.prototype.hasOwnProperty; 188 var illegalAttributeNameCache = {}; 189 var validatedAttributeNameCache = {}; 190 function isAttributeNameSafe(attributeName) { 191 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 192 return true; 193 } 194 195 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 196 return false; 197 } 198 199 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 200 validatedAttributeNameCache[attributeName] = true; 201 return true; 202 } 203 204 illegalAttributeNameCache[attributeName] = true; 205 206 { 207 error('Invalid attribute name: `%s`', attributeName); 208 } 209 210 return false; 211 } 212 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { 213 if (propertyInfo !== null) { 214 return propertyInfo.type === RESERVED; 215 } 216 217 if (isCustomComponentTag) { 218 return false; 219 } 220 221 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 222 return true; 223 } 224 225 return false; 226 } 227 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 228 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 229 return false; 230 } 231 232 switch (typeof value) { 233 case 'function': // $FlowIssue symbol is perfectly valid here 234 235 case 'symbol': 236 // eslint-disable-line 237 return true; 238 239 case 'boolean': 240 { 241 if (isCustomComponentTag) { 242 return false; 243 } 244 245 if (propertyInfo !== null) { 246 return !propertyInfo.acceptsBooleans; 247 } else { 248 var prefix = name.toLowerCase().slice(0, 5); 249 return prefix !== 'data-' && prefix !== 'aria-'; 250 } 251 } 252 253 default: 254 return false; 255 } 256 } 257 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { 258 if (value === null || typeof value === 'undefined') { 259 return true; 260 } 261 262 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { 263 return true; 264 } 265 266 if (isCustomComponentTag) { 267 return false; 268 } 269 270 if (propertyInfo !== null) { 271 272 switch (propertyInfo.type) { 273 case BOOLEAN: 274 return !value; 275 276 case OVERLOADED_BOOLEAN: 277 return value === false; 278 279 case NUMERIC: 280 return isNaN(value); 281 282 case POSITIVE_NUMERIC: 283 return isNaN(value) || value < 1; 284 } 285 } 286 287 return false; 288 } 289 function getPropertyInfo(name) { 290 return properties.hasOwnProperty(name) ? properties[name] : null; 291 } 292 293 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) { 294 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 295 this.attributeName = attributeName; 296 this.attributeNamespace = attributeNamespace; 297 this.mustUseProperty = mustUseProperty; 298 this.propertyName = name; 299 this.type = type; 300 this.sanitizeURL = sanitizeURL; 301 this.removeEmptyString = removeEmptyString; 302 } // When adding attributes to this list, be sure to also add them to 303 // the `possibleStandardNames` module to ensure casing and incorrect 304 // name warnings. 305 306 307 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM. 308 309 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular 310 // elements (not just inputs). Now that ReactDOMInput assigns to the 311 // defaultValue property -- do we need this? 312 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style']; 313 reservedProps.forEach(function (name) { 314 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 315 name, // attributeName 316 null, // attributeNamespace 317 false, // sanitizeURL 318 false); 319 }); // A few React string attributes have a different name. 320 // This is a mapping from React prop names to the attribute names. 321 322 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 323 var name = _ref[0], 324 attributeName = _ref[1]; 325 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 326 attributeName, // attributeName 327 null, // attributeNamespace 328 false, // sanitizeURL 329 false); 330 }); // These are "enumerated" HTML attributes that accept "true" and "false". 331 // In React, we let users pass `true` and `false` even though technically 332 // these aren't boolean attributes (they are coerced to strings). 333 334 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 335 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 336 name.toLowerCase(), // attributeName 337 null, // attributeNamespace 338 false, // sanitizeURL 339 false); 340 }); // These are "enumerated" SVG attributes that accept "true" and "false". 341 // In React, we let users pass `true` and `false` even though technically 342 // these aren't boolean attributes (they are coerced to strings). 343 // Since these are SVG attributes, their attribute names are case-sensitive. 344 345 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 346 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 347 name, // attributeName 348 null, // attributeNamespace 349 false, // sanitizeURL 350 false); 351 }); // These are HTML boolean attributes. 352 353 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM 354 // on the client side because the browsers are inconsistent. Instead we call focus(). 355 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata 356 'itemScope'].forEach(function (name) { 357 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 358 name.toLowerCase(), // attributeName 359 null, // attributeNamespace 360 false, // sanitizeURL 361 false); 362 }); // These are the few React props that we set as DOM properties 363 // rather than attributes. These are all booleans. 364 365 ['checked', // Note: `option.selected` is not updated if `select.multiple` is 366 // disabled with `removeAttribute`. We have special logic for handling this. 367 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list, 368 // you'll need to set attributeName to name.toLowerCase() 369 // instead in the assignment below. 370 ].forEach(function (name) { 371 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 372 name, // attributeName 373 null, // attributeNamespace 374 false, // sanitizeURL 375 false); 376 }); // These are HTML attributes that are "overloaded booleans": they behave like 377 // booleans, but can also accept a string value. 378 379 ['capture', 'download' // NOTE: if you add a camelCased prop to this list, 380 // you'll need to set attributeName to name.toLowerCase() 381 // instead in the assignment below. 382 ].forEach(function (name) { 383 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 384 name, // attributeName 385 null, // attributeNamespace 386 false, // sanitizeURL 387 false); 388 }); // These are HTML attributes that must be positive numbers. 389 390 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list, 391 // you'll need to set attributeName to name.toLowerCase() 392 // instead in the assignment below. 393 ].forEach(function (name) { 394 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 395 name, // attributeName 396 null, // attributeNamespace 397 false, // sanitizeURL 398 false); 399 }); // These are HTML attributes that must be numbers. 400 401 ['rowSpan', 'start'].forEach(function (name) { 402 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 403 name.toLowerCase(), // attributeName 404 null, // attributeNamespace 405 false, // sanitizeURL 406 false); 407 }); 408 var CAMELIZE = /[\-\:]([a-z])/g; 409 410 var capitalize = function (token) { 411 return token[1].toUpperCase(); 412 }; // This is a list of all SVG attributes that need special casing, namespacing, 413 // or boolean value assignment. Regular attributes that just accept strings 414 // and have the same names are omitted, just like in the HTML attribute filter. 415 // Some of these attributes can be hard to find. This list was created by 416 // scraping the MDN documentation. 417 418 419 ['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, 420 // you'll need to set attributeName to name.toLowerCase() 421 // instead in the assignment below. 422 ].forEach(function (attributeName) { 423 var name = attributeName.replace(CAMELIZE, capitalize); 424 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 425 attributeName, null, // attributeNamespace 426 false, // sanitizeURL 427 false); 428 }); // String SVG attributes with the xlink namespace. 429 430 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list, 431 // you'll need to set attributeName to name.toLowerCase() 432 // instead in the assignment below. 433 ].forEach(function (attributeName) { 434 var name = attributeName.replace(CAMELIZE, capitalize); 435 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 436 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL 437 false); 438 }); // String SVG attributes with the xml namespace. 439 440 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list, 441 // you'll need to set attributeName to name.toLowerCase() 442 // instead in the assignment below. 443 ].forEach(function (attributeName) { 444 var name = attributeName.replace(CAMELIZE, capitalize); 445 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 446 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL 447 false); 448 }); // These attribute exists both in HTML and SVG. 449 // The attribute name is case-sensitive in SVG so we can't just use 450 // the React name like we do for attributes that exist only in HTML. 451 452 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) { 453 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 454 attributeName.toLowerCase(), // attributeName 455 null, // attributeNamespace 456 false, // sanitizeURL 457 false); 458 }); // These attributes accept URLs. These must not allow javascript: URLS. 459 // These will also need to accept Trusted Types object in the future. 460 461 var xlinkHref = 'xlinkHref'; 462 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty 463 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL 464 false); 465 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) { 466 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 467 attributeName.toLowerCase(), // attributeName 468 null, // attributeNamespace 469 true, // sanitizeURL 470 true); 471 }); 472 473 // and any newline or tab are filtered out as if they're not part of the URL. 474 // https://url.spec.whatwg.org/#url-parsing 475 // Tab or newline are defined as \r\n\t: 476 // https://infra.spec.whatwg.org/#ascii-tab-or-newline 477 // A C0 control is a code point in the range \u0000 NULL to \u001F 478 // INFORMATION SEPARATOR ONE, inclusive: 479 // https://infra.spec.whatwg.org/#c0-control-or-space 480 481 /* eslint-disable max-len */ 482 483 var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; 484 var didWarn = false; 485 486 function sanitizeURL(url) { 487 { 488 if (!didWarn && isJavaScriptProtocol.test(url)) { 489 didWarn = true; 490 491 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)); 492 } 493 } 494 } 495 496 /** 497 * Get the value for a property on a node. Only used in DEV for SSR validation. 498 * The "expected" argument is used as a hint of what the expected value is. 499 * Some properties have multiple equivalent values. 500 */ 501 function getValueForProperty(node, name, expected, propertyInfo) { 502 { 503 if (propertyInfo.mustUseProperty) { 504 var propertyName = propertyInfo.propertyName; 505 return node[propertyName]; 506 } else { 507 if ( propertyInfo.sanitizeURL) { 508 // If we haven't fully disabled javascript: URLs, and if 509 // the hydration is successful of a javascript: URL, we 510 // still want to warn on the client. 511 sanitizeURL('' + expected); 512 } 513 514 var attributeName = propertyInfo.attributeName; 515 var stringValue = null; 516 517 if (propertyInfo.type === OVERLOADED_BOOLEAN) { 518 if (node.hasAttribute(attributeName)) { 519 var value = node.getAttribute(attributeName); 520 521 if (value === '') { 522 return true; 523 } 524 525 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 526 return value; 527 } 528 529 if (value === '' + expected) { 530 return expected; 531 } 532 533 return value; 534 } 535 } else if (node.hasAttribute(attributeName)) { 536 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 537 // We had an attribute but shouldn't have had one, so read it 538 // for the error message. 539 return node.getAttribute(attributeName); 540 } 541 542 if (propertyInfo.type === BOOLEAN) { 543 // If this was a boolean, it doesn't matter what the value is 544 // the fact that we have it is the same as the expected. 545 return expected; 546 } // Even if this property uses a namespace we use getAttribute 547 // because we assume its namespaced name is the same as our config. 548 // To use getAttributeNS we need the local name which we don't have 549 // in our config atm. 550 551 552 stringValue = node.getAttribute(attributeName); 553 } 554 555 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 556 return stringValue === null ? expected : stringValue; 557 } else if (stringValue === '' + expected) { 558 return expected; 559 } else { 560 return stringValue; 561 } 562 } 563 } 564 } 565 /** 566 * Get the value for a attribute on a node. Only used in DEV for SSR validation. 567 * The third argument is used as a hint of what the expected value is. Some 568 * attributes have multiple equivalent values. 569 */ 570 571 function getValueForAttribute(node, name, expected) { 572 { 573 if (!isAttributeNameSafe(name)) { 574 return; 575 } // If the object is an opaque reference ID, it's expected that 576 // the next prop is different than the server value, so just return 577 // expected 578 579 580 if (isOpaqueHydratingObject(expected)) { 581 return expected; 582 } 583 584 if (!node.hasAttribute(name)) { 585 return expected === undefined ? undefined : null; 586 } 587 588 var value = node.getAttribute(name); 589 590 if (value === '' + expected) { 591 return expected; 592 } 593 594 return value; 595 } 596 } 597 /** 598 * Sets the value for a property on a node. 599 * 600 * @param {DOMElement} node 601 * @param {string} name 602 * @param {*} value 603 */ 604 605 function setValueForProperty(node, name, value, isCustomComponentTag) { 606 var propertyInfo = getPropertyInfo(name); 607 608 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) { 609 return; 610 } 611 612 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) { 613 value = null; 614 } // If the prop isn't in the special list, treat it as a simple attribute. 615 616 617 if (isCustomComponentTag || propertyInfo === null) { 618 if (isAttributeNameSafe(name)) { 619 var _attributeName = name; 620 621 if (value === null) { 622 node.removeAttribute(_attributeName); 623 } else { 624 node.setAttribute(_attributeName, '' + value); 625 } 626 } 627 628 return; 629 } 630 631 var mustUseProperty = propertyInfo.mustUseProperty; 632 633 if (mustUseProperty) { 634 var propertyName = propertyInfo.propertyName; 635 636 if (value === null) { 637 var type = propertyInfo.type; 638 node[propertyName] = type === BOOLEAN ? false : ''; 639 } else { 640 // Contrary to `setAttribute`, object properties are properly 641 // `toString`ed by IE8/9. 642 node[propertyName] = value; 643 } 644 645 return; 646 } // The rest are treated as attributes with special cases. 647 648 649 var attributeName = propertyInfo.attributeName, 650 attributeNamespace = propertyInfo.attributeNamespace; 651 652 if (value === null) { 653 node.removeAttribute(attributeName); 654 } else { 655 var _type = propertyInfo.type; 656 var attributeValue; 657 658 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) { 659 // If attribute type is boolean, we know for sure it won't be an execution sink 660 // and we won't require Trusted Type here. 661 attributeValue = ''; 662 } else { 663 // `setAttribute` with objects becomes only `[object]` in IE8/9, 664 // ('' + value) makes it output the correct toString()-value. 665 { 666 attributeValue = '' + value; 667 } 668 669 if (propertyInfo.sanitizeURL) { 670 sanitizeURL(attributeValue.toString()); 671 } 672 } 673 674 if (attributeNamespace) { 675 node.setAttributeNS(attributeNamespace, attributeName, attributeValue); 676 } else { 677 node.setAttribute(attributeName, attributeValue); 678 } 679 } 680 } 681 682 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 683 var _assign = ReactInternals.assign; 684 685 // ATTENTION 686 // When adding new symbols to this file, 687 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' 688 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol 689 // nor polyfill, then a plain number is used for performance. 690 var REACT_ELEMENT_TYPE = 0xeac7; 691 var REACT_PORTAL_TYPE = 0xeaca; 692 var REACT_FRAGMENT_TYPE = 0xeacb; 693 var REACT_STRICT_MODE_TYPE = 0xeacc; 694 var REACT_PROFILER_TYPE = 0xead2; 695 var REACT_PROVIDER_TYPE = 0xeacd; 696 var REACT_CONTEXT_TYPE = 0xeace; 697 var REACT_FORWARD_REF_TYPE = 0xead0; 698 var REACT_SUSPENSE_TYPE = 0xead1; 699 var REACT_SUSPENSE_LIST_TYPE = 0xead8; 700 var REACT_MEMO_TYPE = 0xead3; 701 var REACT_LAZY_TYPE = 0xead4; 702 var REACT_BLOCK_TYPE = 0xead9; 703 var REACT_SERVER_BLOCK_TYPE = 0xeada; 704 var REACT_FUNDAMENTAL_TYPE = 0xead5; 705 var REACT_SCOPE_TYPE = 0xead7; 706 var REACT_OPAQUE_ID_TYPE = 0xeae0; 707 var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; 708 var REACT_OFFSCREEN_TYPE = 0xeae2; 709 var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; 710 711 if (typeof Symbol === 'function' && Symbol.for) { 712 var symbolFor = Symbol.for; 713 REACT_ELEMENT_TYPE = symbolFor('react.element'); 714 REACT_PORTAL_TYPE = symbolFor('react.portal'); 715 REACT_FRAGMENT_TYPE = symbolFor('react.fragment'); 716 REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode'); 717 REACT_PROFILER_TYPE = symbolFor('react.profiler'); 718 REACT_PROVIDER_TYPE = symbolFor('react.provider'); 719 REACT_CONTEXT_TYPE = symbolFor('react.context'); 720 REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref'); 721 REACT_SUSPENSE_TYPE = symbolFor('react.suspense'); 722 REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list'); 723 REACT_MEMO_TYPE = symbolFor('react.memo'); 724 REACT_LAZY_TYPE = symbolFor('react.lazy'); 725 REACT_BLOCK_TYPE = symbolFor('react.block'); 726 REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block'); 727 REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental'); 728 REACT_SCOPE_TYPE = symbolFor('react.scope'); 729 REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id'); 730 REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode'); 731 REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen'); 732 REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden'); 733 } 734 735 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; 736 var FAUX_ITERATOR_SYMBOL = '@@iterator'; 737 function getIteratorFn(maybeIterable) { 738 if (maybeIterable === null || typeof maybeIterable !== 'object') { 739 return null; 740 } 741 742 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; 743 744 if (typeof maybeIterator === 'function') { 745 return maybeIterator; 746 } 747 748 return null; 749 } 750 751 // Helpers to patch console.logs to avoid logging during side-effect free 752 // replaying on render function. This currently only patches the object 753 // lazily which won't cover if the log function was extracted eagerly. 754 // We could also eagerly patch the method. 755 var disabledDepth = 0; 756 var prevLog; 757 var prevInfo; 758 var prevWarn; 759 var prevError; 760 var prevGroup; 761 var prevGroupCollapsed; 762 var prevGroupEnd; 763 764 function disabledLog() {} 765 766 disabledLog.__reactDisabledLog = true; 767 function disableLogs() { 768 { 769 if (disabledDepth === 0) { 770 /* eslint-disable react-internal/no-production-logging */ 771 prevLog = console.log; 772 prevInfo = console.info; 773 prevWarn = console.warn; 774 prevError = console.error; 775 prevGroup = console.group; 776 prevGroupCollapsed = console.groupCollapsed; 777 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 778 779 var props = { 780 configurable: true, 781 enumerable: true, 782 value: disabledLog, 783 writable: true 784 }; // $FlowFixMe Flow thinks console is immutable. 785 786 Object.defineProperties(console, { 787 info: props, 788 log: props, 789 warn: props, 790 error: props, 791 group: props, 792 groupCollapsed: props, 793 groupEnd: props 794 }); 795 /* eslint-enable react-internal/no-production-logging */ 796 } 797 798 disabledDepth++; 799 } 800 } 801 function reenableLogs() { 802 { 803 disabledDepth--; 804 805 if (disabledDepth === 0) { 806 /* eslint-disable react-internal/no-production-logging */ 807 var props = { 808 configurable: true, 809 enumerable: true, 810 writable: true 811 }; // $FlowFixMe Flow thinks console is immutable. 812 813 Object.defineProperties(console, { 814 log: _assign({}, props, { 815 value: prevLog 816 }), 817 info: _assign({}, props, { 818 value: prevInfo 819 }), 820 warn: _assign({}, props, { 821 value: prevWarn 822 }), 823 error: _assign({}, props, { 824 value: prevError 825 }), 826 group: _assign({}, props, { 827 value: prevGroup 828 }), 829 groupCollapsed: _assign({}, props, { 830 value: prevGroupCollapsed 831 }), 832 groupEnd: _assign({}, props, { 833 value: prevGroupEnd 834 }) 835 }); 836 /* eslint-enable react-internal/no-production-logging */ 837 } 838 839 if (disabledDepth < 0) { 840 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.'); 841 } 842 } 843 } 844 845 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 846 var prefix; 847 function describeBuiltInComponentFrame(name, source, ownerFn) { 848 { 849 if (prefix === undefined) { 850 // Extract the VM specific prefix used by each line. 851 try { 852 throw Error(); 853 } catch (x) { 854 var match = x.stack.trim().match(/\n( *(at )?)/); 855 prefix = match && match[1] || ''; 856 } 857 } // We use the prefix to ensure our stacks line up with native stack frames. 858 859 860 return '\n' + prefix + name; 861 } 862 } 863 var reentry = false; 864 var componentFrameCache; 865 866 { 867 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; 868 componentFrameCache = new PossiblyWeakMap(); 869 } 870 871 function describeNativeComponentFrame(fn, construct) { 872 // If something asked for a stack inside a fake render, it should get ignored. 873 if (!fn || reentry) { 874 return ''; 875 } 876 877 { 878 var frame = componentFrameCache.get(fn); 879 880 if (frame !== undefined) { 881 return frame; 882 } 883 } 884 885 var control; 886 reentry = true; 887 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined. 888 889 Error.prepareStackTrace = undefined; 890 var previousDispatcher; 891 892 { 893 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function 894 // for warnings. 895 896 ReactCurrentDispatcher.current = null; 897 disableLogs(); 898 } 899 900 try { 901 // This should throw. 902 if (construct) { 903 // Something should be setting the props in the constructor. 904 var Fake = function () { 905 throw Error(); 906 }; // $FlowFixMe 907 908 909 Object.defineProperty(Fake.prototype, 'props', { 910 set: function () { 911 // We use a throwing setter instead of frozen or non-writable props 912 // because that won't throw in a non-strict mode function. 913 throw Error(); 914 } 915 }); 916 917 if (typeof Reflect === 'object' && Reflect.construct) { 918 // We construct a different control for this case to include any extra 919 // frames added by the construct call. 920 try { 921 Reflect.construct(Fake, []); 922 } catch (x) { 923 control = x; 924 } 925 926 Reflect.construct(fn, [], Fake); 927 } else { 928 try { 929 Fake.call(); 930 } catch (x) { 931 control = x; 932 } 933 934 fn.call(Fake.prototype); 935 } 936 } else { 937 try { 938 throw Error(); 939 } catch (x) { 940 control = x; 941 } 942 943 fn(); 944 } 945 } catch (sample) { 946 // This is inlined manually because closure doesn't do it for us. 947 if (sample && control && typeof sample.stack === 'string') { 948 // This extracts the first frame from the sample that isn't also in the control. 949 // Skipping one frame that we assume is the frame that calls the two. 950 var sampleLines = sample.stack.split('\n'); 951 var controlLines = control.stack.split('\n'); 952 var s = sampleLines.length - 1; 953 var c = controlLines.length - 1; 954 955 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) { 956 // We expect at least one stack frame to be shared. 957 // Typically this will be the root most one. However, stack frames may be 958 // cut off due to maximum stack limits. In this case, one maybe cut off 959 // earlier than the other. We assume that the sample is longer or the same 960 // and there for cut off earlier. So we should find the root most frame in 961 // the sample somewhere in the control. 962 c--; 963 } 964 965 for (; s >= 1 && c >= 0; s--, c--) { 966 // Next we find the first one that isn't the same which should be the 967 // frame that called our sample function and the control. 968 if (sampleLines[s] !== controlLines[c]) { 969 // In V8, the first line is describing the message but other VMs don't. 970 // If we're about to return the first line, and the control is also on the same 971 // line, that's a pretty good indicator that our sample threw at same line as 972 // the control. I.e. before we entered the sample frame. So we ignore this result. 973 // This can happen if you passed a class to function component, or non-function. 974 if (s !== 1 || c !== 1) { 975 do { 976 s--; 977 c--; // We may still have similar intermediate frames from the construct call. 978 // The next one that isn't the same should be our match though. 979 980 if (c < 0 || sampleLines[s] !== controlLines[c]) { 981 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. 982 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); 983 984 { 985 if (typeof fn === 'function') { 986 componentFrameCache.set(fn, _frame); 987 } 988 } // Return the line we found. 989 990 991 return _frame; 992 } 993 } while (s >= 1 && c >= 0); 994 } 995 996 break; 997 } 998 } 999 } 1000 } finally { 1001 reentry = false; 1002 1003 { 1004 ReactCurrentDispatcher.current = previousDispatcher; 1005 reenableLogs(); 1006 } 1007 1008 Error.prepareStackTrace = previousPrepareStackTrace; 1009 } // Fallback to just using the name if we couldn't make it throw. 1010 1011 1012 var name = fn ? fn.displayName || fn.name : ''; 1013 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; 1014 1015 { 1016 if (typeof fn === 'function') { 1017 componentFrameCache.set(fn, syntheticFrame); 1018 } 1019 } 1020 1021 return syntheticFrame; 1022 } 1023 1024 function describeClassComponentFrame(ctor, source, ownerFn) { 1025 { 1026 return describeNativeComponentFrame(ctor, true); 1027 } 1028 } 1029 function describeFunctionComponentFrame(fn, source, ownerFn) { 1030 { 1031 return describeNativeComponentFrame(fn, false); 1032 } 1033 } 1034 1035 function shouldConstruct(Component) { 1036 var prototype = Component.prototype; 1037 return !!(prototype && prototype.isReactComponent); 1038 } 1039 1040 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { 1041 1042 if (type == null) { 1043 return ''; 1044 } 1045 1046 if (typeof type === 'function') { 1047 { 1048 return describeNativeComponentFrame(type, shouldConstruct(type)); 1049 } 1050 } 1051 1052 if (typeof type === 'string') { 1053 return describeBuiltInComponentFrame(type); 1054 } 1055 1056 switch (type) { 1057 case REACT_SUSPENSE_TYPE: 1058 return describeBuiltInComponentFrame('Suspense'); 1059 1060 case REACT_SUSPENSE_LIST_TYPE: 1061 return describeBuiltInComponentFrame('SuspenseList'); 1062 } 1063 1064 if (typeof type === 'object') { 1065 switch (type.$$typeof) { 1066 case REACT_FORWARD_REF_TYPE: 1067 return describeFunctionComponentFrame(type.render); 1068 1069 case REACT_MEMO_TYPE: 1070 // Memo may contain any component type so we recursively resolve it. 1071 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); 1072 1073 case REACT_BLOCK_TYPE: 1074 return describeFunctionComponentFrame(type._render); 1075 1076 case REACT_LAZY_TYPE: 1077 { 1078 var lazyComponent = type; 1079 var payload = lazyComponent._payload; 1080 var init = lazyComponent._init; 1081 1082 try { 1083 // Lazy may contain any component type so we recursively resolve it. 1084 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); 1085 } catch (x) {} 1086 } 1087 } 1088 } 1089 1090 return ''; 1091 } 1092 1093 function describeFiber(fiber) { 1094 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ; 1095 var source = fiber._debugSource ; 1096 1097 switch (fiber.tag) { 1098 case HostComponent: 1099 return describeBuiltInComponentFrame(fiber.type); 1100 1101 case LazyComponent: 1102 return describeBuiltInComponentFrame('Lazy'); 1103 1104 case SuspenseComponent: 1105 return describeBuiltInComponentFrame('Suspense'); 1106 1107 case SuspenseListComponent: 1108 return describeBuiltInComponentFrame('SuspenseList'); 1109 1110 case FunctionComponent: 1111 case IndeterminateComponent: 1112 case SimpleMemoComponent: 1113 return describeFunctionComponentFrame(fiber.type); 1114 1115 case ForwardRef: 1116 return describeFunctionComponentFrame(fiber.type.render); 1117 1118 case Block: 1119 return describeFunctionComponentFrame(fiber.type._render); 1120 1121 case ClassComponent: 1122 return describeClassComponentFrame(fiber.type); 1123 1124 default: 1125 return ''; 1126 } 1127 } 1128 1129 function getStackByFiberInDevAndProd(workInProgress) { 1130 try { 1131 var info = ''; 1132 var node = workInProgress; 1133 1134 do { 1135 info += describeFiber(node); 1136 node = node.return; 1137 } while (node); 1138 1139 return info; 1140 } catch (x) { 1141 return '\nError generating stack: ' + x.message + '\n' + x.stack; 1142 } 1143 } 1144 1145 function getWrappedName(outerType, innerType, wrapperName) { 1146 var functionName = innerType.displayName || innerType.name || ''; 1147 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName); 1148 } 1149 1150 function getContextName(type) { 1151 return type.displayName || 'Context'; 1152 } 1153 1154 function getComponentName(type) { 1155 if (type == null) { 1156 // Host root, text node or just invalid type. 1157 return null; 1158 } 1159 1160 { 1161 if (typeof type.tag === 'number') { 1162 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.'); 1163 } 1164 } 1165 1166 if (typeof type === 'function') { 1167 return type.displayName || type.name || null; 1168 } 1169 1170 if (typeof type === 'string') { 1171 return type; 1172 } 1173 1174 switch (type) { 1175 case REACT_FRAGMENT_TYPE: 1176 return 'Fragment'; 1177 1178 case REACT_PORTAL_TYPE: 1179 return 'Portal'; 1180 1181 case REACT_PROFILER_TYPE: 1182 return 'Profiler'; 1183 1184 case REACT_STRICT_MODE_TYPE: 1185 return 'StrictMode'; 1186 1187 case REACT_SUSPENSE_TYPE: 1188 return 'Suspense'; 1189 1190 case REACT_SUSPENSE_LIST_TYPE: 1191 return 'SuspenseList'; 1192 } 1193 1194 if (typeof type === 'object') { 1195 switch (type.$$typeof) { 1196 case REACT_CONTEXT_TYPE: 1197 var context = type; 1198 return getContextName(context) + '.Consumer'; 1199 1200 case REACT_PROVIDER_TYPE: 1201 var provider = type; 1202 return getContextName(provider._context) + '.Provider'; 1203 1204 case REACT_FORWARD_REF_TYPE: 1205 return getWrappedName(type, type.render, 'ForwardRef'); 1206 1207 case REACT_MEMO_TYPE: 1208 return getComponentName(type.type); 1209 1210 case REACT_BLOCK_TYPE: 1211 return getComponentName(type._render); 1212 1213 case REACT_LAZY_TYPE: 1214 { 1215 var lazyComponent = type; 1216 var payload = lazyComponent._payload; 1217 var init = lazyComponent._init; 1218 1219 try { 1220 return getComponentName(init(payload)); 1221 } catch (x) { 1222 return null; 1223 } 1224 } 1225 } 1226 } 1227 1228 return null; 1229 } 1230 1231 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 1232 var current = null; 1233 var isRendering = false; 1234 function getCurrentFiberOwnerNameInDevOrNull() { 1235 { 1236 if (current === null) { 1237 return null; 1238 } 1239 1240 var owner = current._debugOwner; 1241 1242 if (owner !== null && typeof owner !== 'undefined') { 1243 return getComponentName(owner.type); 1244 } 1245 } 1246 1247 return null; 1248 } 1249 1250 function getCurrentFiberStackInDev() { 1251 { 1252 if (current === null) { 1253 return ''; 1254 } // Safe because if current fiber exists, we are reconciling, 1255 // and it is guaranteed to be the work-in-progress version. 1256 1257 1258 return getStackByFiberInDevAndProd(current); 1259 } 1260 } 1261 1262 function resetCurrentFiber() { 1263 { 1264 ReactDebugCurrentFrame.getCurrentStack = null; 1265 current = null; 1266 isRendering = false; 1267 } 1268 } 1269 function setCurrentFiber(fiber) { 1270 { 1271 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; 1272 current = fiber; 1273 isRendering = false; 1274 } 1275 } 1276 function setIsRendering(rendering) { 1277 { 1278 isRendering = rendering; 1279 } 1280 } 1281 function getIsRendering() { 1282 { 1283 return isRendering; 1284 } 1285 } 1286 1287 // Flow does not allow string concatenation of most non-string types. To work 1288 // around this limitation, we use an opaque type that can only be obtained by 1289 // passing the value through getToStringValue first. 1290 function toString(value) { 1291 return '' + value; 1292 } 1293 function getToStringValue(value) { 1294 switch (typeof value) { 1295 case 'boolean': 1296 case 'number': 1297 case 'object': 1298 case 'string': 1299 case 'undefined': 1300 return value; 1301 1302 default: 1303 // function, symbol are assigned as empty strings 1304 return ''; 1305 } 1306 } 1307 1308 var hasReadOnlyValue = { 1309 button: true, 1310 checkbox: true, 1311 image: true, 1312 hidden: true, 1313 radio: true, 1314 reset: true, 1315 submit: true 1316 }; 1317 function checkControlledValueProps(tagName, props) { 1318 { 1319 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { 1320 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`.'); 1321 } 1322 1323 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { 1324 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`.'); 1325 } 1326 } 1327 } 1328 1329 function isCheckable(elem) { 1330 var type = elem.type; 1331 var nodeName = elem.nodeName; 1332 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); 1333 } 1334 1335 function getTracker(node) { 1336 return node._valueTracker; 1337 } 1338 1339 function detachTracker(node) { 1340 node._valueTracker = null; 1341 } 1342 1343 function getValueFromNode(node) { 1344 var value = ''; 1345 1346 if (!node) { 1347 return value; 1348 } 1349 1350 if (isCheckable(node)) { 1351 value = node.checked ? 'true' : 'false'; 1352 } else { 1353 value = node.value; 1354 } 1355 1356 return value; 1357 } 1358 1359 function trackValueOnNode(node) { 1360 var valueField = isCheckable(node) ? 'checked' : 'value'; 1361 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); 1362 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail 1363 // and don't track value will cause over reporting of changes, 1364 // but it's better then a hard failure 1365 // (needed for certain tests that spyOn input values and Safari) 1366 1367 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { 1368 return; 1369 } 1370 1371 var get = descriptor.get, 1372 set = descriptor.set; 1373 Object.defineProperty(node, valueField, { 1374 configurable: true, 1375 get: function () { 1376 return get.call(this); 1377 }, 1378 set: function (value) { 1379 currentValue = '' + value; 1380 set.call(this, value); 1381 } 1382 }); // We could've passed this the first time 1383 // but it triggers a bug in IE11 and Edge 14/15. 1384 // Calling defineProperty() again should be equivalent. 1385 // https://github.com/facebook/react/issues/11768 1386 1387 Object.defineProperty(node, valueField, { 1388 enumerable: descriptor.enumerable 1389 }); 1390 var tracker = { 1391 getValue: function () { 1392 return currentValue; 1393 }, 1394 setValue: function (value) { 1395 currentValue = '' + value; 1396 }, 1397 stopTracking: function () { 1398 detachTracker(node); 1399 delete node[valueField]; 1400 } 1401 }; 1402 return tracker; 1403 } 1404 1405 function track(node) { 1406 if (getTracker(node)) { 1407 return; 1408 } // TODO: Once it's just Fiber we can move this to node._wrapperState 1409 1410 1411 node._valueTracker = trackValueOnNode(node); 1412 } 1413 function updateValueIfChanged(node) { 1414 if (!node) { 1415 return false; 1416 } 1417 1418 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely 1419 // that trying again will succeed 1420 1421 if (!tracker) { 1422 return true; 1423 } 1424 1425 var lastValue = tracker.getValue(); 1426 var nextValue = getValueFromNode(node); 1427 1428 if (nextValue !== lastValue) { 1429 tracker.setValue(nextValue); 1430 return true; 1431 } 1432 1433 return false; 1434 } 1435 1436 function getActiveElement(doc) { 1437 doc = doc || (typeof document !== 'undefined' ? document : undefined); 1438 1439 if (typeof doc === 'undefined') { 1440 return null; 1441 } 1442 1443 try { 1444 return doc.activeElement || doc.body; 1445 } catch (e) { 1446 return doc.body; 1447 } 1448 } 1449 1450 var didWarnValueDefaultValue = false; 1451 var didWarnCheckedDefaultChecked = false; 1452 var didWarnControlledToUncontrolled = false; 1453 var didWarnUncontrolledToControlled = false; 1454 1455 function isControlled(props) { 1456 var usesChecked = props.type === 'checkbox' || props.type === 'radio'; 1457 return usesChecked ? props.checked != null : props.value != null; 1458 } 1459 /** 1460 * Implements an <input> host component that allows setting these optional 1461 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. 1462 * 1463 * If `checked` or `value` are not supplied (or null/undefined), user actions 1464 * that affect the checked state or value will trigger updates to the element. 1465 * 1466 * If they are supplied (and not null/undefined), the rendered element will not 1467 * trigger updates to the element. Instead, the props must change in order for 1468 * the rendered element to be updated. 1469 * 1470 * The rendered element will be initialized as unchecked (or `defaultChecked`) 1471 * with an empty value (or `defaultValue`). 1472 * 1473 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html 1474 */ 1475 1476 1477 function getHostProps(element, props) { 1478 var node = element; 1479 var checked = props.checked; 1480 1481 var hostProps = _assign({}, props, { 1482 defaultChecked: undefined, 1483 defaultValue: undefined, 1484 value: undefined, 1485 checked: checked != null ? checked : node._wrapperState.initialChecked 1486 }); 1487 1488 return hostProps; 1489 } 1490 function initWrapperState(element, props) { 1491 { 1492 checkControlledValueProps('input', props); 1493 1494 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { 1495 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); 1496 1497 didWarnCheckedDefaultChecked = true; 1498 } 1499 1500 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { 1501 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); 1502 1503 didWarnValueDefaultValue = true; 1504 } 1505 } 1506 1507 var node = element; 1508 var defaultValue = props.defaultValue == null ? '' : props.defaultValue; 1509 node._wrapperState = { 1510 initialChecked: props.checked != null ? props.checked : props.defaultChecked, 1511 initialValue: getToStringValue(props.value != null ? props.value : defaultValue), 1512 controlled: isControlled(props) 1513 }; 1514 } 1515 function updateChecked(element, props) { 1516 var node = element; 1517 var checked = props.checked; 1518 1519 if (checked != null) { 1520 setValueForProperty(node, 'checked', checked, false); 1521 } 1522 } 1523 function updateWrapper(element, props) { 1524 var node = element; 1525 1526 { 1527 var controlled = isControlled(props); 1528 1529 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { 1530 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'); 1531 1532 didWarnUncontrolledToControlled = true; 1533 } 1534 1535 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { 1536 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'); 1537 1538 didWarnControlledToUncontrolled = true; 1539 } 1540 } 1541 1542 updateChecked(element, props); 1543 var value = getToStringValue(props.value); 1544 var type = props.type; 1545 1546 if (value != null) { 1547 if (type === 'number') { 1548 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible. 1549 // eslint-disable-next-line 1550 node.value != value) { 1551 node.value = toString(value); 1552 } 1553 } else if (node.value !== toString(value)) { 1554 node.value = toString(value); 1555 } 1556 } else if (type === 'submit' || type === 'reset') { 1557 // Submit/reset inputs need the attribute removed completely to avoid 1558 // blank-text buttons. 1559 node.removeAttribute('value'); 1560 return; 1561 } 1562 1563 { 1564 // When syncing the value attribute, the value comes from a cascade of 1565 // properties: 1566 // 1. The value React property 1567 // 2. The defaultValue React property 1568 // 3. Otherwise there should be no change 1569 if (props.hasOwnProperty('value')) { 1570 setDefaultValue(node, props.type, value); 1571 } else if (props.hasOwnProperty('defaultValue')) { 1572 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 1573 } 1574 } 1575 1576 { 1577 // When syncing the checked attribute, it only changes when it needs 1578 // to be removed, such as transitioning from a checkbox into a text input 1579 if (props.checked == null && props.defaultChecked != null) { 1580 node.defaultChecked = !!props.defaultChecked; 1581 } 1582 } 1583 } 1584 function postMountWrapper(element, props, isHydrating) { 1585 var node = element; // Do not assign value if it is already set. This prevents user text input 1586 // from being lost during SSR hydration. 1587 1588 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { 1589 var type = props.type; 1590 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the 1591 // default value provided by the browser. See: #12872 1592 1593 if (isButton && (props.value === undefined || props.value === null)) { 1594 return; 1595 } 1596 1597 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input 1598 // from being lost during SSR hydration. 1599 1600 if (!isHydrating) { 1601 { 1602 // When syncing the value attribute, the value property should use 1603 // the wrapperState._initialValue property. This uses: 1604 // 1605 // 1. The value React property when present 1606 // 2. The defaultValue React property when present 1607 // 3. An empty string 1608 if (initialValue !== node.value) { 1609 node.value = initialValue; 1610 } 1611 } 1612 } 1613 1614 { 1615 // Otherwise, the value attribute is synchronized to the property, 1616 // so we assign defaultValue to the same thing as the value property 1617 // assignment step above. 1618 node.defaultValue = initialValue; 1619 } 1620 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug 1621 // this is needed to work around a chrome bug where setting defaultChecked 1622 // will sometimes influence the value of checked (even after detachment). 1623 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 1624 // We need to temporarily unset name to avoid disrupting radio button groups. 1625 1626 1627 var name = node.name; 1628 1629 if (name !== '') { 1630 node.name = ''; 1631 } 1632 1633 { 1634 // When syncing the checked attribute, both the checked property and 1635 // attribute are assigned at the same time using defaultChecked. This uses: 1636 // 1637 // 1. The checked React property when present 1638 // 2. The defaultChecked React property when present 1639 // 3. Otherwise, false 1640 node.defaultChecked = !node.defaultChecked; 1641 node.defaultChecked = !!node._wrapperState.initialChecked; 1642 } 1643 1644 if (name !== '') { 1645 node.name = name; 1646 } 1647 } 1648 function restoreControlledState(element, props) { 1649 var node = element; 1650 updateWrapper(node, props); 1651 updateNamedCousins(node, props); 1652 } 1653 1654 function updateNamedCousins(rootNode, props) { 1655 var name = props.name; 1656 1657 if (props.type === 'radio' && name != null) { 1658 var queryRoot = rootNode; 1659 1660 while (queryRoot.parentNode) { 1661 queryRoot = queryRoot.parentNode; 1662 } // If `rootNode.form` was non-null, then we could try `form.elements`, 1663 // but that sometimes behaves strangely in IE8. We could also try using 1664 // `form.getElementsByName`, but that will only return direct children 1665 // and won't include inputs that use the HTML5 `form=` attribute. Since 1666 // the input might not even be in a form. It might not even be in the 1667 // document. Let's just use the local `querySelectorAll` to ensure we don't 1668 // miss anything. 1669 1670 1671 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); 1672 1673 for (var i = 0; i < group.length; i++) { 1674 var otherNode = group[i]; 1675 1676 if (otherNode === rootNode || otherNode.form !== rootNode.form) { 1677 continue; 1678 } // This will throw if radio buttons rendered by different copies of React 1679 // and the same name are rendered into the same form (same as #1939). 1680 // That's probably okay; we don't support it just as we don't support 1681 // mixing React radio buttons with non-React ones. 1682 1683 1684 var otherProps = getFiberCurrentPropsFromNode(otherNode); 1685 1686 if (!otherProps) { 1687 { 1688 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." ); 1689 } 1690 } // We need update the tracked value on the named cousin since the value 1691 // was changed but the input saw no event or value set 1692 1693 1694 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that 1695 // was previously checked to update will cause it to be come re-checked 1696 // as appropriate. 1697 1698 updateWrapper(otherNode, otherProps); 1699 } 1700 } 1701 } // In Chrome, assigning defaultValue to certain input types triggers input validation. 1702 // For number inputs, the display value loses trailing decimal points. For email inputs, 1703 // Chrome raises "The specified value <x> is not a valid email address". 1704 // 1705 // Here we check to see if the defaultValue has actually changed, avoiding these problems 1706 // when the user is inputting text 1707 // 1708 // https://github.com/facebook/react/issues/7253 1709 1710 1711 function setDefaultValue(node, type, value) { 1712 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js 1713 type !== 'number' || getActiveElement(node.ownerDocument) !== node) { 1714 if (value == null) { 1715 node.defaultValue = toString(node._wrapperState.initialValue); 1716 } else if (node.defaultValue !== toString(value)) { 1717 node.defaultValue = toString(value); 1718 } 1719 } 1720 } 1721 1722 var didWarnSelectedSetOnOption = false; 1723 var didWarnInvalidChild = false; 1724 1725 function flattenChildren(children) { 1726 var content = ''; // Flatten children. We'll warn if they are invalid 1727 // during validateProps() which runs for hydration too. 1728 // Note that this would throw on non-element objects. 1729 // Elements are stringified (which is normally irrelevant 1730 // but matters for <fbt>). 1731 1732 React.Children.forEach(children, function (child) { 1733 if (child == null) { 1734 return; 1735 } 1736 1737 content += child; // Note: we don't warn about invalid children here. 1738 // Instead, this is done separately below so that 1739 // it happens during the hydration code path too. 1740 }); 1741 return content; 1742 } 1743 /** 1744 * Implements an <option> host component that warns when `selected` is set. 1745 */ 1746 1747 1748 function validateProps(element, props) { 1749 { 1750 // This mirrors the code path above, but runs for hydration too. 1751 // Warn about invalid children here so that client and hydration are consistent. 1752 // TODO: this seems like it could cause a DEV-only throw for hydration 1753 // if children contains a non-element object. We should try to avoid that. 1754 if (typeof props.children === 'object' && props.children !== null) { 1755 React.Children.forEach(props.children, function (child) { 1756 if (child == null) { 1757 return; 1758 } 1759 1760 if (typeof child === 'string' || typeof child === 'number') { 1761 return; 1762 } 1763 1764 if (typeof child.type !== 'string') { 1765 return; 1766 } 1767 1768 if (!didWarnInvalidChild) { 1769 didWarnInvalidChild = true; 1770 1771 error('Only strings and numbers are supported as <option> children.'); 1772 } 1773 }); 1774 } // TODO: Remove support for `selected` in <option>. 1775 1776 1777 if (props.selected != null && !didWarnSelectedSetOnOption) { 1778 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 1779 1780 didWarnSelectedSetOnOption = true; 1781 } 1782 } 1783 } 1784 function postMountWrapper$1(element, props) { 1785 // value="" should make a value attribute (#6219) 1786 if (props.value != null) { 1787 element.setAttribute('value', toString(getToStringValue(props.value))); 1788 } 1789 } 1790 function getHostProps$1(element, props) { 1791 var hostProps = _assign({ 1792 children: undefined 1793 }, props); 1794 1795 var content = flattenChildren(props.children); 1796 1797 if (content) { 1798 hostProps.children = content; 1799 } 1800 1801 return hostProps; 1802 } 1803 1804 var didWarnValueDefaultValue$1; 1805 1806 { 1807 didWarnValueDefaultValue$1 = false; 1808 } 1809 1810 function getDeclarationErrorAddendum() { 1811 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 1812 1813 if (ownerName) { 1814 return '\n\nCheck the render method of `' + ownerName + '`.'; 1815 } 1816 1817 return ''; 1818 } 1819 1820 var valuePropNames = ['value', 'defaultValue']; 1821 /** 1822 * Validation function for `value` and `defaultValue`. 1823 */ 1824 1825 function checkSelectPropTypes(props) { 1826 { 1827 checkControlledValueProps('select', props); 1828 1829 for (var i = 0; i < valuePropNames.length; i++) { 1830 var propName = valuePropNames[i]; 1831 1832 if (props[propName] == null) { 1833 continue; 1834 } 1835 1836 var isArray = Array.isArray(props[propName]); 1837 1838 if (props.multiple && !isArray) { 1839 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum()); 1840 } else if (!props.multiple && isArray) { 1841 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum()); 1842 } 1843 } 1844 } 1845 } 1846 1847 function updateOptions(node, multiple, propValue, setDefaultSelected) { 1848 var options = node.options; 1849 1850 if (multiple) { 1851 var selectedValues = propValue; 1852 var selectedValue = {}; 1853 1854 for (var i = 0; i < selectedValues.length; i++) { 1855 // Prefix to avoid chaos with special keys. 1856 selectedValue['$' + selectedValues[i]] = true; 1857 } 1858 1859 for (var _i = 0; _i < options.length; _i++) { 1860 var selected = selectedValue.hasOwnProperty('$' + options[_i].value); 1861 1862 if (options[_i].selected !== selected) { 1863 options[_i].selected = selected; 1864 } 1865 1866 if (selected && setDefaultSelected) { 1867 options[_i].defaultSelected = true; 1868 } 1869 } 1870 } else { 1871 // Do not set `select.value` as exact behavior isn't consistent across all 1872 // browsers for all cases. 1873 var _selectedValue = toString(getToStringValue(propValue)); 1874 1875 var defaultSelected = null; 1876 1877 for (var _i2 = 0; _i2 < options.length; _i2++) { 1878 if (options[_i2].value === _selectedValue) { 1879 options[_i2].selected = true; 1880 1881 if (setDefaultSelected) { 1882 options[_i2].defaultSelected = true; 1883 } 1884 1885 return; 1886 } 1887 1888 if (defaultSelected === null && !options[_i2].disabled) { 1889 defaultSelected = options[_i2]; 1890 } 1891 } 1892 1893 if (defaultSelected !== null) { 1894 defaultSelected.selected = true; 1895 } 1896 } 1897 } 1898 /** 1899 * Implements a <select> host component that allows optionally setting the 1900 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a 1901 * stringable. If `multiple` is true, the prop must be an array of stringables. 1902 * 1903 * If `value` is not supplied (or null/undefined), user actions that change the 1904 * selected option will trigger updates to the rendered options. 1905 * 1906 * If it is supplied (and not null/undefined), the rendered options will not 1907 * update in response to user actions. Instead, the `value` prop must change in 1908 * order for the rendered options to update. 1909 * 1910 * If `defaultValue` is provided, any options with the supplied values will be 1911 * selected. 1912 */ 1913 1914 1915 function getHostProps$2(element, props) { 1916 return _assign({}, props, { 1917 value: undefined 1918 }); 1919 } 1920 function initWrapperState$1(element, props) { 1921 var node = element; 1922 1923 { 1924 checkSelectPropTypes(props); 1925 } 1926 1927 node._wrapperState = { 1928 wasMultiple: !!props.multiple 1929 }; 1930 1931 { 1932 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { 1933 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'); 1934 1935 didWarnValueDefaultValue$1 = true; 1936 } 1937 } 1938 } 1939 function postMountWrapper$2(element, props) { 1940 var node = element; 1941 node.multiple = !!props.multiple; 1942 var value = props.value; 1943 1944 if (value != null) { 1945 updateOptions(node, !!props.multiple, value, false); 1946 } else if (props.defaultValue != null) { 1947 updateOptions(node, !!props.multiple, props.defaultValue, true); 1948 } 1949 } 1950 function postUpdateWrapper(element, props) { 1951 var node = element; 1952 var wasMultiple = node._wrapperState.wasMultiple; 1953 node._wrapperState.wasMultiple = !!props.multiple; 1954 var value = props.value; 1955 1956 if (value != null) { 1957 updateOptions(node, !!props.multiple, value, false); 1958 } else if (wasMultiple !== !!props.multiple) { 1959 // For simplicity, reapply `defaultValue` if `multiple` is toggled. 1960 if (props.defaultValue != null) { 1961 updateOptions(node, !!props.multiple, props.defaultValue, true); 1962 } else { 1963 // Revert the select back to its default unselected state. 1964 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false); 1965 } 1966 } 1967 } 1968 function restoreControlledState$1(element, props) { 1969 var node = element; 1970 var value = props.value; 1971 1972 if (value != null) { 1973 updateOptions(node, !!props.multiple, value, false); 1974 } 1975 } 1976 1977 var didWarnValDefaultVal = false; 1978 1979 /** 1980 * Implements a <textarea> host component that allows setting `value`, and 1981 * `defaultValue`. This differs from the traditional DOM API because value is 1982 * usually set as PCDATA children. 1983 * 1984 * If `value` is not supplied (or null/undefined), user actions that affect the 1985 * value will trigger updates to the element. 1986 * 1987 * If `value` is supplied (and not null/undefined), the rendered element will 1988 * not trigger updates to the element. Instead, the `value` prop must change in 1989 * order for the rendered element to be updated. 1990 * 1991 * The rendered element will be initialized with an empty value, the prop 1992 * `defaultValue` if specified, or the children content (deprecated). 1993 */ 1994 function getHostProps$3(element, props) { 1995 var node = element; 1996 1997 if (!(props.dangerouslySetInnerHTML == null)) { 1998 { 1999 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." ); 2000 } 2001 } // Always set children to the same thing. In IE9, the selection range will 2002 // get reset if `textContent` is mutated. We could add a check in setTextContent 2003 // to only set the value if/when the value differs from the node value (which would 2004 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this 2005 // solution. The value can be a boolean or object so that's why it's forced 2006 // to be a string. 2007 2008 2009 var hostProps = _assign({}, props, { 2010 value: undefined, 2011 defaultValue: undefined, 2012 children: toString(node._wrapperState.initialValue) 2013 }); 2014 2015 return hostProps; 2016 } 2017 function initWrapperState$2(element, props) { 2018 var node = element; 2019 2020 { 2021 checkControlledValueProps('textarea', props); 2022 2023 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { 2024 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'); 2025 2026 didWarnValDefaultVal = true; 2027 } 2028 } 2029 2030 var initialValue = props.value; // Only bother fetching default value if we're going to use it 2031 2032 if (initialValue == null) { 2033 var children = props.children, 2034 defaultValue = props.defaultValue; 2035 2036 if (children != null) { 2037 { 2038 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 2039 } 2040 2041 { 2042 if (!(defaultValue == null)) { 2043 { 2044 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." ); 2045 } 2046 } 2047 2048 if (Array.isArray(children)) { 2049 if (!(children.length <= 1)) { 2050 { 2051 throw Error( "<textarea> can only have at most one child." ); 2052 } 2053 } 2054 2055 children = children[0]; 2056 } 2057 2058 defaultValue = children; 2059 } 2060 } 2061 2062 if (defaultValue == null) { 2063 defaultValue = ''; 2064 } 2065 2066 initialValue = defaultValue; 2067 } 2068 2069 node._wrapperState = { 2070 initialValue: getToStringValue(initialValue) 2071 }; 2072 } 2073 function updateWrapper$1(element, props) { 2074 var node = element; 2075 var value = getToStringValue(props.value); 2076 var defaultValue = getToStringValue(props.defaultValue); 2077 2078 if (value != null) { 2079 // Cast `value` to a string to ensure the value is set correctly. While 2080 // browsers typically do this as necessary, jsdom doesn't. 2081 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed 2082 2083 if (newValue !== node.value) { 2084 node.value = newValue; 2085 } 2086 2087 if (props.defaultValue == null && node.defaultValue !== newValue) { 2088 node.defaultValue = newValue; 2089 } 2090 } 2091 2092 if (defaultValue != null) { 2093 node.defaultValue = toString(defaultValue); 2094 } 2095 } 2096 function postMountWrapper$3(element, props) { 2097 var node = element; // This is in postMount because we need access to the DOM node, which is not 2098 // available until after the component has mounted. 2099 2100 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected 2101 // initial value. In IE10/IE11 there is a bug where the placeholder attribute 2102 // will populate textContent as well. 2103 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ 2104 2105 if (textContent === node._wrapperState.initialValue) { 2106 if (textContent !== '' && textContent !== null) { 2107 node.value = textContent; 2108 } 2109 } 2110 } 2111 function restoreControlledState$2(element, props) { 2112 // DOM component is still mounted; update 2113 updateWrapper$1(element, props); 2114 } 2115 2116 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; 2117 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 2118 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; 2119 var Namespaces = { 2120 html: HTML_NAMESPACE, 2121 mathml: MATH_NAMESPACE, 2122 svg: SVG_NAMESPACE 2123 }; // Assumes there is no parent namespace. 2124 2125 function getIntrinsicNamespace(type) { 2126 switch (type) { 2127 case 'svg': 2128 return SVG_NAMESPACE; 2129 2130 case 'math': 2131 return MATH_NAMESPACE; 2132 2133 default: 2134 return HTML_NAMESPACE; 2135 } 2136 } 2137 function getChildNamespace(parentNamespace, type) { 2138 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) { 2139 // No (or default) parent namespace: potential entry point. 2140 return getIntrinsicNamespace(type); 2141 } 2142 2143 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') { 2144 // We're leaving SVG. 2145 return HTML_NAMESPACE; 2146 } // By default, pass namespace below. 2147 2148 2149 return parentNamespace; 2150 } 2151 2152 /* globals MSApp */ 2153 2154 /** 2155 * Create a function which has 'unsafe' privileges (required by windows8 apps) 2156 */ 2157 var createMicrosoftUnsafeLocalFunction = function (func) { 2158 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { 2159 return function (arg0, arg1, arg2, arg3) { 2160 MSApp.execUnsafeLocalFunction(function () { 2161 return func(arg0, arg1, arg2, arg3); 2162 }); 2163 }; 2164 } else { 2165 return func; 2166 } 2167 }; 2168 2169 var reusableSVGContainer; 2170 /** 2171 * Set the innerHTML property of a node 2172 * 2173 * @param {DOMElement} node 2174 * @param {string} html 2175 * @internal 2176 */ 2177 2178 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { 2179 if (node.namespaceURI === Namespaces.svg) { 2180 2181 if (!('innerHTML' in node)) { 2182 // IE does not have innerHTML for SVG nodes, so instead we inject the 2183 // new markup in a temp node and then move the child nodes across into 2184 // the target node 2185 reusableSVGContainer = reusableSVGContainer || document.createElement('div'); 2186 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>'; 2187 var svgNode = reusableSVGContainer.firstChild; 2188 2189 while (node.firstChild) { 2190 node.removeChild(node.firstChild); 2191 } 2192 2193 while (svgNode.firstChild) { 2194 node.appendChild(svgNode.firstChild); 2195 } 2196 2197 return; 2198 } 2199 } 2200 2201 node.innerHTML = html; 2202 }); 2203 2204 /** 2205 * HTML nodeType values that represent the type of the node 2206 */ 2207 var ELEMENT_NODE = 1; 2208 var TEXT_NODE = 3; 2209 var COMMENT_NODE = 8; 2210 var DOCUMENT_NODE = 9; 2211 var DOCUMENT_FRAGMENT_NODE = 11; 2212 2213 /** 2214 * Set the textContent property of a node. For text updates, it's faster 2215 * to set the `nodeValue` of the Text node directly instead of using 2216 * `.textContent` which will remove the existing node and create a new one. 2217 * 2218 * @param {DOMElement} node 2219 * @param {string} text 2220 * @internal 2221 */ 2222 2223 var setTextContent = function (node, text) { 2224 if (text) { 2225 var firstChild = node.firstChild; 2226 2227 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) { 2228 firstChild.nodeValue = text; 2229 return; 2230 } 2231 } 2232 2233 node.textContent = text; 2234 }; 2235 2236 // List derived from Gecko source code: 2237 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js 2238 var shorthandToLonghand = { 2239 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'], 2240 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'], 2241 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'], 2242 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'], 2243 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'], 2244 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'], 2245 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'], 2246 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'], 2247 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'], 2248 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'], 2249 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'], 2250 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'], 2251 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'], 2252 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'], 2253 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'], 2254 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'], 2255 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'], 2256 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'], 2257 columns: ['columnCount', 'columnWidth'], 2258 flex: ['flexBasis', 'flexGrow', 'flexShrink'], 2259 flexFlow: ['flexDirection', 'flexWrap'], 2260 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'], 2261 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'], 2262 gap: ['columnGap', 'rowGap'], 2263 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 2264 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'], 2265 gridColumn: ['gridColumnEnd', 'gridColumnStart'], 2266 gridColumnGap: ['columnGap'], 2267 gridGap: ['columnGap', 'rowGap'], 2268 gridRow: ['gridRowEnd', 'gridRowStart'], 2269 gridRowGap: ['rowGap'], 2270 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 2271 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'], 2272 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'], 2273 marker: ['markerEnd', 'markerMid', 'markerStart'], 2274 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'], 2275 maskPosition: ['maskPositionX', 'maskPositionY'], 2276 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'], 2277 overflow: ['overflowX', 'overflowY'], 2278 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'], 2279 placeContent: ['alignContent', 'justifyContent'], 2280 placeItems: ['alignItems', 'justifyItems'], 2281 placeSelf: ['alignSelf', 'justifySelf'], 2282 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'], 2283 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'], 2284 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'], 2285 wordWrap: ['overflowWrap'] 2286 }; 2287 2288 /** 2289 * CSS properties which accept numbers but are not in units of "px". 2290 */ 2291 var isUnitlessNumber = { 2292 animationIterationCount: true, 2293 borderImageOutset: true, 2294 borderImageSlice: true, 2295 borderImageWidth: true, 2296 boxFlex: true, 2297 boxFlexGroup: true, 2298 boxOrdinalGroup: true, 2299 columnCount: true, 2300 columns: true, 2301 flex: true, 2302 flexGrow: true, 2303 flexPositive: true, 2304 flexShrink: true, 2305 flexNegative: true, 2306 flexOrder: true, 2307 gridArea: true, 2308 gridRow: true, 2309 gridRowEnd: true, 2310 gridRowSpan: true, 2311 gridRowStart: true, 2312 gridColumn: true, 2313 gridColumnEnd: true, 2314 gridColumnSpan: true, 2315 gridColumnStart: true, 2316 fontWeight: true, 2317 lineClamp: true, 2318 lineHeight: true, 2319 opacity: true, 2320 order: true, 2321 orphans: true, 2322 tabSize: true, 2323 widows: true, 2324 zIndex: true, 2325 zoom: true, 2326 // SVG-related properties 2327 fillOpacity: true, 2328 floodOpacity: true, 2329 stopOpacity: true, 2330 strokeDasharray: true, 2331 strokeDashoffset: true, 2332 strokeMiterlimit: true, 2333 strokeOpacity: true, 2334 strokeWidth: true 2335 }; 2336 /** 2337 * @param {string} prefix vendor-specific prefix, eg: Webkit 2338 * @param {string} key style name, eg: transitionDuration 2339 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 2340 * WebkitTransitionDuration 2341 */ 2342 2343 function prefixKey(prefix, key) { 2344 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 2345 } 2346 /** 2347 * Support style names that may come passed in prefixed by adding permutations 2348 * of vendor prefixes. 2349 */ 2350 2351 2352 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 2353 // infinite loop, because it iterates over the newly added props too. 2354 2355 Object.keys(isUnitlessNumber).forEach(function (prop) { 2356 prefixes.forEach(function (prefix) { 2357 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 2358 }); 2359 }); 2360 2361 /** 2362 * Convert a value into the proper css writable value. The style name `name` 2363 * should be logical (no hyphens), as specified 2364 * in `CSSProperty.isUnitlessNumber`. 2365 * 2366 * @param {string} name CSS property name such as `topMargin`. 2367 * @param {*} value CSS property value such as `10px`. 2368 * @return {string} Normalized style value with dimensions applied. 2369 */ 2370 2371 function dangerousStyleValue(name, value, isCustomProperty) { 2372 // Note that we've removed escapeTextForBrowser() calls here since the 2373 // whole string will be escaped when the attribute is injected into 2374 // the markup. If you provide unsafe user data here they can inject 2375 // arbitrary CSS which may be problematic (I couldn't repro this): 2376 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 2377 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 2378 // This is not an XSS hole but instead a potential CSS injection issue 2379 // which has lead to a greater discussion about how we're going to 2380 // trust URLs moving forward. See #2115901 2381 var isEmpty = value == null || typeof value === 'boolean' || value === ''; 2382 2383 if (isEmpty) { 2384 return ''; 2385 } 2386 2387 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) { 2388 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers 2389 } 2390 2391 return ('' + value).trim(); 2392 } 2393 2394 var uppercasePattern = /([A-Z])/g; 2395 var msPattern = /^ms-/; 2396 /** 2397 * Hyphenates a camelcased CSS property name, for example: 2398 * 2399 * > hyphenateStyleName('backgroundColor') 2400 * < "background-color" 2401 * > hyphenateStyleName('MozTransition') 2402 * < "-moz-transition" 2403 * > hyphenateStyleName('msTransition') 2404 * < "-ms-transition" 2405 * 2406 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 2407 * is converted to `-ms-`. 2408 */ 2409 2410 function hyphenateStyleName(name) { 2411 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); 2412 } 2413 2414 var warnValidStyle = function () {}; 2415 2416 { 2417 // 'msTransform' is correct, but the other prefixes should be capitalized 2418 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 2419 var msPattern$1 = /^-ms-/; 2420 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon 2421 2422 var badStyleValueWithSemicolonPattern = /;\s*$/; 2423 var warnedStyleNames = {}; 2424 var warnedStyleValues = {}; 2425 var warnedForNaNValue = false; 2426 var warnedForInfinityValue = false; 2427 2428 var camelize = function (string) { 2429 return string.replace(hyphenPattern, function (_, character) { 2430 return character.toUpperCase(); 2431 }); 2432 }; 2433 2434 var warnHyphenatedStyleName = function (name) { 2435 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 2436 return; 2437 } 2438 2439 warnedStyleNames[name] = true; 2440 2441 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests 2442 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 2443 // is converted to lowercase `ms`. 2444 camelize(name.replace(msPattern$1, 'ms-'))); 2445 }; 2446 2447 var warnBadVendoredStyleName = function (name) { 2448 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 2449 return; 2450 } 2451 2452 warnedStyleNames[name] = true; 2453 2454 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 2455 }; 2456 2457 var warnStyleValueWithSemicolon = function (name, value) { 2458 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 2459 return; 2460 } 2461 2462 warnedStyleValues[value] = true; 2463 2464 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 2465 }; 2466 2467 var warnStyleValueIsNaN = function (name, value) { 2468 if (warnedForNaNValue) { 2469 return; 2470 } 2471 2472 warnedForNaNValue = true; 2473 2474 error('`NaN` is an invalid value for the `%s` css style property.', name); 2475 }; 2476 2477 var warnStyleValueIsInfinity = function (name, value) { 2478 if (warnedForInfinityValue) { 2479 return; 2480 } 2481 2482 warnedForInfinityValue = true; 2483 2484 error('`Infinity` is an invalid value for the `%s` css style property.', name); 2485 }; 2486 2487 warnValidStyle = function (name, value) { 2488 if (name.indexOf('-') > -1) { 2489 warnHyphenatedStyleName(name); 2490 } else if (badVendoredStyleNamePattern.test(name)) { 2491 warnBadVendoredStyleName(name); 2492 } else if (badStyleValueWithSemicolonPattern.test(value)) { 2493 warnStyleValueWithSemicolon(name, value); 2494 } 2495 2496 if (typeof value === 'number') { 2497 if (isNaN(value)) { 2498 warnStyleValueIsNaN(name, value); 2499 } else if (!isFinite(value)) { 2500 warnStyleValueIsInfinity(name, value); 2501 } 2502 } 2503 }; 2504 } 2505 2506 var warnValidStyle$1 = warnValidStyle; 2507 2508 /** 2509 * Operations for dealing with CSS properties. 2510 */ 2511 2512 /** 2513 * This creates a string that is expected to be equivalent to the style 2514 * attribute generated by server-side rendering. It by-passes warnings and 2515 * security checks so it's not safe to use this value for anything other than 2516 * comparison. It is only used in DEV for SSR validation. 2517 */ 2518 2519 function createDangerousStringForStyles(styles) { 2520 { 2521 var serialized = ''; 2522 var delimiter = ''; 2523 2524 for (var styleName in styles) { 2525 if (!styles.hasOwnProperty(styleName)) { 2526 continue; 2527 } 2528 2529 var styleValue = styles[styleName]; 2530 2531 if (styleValue != null) { 2532 var isCustomProperty = styleName.indexOf('--') === 0; 2533 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':'; 2534 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty); 2535 delimiter = ';'; 2536 } 2537 } 2538 2539 return serialized || null; 2540 } 2541 } 2542 /** 2543 * Sets the value for multiple styles on a node. If a value is specified as 2544 * '' (empty string), the corresponding style property will be unset. 2545 * 2546 * @param {DOMElement} node 2547 * @param {object} styles 2548 */ 2549 2550 function setValueForStyles(node, styles) { 2551 var style = node.style; 2552 2553 for (var styleName in styles) { 2554 if (!styles.hasOwnProperty(styleName)) { 2555 continue; 2556 } 2557 2558 var isCustomProperty = styleName.indexOf('--') === 0; 2559 2560 { 2561 if (!isCustomProperty) { 2562 warnValidStyle$1(styleName, styles[styleName]); 2563 } 2564 } 2565 2566 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty); 2567 2568 if (styleName === 'float') { 2569 styleName = 'cssFloat'; 2570 } 2571 2572 if (isCustomProperty) { 2573 style.setProperty(styleName, styleValue); 2574 } else { 2575 style[styleName] = styleValue; 2576 } 2577 } 2578 } 2579 2580 function isValueEmpty(value) { 2581 return value == null || typeof value === 'boolean' || value === ''; 2582 } 2583 /** 2584 * Given {color: 'red', overflow: 'hidden'} returns { 2585 * color: 'color', 2586 * overflowX: 'overflow', 2587 * overflowY: 'overflow', 2588 * }. This can be read as "the overflowY property was set by the overflow 2589 * shorthand". That is, the values are the property that each was derived from. 2590 */ 2591 2592 2593 function expandShorthandMap(styles) { 2594 var expanded = {}; 2595 2596 for (var key in styles) { 2597 var longhands = shorthandToLonghand[key] || [key]; 2598 2599 for (var i = 0; i < longhands.length; i++) { 2600 expanded[longhands[i]] = key; 2601 } 2602 } 2603 2604 return expanded; 2605 } 2606 /** 2607 * When mixing shorthand and longhand property names, we warn during updates if 2608 * we expect an incorrect result to occur. In particular, we warn for: 2609 * 2610 * Updating a shorthand property (longhand gets overwritten): 2611 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'} 2612 * becomes .style.font = 'baz' 2613 * Removing a shorthand property (longhand gets lost too): 2614 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'} 2615 * becomes .style.font = '' 2616 * Removing a longhand property (should revert to shorthand; doesn't): 2617 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'} 2618 * becomes .style.fontVariant = '' 2619 */ 2620 2621 2622 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) { 2623 { 2624 if (!nextStyles) { 2625 return; 2626 } 2627 2628 var expandedUpdates = expandShorthandMap(styleUpdates); 2629 var expandedStyles = expandShorthandMap(nextStyles); 2630 var warnedAbout = {}; 2631 2632 for (var key in expandedUpdates) { 2633 var originalKey = expandedUpdates[key]; 2634 var correctOriginalKey = expandedStyles[key]; 2635 2636 if (correctOriginalKey && originalKey !== correctOriginalKey) { 2637 var warningKey = originalKey + ',' + correctOriginalKey; 2638 2639 if (warnedAbout[warningKey]) { 2640 continue; 2641 } 2642 2643 warnedAbout[warningKey] = true; 2644 2645 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); 2646 } 2647 } 2648 } 2649 } 2650 2651 // For HTML, certain tags should omit their close tag. We keep a list for 2652 // those special-case tags. 2653 var omittedCloseTags = { 2654 area: true, 2655 base: true, 2656 br: true, 2657 col: true, 2658 embed: true, 2659 hr: true, 2660 img: true, 2661 input: true, 2662 keygen: true, 2663 link: true, 2664 meta: true, 2665 param: true, 2666 source: true, 2667 track: true, 2668 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems. 2669 2670 }; 2671 2672 // `omittedCloseTags` except that `menuitem` should still have its closing tag. 2673 2674 var voidElementTags = _assign({ 2675 menuitem: true 2676 }, omittedCloseTags); 2677 2678 var HTML = '__html'; 2679 2680 function assertValidProps(tag, props) { 2681 if (!props) { 2682 return; 2683 } // Note the use of `==` which checks for null or undefined. 2684 2685 2686 if (voidElementTags[tag]) { 2687 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) { 2688 { 2689 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." ); 2690 } 2691 } 2692 } 2693 2694 if (props.dangerouslySetInnerHTML != null) { 2695 if (!(props.children == null)) { 2696 { 2697 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." ); 2698 } 2699 } 2700 2701 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) { 2702 { 2703 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://reactjs.org/link/dangerously-set-inner-html for more information." ); 2704 } 2705 } 2706 } 2707 2708 { 2709 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) { 2710 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.'); 2711 } 2712 } 2713 2714 if (!(props.style == null || typeof props.style === 'object')) { 2715 { 2716 throw Error( "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." ); 2717 } 2718 } 2719 } 2720 2721 function isCustomComponent(tagName, props) { 2722 if (tagName.indexOf('-') === -1) { 2723 return typeof props.is === 'string'; 2724 } 2725 2726 switch (tagName) { 2727 // These are reserved SVG and MathML elements. 2728 // We don't mind this list too much because we expect it to never grow. 2729 // The alternative is to track the namespace in a few places which is convoluted. 2730 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 2731 case 'annotation-xml': 2732 case 'color-profile': 2733 case 'font-face': 2734 case 'font-face-src': 2735 case 'font-face-uri': 2736 case 'font-face-format': 2737 case 'font-face-name': 2738 case 'missing-glyph': 2739 return false; 2740 2741 default: 2742 return true; 2743 } 2744 } 2745 2746 // When adding attributes to the HTML or SVG allowed attribute list, be sure to 2747 // also add them to this module to ensure casing and incorrect name 2748 // warnings. 2749 var possibleStandardNames = { 2750 // HTML 2751 accept: 'accept', 2752 acceptcharset: 'acceptCharset', 2753 'accept-charset': 'acceptCharset', 2754 accesskey: 'accessKey', 2755 action: 'action', 2756 allowfullscreen: 'allowFullScreen', 2757 alt: 'alt', 2758 as: 'as', 2759 async: 'async', 2760 autocapitalize: 'autoCapitalize', 2761 autocomplete: 'autoComplete', 2762 autocorrect: 'autoCorrect', 2763 autofocus: 'autoFocus', 2764 autoplay: 'autoPlay', 2765 autosave: 'autoSave', 2766 capture: 'capture', 2767 cellpadding: 'cellPadding', 2768 cellspacing: 'cellSpacing', 2769 challenge: 'challenge', 2770 charset: 'charSet', 2771 checked: 'checked', 2772 children: 'children', 2773 cite: 'cite', 2774 class: 'className', 2775 classid: 'classID', 2776 classname: 'className', 2777 cols: 'cols', 2778 colspan: 'colSpan', 2779 content: 'content', 2780 contenteditable: 'contentEditable', 2781 contextmenu: 'contextMenu', 2782 controls: 'controls', 2783 controlslist: 'controlsList', 2784 coords: 'coords', 2785 crossorigin: 'crossOrigin', 2786 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 2787 data: 'data', 2788 datetime: 'dateTime', 2789 default: 'default', 2790 defaultchecked: 'defaultChecked', 2791 defaultvalue: 'defaultValue', 2792 defer: 'defer', 2793 dir: 'dir', 2794 disabled: 'disabled', 2795 disablepictureinpicture: 'disablePictureInPicture', 2796 disableremoteplayback: 'disableRemotePlayback', 2797 download: 'download', 2798 draggable: 'draggable', 2799 enctype: 'encType', 2800 enterkeyhint: 'enterKeyHint', 2801 for: 'htmlFor', 2802 form: 'form', 2803 formmethod: 'formMethod', 2804 formaction: 'formAction', 2805 formenctype: 'formEncType', 2806 formnovalidate: 'formNoValidate', 2807 formtarget: 'formTarget', 2808 frameborder: 'frameBorder', 2809 headers: 'headers', 2810 height: 'height', 2811 hidden: 'hidden', 2812 high: 'high', 2813 href: 'href', 2814 hreflang: 'hrefLang', 2815 htmlfor: 'htmlFor', 2816 httpequiv: 'httpEquiv', 2817 'http-equiv': 'httpEquiv', 2818 icon: 'icon', 2819 id: 'id', 2820 innerhtml: 'innerHTML', 2821 inputmode: 'inputMode', 2822 integrity: 'integrity', 2823 is: 'is', 2824 itemid: 'itemID', 2825 itemprop: 'itemProp', 2826 itemref: 'itemRef', 2827 itemscope: 'itemScope', 2828 itemtype: 'itemType', 2829 keyparams: 'keyParams', 2830 keytype: 'keyType', 2831 kind: 'kind', 2832 label: 'label', 2833 lang: 'lang', 2834 list: 'list', 2835 loop: 'loop', 2836 low: 'low', 2837 manifest: 'manifest', 2838 marginwidth: 'marginWidth', 2839 marginheight: 'marginHeight', 2840 max: 'max', 2841 maxlength: 'maxLength', 2842 media: 'media', 2843 mediagroup: 'mediaGroup', 2844 method: 'method', 2845 min: 'min', 2846 minlength: 'minLength', 2847 multiple: 'multiple', 2848 muted: 'muted', 2849 name: 'name', 2850 nomodule: 'noModule', 2851 nonce: 'nonce', 2852 novalidate: 'noValidate', 2853 open: 'open', 2854 optimum: 'optimum', 2855 pattern: 'pattern', 2856 placeholder: 'placeholder', 2857 playsinline: 'playsInline', 2858 poster: 'poster', 2859 preload: 'preload', 2860 profile: 'profile', 2861 radiogroup: 'radioGroup', 2862 readonly: 'readOnly', 2863 referrerpolicy: 'referrerPolicy', 2864 rel: 'rel', 2865 required: 'required', 2866 reversed: 'reversed', 2867 role: 'role', 2868 rows: 'rows', 2869 rowspan: 'rowSpan', 2870 sandbox: 'sandbox', 2871 scope: 'scope', 2872 scoped: 'scoped', 2873 scrolling: 'scrolling', 2874 seamless: 'seamless', 2875 selected: 'selected', 2876 shape: 'shape', 2877 size: 'size', 2878 sizes: 'sizes', 2879 span: 'span', 2880 spellcheck: 'spellCheck', 2881 src: 'src', 2882 srcdoc: 'srcDoc', 2883 srclang: 'srcLang', 2884 srcset: 'srcSet', 2885 start: 'start', 2886 step: 'step', 2887 style: 'style', 2888 summary: 'summary', 2889 tabindex: 'tabIndex', 2890 target: 'target', 2891 title: 'title', 2892 type: 'type', 2893 usemap: 'useMap', 2894 value: 'value', 2895 width: 'width', 2896 wmode: 'wmode', 2897 wrap: 'wrap', 2898 // SVG 2899 about: 'about', 2900 accentheight: 'accentHeight', 2901 'accent-height': 'accentHeight', 2902 accumulate: 'accumulate', 2903 additive: 'additive', 2904 alignmentbaseline: 'alignmentBaseline', 2905 'alignment-baseline': 'alignmentBaseline', 2906 allowreorder: 'allowReorder', 2907 alphabetic: 'alphabetic', 2908 amplitude: 'amplitude', 2909 arabicform: 'arabicForm', 2910 'arabic-form': 'arabicForm', 2911 ascent: 'ascent', 2912 attributename: 'attributeName', 2913 attributetype: 'attributeType', 2914 autoreverse: 'autoReverse', 2915 azimuth: 'azimuth', 2916 basefrequency: 'baseFrequency', 2917 baselineshift: 'baselineShift', 2918 'baseline-shift': 'baselineShift', 2919 baseprofile: 'baseProfile', 2920 bbox: 'bbox', 2921 begin: 'begin', 2922 bias: 'bias', 2923 by: 'by', 2924 calcmode: 'calcMode', 2925 capheight: 'capHeight', 2926 'cap-height': 'capHeight', 2927 clip: 'clip', 2928 clippath: 'clipPath', 2929 'clip-path': 'clipPath', 2930 clippathunits: 'clipPathUnits', 2931 cliprule: 'clipRule', 2932 'clip-rule': 'clipRule', 2933 color: 'color', 2934 colorinterpolation: 'colorInterpolation', 2935 'color-interpolation': 'colorInterpolation', 2936 colorinterpolationfilters: 'colorInterpolationFilters', 2937 'color-interpolation-filters': 'colorInterpolationFilters', 2938 colorprofile: 'colorProfile', 2939 'color-profile': 'colorProfile', 2940 colorrendering: 'colorRendering', 2941 'color-rendering': 'colorRendering', 2942 contentscripttype: 'contentScriptType', 2943 contentstyletype: 'contentStyleType', 2944 cursor: 'cursor', 2945 cx: 'cx', 2946 cy: 'cy', 2947 d: 'd', 2948 datatype: 'datatype', 2949 decelerate: 'decelerate', 2950 descent: 'descent', 2951 diffuseconstant: 'diffuseConstant', 2952 direction: 'direction', 2953 display: 'display', 2954 divisor: 'divisor', 2955 dominantbaseline: 'dominantBaseline', 2956 'dominant-baseline': 'dominantBaseline', 2957 dur: 'dur', 2958 dx: 'dx', 2959 dy: 'dy', 2960 edgemode: 'edgeMode', 2961 elevation: 'elevation', 2962 enablebackground: 'enableBackground', 2963 'enable-background': 'enableBackground', 2964 end: 'end', 2965 exponent: 'exponent', 2966 externalresourcesrequired: 'externalResourcesRequired', 2967 fill: 'fill', 2968 fillopacity: 'fillOpacity', 2969 'fill-opacity': 'fillOpacity', 2970 fillrule: 'fillRule', 2971 'fill-rule': 'fillRule', 2972 filter: 'filter', 2973 filterres: 'filterRes', 2974 filterunits: 'filterUnits', 2975 floodopacity: 'floodOpacity', 2976 'flood-opacity': 'floodOpacity', 2977 floodcolor: 'floodColor', 2978 'flood-color': 'floodColor', 2979 focusable: 'focusable', 2980 fontfamily: 'fontFamily', 2981 'font-family': 'fontFamily', 2982 fontsize: 'fontSize', 2983 'font-size': 'fontSize', 2984 fontsizeadjust: 'fontSizeAdjust', 2985 'font-size-adjust': 'fontSizeAdjust', 2986 fontstretch: 'fontStretch', 2987 'font-stretch': 'fontStretch', 2988 fontstyle: 'fontStyle', 2989 'font-style': 'fontStyle', 2990 fontvariant: 'fontVariant', 2991 'font-variant': 'fontVariant', 2992 fontweight: 'fontWeight', 2993 'font-weight': 'fontWeight', 2994 format: 'format', 2995 from: 'from', 2996 fx: 'fx', 2997 fy: 'fy', 2998 g1: 'g1', 2999 g2: 'g2', 3000 glyphname: 'glyphName', 3001 'glyph-name': 'glyphName', 3002 glyphorientationhorizontal: 'glyphOrientationHorizontal', 3003 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 3004 glyphorientationvertical: 'glyphOrientationVertical', 3005 'glyph-orientation-vertical': 'glyphOrientationVertical', 3006 glyphref: 'glyphRef', 3007 gradienttransform: 'gradientTransform', 3008 gradientunits: 'gradientUnits', 3009 hanging: 'hanging', 3010 horizadvx: 'horizAdvX', 3011 'horiz-adv-x': 'horizAdvX', 3012 horizoriginx: 'horizOriginX', 3013 'horiz-origin-x': 'horizOriginX', 3014 ideographic: 'ideographic', 3015 imagerendering: 'imageRendering', 3016 'image-rendering': 'imageRendering', 3017 in2: 'in2', 3018 in: 'in', 3019 inlist: 'inlist', 3020 intercept: 'intercept', 3021 k1: 'k1', 3022 k2: 'k2', 3023 k3: 'k3', 3024 k4: 'k4', 3025 k: 'k', 3026 kernelmatrix: 'kernelMatrix', 3027 kernelunitlength: 'kernelUnitLength', 3028 kerning: 'kerning', 3029 keypoints: 'keyPoints', 3030 keysplines: 'keySplines', 3031 keytimes: 'keyTimes', 3032 lengthadjust: 'lengthAdjust', 3033 letterspacing: 'letterSpacing', 3034 'letter-spacing': 'letterSpacing', 3035 lightingcolor: 'lightingColor', 3036 'lighting-color': 'lightingColor', 3037 limitingconeangle: 'limitingConeAngle', 3038 local: 'local', 3039 markerend: 'markerEnd', 3040 'marker-end': 'markerEnd', 3041 markerheight: 'markerHeight', 3042 markermid: 'markerMid', 3043 'marker-mid': 'markerMid', 3044 markerstart: 'markerStart', 3045 'marker-start': 'markerStart', 3046 markerunits: 'markerUnits', 3047 markerwidth: 'markerWidth', 3048 mask: 'mask', 3049 maskcontentunits: 'maskContentUnits', 3050 maskunits: 'maskUnits', 3051 mathematical: 'mathematical', 3052 mode: 'mode', 3053 numoctaves: 'numOctaves', 3054 offset: 'offset', 3055 opacity: 'opacity', 3056 operator: 'operator', 3057 order: 'order', 3058 orient: 'orient', 3059 orientation: 'orientation', 3060 origin: 'origin', 3061 overflow: 'overflow', 3062 overlineposition: 'overlinePosition', 3063 'overline-position': 'overlinePosition', 3064 overlinethickness: 'overlineThickness', 3065 'overline-thickness': 'overlineThickness', 3066 paintorder: 'paintOrder', 3067 'paint-order': 'paintOrder', 3068 panose1: 'panose1', 3069 'panose-1': 'panose1', 3070 pathlength: 'pathLength', 3071 patterncontentunits: 'patternContentUnits', 3072 patterntransform: 'patternTransform', 3073 patternunits: 'patternUnits', 3074 pointerevents: 'pointerEvents', 3075 'pointer-events': 'pointerEvents', 3076 points: 'points', 3077 pointsatx: 'pointsAtX', 3078 pointsaty: 'pointsAtY', 3079 pointsatz: 'pointsAtZ', 3080 prefix: 'prefix', 3081 preservealpha: 'preserveAlpha', 3082 preserveaspectratio: 'preserveAspectRatio', 3083 primitiveunits: 'primitiveUnits', 3084 property: 'property', 3085 r: 'r', 3086 radius: 'radius', 3087 refx: 'refX', 3088 refy: 'refY', 3089 renderingintent: 'renderingIntent', 3090 'rendering-intent': 'renderingIntent', 3091 repeatcount: 'repeatCount', 3092 repeatdur: 'repeatDur', 3093 requiredextensions: 'requiredExtensions', 3094 requiredfeatures: 'requiredFeatures', 3095 resource: 'resource', 3096 restart: 'restart', 3097 result: 'result', 3098 results: 'results', 3099 rotate: 'rotate', 3100 rx: 'rx', 3101 ry: 'ry', 3102 scale: 'scale', 3103 security: 'security', 3104 seed: 'seed', 3105 shaperendering: 'shapeRendering', 3106 'shape-rendering': 'shapeRendering', 3107 slope: 'slope', 3108 spacing: 'spacing', 3109 specularconstant: 'specularConstant', 3110 specularexponent: 'specularExponent', 3111 speed: 'speed', 3112 spreadmethod: 'spreadMethod', 3113 startoffset: 'startOffset', 3114 stddeviation: 'stdDeviation', 3115 stemh: 'stemh', 3116 stemv: 'stemv', 3117 stitchtiles: 'stitchTiles', 3118 stopcolor: 'stopColor', 3119 'stop-color': 'stopColor', 3120 stopopacity: 'stopOpacity', 3121 'stop-opacity': 'stopOpacity', 3122 strikethroughposition: 'strikethroughPosition', 3123 'strikethrough-position': 'strikethroughPosition', 3124 strikethroughthickness: 'strikethroughThickness', 3125 'strikethrough-thickness': 'strikethroughThickness', 3126 string: 'string', 3127 stroke: 'stroke', 3128 strokedasharray: 'strokeDasharray', 3129 'stroke-dasharray': 'strokeDasharray', 3130 strokedashoffset: 'strokeDashoffset', 3131 'stroke-dashoffset': 'strokeDashoffset', 3132 strokelinecap: 'strokeLinecap', 3133 'stroke-linecap': 'strokeLinecap', 3134 strokelinejoin: 'strokeLinejoin', 3135 'stroke-linejoin': 'strokeLinejoin', 3136 strokemiterlimit: 'strokeMiterlimit', 3137 'stroke-miterlimit': 'strokeMiterlimit', 3138 strokewidth: 'strokeWidth', 3139 'stroke-width': 'strokeWidth', 3140 strokeopacity: 'strokeOpacity', 3141 'stroke-opacity': 'strokeOpacity', 3142 suppresscontenteditablewarning: 'suppressContentEditableWarning', 3143 suppresshydrationwarning: 'suppressHydrationWarning', 3144 surfacescale: 'surfaceScale', 3145 systemlanguage: 'systemLanguage', 3146 tablevalues: 'tableValues', 3147 targetx: 'targetX', 3148 targety: 'targetY', 3149 textanchor: 'textAnchor', 3150 'text-anchor': 'textAnchor', 3151 textdecoration: 'textDecoration', 3152 'text-decoration': 'textDecoration', 3153 textlength: 'textLength', 3154 textrendering: 'textRendering', 3155 'text-rendering': 'textRendering', 3156 to: 'to', 3157 transform: 'transform', 3158 typeof: 'typeof', 3159 u1: 'u1', 3160 u2: 'u2', 3161 underlineposition: 'underlinePosition', 3162 'underline-position': 'underlinePosition', 3163 underlinethickness: 'underlineThickness', 3164 'underline-thickness': 'underlineThickness', 3165 unicode: 'unicode', 3166 unicodebidi: 'unicodeBidi', 3167 'unicode-bidi': 'unicodeBidi', 3168 unicoderange: 'unicodeRange', 3169 'unicode-range': 'unicodeRange', 3170 unitsperem: 'unitsPerEm', 3171 'units-per-em': 'unitsPerEm', 3172 unselectable: 'unselectable', 3173 valphabetic: 'vAlphabetic', 3174 'v-alphabetic': 'vAlphabetic', 3175 values: 'values', 3176 vectoreffect: 'vectorEffect', 3177 'vector-effect': 'vectorEffect', 3178 version: 'version', 3179 vertadvy: 'vertAdvY', 3180 'vert-adv-y': 'vertAdvY', 3181 vertoriginx: 'vertOriginX', 3182 'vert-origin-x': 'vertOriginX', 3183 vertoriginy: 'vertOriginY', 3184 'vert-origin-y': 'vertOriginY', 3185 vhanging: 'vHanging', 3186 'v-hanging': 'vHanging', 3187 videographic: 'vIdeographic', 3188 'v-ideographic': 'vIdeographic', 3189 viewbox: 'viewBox', 3190 viewtarget: 'viewTarget', 3191 visibility: 'visibility', 3192 vmathematical: 'vMathematical', 3193 'v-mathematical': 'vMathematical', 3194 vocab: 'vocab', 3195 widths: 'widths', 3196 wordspacing: 'wordSpacing', 3197 'word-spacing': 'wordSpacing', 3198 writingmode: 'writingMode', 3199 'writing-mode': 'writingMode', 3200 x1: 'x1', 3201 x2: 'x2', 3202 x: 'x', 3203 xchannelselector: 'xChannelSelector', 3204 xheight: 'xHeight', 3205 'x-height': 'xHeight', 3206 xlinkactuate: 'xlinkActuate', 3207 'xlink:actuate': 'xlinkActuate', 3208 xlinkarcrole: 'xlinkArcrole', 3209 'xlink:arcrole': 'xlinkArcrole', 3210 xlinkhref: 'xlinkHref', 3211 'xlink:href': 'xlinkHref', 3212 xlinkrole: 'xlinkRole', 3213 'xlink:role': 'xlinkRole', 3214 xlinkshow: 'xlinkShow', 3215 'xlink:show': 'xlinkShow', 3216 xlinktitle: 'xlinkTitle', 3217 'xlink:title': 'xlinkTitle', 3218 xlinktype: 'xlinkType', 3219 'xlink:type': 'xlinkType', 3220 xmlbase: 'xmlBase', 3221 'xml:base': 'xmlBase', 3222 xmllang: 'xmlLang', 3223 'xml:lang': 'xmlLang', 3224 xmlns: 'xmlns', 3225 'xml:space': 'xmlSpace', 3226 xmlnsxlink: 'xmlnsXlink', 3227 'xmlns:xlink': 'xmlnsXlink', 3228 xmlspace: 'xmlSpace', 3229 y1: 'y1', 3230 y2: 'y2', 3231 y: 'y', 3232 ychannelselector: 'yChannelSelector', 3233 z: 'z', 3234 zoomandpan: 'zoomAndPan' 3235 }; 3236 3237 var ariaProperties = { 3238 'aria-current': 0, 3239 // state 3240 'aria-details': 0, 3241 'aria-disabled': 0, 3242 // state 3243 'aria-hidden': 0, 3244 // state 3245 'aria-invalid': 0, 3246 // state 3247 'aria-keyshortcuts': 0, 3248 'aria-label': 0, 3249 'aria-roledescription': 0, 3250 // Widget Attributes 3251 'aria-autocomplete': 0, 3252 'aria-checked': 0, 3253 'aria-expanded': 0, 3254 'aria-haspopup': 0, 3255 'aria-level': 0, 3256 'aria-modal': 0, 3257 'aria-multiline': 0, 3258 'aria-multiselectable': 0, 3259 'aria-orientation': 0, 3260 'aria-placeholder': 0, 3261 'aria-pressed': 0, 3262 'aria-readonly': 0, 3263 'aria-required': 0, 3264 'aria-selected': 0, 3265 'aria-sort': 0, 3266 'aria-valuemax': 0, 3267 'aria-valuemin': 0, 3268 'aria-valuenow': 0, 3269 'aria-valuetext': 0, 3270 // Live Region Attributes 3271 'aria-atomic': 0, 3272 'aria-busy': 0, 3273 'aria-live': 0, 3274 'aria-relevant': 0, 3275 // Drag-and-Drop Attributes 3276 'aria-dropeffect': 0, 3277 'aria-grabbed': 0, 3278 // Relationship Attributes 3279 'aria-activedescendant': 0, 3280 'aria-colcount': 0, 3281 'aria-colindex': 0, 3282 'aria-colspan': 0, 3283 'aria-controls': 0, 3284 'aria-describedby': 0, 3285 'aria-errormessage': 0, 3286 'aria-flowto': 0, 3287 'aria-labelledby': 0, 3288 'aria-owns': 0, 3289 'aria-posinset': 0, 3290 'aria-rowcount': 0, 3291 'aria-rowindex': 0, 3292 'aria-rowspan': 0, 3293 'aria-setsize': 0 3294 }; 3295 3296 var warnedProperties = {}; 3297 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 3298 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 3299 var hasOwnProperty$1 = Object.prototype.hasOwnProperty; 3300 3301 function validateProperty(tagName, name) { 3302 { 3303 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) { 3304 return true; 3305 } 3306 3307 if (rARIACamel.test(name)) { 3308 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 3309 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM 3310 // DOM properties, then it is an invalid aria-* attribute. 3311 3312 if (correctName == null) { 3313 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 3314 3315 warnedProperties[name] = true; 3316 return true; 3317 } // aria-* attributes should be lowercase; suggest the lowercase version. 3318 3319 3320 if (name !== correctName) { 3321 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 3322 3323 warnedProperties[name] = true; 3324 return true; 3325 } 3326 } 3327 3328 if (rARIA.test(name)) { 3329 var lowerCasedName = name.toLowerCase(); 3330 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM 3331 // DOM properties, then it is an invalid aria-* attribute. 3332 3333 if (standardName == null) { 3334 warnedProperties[name] = true; 3335 return false; 3336 } // aria-* attributes should be lowercase; suggest the lowercase version. 3337 3338 3339 if (name !== standardName) { 3340 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 3341 3342 warnedProperties[name] = true; 3343 return true; 3344 } 3345 } 3346 } 3347 3348 return true; 3349 } 3350 3351 function warnInvalidARIAProps(type, props) { 3352 { 3353 var invalidProps = []; 3354 3355 for (var key in props) { 3356 var isValid = validateProperty(type, key); 3357 3358 if (!isValid) { 3359 invalidProps.push(key); 3360 } 3361 } 3362 3363 var unknownPropString = invalidProps.map(function (prop) { 3364 return '`' + prop + '`'; 3365 }).join(', '); 3366 3367 if (invalidProps.length === 1) { 3368 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 3369 } else if (invalidProps.length > 1) { 3370 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 3371 } 3372 } 3373 } 3374 3375 function validateProperties(type, props) { 3376 if (isCustomComponent(type, props)) { 3377 return; 3378 } 3379 3380 warnInvalidARIAProps(type, props); 3381 } 3382 3383 var didWarnValueNull = false; 3384 function validateProperties$1(type, props) { 3385 { 3386 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 3387 return; 3388 } 3389 3390 if (props != null && props.value === null && !didWarnValueNull) { 3391 didWarnValueNull = true; 3392 3393 if (type === 'select' && props.multiple) { 3394 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); 3395 } else { 3396 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); 3397 } 3398 } 3399 } 3400 } 3401 3402 var validateProperty$1 = function () {}; 3403 3404 { 3405 var warnedProperties$1 = {}; 3406 var _hasOwnProperty = Object.prototype.hasOwnProperty; 3407 var EVENT_NAME_REGEX = /^on./; 3408 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 3409 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 3410 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 3411 3412 validateProperty$1 = function (tagName, name, value, eventRegistry) { 3413 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 3414 return true; 3415 } 3416 3417 var lowerCasedName = name.toLowerCase(); 3418 3419 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 3420 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.'); 3421 3422 warnedProperties$1[name] = true; 3423 return true; 3424 } // We can't rely on the event system being injected on the server. 3425 3426 3427 if (eventRegistry != null) { 3428 var registrationNameDependencies = eventRegistry.registrationNameDependencies, 3429 possibleRegistrationNames = eventRegistry.possibleRegistrationNames; 3430 3431 if (registrationNameDependencies.hasOwnProperty(name)) { 3432 return true; 3433 } 3434 3435 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 3436 3437 if (registrationName != null) { 3438 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 3439 3440 warnedProperties$1[name] = true; 3441 return true; 3442 } 3443 3444 if (EVENT_NAME_REGEX.test(name)) { 3445 error('Unknown event handler property `%s`. It will be ignored.', name); 3446 3447 warnedProperties$1[name] = true; 3448 return true; 3449 } 3450 } else if (EVENT_NAME_REGEX.test(name)) { 3451 // If no event plugins have been injected, we are in a server environment. 3452 // So we can't tell if the event name is correct for sure, but we can filter 3453 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 3454 if (INVALID_EVENT_NAME_REGEX.test(name)) { 3455 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 3456 } 3457 3458 warnedProperties$1[name] = true; 3459 return true; 3460 } // Let the ARIA attribute hook validate ARIA attributes 3461 3462 3463 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 3464 return true; 3465 } 3466 3467 if (lowerCasedName === 'innerhtml') { 3468 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 3469 3470 warnedProperties$1[name] = true; 3471 return true; 3472 } 3473 3474 if (lowerCasedName === 'aria') { 3475 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 3476 3477 warnedProperties$1[name] = true; 3478 return true; 3479 } 3480 3481 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 3482 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 3483 3484 warnedProperties$1[name] = true; 3485 return true; 3486 } 3487 3488 if (typeof value === 'number' && isNaN(value)) { 3489 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 3490 3491 warnedProperties$1[name] = true; 3492 return true; 3493 } 3494 3495 var propertyInfo = getPropertyInfo(name); 3496 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config. 3497 3498 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 3499 var standardName = possibleStandardNames[lowerCasedName]; 3500 3501 if (standardName !== name) { 3502 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 3503 3504 warnedProperties$1[name] = true; 3505 return true; 3506 } 3507 } else if (!isReserved && name !== lowerCasedName) { 3508 // Unknown attributes should have lowercase casing since that's how they 3509 // will be cased anyway with server rendering. 3510 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); 3511 3512 warnedProperties$1[name] = true; 3513 return true; 3514 } 3515 3516 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 3517 if (value) { 3518 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); 3519 } else { 3520 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); 3521 } 3522 3523 warnedProperties$1[name] = true; 3524 return true; 3525 } // Now that we've validated casing, do not validate 3526 // data types for reserved props 3527 3528 3529 if (isReserved) { 3530 return true; 3531 } // Warn when a known attribute is a bad type 3532 3533 3534 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 3535 warnedProperties$1[name] = true; 3536 return false; 3537 } // Warn when passing the strings 'false' or 'true' into a boolean prop 3538 3539 3540 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 3541 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); 3542 3543 warnedProperties$1[name] = true; 3544 return true; 3545 } 3546 3547 return true; 3548 }; 3549 } 3550 3551 var warnUnknownProperties = function (type, props, eventRegistry) { 3552 { 3553 var unknownProps = []; 3554 3555 for (var key in props) { 3556 var isValid = validateProperty$1(type, key, props[key], eventRegistry); 3557 3558 if (!isValid) { 3559 unknownProps.push(key); 3560 } 3561 } 3562 3563 var unknownPropString = unknownProps.map(function (prop) { 3564 return '`' + prop + '`'; 3565 }).join(', '); 3566 3567 if (unknownProps.length === 1) { 3568 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); 3569 } else if (unknownProps.length > 1) { 3570 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); 3571 } 3572 } 3573 }; 3574 3575 function validateProperties$2(type, props, eventRegistry) { 3576 if (isCustomComponent(type, props)) { 3577 return; 3578 } 3579 3580 warnUnknownProperties(type, props, eventRegistry); 3581 } 3582 3583 var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1; 3584 var IS_NON_DELEGATED = 1 << 1; 3585 var IS_CAPTURE_PHASE = 1 << 2; 3586 var IS_REPLAYED = 1 << 4; 3587 // set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when 3588 // we call willDeferLaterForLegacyFBSupport, thus not bailing out 3589 // will result in endless cycles like an infinite loop. 3590 // We also don't want to defer during event replaying. 3591 3592 var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE; 3593 3594 /** 3595 * Gets the target node from a native browser event by accounting for 3596 * inconsistencies in browser DOM APIs. 3597 * 3598 * @param {object} nativeEvent Native browser event. 3599 * @return {DOMEventTarget} Target node. 3600 */ 3601 3602 function getEventTarget(nativeEvent) { 3603 // Fallback to nativeEvent.srcElement for IE9 3604 // https://github.com/facebook/react/issues/12506 3605 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963 3606 3607 if (target.correspondingUseElement) { 3608 target = target.correspondingUseElement; 3609 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3). 3610 // @see http://www.quirksmode.org/js/events_properties.html 3611 3612 3613 return target.nodeType === TEXT_NODE ? target.parentNode : target; 3614 } 3615 3616 var restoreImpl = null; 3617 var restoreTarget = null; 3618 var restoreQueue = null; 3619 3620 function restoreStateOfTarget(target) { 3621 // We perform this translation at the end of the event loop so that we 3622 // always receive the correct fiber here 3623 var internalInstance = getInstanceFromNode(target); 3624 3625 if (!internalInstance) { 3626 // Unmounted 3627 return; 3628 } 3629 3630 if (!(typeof restoreImpl === 'function')) { 3631 { 3632 throw 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." ); 3633 } 3634 } 3635 3636 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. 3637 3638 if (stateNode) { 3639 var _props = getFiberCurrentPropsFromNode(stateNode); 3640 3641 restoreImpl(internalInstance.stateNode, internalInstance.type, _props); 3642 } 3643 } 3644 3645 function setRestoreImplementation(impl) { 3646 restoreImpl = impl; 3647 } 3648 function enqueueStateRestore(target) { 3649 if (restoreTarget) { 3650 if (restoreQueue) { 3651 restoreQueue.push(target); 3652 } else { 3653 restoreQueue = [target]; 3654 } 3655 } else { 3656 restoreTarget = target; 3657 } 3658 } 3659 function needsStateRestore() { 3660 return restoreTarget !== null || restoreQueue !== null; 3661 } 3662 function restoreStateIfNeeded() { 3663 if (!restoreTarget) { 3664 return; 3665 } 3666 3667 var target = restoreTarget; 3668 var queuedTargets = restoreQueue; 3669 restoreTarget = null; 3670 restoreQueue = null; 3671 restoreStateOfTarget(target); 3672 3673 if (queuedTargets) { 3674 for (var i = 0; i < queuedTargets.length; i++) { 3675 restoreStateOfTarget(queuedTargets[i]); 3676 } 3677 } 3678 } 3679 3680 // the renderer. Such as when we're dispatching events or if third party 3681 // libraries need to call batchedUpdates. Eventually, this API will go away when 3682 // everything is batched by default. We'll then have a similar API to opt-out of 3683 // scheduled work and instead do synchronous work. 3684 // Defaults 3685 3686 var batchedUpdatesImpl = function (fn, bookkeeping) { 3687 return fn(bookkeeping); 3688 }; 3689 3690 var discreteUpdatesImpl = function (fn, a, b, c, d) { 3691 return fn(a, b, c, d); 3692 }; 3693 3694 var flushDiscreteUpdatesImpl = function () {}; 3695 3696 var batchedEventUpdatesImpl = batchedUpdatesImpl; 3697 var isInsideEventHandler = false; 3698 var isBatchingEventUpdates = false; 3699 3700 function finishEventHandler() { 3701 // Here we wait until all updates have propagated, which is important 3702 // when using controlled components within layers: 3703 // https://github.com/facebook/react/issues/1698 3704 // Then we restore state of any controlled component. 3705 var controlledComponentsHavePendingUpdates = needsStateRestore(); 3706 3707 if (controlledComponentsHavePendingUpdates) { 3708 // If a controlled event was fired, we may need to restore the state of 3709 // the DOM node back to the controlled value. This is necessary when React 3710 // bails out of the update without touching the DOM. 3711 flushDiscreteUpdatesImpl(); 3712 restoreStateIfNeeded(); 3713 } 3714 } 3715 3716 function batchedUpdates(fn, bookkeeping) { 3717 if (isInsideEventHandler) { 3718 // If we are currently inside another batch, we need to wait until it 3719 // fully completes before restoring state. 3720 return fn(bookkeeping); 3721 } 3722 3723 isInsideEventHandler = true; 3724 3725 try { 3726 return batchedUpdatesImpl(fn, bookkeeping); 3727 } finally { 3728 isInsideEventHandler = false; 3729 finishEventHandler(); 3730 } 3731 } 3732 function batchedEventUpdates(fn, a, b) { 3733 if (isBatchingEventUpdates) { 3734 // If we are currently inside another batch, we need to wait until it 3735 // fully completes before restoring state. 3736 return fn(a, b); 3737 } 3738 3739 isBatchingEventUpdates = true; 3740 3741 try { 3742 return batchedEventUpdatesImpl(fn, a, b); 3743 } finally { 3744 isBatchingEventUpdates = false; 3745 finishEventHandler(); 3746 } 3747 } 3748 function discreteUpdates(fn, a, b, c, d) { 3749 var prevIsInsideEventHandler = isInsideEventHandler; 3750 isInsideEventHandler = true; 3751 3752 try { 3753 return discreteUpdatesImpl(fn, a, b, c, d); 3754 } finally { 3755 isInsideEventHandler = prevIsInsideEventHandler; 3756 3757 if (!isInsideEventHandler) { 3758 finishEventHandler(); 3759 } 3760 } 3761 } 3762 function flushDiscreteUpdatesIfNeeded(timeStamp) { 3763 { 3764 if (!isInsideEventHandler) { 3765 flushDiscreteUpdatesImpl(); 3766 } 3767 } 3768 } 3769 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) { 3770 batchedUpdatesImpl = _batchedUpdatesImpl; 3771 discreteUpdatesImpl = _discreteUpdatesImpl; 3772 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; 3773 batchedEventUpdatesImpl = _batchedEventUpdatesImpl; 3774 } 3775 3776 function isInteractive(tag) { 3777 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; 3778 } 3779 3780 function shouldPreventMouseEvent(name, type, props) { 3781 switch (name) { 3782 case 'onClick': 3783 case 'onClickCapture': 3784 case 'onDoubleClick': 3785 case 'onDoubleClickCapture': 3786 case 'onMouseDown': 3787 case 'onMouseDownCapture': 3788 case 'onMouseMove': 3789 case 'onMouseMoveCapture': 3790 case 'onMouseUp': 3791 case 'onMouseUpCapture': 3792 case 'onMouseEnter': 3793 return !!(props.disabled && isInteractive(type)); 3794 3795 default: 3796 return false; 3797 } 3798 } 3799 /** 3800 * @param {object} inst The instance, which is the source of events. 3801 * @param {string} registrationName Name of listener (e.g. `onClick`). 3802 * @return {?function} The stored callback. 3803 */ 3804 3805 3806 function getListener(inst, registrationName) { 3807 var stateNode = inst.stateNode; 3808 3809 if (stateNode === null) { 3810 // Work in progress (ex: onload events in incremental mode). 3811 return null; 3812 } 3813 3814 var props = getFiberCurrentPropsFromNode(stateNode); 3815 3816 if (props === null) { 3817 // Work in progress. 3818 return null; 3819 } 3820 3821 var listener = props[registrationName]; 3822 3823 if (shouldPreventMouseEvent(registrationName, inst.type, props)) { 3824 return null; 3825 } 3826 3827 if (!(!listener || typeof listener === 'function')) { 3828 { 3829 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." ); 3830 } 3831 } 3832 3833 return listener; 3834 } 3835 3836 var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners 3837 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support 3838 3839 if (canUseDOM) { 3840 try { 3841 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value 3842 3843 Object.defineProperty(options, 'passive', { 3844 get: function () { 3845 passiveBrowserEventsSupported = true; 3846 } 3847 }); 3848 window.addEventListener('test', options, options); 3849 window.removeEventListener('test', options, options); 3850 } catch (e) { 3851 passiveBrowserEventsSupported = false; 3852 } 3853 } 3854 3855 function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) { 3856 var funcArgs = Array.prototype.slice.call(arguments, 3); 3857 3858 try { 3859 func.apply(context, funcArgs); 3860 } catch (error) { 3861 this.onError(error); 3862 } 3863 } 3864 3865 var invokeGuardedCallbackImpl = invokeGuardedCallbackProd; 3866 3867 { 3868 // In DEV mode, we swap out invokeGuardedCallback for a special version 3869 // that plays more nicely with the browser's DevTools. The idea is to preserve 3870 // "Pause on exceptions" behavior. Because React wraps all user-provided 3871 // functions in invokeGuardedCallback, and the production version of 3872 // invokeGuardedCallback uses a try-catch, all user exceptions are treated 3873 // like caught exceptions, and the DevTools won't pause unless the developer 3874 // takes the extra step of enabling pause on caught exceptions. This is 3875 // unintuitive, though, because even though React has caught the error, from 3876 // the developer's perspective, the error is uncaught. 3877 // 3878 // To preserve the expected "Pause on exceptions" behavior, we don't use a 3879 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake 3880 // DOM node, and call the user-provided callback from inside an event handler 3881 // for that fake event. If the callback throws, the error is "captured" using 3882 // a global event handler. But because the error happens in a different 3883 // event loop context, it does not interrupt the normal program flow. 3884 // Effectively, this gives us try-catch behavior without actually using 3885 // try-catch. Neat! 3886 // Check that the browser supports the APIs we need to implement our special 3887 // DEV version of invokeGuardedCallback 3888 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { 3889 var fakeNode = document.createElement('react'); 3890 3891 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) { 3892 // If document doesn't exist we know for sure we will crash in this method 3893 // when we call document.createEvent(). However this can cause confusing 3894 // errors: https://github.com/facebookincubator/create-react-app/issues/3482 3895 // So we preemptively throw with a better message instead. 3896 if (!(typeof document !== 'undefined')) { 3897 { 3898 throw 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." ); 3899 } 3900 } 3901 3902 var evt = document.createEvent('Event'); 3903 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We 3904 // set this to true at the beginning, then set it to false right after 3905 // calling the function. If the function errors, `didError` will never be 3906 // set to false. This strategy works even if the browser is flaky and 3907 // fails to call our global error handler, because it doesn't rely on 3908 // the error event at all. 3909 3910 var didError = true; // Keeps track of the value of window.event so that we can reset it 3911 // during the callback to let user code access window.event in the 3912 // browsers that support it. 3913 3914 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event 3915 // dispatching: https://github.com/facebook/react/issues/13688 3916 3917 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); 3918 3919 function restoreAfterDispatch() { 3920 // We immediately remove the callback from event listeners so that 3921 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a 3922 // nested call would trigger the fake event handlers of any call higher 3923 // in the stack. 3924 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the 3925 // window.event assignment in both IE <= 10 as they throw an error 3926 // "Member not found" in strict mode, and in Firefox which does not 3927 // support window.event. 3928 3929 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) { 3930 window.event = windowEvent; 3931 } 3932 } // Create an event handler for our fake event. We will synchronously 3933 // dispatch our fake event using `dispatchEvent`. Inside the handler, we 3934 // call the user-provided callback. 3935 3936 3937 var funcArgs = Array.prototype.slice.call(arguments, 3); 3938 3939 function callCallback() { 3940 didCall = true; 3941 restoreAfterDispatch(); 3942 func.apply(context, funcArgs); 3943 didError = false; 3944 } // Create a global error event handler. We use this to capture the value 3945 // that was thrown. It's possible that this error handler will fire more 3946 // than once; for example, if non-React code also calls `dispatchEvent` 3947 // and a handler for that event throws. We should be resilient to most of 3948 // those cases. Even if our error event handler fires more than once, the 3949 // last error event is always used. If the callback actually does error, 3950 // we know that the last error event is the correct one, because it's not 3951 // possible for anything else to have happened in between our callback 3952 // erroring and the code that follows the `dispatchEvent` call below. If 3953 // the callback doesn't error, but the error event was fired, we know to 3954 // ignore it because `didError` will be false, as described above. 3955 3956 3957 var error; // Use this to track whether the error event is ever called. 3958 3959 var didSetError = false; 3960 var isCrossOriginError = false; 3961 3962 function handleWindowError(event) { 3963 error = event.error; 3964 didSetError = true; 3965 3966 if (error === null && event.colno === 0 && event.lineno === 0) { 3967 isCrossOriginError = true; 3968 } 3969 3970 if (event.defaultPrevented) { 3971 // Some other error handler has prevented default. 3972 // Browsers silence the error report if this happens. 3973 // We'll remember this to later decide whether to log it or not. 3974 if (error != null && typeof error === 'object') { 3975 try { 3976 error._suppressLogging = true; 3977 } catch (inner) {// Ignore. 3978 } 3979 } 3980 } 3981 } // Create a fake event type. 3982 3983 3984 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers 3985 3986 window.addEventListener('error', handleWindowError); 3987 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function 3988 // errors, it will trigger our global error handler. 3989 3990 evt.initEvent(evtType, false, false); 3991 fakeNode.dispatchEvent(evt); 3992 3993 if (windowEventDescriptor) { 3994 Object.defineProperty(window, 'event', windowEventDescriptor); 3995 } 3996 3997 if (didCall && didError) { 3998 if (!didSetError) { 3999 // The callback errored, but the error event never fired. 4000 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.'); 4001 } else if (isCrossOriginError) { 4002 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.'); 4003 } 4004 4005 this.onError(error); 4006 } // Remove our event listeners 4007 4008 4009 window.removeEventListener('error', handleWindowError); 4010 4011 if (!didCall) { 4012 // Something went really wrong, and our event was not dispatched. 4013 // https://github.com/facebook/react/issues/16734 4014 // https://github.com/facebook/react/issues/16585 4015 // Fall back to the production implementation. 4016 restoreAfterDispatch(); 4017 return invokeGuardedCallbackProd.apply(this, arguments); 4018 } 4019 }; 4020 } 4021 } 4022 4023 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl; 4024 4025 var hasError = false; 4026 var caughtError = null; // Used by event system to capture/rethrow the first error. 4027 4028 var hasRethrowError = false; 4029 var rethrowError = null; 4030 var reporter = { 4031 onError: function (error) { 4032 hasError = true; 4033 caughtError = error; 4034 } 4035 }; 4036 /** 4037 * Call a function while guarding against errors that happens within it. 4038 * Returns an error if it throws, otherwise null. 4039 * 4040 * In production, this is implemented using a try-catch. The reason we don't 4041 * use a try-catch directly is so that we can swap out a different 4042 * implementation in DEV mode. 4043 * 4044 * @param {String} name of the guard to use for logging or debugging 4045 * @param {Function} func The function to invoke 4046 * @param {*} context The context to use when calling the function 4047 * @param {...*} args Arguments for function 4048 */ 4049 4050 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { 4051 hasError = false; 4052 caughtError = null; 4053 invokeGuardedCallbackImpl$1.apply(reporter, arguments); 4054 } 4055 /** 4056 * Same as invokeGuardedCallback, but instead of returning an error, it stores 4057 * it in a global so it can be rethrown by `rethrowCaughtError` later. 4058 * TODO: See if caughtError and rethrowError can be unified. 4059 * 4060 * @param {String} name of the guard to use for logging or debugging 4061 * @param {Function} func The function to invoke 4062 * @param {*} context The context to use when calling the function 4063 * @param {...*} args Arguments for function 4064 */ 4065 4066 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) { 4067 invokeGuardedCallback.apply(this, arguments); 4068 4069 if (hasError) { 4070 var error = clearCaughtError(); 4071 4072 if (!hasRethrowError) { 4073 hasRethrowError = true; 4074 rethrowError = error; 4075 } 4076 } 4077 } 4078 /** 4079 * During execution of guarded functions we will capture the first error which 4080 * we will rethrow to be handled by the top level error handler. 4081 */ 4082 4083 function rethrowCaughtError() { 4084 if (hasRethrowError) { 4085 var error = rethrowError; 4086 hasRethrowError = false; 4087 rethrowError = null; 4088 throw error; 4089 } 4090 } 4091 function hasCaughtError() { 4092 return hasError; 4093 } 4094 function clearCaughtError() { 4095 if (hasError) { 4096 var error = caughtError; 4097 hasError = false; 4098 caughtError = null; 4099 return error; 4100 } else { 4101 { 4102 { 4103 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." ); 4104 } 4105 } 4106 } 4107 } 4108 4109 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 4110 var _ReactInternals$Sched = ReactInternals$1.Scheduler, 4111 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback, 4112 unstable_now = _ReactInternals$Sched.unstable_now, 4113 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback, 4114 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield, 4115 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint, 4116 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode, 4117 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority, 4118 unstable_next = _ReactInternals$Sched.unstable_next, 4119 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution, 4120 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution, 4121 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel, 4122 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority, 4123 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority, 4124 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority, 4125 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority, 4126 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority, 4127 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate, 4128 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting; 4129 4130 /** 4131 * `ReactInstanceMap` maintains a mapping from a public facing stateful 4132 * instance (key) and the internal representation (value). This allows public 4133 * methods to accept the user facing instance as an argument and map them back 4134 * to internal methods. 4135 * 4136 * Note that this module is currently shared and assumed to be stateless. 4137 * If this becomes an actual Map, that will break. 4138 */ 4139 function get(key) { 4140 return key._reactInternals; 4141 } 4142 function has(key) { 4143 return key._reactInternals !== undefined; 4144 } 4145 function set(key, value) { 4146 key._reactInternals = value; 4147 } 4148 4149 // Don't change these two values. They're used by React Dev Tools. 4150 var NoFlags = 4151 /* */ 4152 0; 4153 var PerformedWork = 4154 /* */ 4155 1; // You can change the rest (and add more). 4156 4157 var Placement = 4158 /* */ 4159 2; 4160 var Update = 4161 /* */ 4162 4; 4163 var PlacementAndUpdate = 4164 /* */ 4165 6; 4166 var Deletion = 4167 /* */ 4168 8; 4169 var ContentReset = 4170 /* */ 4171 16; 4172 var Callback = 4173 /* */ 4174 32; 4175 var DidCapture = 4176 /* */ 4177 64; 4178 var Ref = 4179 /* */ 4180 128; 4181 var Snapshot = 4182 /* */ 4183 256; 4184 var Passive = 4185 /* */ 4186 512; // TODO (effects) Remove this bit once the new reconciler is synced to the old. 4187 4188 var PassiveUnmountPendingDev = 4189 /* */ 4190 8192; 4191 var Hydrating = 4192 /* */ 4193 1024; 4194 var HydratingAndUpdate = 4195 /* */ 4196 1028; // Passive & Update & Callback & Ref & Snapshot 4197 4198 var LifecycleEffectMask = 4199 /* */ 4200 932; // Union of all host effects 4201 4202 var HostEffectMask = 4203 /* */ 4204 2047; // These are not really side effects, but we still reuse this field. 4205 4206 var Incomplete = 4207 /* */ 4208 2048; 4209 var ShouldCapture = 4210 /* */ 4211 4096; 4212 var ForceUpdateForLegacySuspense = 4213 /* */ 4214 16384; // Static tags describe aspects of a fiber that are not specific to a render, 4215 4216 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; 4217 function getNearestMountedFiber(fiber) { 4218 var node = fiber; 4219 var nearestMounted = fiber; 4220 4221 if (!fiber.alternate) { 4222 // If there is no alternate, this might be a new tree that isn't inserted 4223 // yet. If it is, then it will have a pending insertion effect on it. 4224 var nextNode = node; 4225 4226 do { 4227 node = nextNode; 4228 4229 if ((node.flags & (Placement | Hydrating)) !== NoFlags) { 4230 // This is an insertion or in-progress hydration. The nearest possible 4231 // mounted fiber is the parent but we need to continue to figure out 4232 // if that one is still mounted. 4233 nearestMounted = node.return; 4234 } 4235 4236 nextNode = node.return; 4237 } while (nextNode); 4238 } else { 4239 while (node.return) { 4240 node = node.return; 4241 } 4242 } 4243 4244 if (node.tag === HostRoot) { 4245 // TODO: Check if this was a nested HostRoot when used with 4246 // renderContainerIntoSubtree. 4247 return nearestMounted; 4248 } // If we didn't hit the root, that means that we're in an disconnected tree 4249 // that has been unmounted. 4250 4251 4252 return null; 4253 } 4254 function getSuspenseInstanceFromFiber(fiber) { 4255 if (fiber.tag === SuspenseComponent) { 4256 var suspenseState = fiber.memoizedState; 4257 4258 if (suspenseState === null) { 4259 var current = fiber.alternate; 4260 4261 if (current !== null) { 4262 suspenseState = current.memoizedState; 4263 } 4264 } 4265 4266 if (suspenseState !== null) { 4267 return suspenseState.dehydrated; 4268 } 4269 } 4270 4271 return null; 4272 } 4273 function getContainerFromFiber(fiber) { 4274 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null; 4275 } 4276 function isFiberMounted(fiber) { 4277 return getNearestMountedFiber(fiber) === fiber; 4278 } 4279 function isMounted(component) { 4280 { 4281 var owner = ReactCurrentOwner.current; 4282 4283 if (owner !== null && owner.tag === ClassComponent) { 4284 var ownerFiber = owner; 4285 var instance = ownerFiber.stateNode; 4286 4287 if (!instance._warnedAboutRefsInRender) { 4288 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.', getComponentName(ownerFiber.type) || 'A component'); 4289 } 4290 4291 instance._warnedAboutRefsInRender = true; 4292 } 4293 } 4294 4295 var fiber = get(component); 4296 4297 if (!fiber) { 4298 return false; 4299 } 4300 4301 return getNearestMountedFiber(fiber) === fiber; 4302 } 4303 4304 function assertIsMounted(fiber) { 4305 if (!(getNearestMountedFiber(fiber) === fiber)) { 4306 { 4307 throw Error( "Unable to find node on an unmounted component." ); 4308 } 4309 } 4310 } 4311 4312 function findCurrentFiberUsingSlowPath(fiber) { 4313 var alternate = fiber.alternate; 4314 4315 if (!alternate) { 4316 // If there is no alternate, then we only need to check if it is mounted. 4317 var nearestMounted = getNearestMountedFiber(fiber); 4318 4319 if (!(nearestMounted !== null)) { 4320 { 4321 throw Error( "Unable to find node on an unmounted component." ); 4322 } 4323 } 4324 4325 if (nearestMounted !== fiber) { 4326 return null; 4327 } 4328 4329 return fiber; 4330 } // If we have two possible branches, we'll walk backwards up to the root 4331 // to see what path the root points to. On the way we may hit one of the 4332 // special cases and we'll deal with them. 4333 4334 4335 var a = fiber; 4336 var b = alternate; 4337 4338 while (true) { 4339 var parentA = a.return; 4340 4341 if (parentA === null) { 4342 // We're at the root. 4343 break; 4344 } 4345 4346 var parentB = parentA.alternate; 4347 4348 if (parentB === null) { 4349 // There is no alternate. This is an unusual case. Currently, it only 4350 // happens when a Suspense component is hidden. An extra fragment fiber 4351 // is inserted in between the Suspense fiber and its children. Skip 4352 // over this extra fragment fiber and proceed to the next parent. 4353 var nextParent = parentA.return; 4354 4355 if (nextParent !== null) { 4356 a = b = nextParent; 4357 continue; 4358 } // If there's no parent, we're at the root. 4359 4360 4361 break; 4362 } // If both copies of the parent fiber point to the same child, we can 4363 // assume that the child is current. This happens when we bailout on low 4364 // priority: the bailed out fiber's child reuses the current child. 4365 4366 4367 if (parentA.child === parentB.child) { 4368 var child = parentA.child; 4369 4370 while (child) { 4371 if (child === a) { 4372 // We've determined that A is the current branch. 4373 assertIsMounted(parentA); 4374 return fiber; 4375 } 4376 4377 if (child === b) { 4378 // We've determined that B is the current branch. 4379 assertIsMounted(parentA); 4380 return alternate; 4381 } 4382 4383 child = child.sibling; 4384 } // We should never have an alternate for any mounting node. So the only 4385 // way this could possibly happen is if this was unmounted, if at all. 4386 4387 4388 { 4389 { 4390 throw Error( "Unable to find node on an unmounted component." ); 4391 } 4392 } 4393 } 4394 4395 if (a.return !== b.return) { 4396 // The return pointer of A and the return pointer of B point to different 4397 // fibers. We assume that return pointers never criss-cross, so A must 4398 // belong to the child set of A.return, and B must belong to the child 4399 // set of B.return. 4400 a = parentA; 4401 b = parentB; 4402 } else { 4403 // The return pointers point to the same fiber. We'll have to use the 4404 // default, slow path: scan the child sets of each parent alternate to see 4405 // which child belongs to which set. 4406 // 4407 // Search parent A's child set 4408 var didFindChild = false; 4409 var _child = parentA.child; 4410 4411 while (_child) { 4412 if (_child === a) { 4413 didFindChild = true; 4414 a = parentA; 4415 b = parentB; 4416 break; 4417 } 4418 4419 if (_child === b) { 4420 didFindChild = true; 4421 b = parentA; 4422 a = parentB; 4423 break; 4424 } 4425 4426 _child = _child.sibling; 4427 } 4428 4429 if (!didFindChild) { 4430 // Search parent B's child set 4431 _child = parentB.child; 4432 4433 while (_child) { 4434 if (_child === a) { 4435 didFindChild = true; 4436 a = parentB; 4437 b = parentA; 4438 break; 4439 } 4440 4441 if (_child === b) { 4442 didFindChild = true; 4443 b = parentB; 4444 a = parentA; 4445 break; 4446 } 4447 4448 _child = _child.sibling; 4449 } 4450 4451 if (!didFindChild) { 4452 { 4453 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." ); 4454 } 4455 } 4456 } 4457 } 4458 4459 if (!(a.alternate === b)) { 4460 { 4461 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." ); 4462 } 4463 } 4464 } // If the root is not a host container, we're in a disconnected tree. I.e. 4465 // unmounted. 4466 4467 4468 if (!(a.tag === HostRoot)) { 4469 { 4470 throw Error( "Unable to find node on an unmounted component." ); 4471 } 4472 } 4473 4474 if (a.stateNode.current === a) { 4475 // We've determined that A is the current branch. 4476 return fiber; 4477 } // Otherwise B has to be current branch. 4478 4479 4480 return alternate; 4481 } 4482 function findCurrentHostFiber(parent) { 4483 var currentParent = findCurrentFiberUsingSlowPath(parent); 4484 4485 if (!currentParent) { 4486 return null; 4487 } // Next we'll drill down this component to find the first HostComponent/Text. 4488 4489 4490 var node = currentParent; 4491 4492 while (true) { 4493 if (node.tag === HostComponent || node.tag === HostText) { 4494 return node; 4495 } else if (node.child) { 4496 node.child.return = node; 4497 node = node.child; 4498 continue; 4499 } 4500 4501 if (node === currentParent) { 4502 return null; 4503 } 4504 4505 while (!node.sibling) { 4506 if (!node.return || node.return === currentParent) { 4507 return null; 4508 } 4509 4510 node = node.return; 4511 } 4512 4513 node.sibling.return = node.return; 4514 node = node.sibling; 4515 } // Flow needs the return null here, but ESLint complains about it. 4516 // eslint-disable-next-line no-unreachable 4517 4518 4519 return null; 4520 } 4521 function findCurrentHostFiberWithNoPortals(parent) { 4522 var currentParent = findCurrentFiberUsingSlowPath(parent); 4523 4524 if (!currentParent) { 4525 return null; 4526 } // Next we'll drill down this component to find the first HostComponent/Text. 4527 4528 4529 var node = currentParent; 4530 4531 while (true) { 4532 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) { 4533 return node; 4534 } else if (node.child && node.tag !== HostPortal) { 4535 node.child.return = node; 4536 node = node.child; 4537 continue; 4538 } 4539 4540 if (node === currentParent) { 4541 return null; 4542 } 4543 4544 while (!node.sibling) { 4545 if (!node.return || node.return === currentParent) { 4546 return null; 4547 } 4548 4549 node = node.return; 4550 } 4551 4552 node.sibling.return = node.return; 4553 node = node.sibling; 4554 } // Flow needs the return null here, but ESLint complains about it. 4555 // eslint-disable-next-line no-unreachable 4556 4557 4558 return null; 4559 } 4560 function doesFiberContain(parentFiber, childFiber) { 4561 var node = childFiber; 4562 var parentFiberAlternate = parentFiber.alternate; 4563 4564 while (node !== null) { 4565 if (node === parentFiber || node === parentFiberAlternate) { 4566 return true; 4567 } 4568 4569 node = node.return; 4570 } 4571 4572 return false; 4573 } 4574 4575 var attemptUserBlockingHydration; 4576 function setAttemptUserBlockingHydration(fn) { 4577 attemptUserBlockingHydration = fn; 4578 } 4579 var attemptContinuousHydration; 4580 function setAttemptContinuousHydration(fn) { 4581 attemptContinuousHydration = fn; 4582 } 4583 var attemptHydrationAtCurrentPriority; 4584 function setAttemptHydrationAtCurrentPriority(fn) { 4585 attemptHydrationAtCurrentPriority = fn; 4586 } 4587 var attemptHydrationAtPriority; 4588 function setAttemptHydrationAtPriority(fn) { 4589 attemptHydrationAtPriority = fn; 4590 } // TODO: Upgrade this definition once we're on a newer version of Flow that 4591 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed. 4592 4593 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout. 4594 // if the last target was dehydrated. 4595 4596 var queuedFocus = null; 4597 var queuedDrag = null; 4598 var queuedMouse = null; // For pointer events there can be one latest event per pointerId. 4599 4600 var queuedPointers = new Map(); 4601 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too. 4602 4603 var queuedExplicitHydrationTargets = []; 4604 function hasQueuedDiscreteEvents() { 4605 return queuedDiscreteEvents.length > 0; 4606 } 4607 var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase 4608 'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit']; 4609 function isReplayableDiscreteEvent(eventType) { 4610 return discreteReplayableEvents.indexOf(eventType) > -1; 4611 } 4612 4613 function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 4614 return { 4615 blockedOn: blockedOn, 4616 domEventName: domEventName, 4617 eventSystemFlags: eventSystemFlags | IS_REPLAYED, 4618 nativeEvent: nativeEvent, 4619 targetContainers: [targetContainer] 4620 }; 4621 } 4622 4623 function queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 4624 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent); 4625 queuedDiscreteEvents.push(queuedEvent); 4626 } // Resets the replaying for this type of continuous event to no event. 4627 4628 function clearIfContinuousEvent(domEventName, nativeEvent) { 4629 switch (domEventName) { 4630 case 'focusin': 4631 case 'focusout': 4632 queuedFocus = null; 4633 break; 4634 4635 case 'dragenter': 4636 case 'dragleave': 4637 queuedDrag = null; 4638 break; 4639 4640 case 'mouseover': 4641 case 'mouseout': 4642 queuedMouse = null; 4643 break; 4644 4645 case 'pointerover': 4646 case 'pointerout': 4647 { 4648 var pointerId = nativeEvent.pointerId; 4649 queuedPointers.delete(pointerId); 4650 break; 4651 } 4652 4653 case 'gotpointercapture': 4654 case 'lostpointercapture': 4655 { 4656 var _pointerId = nativeEvent.pointerId; 4657 queuedPointerCaptures.delete(_pointerId); 4658 break; 4659 } 4660 } 4661 } 4662 4663 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 4664 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) { 4665 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent); 4666 4667 if (blockedOn !== null) { 4668 var _fiber2 = getInstanceFromNode(blockedOn); 4669 4670 if (_fiber2 !== null) { 4671 // Attempt to increase the priority of this target. 4672 attemptContinuousHydration(_fiber2); 4673 } 4674 } 4675 4676 return queuedEvent; 4677 } // If we have already queued this exact event, then it's because 4678 // the different event systems have different DOM event listeners. 4679 // We can accumulate the flags, and the targetContainers, and 4680 // store a single event to be replayed. 4681 4682 4683 existingQueuedEvent.eventSystemFlags |= eventSystemFlags; 4684 var targetContainers = existingQueuedEvent.targetContainers; 4685 4686 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) { 4687 targetContainers.push(targetContainer); 4688 } 4689 4690 return existingQueuedEvent; 4691 } 4692 4693 function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 4694 // These set relatedTarget to null because the replayed event will be treated as if we 4695 // moved from outside the window (no target) onto the target once it hydrates. 4696 // Instead of mutating we could clone the event. 4697 switch (domEventName) { 4698 case 'focusin': 4699 { 4700 var focusEvent = nativeEvent; 4701 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent); 4702 return true; 4703 } 4704 4705 case 'dragenter': 4706 { 4707 var dragEvent = nativeEvent; 4708 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent); 4709 return true; 4710 } 4711 4712 case 'mouseover': 4713 { 4714 var mouseEvent = nativeEvent; 4715 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent); 4716 return true; 4717 } 4718 4719 case 'pointerover': 4720 { 4721 var pointerEvent = nativeEvent; 4722 var pointerId = pointerEvent.pointerId; 4723 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent)); 4724 return true; 4725 } 4726 4727 case 'gotpointercapture': 4728 { 4729 var _pointerEvent = nativeEvent; 4730 var _pointerId2 = _pointerEvent.pointerId; 4731 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent)); 4732 return true; 4733 } 4734 } 4735 4736 return false; 4737 } // Check if this target is unblocked. Returns true if it's unblocked. 4738 4739 function attemptExplicitHydrationTarget(queuedTarget) { 4740 // TODO: This function shares a lot of logic with attemptToDispatchEvent. 4741 // Try to unify them. It's a bit tricky since it would require two return 4742 // values. 4743 var targetInst = getClosestInstanceFromNode(queuedTarget.target); 4744 4745 if (targetInst !== null) { 4746 var nearestMounted = getNearestMountedFiber(targetInst); 4747 4748 if (nearestMounted !== null) { 4749 var tag = nearestMounted.tag; 4750 4751 if (tag === SuspenseComponent) { 4752 var instance = getSuspenseInstanceFromFiber(nearestMounted); 4753 4754 if (instance !== null) { 4755 // We're blocked on hydrating this boundary. 4756 // Increase its priority. 4757 queuedTarget.blockedOn = instance; 4758 attemptHydrationAtPriority(queuedTarget.lanePriority, function () { 4759 unstable_runWithPriority(queuedTarget.priority, function () { 4760 attemptHydrationAtCurrentPriority(nearestMounted); 4761 }); 4762 }); 4763 return; 4764 } 4765 } else if (tag === HostRoot) { 4766 var root = nearestMounted.stateNode; 4767 4768 if (root.hydrate) { 4769 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of 4770 // a root other than sync. 4771 4772 return; 4773 } 4774 } 4775 } 4776 } 4777 4778 queuedTarget.blockedOn = null; 4779 } 4780 4781 function attemptReplayContinuousQueuedEvent(queuedEvent) { 4782 if (queuedEvent.blockedOn !== null) { 4783 return false; 4784 } 4785 4786 var targetContainers = queuedEvent.targetContainers; 4787 4788 while (targetContainers.length > 0) { 4789 var targetContainer = targetContainers[0]; 4790 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent); 4791 4792 if (nextBlockedOn !== null) { 4793 // We're still blocked. Try again later. 4794 var _fiber3 = getInstanceFromNode(nextBlockedOn); 4795 4796 if (_fiber3 !== null) { 4797 attemptContinuousHydration(_fiber3); 4798 } 4799 4800 queuedEvent.blockedOn = nextBlockedOn; 4801 return false; 4802 } // This target container was successfully dispatched. Try the next. 4803 4804 4805 targetContainers.shift(); 4806 } 4807 4808 return true; 4809 } 4810 4811 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) { 4812 if (attemptReplayContinuousQueuedEvent(queuedEvent)) { 4813 map.delete(key); 4814 } 4815 } 4816 4817 function replayUnblockedEvents() { 4818 hasScheduledReplayAttempt = false; // First replay discrete events. 4819 4820 while (queuedDiscreteEvents.length > 0) { 4821 var nextDiscreteEvent = queuedDiscreteEvents[0]; 4822 4823 if (nextDiscreteEvent.blockedOn !== null) { 4824 // We're still blocked. 4825 // Increase the priority of this boundary to unblock 4826 // the next discrete event. 4827 var _fiber4 = getInstanceFromNode(nextDiscreteEvent.blockedOn); 4828 4829 if (_fiber4 !== null) { 4830 attemptUserBlockingHydration(_fiber4); 4831 } 4832 4833 break; 4834 } 4835 4836 var targetContainers = nextDiscreteEvent.targetContainers; 4837 4838 while (targetContainers.length > 0) { 4839 var targetContainer = targetContainers[0]; 4840 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.domEventName, nextDiscreteEvent.eventSystemFlags, targetContainer, nextDiscreteEvent.nativeEvent); 4841 4842 if (nextBlockedOn !== null) { 4843 // We're still blocked. Try again later. 4844 nextDiscreteEvent.blockedOn = nextBlockedOn; 4845 break; 4846 } // This target container was successfully dispatched. Try the next. 4847 4848 4849 targetContainers.shift(); 4850 } 4851 4852 if (nextDiscreteEvent.blockedOn === null) { 4853 // We've successfully replayed the first event. Let's try the next one. 4854 queuedDiscreteEvents.shift(); 4855 } 4856 } // Next replay any continuous events. 4857 4858 4859 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) { 4860 queuedFocus = null; 4861 } 4862 4863 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) { 4864 queuedDrag = null; 4865 } 4866 4867 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) { 4868 queuedMouse = null; 4869 } 4870 4871 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap); 4872 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap); 4873 } 4874 4875 function scheduleCallbackIfUnblocked(queuedEvent, unblocked) { 4876 if (queuedEvent.blockedOn === unblocked) { 4877 queuedEvent.blockedOn = null; 4878 4879 if (!hasScheduledReplayAttempt) { 4880 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are 4881 // now unblocked. This first might not actually be unblocked yet. 4882 // We could check it early to avoid scheduling an unnecessary callback. 4883 4884 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents); 4885 } 4886 } 4887 } 4888 4889 function retryIfBlockedOn(unblocked) { 4890 // Mark anything that was blocked on this as no longer blocked 4891 // and eligible for a replay. 4892 if (queuedDiscreteEvents.length > 0) { 4893 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's 4894 // worth it because we expect very few discrete events to queue up and once 4895 // we are actually fully unblocked it will be fast to replay them. 4896 4897 for (var i = 1; i < queuedDiscreteEvents.length; i++) { 4898 var queuedEvent = queuedDiscreteEvents[i]; 4899 4900 if (queuedEvent.blockedOn === unblocked) { 4901 queuedEvent.blockedOn = null; 4902 } 4903 } 4904 } 4905 4906 if (queuedFocus !== null) { 4907 scheduleCallbackIfUnblocked(queuedFocus, unblocked); 4908 } 4909 4910 if (queuedDrag !== null) { 4911 scheduleCallbackIfUnblocked(queuedDrag, unblocked); 4912 } 4913 4914 if (queuedMouse !== null) { 4915 scheduleCallbackIfUnblocked(queuedMouse, unblocked); 4916 } 4917 4918 var unblock = function (queuedEvent) { 4919 return scheduleCallbackIfUnblocked(queuedEvent, unblocked); 4920 }; 4921 4922 queuedPointers.forEach(unblock); 4923 queuedPointerCaptures.forEach(unblock); 4924 4925 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) { 4926 var queuedTarget = queuedExplicitHydrationTargets[_i]; 4927 4928 if (queuedTarget.blockedOn === unblocked) { 4929 queuedTarget.blockedOn = null; 4930 } 4931 } 4932 4933 while (queuedExplicitHydrationTargets.length > 0) { 4934 var nextExplicitTarget = queuedExplicitHydrationTargets[0]; 4935 4936 if (nextExplicitTarget.blockedOn !== null) { 4937 // We're still blocked. 4938 break; 4939 } else { 4940 attemptExplicitHydrationTarget(nextExplicitTarget); 4941 4942 if (nextExplicitTarget.blockedOn === null) { 4943 // We're unblocked. 4944 queuedExplicitHydrationTargets.shift(); 4945 } 4946 } 4947 } 4948 } 4949 4950 var DiscreteEvent = 0; 4951 var UserBlockingEvent = 1; 4952 var ContinuousEvent = 2; 4953 4954 /** 4955 * Generate a mapping of standard vendor prefixes using the defined style property and event name. 4956 * 4957 * @param {string} styleProp 4958 * @param {string} eventName 4959 * @returns {object} 4960 */ 4961 4962 function makePrefixMap(styleProp, eventName) { 4963 var prefixes = {}; 4964 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); 4965 prefixes['Webkit' + styleProp] = 'webkit' + eventName; 4966 prefixes['Moz' + styleProp] = 'moz' + eventName; 4967 return prefixes; 4968 } 4969 /** 4970 * A list of event names to a configurable list of vendor prefixes. 4971 */ 4972 4973 4974 var vendorPrefixes = { 4975 animationend: makePrefixMap('Animation', 'AnimationEnd'), 4976 animationiteration: makePrefixMap('Animation', 'AnimationIteration'), 4977 animationstart: makePrefixMap('Animation', 'AnimationStart'), 4978 transitionend: makePrefixMap('Transition', 'TransitionEnd') 4979 }; 4980 /** 4981 * Event names that have already been detected and prefixed (if applicable). 4982 */ 4983 4984 var prefixedEventNames = {}; 4985 /** 4986 * Element to check for prefixes on. 4987 */ 4988 4989 var style = {}; 4990 /** 4991 * Bootstrap if a DOM exists. 4992 */ 4993 4994 if (canUseDOM) { 4995 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x, 4996 // the un-prefixed "animation" and "transition" properties are defined on the 4997 // style object but the events that fire will still be prefixed, so we need 4998 // to check if the un-prefixed events are usable, and if not remove them from the map. 4999 5000 if (!('AnimationEvent' in window)) { 5001 delete vendorPrefixes.animationend.animation; 5002 delete vendorPrefixes.animationiteration.animation; 5003 delete vendorPrefixes.animationstart.animation; 5004 } // Same as above 5005 5006 5007 if (!('TransitionEvent' in window)) { 5008 delete vendorPrefixes.transitionend.transition; 5009 } 5010 } 5011 /** 5012 * Attempts to determine the correct vendor prefixed event name. 5013 * 5014 * @param {string} eventName 5015 * @returns {string} 5016 */ 5017 5018 5019 function getVendorPrefixedEventName(eventName) { 5020 if (prefixedEventNames[eventName]) { 5021 return prefixedEventNames[eventName]; 5022 } else if (!vendorPrefixes[eventName]) { 5023 return eventName; 5024 } 5025 5026 var prefixMap = vendorPrefixes[eventName]; 5027 5028 for (var styleProp in prefixMap) { 5029 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { 5030 return prefixedEventNames[eventName] = prefixMap[styleProp]; 5031 } 5032 } 5033 5034 return eventName; 5035 } 5036 5037 var ANIMATION_END = getVendorPrefixedEventName('animationend'); 5038 var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration'); 5039 var ANIMATION_START = getVendorPrefixedEventName('animationstart'); 5040 var TRANSITION_END = getVendorPrefixedEventName('transitionend'); 5041 5042 var topLevelEventsToReactNames = new Map(); 5043 var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use 5044 // the code required to apply the same logic for event prioritization and that of the 5045 // SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code 5046 // duplication (for which there would be quite a bit). For the events that are not needed 5047 // for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an 5048 // array of top level events. 5049 // Lastly, we ignore prettier so we can keep the formatting sane. 5050 // prettier-ignore 5051 5052 var discreteEventPairsForSimpleEventPlugin = ['cancel', 'cancel', 'click', 'click', 'close', 'close', 'contextmenu', 'contextMenu', 'copy', 'copy', 'cut', 'cut', 'auxclick', 'auxClick', 'dblclick', 'doubleClick', // Careful! 5053 'dragend', 'dragEnd', 'dragstart', 'dragStart', 'drop', 'drop', 'focusin', 'focus', // Careful! 5054 'focusout', 'blur', // Careful! 5055 'input', 'input', 'invalid', 'invalid', 'keydown', 'keyDown', 'keypress', 'keyPress', 'keyup', 'keyUp', 'mousedown', 'mouseDown', 'mouseup', 'mouseUp', 'paste', 'paste', 'pause', 'pause', 'play', 'play', 'pointercancel', 'pointerCancel', 'pointerdown', 'pointerDown', 'pointerup', 'pointerUp', 'ratechange', 'rateChange', 'reset', 'reset', 'seeked', 'seeked', 'submit', 'submit', 'touchcancel', 'touchCancel', 'touchend', 'touchEnd', 'touchstart', 'touchStart', 'volumechange', 'volumeChange']; 5056 var otherDiscreteEvents = ['change', 'selectionchange', 'textInput', 'compositionstart', 'compositionend', 'compositionupdate']; 5057 5058 5059 var userBlockingPairsForSimpleEventPlugin = ['drag', 'drag', 'dragenter', 'dragEnter', 'dragexit', 'dragExit', 'dragleave', 'dragLeave', 'dragover', 'dragOver', 'mousemove', 'mouseMove', 'mouseout', 'mouseOut', 'mouseover', 'mouseOver', 'pointermove', 'pointerMove', 'pointerout', 'pointerOut', 'pointerover', 'pointerOver', 'scroll', 'scroll', 'toggle', 'toggle', 'touchmove', 'touchMove', 'wheel', 'wheel']; // prettier-ignore 5060 5061 var continuousPairsForSimpleEventPlugin = ['abort', 'abort', ANIMATION_END, 'animationEnd', ANIMATION_ITERATION, 'animationIteration', ANIMATION_START, 'animationStart', 'canplay', 'canPlay', 'canplaythrough', 'canPlayThrough', 'durationchange', 'durationChange', 'emptied', 'emptied', 'encrypted', 'encrypted', 'ended', 'ended', 'error', 'error', 'gotpointercapture', 'gotPointerCapture', 'load', 'load', 'loadeddata', 'loadedData', 'loadedmetadata', 'loadedMetadata', 'loadstart', 'loadStart', 'lostpointercapture', 'lostPointerCapture', 'playing', 'playing', 'progress', 'progress', 'seeking', 'seeking', 'stalled', 'stalled', 'suspend', 'suspend', 'timeupdate', 'timeUpdate', TRANSITION_END, 'transitionEnd', 'waiting', 'waiting']; 5062 /** 5063 * Turns 5064 * ['abort', ...] 5065 * 5066 * into 5067 * 5068 * topLevelEventsToReactNames = new Map([ 5069 * ['abort', 'onAbort'], 5070 * ]); 5071 * 5072 * and registers them. 5073 */ 5074 5075 function registerSimplePluginEventsAndSetTheirPriorities(eventTypes, priority) { 5076 // As the event types are in pairs of two, we need to iterate 5077 // through in twos. The events are in pairs of two to save code 5078 // and improve init perf of processing this array, as it will 5079 // result in far fewer object allocations and property accesses 5080 // if we only use three arrays to process all the categories of 5081 // instead of tuples. 5082 for (var i = 0; i < eventTypes.length; i += 2) { 5083 var topEvent = eventTypes[i]; 5084 var event = eventTypes[i + 1]; 5085 var capitalizedEvent = event[0].toUpperCase() + event.slice(1); 5086 var reactName = 'on' + capitalizedEvent; 5087 eventPriorities.set(topEvent, priority); 5088 topLevelEventsToReactNames.set(topEvent, reactName); 5089 registerTwoPhaseEvent(reactName, [topEvent]); 5090 } 5091 } 5092 5093 function setEventPriorities(eventTypes, priority) { 5094 for (var i = 0; i < eventTypes.length; i++) { 5095 eventPriorities.set(eventTypes[i], priority); 5096 } 5097 } 5098 5099 function getEventPriorityForPluginSystem(domEventName) { 5100 var priority = eventPriorities.get(domEventName); // Default to a ContinuousEvent. Note: we might 5101 // want to warn if we can't detect the priority 5102 // for the event. 5103 5104 return priority === undefined ? ContinuousEvent : priority; 5105 } 5106 function registerSimpleEvents() { 5107 registerSimplePluginEventsAndSetTheirPriorities(discreteEventPairsForSimpleEventPlugin, DiscreteEvent); 5108 registerSimplePluginEventsAndSetTheirPriorities(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent); 5109 registerSimplePluginEventsAndSetTheirPriorities(continuousPairsForSimpleEventPlugin, ContinuousEvent); 5110 setEventPriorities(otherDiscreteEvents, DiscreteEvent); 5111 } 5112 5113 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 5114 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing, 5115 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef, 5116 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef, 5117 unstable_clear = _ReactInternals$Sched$1.unstable_clear, 5118 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent, 5119 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID, 5120 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe, 5121 unstable_trace = _ReactInternals$Sched$1.unstable_trace, 5122 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe, 5123 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap; 5124 5125 var Scheduler_now = unstable_now; 5126 5127 { 5128 // Provide explicit error message when production+profiling bundle of e.g. 5129 // react-dom is used with production (non-profiling) bundle of 5130 // scheduler/tracing 5131 if (!(__interactionsRef != null && __interactionsRef.current != null)) { 5132 { 5133 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); 5134 } 5135 } 5136 } 5137 // ascending numbers so we can compare them like numbers. They start at 90 to 5138 // avoid clashing with Scheduler's priorities. 5139 5140 var ImmediatePriority = 99; 5141 var UserBlockingPriority = 98; 5142 var NormalPriority = 97; 5143 var LowPriority = 96; 5144 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. 5145 5146 var NoPriority = 90; 5147 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. 5148 5149 var SyncLanePriority = 15; 5150 var SyncBatchedLanePriority = 14; 5151 var InputDiscreteHydrationLanePriority = 13; 5152 var InputDiscreteLanePriority = 12; 5153 var InputContinuousHydrationLanePriority = 11; 5154 var InputContinuousLanePriority = 10; 5155 var DefaultHydrationLanePriority = 9; 5156 var DefaultLanePriority = 8; 5157 var TransitionHydrationPriority = 7; 5158 var TransitionPriority = 6; 5159 var RetryLanePriority = 5; 5160 var SelectiveHydrationLanePriority = 4; 5161 var IdleHydrationLanePriority = 3; 5162 var IdleLanePriority = 2; 5163 var OffscreenLanePriority = 1; 5164 var NoLanePriority = 0; 5165 var TotalLanes = 31; 5166 var NoLanes = 5167 /* */ 5168 0; 5169 var NoLane = 5170 /* */ 5171 0; 5172 var SyncLane = 5173 /* */ 5174 1; 5175 var SyncBatchedLane = 5176 /* */ 5177 2; 5178 var InputDiscreteHydrationLane = 5179 /* */ 5180 4; 5181 var InputDiscreteLanes = 5182 /* */ 5183 24; 5184 var InputContinuousHydrationLane = 5185 /* */ 5186 32; 5187 var InputContinuousLanes = 5188 /* */ 5189 192; 5190 var DefaultHydrationLane = 5191 /* */ 5192 256; 5193 var DefaultLanes = 5194 /* */ 5195 3584; 5196 var TransitionHydrationLane = 5197 /* */ 5198 4096; 5199 var TransitionLanes = 5200 /* */ 5201 4186112; 5202 var RetryLanes = 5203 /* */ 5204 62914560; 5205 var SomeRetryLane = 5206 /* */ 5207 33554432; 5208 var SelectiveHydrationLane = 5209 /* */ 5210 67108864; 5211 var NonIdleLanes = 5212 /* */ 5213 134217727; 5214 var IdleHydrationLane = 5215 /* */ 5216 134217728; 5217 var IdleLanes = 5218 /* */ 5219 805306368; 5220 var OffscreenLane = 5221 /* */ 5222 1073741824; 5223 var NoTimestamp = -1; 5224 function setCurrentUpdateLanePriority(newLanePriority) { 5225 } // "Registers" used to "return" multiple values 5226 // Used by getHighestPriorityLanes and getNextLanes: 5227 5228 var return_highestLanePriority = DefaultLanePriority; 5229 5230 function getHighestPriorityLanes(lanes) { 5231 if ((SyncLane & lanes) !== NoLanes) { 5232 return_highestLanePriority = SyncLanePriority; 5233 return SyncLane; 5234 } 5235 5236 if ((SyncBatchedLane & lanes) !== NoLanes) { 5237 return_highestLanePriority = SyncBatchedLanePriority; 5238 return SyncBatchedLane; 5239 } 5240 5241 if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { 5242 return_highestLanePriority = InputDiscreteHydrationLanePriority; 5243 return InputDiscreteHydrationLane; 5244 } 5245 5246 var inputDiscreteLanes = InputDiscreteLanes & lanes; 5247 5248 if (inputDiscreteLanes !== NoLanes) { 5249 return_highestLanePriority = InputDiscreteLanePriority; 5250 return inputDiscreteLanes; 5251 } 5252 5253 if ((lanes & InputContinuousHydrationLane) !== NoLanes) { 5254 return_highestLanePriority = InputContinuousHydrationLanePriority; 5255 return InputContinuousHydrationLane; 5256 } 5257 5258 var inputContinuousLanes = InputContinuousLanes & lanes; 5259 5260 if (inputContinuousLanes !== NoLanes) { 5261 return_highestLanePriority = InputContinuousLanePriority; 5262 return inputContinuousLanes; 5263 } 5264 5265 if ((lanes & DefaultHydrationLane) !== NoLanes) { 5266 return_highestLanePriority = DefaultHydrationLanePriority; 5267 return DefaultHydrationLane; 5268 } 5269 5270 var defaultLanes = DefaultLanes & lanes; 5271 5272 if (defaultLanes !== NoLanes) { 5273 return_highestLanePriority = DefaultLanePriority; 5274 return defaultLanes; 5275 } 5276 5277 if ((lanes & TransitionHydrationLane) !== NoLanes) { 5278 return_highestLanePriority = TransitionHydrationPriority; 5279 return TransitionHydrationLane; 5280 } 5281 5282 var transitionLanes = TransitionLanes & lanes; 5283 5284 if (transitionLanes !== NoLanes) { 5285 return_highestLanePriority = TransitionPriority; 5286 return transitionLanes; 5287 } 5288 5289 var retryLanes = RetryLanes & lanes; 5290 5291 if (retryLanes !== NoLanes) { 5292 return_highestLanePriority = RetryLanePriority; 5293 return retryLanes; 5294 } 5295 5296 if (lanes & SelectiveHydrationLane) { 5297 return_highestLanePriority = SelectiveHydrationLanePriority; 5298 return SelectiveHydrationLane; 5299 } 5300 5301 if ((lanes & IdleHydrationLane) !== NoLanes) { 5302 return_highestLanePriority = IdleHydrationLanePriority; 5303 return IdleHydrationLane; 5304 } 5305 5306 var idleLanes = IdleLanes & lanes; 5307 5308 if (idleLanes !== NoLanes) { 5309 return_highestLanePriority = IdleLanePriority; 5310 return idleLanes; 5311 } 5312 5313 if ((OffscreenLane & lanes) !== NoLanes) { 5314 return_highestLanePriority = OffscreenLanePriority; 5315 return OffscreenLane; 5316 } 5317 5318 { 5319 error('Should have found matching lanes. This is a bug in React.'); 5320 } // This shouldn't be reachable, but as a fallback, return the entire bitmask. 5321 5322 5323 return_highestLanePriority = DefaultLanePriority; 5324 return lanes; 5325 } 5326 5327 function schedulerPriorityToLanePriority(schedulerPriorityLevel) { 5328 switch (schedulerPriorityLevel) { 5329 case ImmediatePriority: 5330 return SyncLanePriority; 5331 5332 case UserBlockingPriority: 5333 return InputContinuousLanePriority; 5334 5335 case NormalPriority: 5336 case LowPriority: 5337 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. 5338 return DefaultLanePriority; 5339 5340 case IdlePriority: 5341 return IdleLanePriority; 5342 5343 default: 5344 return NoLanePriority; 5345 } 5346 } 5347 function lanePriorityToSchedulerPriority(lanePriority) { 5348 switch (lanePriority) { 5349 case SyncLanePriority: 5350 case SyncBatchedLanePriority: 5351 return ImmediatePriority; 5352 5353 case InputDiscreteHydrationLanePriority: 5354 case InputDiscreteLanePriority: 5355 case InputContinuousHydrationLanePriority: 5356 case InputContinuousLanePriority: 5357 return UserBlockingPriority; 5358 5359 case DefaultHydrationLanePriority: 5360 case DefaultLanePriority: 5361 case TransitionHydrationPriority: 5362 case TransitionPriority: 5363 case SelectiveHydrationLanePriority: 5364 case RetryLanePriority: 5365 return NormalPriority; 5366 5367 case IdleHydrationLanePriority: 5368 case IdleLanePriority: 5369 case OffscreenLanePriority: 5370 return IdlePriority; 5371 5372 case NoLanePriority: 5373 return NoPriority; 5374 5375 default: 5376 { 5377 { 5378 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." ); 5379 } 5380 } 5381 5382 } 5383 } 5384 function getNextLanes(root, wipLanes) { 5385 // Early bailout if there's no pending work left. 5386 var pendingLanes = root.pendingLanes; 5387 5388 if (pendingLanes === NoLanes) { 5389 return_highestLanePriority = NoLanePriority; 5390 return NoLanes; 5391 } 5392 5393 var nextLanes = NoLanes; 5394 var nextLanePriority = NoLanePriority; 5395 var expiredLanes = root.expiredLanes; 5396 var suspendedLanes = root.suspendedLanes; 5397 var pingedLanes = root.pingedLanes; // Check if any work has expired. 5398 5399 if (expiredLanes !== NoLanes) { 5400 nextLanes = expiredLanes; 5401 nextLanePriority = return_highestLanePriority = SyncLanePriority; 5402 } else { 5403 // Do not work on any idle work until all the non-idle work has finished, 5404 // even if the work is suspended. 5405 var nonIdlePendingLanes = pendingLanes & NonIdleLanes; 5406 5407 if (nonIdlePendingLanes !== NoLanes) { 5408 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; 5409 5410 if (nonIdleUnblockedLanes !== NoLanes) { 5411 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); 5412 nextLanePriority = return_highestLanePriority; 5413 } else { 5414 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; 5415 5416 if (nonIdlePingedLanes !== NoLanes) { 5417 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); 5418 nextLanePriority = return_highestLanePriority; 5419 } 5420 } 5421 } else { 5422 // The only remaining work is Idle. 5423 var unblockedLanes = pendingLanes & ~suspendedLanes; 5424 5425 if (unblockedLanes !== NoLanes) { 5426 nextLanes = getHighestPriorityLanes(unblockedLanes); 5427 nextLanePriority = return_highestLanePriority; 5428 } else { 5429 if (pingedLanes !== NoLanes) { 5430 nextLanes = getHighestPriorityLanes(pingedLanes); 5431 nextLanePriority = return_highestLanePriority; 5432 } 5433 } 5434 } 5435 } 5436 5437 if (nextLanes === NoLanes) { 5438 // This should only be reachable if we're suspended 5439 // TODO: Consider warning in this path if a fallback timer is not scheduled. 5440 return NoLanes; 5441 } // If there are higher priority lanes, we'll include them even if they 5442 // are suspended. 5443 5444 5445 nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt 5446 // it and we'll lose our progress. We should only do this if the new lanes are 5447 // higher priority. 5448 5449 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't 5450 // bother waiting until the root is complete. 5451 (wipLanes & suspendedLanes) === NoLanes) { 5452 getHighestPriorityLanes(wipLanes); 5453 var wipLanePriority = return_highestLanePriority; 5454 5455 if (nextLanePriority <= wipLanePriority) { 5456 return wipLanes; 5457 } else { 5458 return_highestLanePriority = nextLanePriority; 5459 } 5460 } // Check for entangled lanes and add them to the batch. 5461 // 5462 // A lane is said to be entangled with another when it's not allowed to render 5463 // in a batch that does not also include the other lane. Typically we do this 5464 // when multiple updates have the same source, and we only want to respond to 5465 // the most recent event from that source. 5466 // 5467 // Note that we apply entanglements *after* checking for partial work above. 5468 // This means that if a lane is entangled during an interleaved event while 5469 // it's already rendering, we won't interrupt it. This is intentional, since 5470 // entanglement is usually "best effort": we'll try our best to render the 5471 // lanes in the same batch, but it's not worth throwing out partially 5472 // completed work in order to do it. 5473 // 5474 // For those exceptions where entanglement is semantically important, like 5475 // useMutableSource, we should ensure that there is no partial work at the 5476 // time we apply the entanglement. 5477 5478 5479 var entangledLanes = root.entangledLanes; 5480 5481 if (entangledLanes !== NoLanes) { 5482 var entanglements = root.entanglements; 5483 var lanes = nextLanes & entangledLanes; 5484 5485 while (lanes > 0) { 5486 var index = pickArbitraryLaneIndex(lanes); 5487 var lane = 1 << index; 5488 nextLanes |= entanglements[index]; 5489 lanes &= ~lane; 5490 } 5491 } 5492 5493 return nextLanes; 5494 } 5495 function getMostRecentEventTime(root, lanes) { 5496 var eventTimes = root.eventTimes; 5497 var mostRecentEventTime = NoTimestamp; 5498 5499 while (lanes > 0) { 5500 var index = pickArbitraryLaneIndex(lanes); 5501 var lane = 1 << index; 5502 var eventTime = eventTimes[index]; 5503 5504 if (eventTime > mostRecentEventTime) { 5505 mostRecentEventTime = eventTime; 5506 } 5507 5508 lanes &= ~lane; 5509 } 5510 5511 return mostRecentEventTime; 5512 } 5513 5514 function computeExpirationTime(lane, currentTime) { 5515 // TODO: Expiration heuristic is constant per lane, so could use a map. 5516 getHighestPriorityLanes(lane); 5517 var priority = return_highestLanePriority; 5518 5519 if (priority >= InputContinuousLanePriority) { 5520 // User interactions should expire slightly more quickly. 5521 // 5522 // NOTE: This is set to the corresponding constant as in Scheduler.js. When 5523 // we made it larger, a product metric in www regressed, suggesting there's 5524 // a user interaction that's being starved by a series of synchronous 5525 // updates. If that theory is correct, the proper solution is to fix the 5526 // starvation. However, this scenario supports the idea that expiration 5527 // times are an important safeguard when starvation does happen. 5528 // 5529 // Also note that, in the case of user input specifically, this will soon no 5530 // longer be an issue because we plan to make user input synchronous by 5531 // default (until you enter `startTransition`, of course.) 5532 // 5533 // If weren't planning to make these updates synchronous soon anyway, I 5534 // would probably make this number a configurable parameter. 5535 return currentTime + 250; 5536 } else if (priority >= TransitionPriority) { 5537 return currentTime + 5000; 5538 } else { 5539 // Anything idle priority or lower should never expire. 5540 return NoTimestamp; 5541 } 5542 } 5543 5544 function markStarvedLanesAsExpired(root, currentTime) { 5545 // TODO: This gets called every time we yield. We can optimize by storing 5546 // the earliest expiration time on the root. Then use that to quickly bail out 5547 // of this function. 5548 var pendingLanes = root.pendingLanes; 5549 var suspendedLanes = root.suspendedLanes; 5550 var pingedLanes = root.pingedLanes; 5551 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their 5552 // expiration time. If so, we'll assume the update is being starved and mark 5553 // it as expired to force it to finish. 5554 5555 var lanes = pendingLanes; 5556 5557 while (lanes > 0) { 5558 var index = pickArbitraryLaneIndex(lanes); 5559 var lane = 1 << index; 5560 var expirationTime = expirationTimes[index]; 5561 5562 if (expirationTime === NoTimestamp) { 5563 // Found a pending lane with no expiration time. If it's not suspended, or 5564 // if it's pinged, assume it's CPU-bound. Compute a new expiration time 5565 // using the current time. 5566 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) { 5567 // Assumes timestamps are monotonically increasing. 5568 expirationTimes[index] = computeExpirationTime(lane, currentTime); 5569 } 5570 } else if (expirationTime <= currentTime) { 5571 // This lane expired 5572 root.expiredLanes |= lane; 5573 } 5574 5575 lanes &= ~lane; 5576 } 5577 } // This returns the highest priority pending lanes regardless of whether they 5578 function getLanesToRetrySynchronouslyOnError(root) { 5579 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; 5580 5581 if (everythingButOffscreen !== NoLanes) { 5582 return everythingButOffscreen; 5583 } 5584 5585 if (everythingButOffscreen & OffscreenLane) { 5586 return OffscreenLane; 5587 } 5588 5589 return NoLanes; 5590 } 5591 function returnNextLanesPriority() { 5592 return return_highestLanePriority; 5593 } 5594 function includesNonIdleWork(lanes) { 5595 return (lanes & NonIdleLanes) !== NoLanes; 5596 } 5597 function includesOnlyRetries(lanes) { 5598 return (lanes & RetryLanes) === lanes; 5599 } 5600 function includesOnlyTransitions(lanes) { 5601 return (lanes & TransitionLanes) === lanes; 5602 } // To ensure consistency across multiple updates in the same event, this should 5603 // be a pure function, so that it always returns the same lane for given inputs. 5604 5605 function findUpdateLane(lanePriority, wipLanes) { 5606 switch (lanePriority) { 5607 case NoLanePriority: 5608 break; 5609 5610 case SyncLanePriority: 5611 return SyncLane; 5612 5613 case SyncBatchedLanePriority: 5614 return SyncBatchedLane; 5615 5616 case InputDiscreteLanePriority: 5617 { 5618 var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); 5619 5620 if (_lane === NoLane) { 5621 // Shift to the next priority level 5622 return findUpdateLane(InputContinuousLanePriority, wipLanes); 5623 } 5624 5625 return _lane; 5626 } 5627 5628 case InputContinuousLanePriority: 5629 { 5630 var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); 5631 5632 if (_lane2 === NoLane) { 5633 // Shift to the next priority level 5634 return findUpdateLane(DefaultLanePriority, wipLanes); 5635 } 5636 5637 return _lane2; 5638 } 5639 5640 case DefaultLanePriority: 5641 { 5642 var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); 5643 5644 if (_lane3 === NoLane) { 5645 // If all the default lanes are already being worked on, look for a 5646 // lane in the transition range. 5647 _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); 5648 5649 if (_lane3 === NoLane) { 5650 // All the transition lanes are taken, too. This should be very 5651 // rare, but as a last resort, pick a default lane. This will have 5652 // the effect of interrupting the current work-in-progress render. 5653 _lane3 = pickArbitraryLane(DefaultLanes); 5654 } 5655 } 5656 5657 return _lane3; 5658 } 5659 5660 case TransitionPriority: // Should be handled by findTransitionLane instead 5661 5662 case RetryLanePriority: 5663 // Should be handled by findRetryLane instead 5664 break; 5665 5666 case IdleLanePriority: 5667 var lane = pickArbitraryLane(IdleLanes & ~wipLanes); 5668 5669 if (lane === NoLane) { 5670 lane = pickArbitraryLane(IdleLanes); 5671 } 5672 5673 return lane; 5674 } 5675 5676 { 5677 { 5678 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." ); 5679 } 5680 } 5681 } // To ensure consistency across multiple updates in the same event, this should 5682 // be pure function, so that it always returns the same lane for given inputs. 5683 5684 function findTransitionLane(wipLanes, pendingLanes) { 5685 // First look for lanes that are completely unclaimed, i.e. have no 5686 // pending work. 5687 var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); 5688 5689 if (lane === NoLane) { 5690 // If all lanes have pending work, look for a lane that isn't currently 5691 // being worked on. 5692 lane = pickArbitraryLane(TransitionLanes & ~wipLanes); 5693 5694 if (lane === NoLane) { 5695 // If everything is being worked on, pick any lane. This has the 5696 // effect of interrupting the current work-in-progress. 5697 lane = pickArbitraryLane(TransitionLanes); 5698 } 5699 } 5700 5701 return lane; 5702 } // To ensure consistency across multiple updates in the same event, this should 5703 // be pure function, so that it always returns the same lane for given inputs. 5704 5705 function findRetryLane(wipLanes) { 5706 // This is a fork of `findUpdateLane` designed specifically for Suspense 5707 // "retries" — a special update that attempts to flip a Suspense boundary 5708 // from its placeholder state to its primary/resolved state. 5709 var lane = pickArbitraryLane(RetryLanes & ~wipLanes); 5710 5711 if (lane === NoLane) { 5712 lane = pickArbitraryLane(RetryLanes); 5713 } 5714 5715 return lane; 5716 } 5717 5718 function getHighestPriorityLane(lanes) { 5719 return lanes & -lanes; 5720 } 5721 5722 function getLowestPriorityLane(lanes) { 5723 // This finds the most significant non-zero bit. 5724 var index = 31 - clz32(lanes); 5725 return index < 0 ? NoLanes : 1 << index; 5726 } 5727 5728 function getEqualOrHigherPriorityLanes(lanes) { 5729 return (getLowestPriorityLane(lanes) << 1) - 1; 5730 } 5731 5732 function pickArbitraryLane(lanes) { 5733 // This wrapper function gets inlined. Only exists so to communicate that it 5734 // doesn't matter which bit is selected; you can pick any bit without 5735 // affecting the algorithms where its used. Here I'm using 5736 // getHighestPriorityLane because it requires the fewest operations. 5737 return getHighestPriorityLane(lanes); 5738 } 5739 5740 function pickArbitraryLaneIndex(lanes) { 5741 return 31 - clz32(lanes); 5742 } 5743 5744 function laneToIndex(lane) { 5745 return pickArbitraryLaneIndex(lane); 5746 } 5747 5748 function includesSomeLane(a, b) { 5749 return (a & b) !== NoLanes; 5750 } 5751 function isSubsetOfLanes(set, subset) { 5752 return (set & subset) === subset; 5753 } 5754 function mergeLanes(a, b) { 5755 return a | b; 5756 } 5757 function removeLanes(set, subset) { 5758 return set & ~subset; 5759 } // Seems redundant, but it changes the type from a single lane (used for 5760 // updates) to a group of lanes (used for flushing work). 5761 5762 function laneToLanes(lane) { 5763 return lane; 5764 } 5765 function higherPriorityLane(a, b) { 5766 // This works because the bit ranges decrease in priority as you go left. 5767 return a !== NoLane && a < b ? a : b; 5768 } 5769 function createLaneMap(initial) { 5770 // Intentionally pushing one by one. 5771 // https://v8.dev/blog/elements-kinds#avoid-creating-holes 5772 var laneMap = []; 5773 5774 for (var i = 0; i < TotalLanes; i++) { 5775 laneMap.push(initial); 5776 } 5777 5778 return laneMap; 5779 } 5780 function markRootUpdated(root, updateLane, eventTime) { 5781 root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But 5782 // it's not practical to try every single possible combination. We need a 5783 // heuristic to decide which lanes to attempt to render, and in which batches. 5784 // For now, we use the same heuristic as in the old ExpirationTimes model: 5785 // retry any lane at equal or lower priority, but don't try updates at higher 5786 // priority without also including the lower priority updates. This works well 5787 // when considering updates across different priority levels, but isn't 5788 // sufficient for updates within the same priority, since we want to treat 5789 // those updates as parallel. 5790 // Unsuspend any update at equal or lower priority. 5791 5792 var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 5793 5794 root.suspendedLanes &= higherPriorityLanes; 5795 root.pingedLanes &= higherPriorityLanes; 5796 var eventTimes = root.eventTimes; 5797 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most 5798 // recent event, and we assume time is monotonically increasing. 5799 5800 eventTimes[index] = eventTime; 5801 } 5802 function markRootSuspended(root, suspendedLanes) { 5803 root.suspendedLanes |= suspendedLanes; 5804 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. 5805 5806 var expirationTimes = root.expirationTimes; 5807 var lanes = suspendedLanes; 5808 5809 while (lanes > 0) { 5810 var index = pickArbitraryLaneIndex(lanes); 5811 var lane = 1 << index; 5812 expirationTimes[index] = NoTimestamp; 5813 lanes &= ~lane; 5814 } 5815 } 5816 function markRootPinged(root, pingedLanes, eventTime) { 5817 root.pingedLanes |= root.suspendedLanes & pingedLanes; 5818 } 5819 function markDiscreteUpdatesExpired(root) { 5820 root.expiredLanes |= InputDiscreteLanes & root.pendingLanes; 5821 } 5822 function hasDiscreteLanes(lanes) { 5823 return (lanes & InputDiscreteLanes) !== NoLanes; 5824 } 5825 function markRootMutableRead(root, updateLane) { 5826 root.mutableReadLanes |= updateLane & root.pendingLanes; 5827 } 5828 function markRootFinished(root, remainingLanes) { 5829 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; 5830 root.pendingLanes = remainingLanes; // Let's try everything again 5831 5832 root.suspendedLanes = 0; 5833 root.pingedLanes = 0; 5834 root.expiredLanes &= remainingLanes; 5835 root.mutableReadLanes &= remainingLanes; 5836 root.entangledLanes &= remainingLanes; 5837 var entanglements = root.entanglements; 5838 var eventTimes = root.eventTimes; 5839 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work 5840 5841 var lanes = noLongerPendingLanes; 5842 5843 while (lanes > 0) { 5844 var index = pickArbitraryLaneIndex(lanes); 5845 var lane = 1 << index; 5846 entanglements[index] = NoLanes; 5847 eventTimes[index] = NoTimestamp; 5848 expirationTimes[index] = NoTimestamp; 5849 lanes &= ~lane; 5850 } 5851 } 5852 function markRootEntangled(root, entangledLanes) { 5853 root.entangledLanes |= entangledLanes; 5854 var entanglements = root.entanglements; 5855 var lanes = entangledLanes; 5856 5857 while (lanes > 0) { 5858 var index = pickArbitraryLaneIndex(lanes); 5859 var lane = 1 << index; 5860 entanglements[index] |= entangledLanes; 5861 lanes &= ~lane; 5862 } 5863 } 5864 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. 5865 // Based on: 5866 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 5867 5868 var log = Math.log; 5869 var LN2 = Math.LN2; 5870 5871 function clz32Fallback(lanes) { 5872 if (lanes === 0) { 5873 return 32; 5874 } 5875 5876 return 31 - (log(lanes) / LN2 | 0) | 0; 5877 } 5878 5879 // Intentionally not named imports because Rollup would use dynamic dispatch for 5880 var UserBlockingPriority$1 = unstable_UserBlockingPriority, 5881 runWithPriority = unstable_runWithPriority; // TODO: can we stop exporting these? 5882 5883 var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra. 5884 // We'd like to remove this but it's not clear if this is safe. 5885 5886 function setEnabled(enabled) { 5887 _enabled = !!enabled; 5888 } 5889 function isEnabled() { 5890 return _enabled; 5891 } 5892 function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) { 5893 var eventPriority = getEventPriorityForPluginSystem(domEventName); 5894 var listenerWrapper; 5895 5896 switch (eventPriority) { 5897 case DiscreteEvent: 5898 listenerWrapper = dispatchDiscreteEvent; 5899 break; 5900 5901 case UserBlockingEvent: 5902 listenerWrapper = dispatchUserBlockingUpdate; 5903 break; 5904 5905 case ContinuousEvent: 5906 default: 5907 listenerWrapper = dispatchEvent; 5908 break; 5909 } 5910 5911 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer); 5912 } 5913 5914 function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) { 5915 { 5916 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp); 5917 } 5918 5919 discreteUpdates(dispatchEvent, domEventName, eventSystemFlags, container, nativeEvent); 5920 } 5921 5922 function dispatchUserBlockingUpdate(domEventName, eventSystemFlags, container, nativeEvent) { 5923 { 5924 runWithPriority(UserBlockingPriority$1, dispatchEvent.bind(null, domEventName, eventSystemFlags, container, nativeEvent)); 5925 } 5926 } 5927 5928 function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) { 5929 if (!_enabled) { 5930 return; 5931 } 5932 5933 var allowReplay = true; 5934 5935 { 5936 // TODO: replaying capture phase events is currently broken 5937 // because we used to do it during top-level native bubble handlers 5938 // but now we use different bubble and capture handlers. 5939 // In eager mode, we attach capture listeners early, so we need 5940 // to filter them out until we fix the logic to handle them correctly. 5941 // This could've been outside the flag but I put it inside to reduce risk. 5942 allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0; 5943 } 5944 5945 if (allowReplay && hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(domEventName)) { 5946 // If we already have a queue of discrete events, and this is another discrete 5947 // event, then we can't dispatch it regardless of its target, since they 5948 // need to dispatch in order. 5949 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know. 5950 domEventName, eventSystemFlags, targetContainer, nativeEvent); 5951 return; 5952 } 5953 5954 var blockedOn = attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent); 5955 5956 if (blockedOn === null) { 5957 // We successfully dispatched this event. 5958 if (allowReplay) { 5959 clearIfContinuousEvent(domEventName, nativeEvent); 5960 } 5961 5962 return; 5963 } 5964 5965 if (allowReplay) { 5966 if (isReplayableDiscreteEvent(domEventName)) { 5967 // This this to be replayed later once the target is available. 5968 queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent); 5969 return; 5970 } 5971 5972 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) { 5973 return; 5974 } // We need to clear only if we didn't queue because 5975 // queueing is accummulative. 5976 5977 5978 clearIfContinuousEvent(domEventName, nativeEvent); 5979 } // This is not replayable so we'll invoke it but without a target, 5980 // in case the event system needs to trace it. 5981 5982 5983 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer); 5984 } // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked. 5985 5986 function attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) { 5987 // TODO: Warn if _enabled is false. 5988 var nativeEventTarget = getEventTarget(nativeEvent); 5989 var targetInst = getClosestInstanceFromNode(nativeEventTarget); 5990 5991 if (targetInst !== null) { 5992 var nearestMounted = getNearestMountedFiber(targetInst); 5993 5994 if (nearestMounted === null) { 5995 // This tree has been unmounted already. Dispatch without a target. 5996 targetInst = null; 5997 } else { 5998 var tag = nearestMounted.tag; 5999 6000 if (tag === SuspenseComponent) { 6001 var instance = getSuspenseInstanceFromFiber(nearestMounted); 6002 6003 if (instance !== null) { 6004 // Queue the event to be replayed later. Abort dispatching since we 6005 // don't want this event dispatched twice through the event system. 6006 // TODO: If this is the first discrete event in the queue. Schedule an increased 6007 // priority for this boundary. 6008 return instance; 6009 } // This shouldn't happen, something went wrong but to avoid blocking 6010 // the whole system, dispatch the event without a target. 6011 // TODO: Warn. 6012 6013 6014 targetInst = null; 6015 } else if (tag === HostRoot) { 6016 var root = nearestMounted.stateNode; 6017 6018 if (root.hydrate) { 6019 // If this happens during a replay something went wrong and it might block 6020 // the whole system. 6021 return getContainerFromFiber(nearestMounted); 6022 } 6023 6024 targetInst = null; 6025 } else if (nearestMounted !== targetInst) { 6026 // If we get an event (ex: img onload) before committing that 6027 // component's mount, ignore it for now (that is, treat it as if it was an 6028 // event on a non-React tree). We might also consider queueing events and 6029 // dispatching them after the mount. 6030 targetInst = null; 6031 } 6032 } 6033 } 6034 6035 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer); // We're not blocked on anything. 6036 6037 return null; 6038 } 6039 6040 function addEventBubbleListener(target, eventType, listener) { 6041 target.addEventListener(eventType, listener, false); 6042 return listener; 6043 } 6044 function addEventCaptureListener(target, eventType, listener) { 6045 target.addEventListener(eventType, listener, true); 6046 return listener; 6047 } 6048 function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) { 6049 target.addEventListener(eventType, listener, { 6050 capture: true, 6051 passive: passive 6052 }); 6053 return listener; 6054 } 6055 function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) { 6056 target.addEventListener(eventType, listener, { 6057 passive: passive 6058 }); 6059 return listener; 6060 } 6061 6062 /** 6063 * These variables store information about text content of a target node, 6064 * allowing comparison of content before and after a given event. 6065 * 6066 * Identify the node where selection currently begins, then observe 6067 * both its text content and its current position in the DOM. Since the 6068 * browser may natively replace the target node during composition, we can 6069 * use its position to find its replacement. 6070 * 6071 * 6072 */ 6073 var root = null; 6074 var startText = null; 6075 var fallbackText = null; 6076 function initialize(nativeEventTarget) { 6077 root = nativeEventTarget; 6078 startText = getText(); 6079 return true; 6080 } 6081 function reset() { 6082 root = null; 6083 startText = null; 6084 fallbackText = null; 6085 } 6086 function getData() { 6087 if (fallbackText) { 6088 return fallbackText; 6089 } 6090 6091 var start; 6092 var startValue = startText; 6093 var startLength = startValue.length; 6094 var end; 6095 var endValue = getText(); 6096 var endLength = endValue.length; 6097 6098 for (start = 0; start < startLength; start++) { 6099 if (startValue[start] !== endValue[start]) { 6100 break; 6101 } 6102 } 6103 6104 var minEnd = startLength - start; 6105 6106 for (end = 1; end <= minEnd; end++) { 6107 if (startValue[startLength - end] !== endValue[endLength - end]) { 6108 break; 6109 } 6110 } 6111 6112 var sliceTail = end > 1 ? 1 - end : undefined; 6113 fallbackText = endValue.slice(start, sliceTail); 6114 return fallbackText; 6115 } 6116 function getText() { 6117 if ('value' in root) { 6118 return root.value; 6119 } 6120 6121 return root.textContent; 6122 } 6123 6124 /** 6125 * `charCode` represents the actual "character code" and is safe to use with 6126 * `String.fromCharCode`. As such, only keys that correspond to printable 6127 * characters produce a valid `charCode`, the only exception to this is Enter. 6128 * The Tab-key is considered non-printable and does not have a `charCode`, 6129 * presumably because it does not produce a tab-character in browsers. 6130 * 6131 * @param {object} nativeEvent Native browser event. 6132 * @return {number} Normalized `charCode` property. 6133 */ 6134 function getEventCharCode(nativeEvent) { 6135 var charCode; 6136 var keyCode = nativeEvent.keyCode; 6137 6138 if ('charCode' in nativeEvent) { 6139 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`. 6140 6141 if (charCode === 0 && keyCode === 13) { 6142 charCode = 13; 6143 } 6144 } else { 6145 // IE8 does not implement `charCode`, but `keyCode` has the correct value. 6146 charCode = keyCode; 6147 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux) 6148 // report Enter as charCode 10 when ctrl is pressed. 6149 6150 6151 if (charCode === 10) { 6152 charCode = 13; 6153 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. 6154 // Must not discard the (non-)printable Enter-key. 6155 6156 6157 if (charCode >= 32 || charCode === 13) { 6158 return charCode; 6159 } 6160 6161 return 0; 6162 } 6163 6164 function functionThatReturnsTrue() { 6165 return true; 6166 } 6167 6168 function functionThatReturnsFalse() { 6169 return false; 6170 } // This is intentionally a factory so that we have different returned constructors. 6171 // If we had a single constructor, it would be megamorphic and engines would deopt. 6172 6173 6174 function createSyntheticEvent(Interface) { 6175 /** 6176 * Synthetic events are dispatched by event plugins, typically in response to a 6177 * top-level event delegation handler. 6178 * 6179 * These systems should generally use pooling to reduce the frequency of garbage 6180 * collection. The system should check `isPersistent` to determine whether the 6181 * event should be released into the pool after being dispatched. Users that 6182 * need a persisted event should invoke `persist`. 6183 * 6184 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by 6185 * normalizing browser quirks. Subclasses do not necessarily have to implement a 6186 * DOM interface; custom application-specific events can also subclass this. 6187 */ 6188 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) { 6189 this._reactName = reactName; 6190 this._targetInst = targetInst; 6191 this.type = reactEventType; 6192 this.nativeEvent = nativeEvent; 6193 this.target = nativeEventTarget; 6194 this.currentTarget = null; 6195 6196 for (var _propName in Interface) { 6197 if (!Interface.hasOwnProperty(_propName)) { 6198 continue; 6199 } 6200 6201 var normalize = Interface[_propName]; 6202 6203 if (normalize) { 6204 this[_propName] = normalize(nativeEvent); 6205 } else { 6206 this[_propName] = nativeEvent[_propName]; 6207 } 6208 } 6209 6210 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; 6211 6212 if (defaultPrevented) { 6213 this.isDefaultPrevented = functionThatReturnsTrue; 6214 } else { 6215 this.isDefaultPrevented = functionThatReturnsFalse; 6216 } 6217 6218 this.isPropagationStopped = functionThatReturnsFalse; 6219 return this; 6220 } 6221 6222 _assign(SyntheticBaseEvent.prototype, { 6223 preventDefault: function () { 6224 this.defaultPrevented = true; 6225 var event = this.nativeEvent; 6226 6227 if (!event) { 6228 return; 6229 } 6230 6231 if (event.preventDefault) { 6232 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE 6233 } else if (typeof event.returnValue !== 'unknown') { 6234 event.returnValue = false; 6235 } 6236 6237 this.isDefaultPrevented = functionThatReturnsTrue; 6238 }, 6239 stopPropagation: function () { 6240 var event = this.nativeEvent; 6241 6242 if (!event) { 6243 return; 6244 } 6245 6246 if (event.stopPropagation) { 6247 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE 6248 } else if (typeof event.cancelBubble !== 'unknown') { 6249 // The ChangeEventPlugin registers a "propertychange" event for 6250 // IE. This event does not support bubbling or cancelling, and 6251 // any references to cancelBubble throw "Member not found". A 6252 // typeof check of "unknown" circumvents this issue (and is also 6253 // IE specific). 6254 event.cancelBubble = true; 6255 } 6256 6257 this.isPropagationStopped = functionThatReturnsTrue; 6258 }, 6259 6260 /** 6261 * We release all dispatched `SyntheticEvent`s after each event loop, adding 6262 * them back into the pool. This allows a way to hold onto a reference that 6263 * won't be added back into the pool. 6264 */ 6265 persist: function () {// Modern event system doesn't use pooling. 6266 }, 6267 6268 /** 6269 * Checks if this event should be released back into the pool. 6270 * 6271 * @return {boolean} True if this should not be released, false otherwise. 6272 */ 6273 isPersistent: functionThatReturnsTrue 6274 }); 6275 6276 return SyntheticBaseEvent; 6277 } 6278 /** 6279 * @interface Event 6280 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6281 */ 6282 6283 6284 var EventInterface = { 6285 eventPhase: 0, 6286 bubbles: 0, 6287 cancelable: 0, 6288 timeStamp: function (event) { 6289 return event.timeStamp || Date.now(); 6290 }, 6291 defaultPrevented: 0, 6292 isTrusted: 0 6293 }; 6294 var SyntheticEvent = createSyntheticEvent(EventInterface); 6295 6296 var UIEventInterface = _assign({}, EventInterface, { 6297 view: 0, 6298 detail: 0 6299 }); 6300 6301 var SyntheticUIEvent = createSyntheticEvent(UIEventInterface); 6302 var lastMovementX; 6303 var lastMovementY; 6304 var lastMouseEvent; 6305 6306 function updateMouseMovementPolyfillState(event) { 6307 if (event !== lastMouseEvent) { 6308 if (lastMouseEvent && event.type === 'mousemove') { 6309 lastMovementX = event.screenX - lastMouseEvent.screenX; 6310 lastMovementY = event.screenY - lastMouseEvent.screenY; 6311 } else { 6312 lastMovementX = 0; 6313 lastMovementY = 0; 6314 } 6315 6316 lastMouseEvent = event; 6317 } 6318 } 6319 /** 6320 * @interface MouseEvent 6321 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6322 */ 6323 6324 6325 var MouseEventInterface = _assign({}, UIEventInterface, { 6326 screenX: 0, 6327 screenY: 0, 6328 clientX: 0, 6329 clientY: 0, 6330 pageX: 0, 6331 pageY: 0, 6332 ctrlKey: 0, 6333 shiftKey: 0, 6334 altKey: 0, 6335 metaKey: 0, 6336 getModifierState: getEventModifierState, 6337 button: 0, 6338 buttons: 0, 6339 relatedTarget: function (event) { 6340 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement; 6341 return event.relatedTarget; 6342 }, 6343 movementX: function (event) { 6344 if ('movementX' in event) { 6345 return event.movementX; 6346 } 6347 6348 updateMouseMovementPolyfillState(event); 6349 return lastMovementX; 6350 }, 6351 movementY: function (event) { 6352 if ('movementY' in event) { 6353 return event.movementY; 6354 } // Don't need to call updateMouseMovementPolyfillState() here 6355 // because it's guaranteed to have already run when movementX 6356 // was copied. 6357 6358 6359 return lastMovementY; 6360 } 6361 }); 6362 6363 var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface); 6364 /** 6365 * @interface DragEvent 6366 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6367 */ 6368 6369 var DragEventInterface = _assign({}, MouseEventInterface, { 6370 dataTransfer: 0 6371 }); 6372 6373 var SyntheticDragEvent = createSyntheticEvent(DragEventInterface); 6374 /** 6375 * @interface FocusEvent 6376 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6377 */ 6378 6379 var FocusEventInterface = _assign({}, UIEventInterface, { 6380 relatedTarget: 0 6381 }); 6382 6383 var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface); 6384 /** 6385 * @interface Event 6386 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface 6387 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent 6388 */ 6389 6390 var AnimationEventInterface = _assign({}, EventInterface, { 6391 animationName: 0, 6392 elapsedTime: 0, 6393 pseudoElement: 0 6394 }); 6395 6396 var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface); 6397 /** 6398 * @interface Event 6399 * @see http://www.w3.org/TR/clipboard-apis/ 6400 */ 6401 6402 var ClipboardEventInterface = _assign({}, EventInterface, { 6403 clipboardData: function (event) { 6404 return 'clipboardData' in event ? event.clipboardData : window.clipboardData; 6405 } 6406 }); 6407 6408 var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface); 6409 /** 6410 * @interface Event 6411 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents 6412 */ 6413 6414 var CompositionEventInterface = _assign({}, EventInterface, { 6415 data: 0 6416 }); 6417 6418 var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface); 6419 /** 6420 * @interface Event 6421 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 6422 * /#events-inputevents 6423 */ 6424 // Happens to share the same list for now. 6425 6426 var SyntheticInputEvent = SyntheticCompositionEvent; 6427 /** 6428 * Normalization of deprecated HTML5 `key` values 6429 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 6430 */ 6431 6432 var normalizeKey = { 6433 Esc: 'Escape', 6434 Spacebar: ' ', 6435 Left: 'ArrowLeft', 6436 Up: 'ArrowUp', 6437 Right: 'ArrowRight', 6438 Down: 'ArrowDown', 6439 Del: 'Delete', 6440 Win: 'OS', 6441 Menu: 'ContextMenu', 6442 Apps: 'ContextMenu', 6443 Scroll: 'ScrollLock', 6444 MozPrintableKey: 'Unidentified' 6445 }; 6446 /** 6447 * Translation from legacy `keyCode` to HTML5 `key` 6448 * Only special keys supported, all others depend on keyboard layout or browser 6449 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 6450 */ 6451 6452 var translateToKey = { 6453 '8': 'Backspace', 6454 '9': 'Tab', 6455 '12': 'Clear', 6456 '13': 'Enter', 6457 '16': 'Shift', 6458 '17': 'Control', 6459 '18': 'Alt', 6460 '19': 'Pause', 6461 '20': 'CapsLock', 6462 '27': 'Escape', 6463 '32': ' ', 6464 '33': 'PageUp', 6465 '34': 'PageDown', 6466 '35': 'End', 6467 '36': 'Home', 6468 '37': 'ArrowLeft', 6469 '38': 'ArrowUp', 6470 '39': 'ArrowRight', 6471 '40': 'ArrowDown', 6472 '45': 'Insert', 6473 '46': 'Delete', 6474 '112': 'F1', 6475 '113': 'F2', 6476 '114': 'F3', 6477 '115': 'F4', 6478 '116': 'F5', 6479 '117': 'F6', 6480 '118': 'F7', 6481 '119': 'F8', 6482 '120': 'F9', 6483 '121': 'F10', 6484 '122': 'F11', 6485 '123': 'F12', 6486 '144': 'NumLock', 6487 '145': 'ScrollLock', 6488 '224': 'Meta' 6489 }; 6490 /** 6491 * @param {object} nativeEvent Native browser event. 6492 * @return {string} Normalized `key` property. 6493 */ 6494 6495 function getEventKey(nativeEvent) { 6496 if (nativeEvent.key) { 6497 // Normalize inconsistent values reported by browsers due to 6498 // implementations of a working draft specification. 6499 // FireFox implements `key` but returns `MozPrintableKey` for all 6500 // printable characters (normalized to `Unidentified`), ignore it. 6501 var key = normalizeKey[nativeEvent.key] || nativeEvent.key; 6502 6503 if (key !== 'Unidentified') { 6504 return key; 6505 } 6506 } // Browser does not implement `key`, polyfill as much of it as we can. 6507 6508 6509 if (nativeEvent.type === 'keypress') { 6510 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can 6511 // thus be captured by `keypress`, no other non-printable key should. 6512 6513 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); 6514 } 6515 6516 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { 6517 // While user keyboard layout determines the actual meaning of each 6518 // `keyCode` value, almost all function keys have a universal value. 6519 return translateToKey[nativeEvent.keyCode] || 'Unidentified'; 6520 } 6521 6522 return ''; 6523 } 6524 /** 6525 * Translation from modifier key to the associated property in the event. 6526 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers 6527 */ 6528 6529 6530 var modifierKeyToProp = { 6531 Alt: 'altKey', 6532 Control: 'ctrlKey', 6533 Meta: 'metaKey', 6534 Shift: 'shiftKey' 6535 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support 6536 // getModifierState. If getModifierState is not supported, we map it to a set of 6537 // modifier keys exposed by the event. In this case, Lock-keys are not supported. 6538 6539 function modifierStateGetter(keyArg) { 6540 var syntheticEvent = this; 6541 var nativeEvent = syntheticEvent.nativeEvent; 6542 6543 if (nativeEvent.getModifierState) { 6544 return nativeEvent.getModifierState(keyArg); 6545 } 6546 6547 var keyProp = modifierKeyToProp[keyArg]; 6548 return keyProp ? !!nativeEvent[keyProp] : false; 6549 } 6550 6551 function getEventModifierState(nativeEvent) { 6552 return modifierStateGetter; 6553 } 6554 /** 6555 * @interface KeyboardEvent 6556 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6557 */ 6558 6559 6560 var KeyboardEventInterface = _assign({}, UIEventInterface, { 6561 key: getEventKey, 6562 code: 0, 6563 location: 0, 6564 ctrlKey: 0, 6565 shiftKey: 0, 6566 altKey: 0, 6567 metaKey: 0, 6568 repeat: 0, 6569 locale: 0, 6570 getModifierState: getEventModifierState, 6571 // Legacy Interface 6572 charCode: function (event) { 6573 // `charCode` is the result of a KeyPress event and represents the value of 6574 // the actual printable character. 6575 // KeyPress is deprecated, but its replacement is not yet final and not 6576 // implemented in any major browser. Only KeyPress has charCode. 6577 if (event.type === 'keypress') { 6578 return getEventCharCode(event); 6579 } 6580 6581 return 0; 6582 }, 6583 keyCode: function (event) { 6584 // `keyCode` is the result of a KeyDown/Up event and represents the value of 6585 // physical keyboard key. 6586 // The actual meaning of the value depends on the users' keyboard layout 6587 // which cannot be detected. Assuming that it is a US keyboard layout 6588 // provides a surprisingly accurate mapping for US and European users. 6589 // Due to this, it is left to the user to implement at this time. 6590 if (event.type === 'keydown' || event.type === 'keyup') { 6591 return event.keyCode; 6592 } 6593 6594 return 0; 6595 }, 6596 which: function (event) { 6597 // `which` is an alias for either `keyCode` or `charCode` depending on the 6598 // type of the event. 6599 if (event.type === 'keypress') { 6600 return getEventCharCode(event); 6601 } 6602 6603 if (event.type === 'keydown' || event.type === 'keyup') { 6604 return event.keyCode; 6605 } 6606 6607 return 0; 6608 } 6609 }); 6610 6611 var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface); 6612 /** 6613 * @interface PointerEvent 6614 * @see http://www.w3.org/TR/pointerevents/ 6615 */ 6616 6617 var PointerEventInterface = _assign({}, MouseEventInterface, { 6618 pointerId: 0, 6619 width: 0, 6620 height: 0, 6621 pressure: 0, 6622 tangentialPressure: 0, 6623 tiltX: 0, 6624 tiltY: 0, 6625 twist: 0, 6626 pointerType: 0, 6627 isPrimary: 0 6628 }); 6629 6630 var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface); 6631 /** 6632 * @interface TouchEvent 6633 * @see http://www.w3.org/TR/touch-events/ 6634 */ 6635 6636 var TouchEventInterface = _assign({}, UIEventInterface, { 6637 touches: 0, 6638 targetTouches: 0, 6639 changedTouches: 0, 6640 altKey: 0, 6641 metaKey: 0, 6642 ctrlKey: 0, 6643 shiftKey: 0, 6644 getModifierState: getEventModifierState 6645 }); 6646 6647 var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface); 6648 /** 6649 * @interface Event 6650 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- 6651 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent 6652 */ 6653 6654 var TransitionEventInterface = _assign({}, EventInterface, { 6655 propertyName: 0, 6656 elapsedTime: 0, 6657 pseudoElement: 0 6658 }); 6659 6660 var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface); 6661 /** 6662 * @interface WheelEvent 6663 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6664 */ 6665 6666 var WheelEventInterface = _assign({}, MouseEventInterface, { 6667 deltaX: function (event) { 6668 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 6669 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; 6670 }, 6671 deltaY: function (event) { 6672 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 6673 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 6674 'wheelDelta' in event ? -event.wheelDelta : 0; 6675 }, 6676 deltaZ: 0, 6677 // Browsers without "deltaMode" is reporting in raw wheel delta where one 6678 // notch on the scroll is always +/- 120, roughly equivalent to pixels. 6679 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or 6680 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. 6681 deltaMode: 0 6682 }); 6683 6684 var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface); 6685 6686 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space 6687 6688 var START_KEYCODE = 229; 6689 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window; 6690 var documentMode = null; 6691 6692 if (canUseDOM && 'documentMode' in document) { 6693 documentMode = document.documentMode; 6694 } // Webkit offers a very useful `textInput` event that can be used to 6695 // directly represent `beforeInput`. The IE `textinput` event is not as 6696 // useful, so we don't use it. 6697 6698 6699 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied 6700 // by the native compositionend event may be incorrect. Japanese ideographic 6701 // spaces, for instance (\u3000) are not recorded correctly. 6702 6703 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); 6704 var SPACEBAR_CODE = 32; 6705 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); 6706 6707 function registerEvents() { 6708 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']); 6709 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 6710 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 6711 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 6712 } // Track whether we've ever handled a keypress on the space key. 6713 6714 6715 var hasSpaceKeypress = false; 6716 /** 6717 * Return whether a native keypress event is assumed to be a command. 6718 * This is required because Firefox fires `keypress` events for key commands 6719 * (cut, copy, select-all, etc.) even though no character is inserted. 6720 */ 6721 6722 function isKeypressCommand(nativeEvent) { 6723 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command. 6724 !(nativeEvent.ctrlKey && nativeEvent.altKey); 6725 } 6726 /** 6727 * Translate native top level events into event types. 6728 */ 6729 6730 6731 function getCompositionEventType(domEventName) { 6732 switch (domEventName) { 6733 case 'compositionstart': 6734 return 'onCompositionStart'; 6735 6736 case 'compositionend': 6737 return 'onCompositionEnd'; 6738 6739 case 'compositionupdate': 6740 return 'onCompositionUpdate'; 6741 } 6742 } 6743 /** 6744 * Does our fallback best-guess model think this event signifies that 6745 * composition has begun? 6746 */ 6747 6748 6749 function isFallbackCompositionStart(domEventName, nativeEvent) { 6750 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE; 6751 } 6752 /** 6753 * Does our fallback mode think that this event is the end of composition? 6754 */ 6755 6756 6757 function isFallbackCompositionEnd(domEventName, nativeEvent) { 6758 switch (domEventName) { 6759 case 'keyup': 6760 // Command keys insert or clear IME input. 6761 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; 6762 6763 case 'keydown': 6764 // Expect IME keyCode on each keydown. If we get any other 6765 // code we must have exited earlier. 6766 return nativeEvent.keyCode !== START_KEYCODE; 6767 6768 case 'keypress': 6769 case 'mousedown': 6770 case 'focusout': 6771 // Events are not possible without cancelling IME. 6772 return true; 6773 6774 default: 6775 return false; 6776 } 6777 } 6778 /** 6779 * Google Input Tools provides composition data via a CustomEvent, 6780 * with the `data` property populated in the `detail` object. If this 6781 * is available on the event object, use it. If not, this is a plain 6782 * composition event and we have nothing special to extract. 6783 * 6784 * @param {object} nativeEvent 6785 * @return {?string} 6786 */ 6787 6788 6789 function getDataFromCustomEvent(nativeEvent) { 6790 var detail = nativeEvent.detail; 6791 6792 if (typeof detail === 'object' && 'data' in detail) { 6793 return detail.data; 6794 } 6795 6796 return null; 6797 } 6798 /** 6799 * Check if a composition event was triggered by Korean IME. 6800 * Our fallback mode does not work well with IE's Korean IME, 6801 * so just use native composition events when Korean IME is used. 6802 * Although CompositionEvent.locale property is deprecated, 6803 * it is available in IE, where our fallback mode is enabled. 6804 * 6805 * @param {object} nativeEvent 6806 * @return {boolean} 6807 */ 6808 6809 6810 function isUsingKoreanIME(nativeEvent) { 6811 return nativeEvent.locale === 'ko'; 6812 } // Track the current IME composition status, if any. 6813 6814 6815 var isComposing = false; 6816 /** 6817 * @return {?object} A SyntheticCompositionEvent. 6818 */ 6819 6820 function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) { 6821 var eventType; 6822 var fallbackData; 6823 6824 if (canUseCompositionEvent) { 6825 eventType = getCompositionEventType(domEventName); 6826 } else if (!isComposing) { 6827 if (isFallbackCompositionStart(domEventName, nativeEvent)) { 6828 eventType = 'onCompositionStart'; 6829 } 6830 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) { 6831 eventType = 'onCompositionEnd'; 6832 } 6833 6834 if (!eventType) { 6835 return null; 6836 } 6837 6838 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) { 6839 // The current composition is stored statically and must not be 6840 // overwritten while composition continues. 6841 if (!isComposing && eventType === 'onCompositionStart') { 6842 isComposing = initialize(nativeEventTarget); 6843 } else if (eventType === 'onCompositionEnd') { 6844 if (isComposing) { 6845 fallbackData = getData(); 6846 } 6847 } 6848 } 6849 6850 var listeners = accumulateTwoPhaseListeners(targetInst, eventType); 6851 6852 if (listeners.length > 0) { 6853 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget); 6854 dispatchQueue.push({ 6855 event: event, 6856 listeners: listeners 6857 }); 6858 6859 if (fallbackData) { 6860 // Inject data generated from fallback path into the synthetic event. 6861 // This matches the property of native CompositionEventInterface. 6862 event.data = fallbackData; 6863 } else { 6864 var customData = getDataFromCustomEvent(nativeEvent); 6865 6866 if (customData !== null) { 6867 event.data = customData; 6868 } 6869 } 6870 } 6871 } 6872 6873 function getNativeBeforeInputChars(domEventName, nativeEvent) { 6874 switch (domEventName) { 6875 case 'compositionend': 6876 return getDataFromCustomEvent(nativeEvent); 6877 6878 case 'keypress': 6879 /** 6880 * If native `textInput` events are available, our goal is to make 6881 * use of them. However, there is a special case: the spacebar key. 6882 * In Webkit, preventing default on a spacebar `textInput` event 6883 * cancels character insertion, but it *also* causes the browser 6884 * to fall back to its default spacebar behavior of scrolling the 6885 * page. 6886 * 6887 * Tracking at: 6888 * https://code.google.com/p/chromium/issues/detail?id=355103 6889 * 6890 * To avoid this issue, use the keypress event as if no `textInput` 6891 * event is available. 6892 */ 6893 var which = nativeEvent.which; 6894 6895 if (which !== SPACEBAR_CODE) { 6896 return null; 6897 } 6898 6899 hasSpaceKeypress = true; 6900 return SPACEBAR_CHAR; 6901 6902 case 'textInput': 6903 // Record the characters to be added to the DOM. 6904 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled 6905 // it at the keypress level and bail immediately. Android Chrome 6906 // doesn't give us keycodes, so we need to ignore it. 6907 6908 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { 6909 return null; 6910 } 6911 6912 return chars; 6913 6914 default: 6915 // For other native event types, do nothing. 6916 return null; 6917 } 6918 } 6919 /** 6920 * For browsers that do not provide the `textInput` event, extract the 6921 * appropriate string to use for SyntheticInputEvent. 6922 */ 6923 6924 6925 function getFallbackBeforeInputChars(domEventName, nativeEvent) { 6926 // If we are currently composing (IME) and using a fallback to do so, 6927 // try to extract the composed characters from the fallback object. 6928 // If composition event is available, we extract a string only at 6929 // compositionevent, otherwise extract it at fallback events. 6930 if (isComposing) { 6931 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) { 6932 var chars = getData(); 6933 reset(); 6934 isComposing = false; 6935 return chars; 6936 } 6937 6938 return null; 6939 } 6940 6941 switch (domEventName) { 6942 case 'paste': 6943 // If a paste event occurs after a keypress, throw out the input 6944 // chars. Paste events should not lead to BeforeInput events. 6945 return null; 6946 6947 case 'keypress': 6948 /** 6949 * As of v27, Firefox may fire keypress events even when no character 6950 * will be inserted. A few possibilities: 6951 * 6952 * - `which` is `0`. Arrow keys, Esc key, etc. 6953 * 6954 * - `which` is the pressed key code, but no char is available. 6955 * Ex: 'AltGr + d` in Polish. There is no modified character for 6956 * this key combination and no character is inserted into the 6957 * document, but FF fires the keypress for char code `100` anyway. 6958 * No `input` event will occur. 6959 * 6960 * - `which` is the pressed key code, but a command combination is 6961 * being used. Ex: `Cmd+C`. No character is inserted, and no 6962 * `input` event will occur. 6963 */ 6964 if (!isKeypressCommand(nativeEvent)) { 6965 // IE fires the `keypress` event when a user types an emoji via 6966 // Touch keyboard of Windows. In such a case, the `char` property 6967 // holds an emoji character like `\uD83D\uDE0A`. Because its length 6968 // is 2, the property `which` does not represent an emoji correctly. 6969 // In such a case, we directly return the `char` property instead of 6970 // using `which`. 6971 if (nativeEvent.char && nativeEvent.char.length > 1) { 6972 return nativeEvent.char; 6973 } else if (nativeEvent.which) { 6974 return String.fromCharCode(nativeEvent.which); 6975 } 6976 } 6977 6978 return null; 6979 6980 case 'compositionend': 6981 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data; 6982 6983 default: 6984 return null; 6985 } 6986 } 6987 /** 6988 * Extract a SyntheticInputEvent for `beforeInput`, based on either native 6989 * `textInput` or fallback behavior. 6990 * 6991 * @return {?object} A SyntheticInputEvent. 6992 */ 6993 6994 6995 function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) { 6996 var chars; 6997 6998 if (canUseTextInputEvent) { 6999 chars = getNativeBeforeInputChars(domEventName, nativeEvent); 7000 } else { 7001 chars = getFallbackBeforeInputChars(domEventName, nativeEvent); 7002 } // If no characters are being inserted, no BeforeInput event should 7003 // be fired. 7004 7005 7006 if (!chars) { 7007 return null; 7008 } 7009 7010 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput'); 7011 7012 if (listeners.length > 0) { 7013 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget); 7014 dispatchQueue.push({ 7015 event: event, 7016 listeners: listeners 7017 }); 7018 event.data = chars; 7019 } 7020 } 7021 /** 7022 * Create an `onBeforeInput` event to match 7023 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. 7024 * 7025 * This event plugin is based on the native `textInput` event 7026 * available in Chrome, Safari, Opera, and IE. This event fires after 7027 * `onKeyPress` and `onCompositionEnd`, but before `onInput`. 7028 * 7029 * `beforeInput` is spec'd but not implemented in any browsers, and 7030 * the `input` event does not provide any useful information about what has 7031 * actually been added, contrary to the spec. Thus, `textInput` is the best 7032 * available event to identify the characters that have actually been inserted 7033 * into the target node. 7034 * 7035 * This plugin is also responsible for emitting `composition` events, thus 7036 * allowing us to share composition fallback code for both `beforeInput` and 7037 * `composition` event types. 7038 */ 7039 7040 7041 function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 7042 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 7043 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 7044 } 7045 7046 /** 7047 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 7048 */ 7049 var supportedInputTypes = { 7050 color: true, 7051 date: true, 7052 datetime: true, 7053 'datetime-local': true, 7054 email: true, 7055 month: true, 7056 number: true, 7057 password: true, 7058 range: true, 7059 search: true, 7060 tel: true, 7061 text: true, 7062 time: true, 7063 url: true, 7064 week: true 7065 }; 7066 7067 function isTextInputElement(elem) { 7068 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 7069 7070 if (nodeName === 'input') { 7071 return !!supportedInputTypes[elem.type]; 7072 } 7073 7074 if (nodeName === 'textarea') { 7075 return true; 7076 } 7077 7078 return false; 7079 } 7080 7081 /** 7082 * Checks if an event is supported in the current execution environment. 7083 * 7084 * NOTE: This will not work correctly for non-generic events such as `change`, 7085 * `reset`, `load`, `error`, and `select`. 7086 * 7087 * Borrows from Modernizr. 7088 * 7089 * @param {string} eventNameSuffix Event name, e.g. "click". 7090 * @return {boolean} True if the event is supported. 7091 * @internal 7092 * @license Modernizr 3.0.0pre (Custom Build) | MIT 7093 */ 7094 7095 function isEventSupported(eventNameSuffix) { 7096 if (!canUseDOM) { 7097 return false; 7098 } 7099 7100 var eventName = 'on' + eventNameSuffix; 7101 var isSupported = (eventName in document); 7102 7103 if (!isSupported) { 7104 var element = document.createElement('div'); 7105 element.setAttribute(eventName, 'return;'); 7106 isSupported = typeof element[eventName] === 'function'; 7107 } 7108 7109 return isSupported; 7110 } 7111 7112 function registerEvents$1() { 7113 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']); 7114 } 7115 7116 function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) { 7117 // Flag this event loop as needing state restore. 7118 enqueueStateRestore(target); 7119 var listeners = accumulateTwoPhaseListeners(inst, 'onChange'); 7120 7121 if (listeners.length > 0) { 7122 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target); 7123 dispatchQueue.push({ 7124 event: event, 7125 listeners: listeners 7126 }); 7127 } 7128 } 7129 /** 7130 * For IE shims 7131 */ 7132 7133 7134 var activeElement = null; 7135 var activeElementInst = null; 7136 /** 7137 * SECTION: handle `change` event 7138 */ 7139 7140 function shouldUseChangeEvent(elem) { 7141 var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); 7142 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; 7143 } 7144 7145 function manualDispatchChangeEvent(nativeEvent) { 7146 var dispatchQueue = []; 7147 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the 7148 // other events and have it go through ReactBrowserEventEmitter. Since it 7149 // doesn't, we manually listen for the events and so we have to enqueue and 7150 // process the abstract event manually. 7151 // 7152 // Batching is necessary here in order to ensure that all event handlers run 7153 // before the next rerender (including event handlers attached to ancestor 7154 // elements instead of directly on the input). Without this, controlled 7155 // components don't work properly in conjunction with event bubbling because 7156 // the component is rerendered and the value reverted before all the event 7157 // handlers can run. See https://github.com/facebook/react/issues/708. 7158 7159 batchedUpdates(runEventInBatch, dispatchQueue); 7160 } 7161 7162 function runEventInBatch(dispatchQueue) { 7163 processDispatchQueue(dispatchQueue, 0); 7164 } 7165 7166 function getInstIfValueChanged(targetInst) { 7167 var targetNode = getNodeFromInstance(targetInst); 7168 7169 if (updateValueIfChanged(targetNode)) { 7170 return targetInst; 7171 } 7172 } 7173 7174 function getTargetInstForChangeEvent(domEventName, targetInst) { 7175 if (domEventName === 'change') { 7176 return targetInst; 7177 } 7178 } 7179 /** 7180 * SECTION: handle `input` event 7181 */ 7182 7183 7184 var isInputEventSupported = false; 7185 7186 if (canUseDOM) { 7187 // IE9 claims to support the input event but fails to trigger it when 7188 // deleting text, so we ignore its input events. 7189 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9); 7190 } 7191 /** 7192 * (For IE <=9) Starts tracking propertychange events on the passed-in element 7193 * and override the value property so that we can distinguish user events from 7194 * value changes in JS. 7195 */ 7196 7197 7198 function startWatchingForValueChange(target, targetInst) { 7199 activeElement = target; 7200 activeElementInst = targetInst; 7201 activeElement.attachEvent('onpropertychange', handlePropertyChange); 7202 } 7203 /** 7204 * (For IE <=9) Removes the event listeners from the currently-tracked element, 7205 * if any exists. 7206 */ 7207 7208 7209 function stopWatchingForValueChange() { 7210 if (!activeElement) { 7211 return; 7212 } 7213 7214 activeElement.detachEvent('onpropertychange', handlePropertyChange); 7215 activeElement = null; 7216 activeElementInst = null; 7217 } 7218 /** 7219 * (For IE <=9) Handles a propertychange event, sending a `change` event if 7220 * the value of the active element has changed. 7221 */ 7222 7223 7224 function handlePropertyChange(nativeEvent) { 7225 if (nativeEvent.propertyName !== 'value') { 7226 return; 7227 } 7228 7229 if (getInstIfValueChanged(activeElementInst)) { 7230 manualDispatchChangeEvent(nativeEvent); 7231 } 7232 } 7233 7234 function handleEventsForInputEventPolyfill(domEventName, target, targetInst) { 7235 if (domEventName === 'focusin') { 7236 // In IE9, propertychange fires for most input events but is buggy and 7237 // doesn't fire when text is deleted, but conveniently, selectionchange 7238 // appears to fire in all of the remaining cases so we catch those and 7239 // forward the event if the value has changed 7240 // In either case, we don't want to call the event handler if the value 7241 // is changed from JS so we redefine a setter for `.value` that updates 7242 // our activeElementValue variable, allowing us to ignore those changes 7243 // 7244 // stopWatching() should be a noop here but we call it just in case we 7245 // missed a blur event somehow. 7246 stopWatchingForValueChange(); 7247 startWatchingForValueChange(target, targetInst); 7248 } else if (domEventName === 'focusout') { 7249 stopWatchingForValueChange(); 7250 } 7251 } // For IE8 and IE9. 7252 7253 7254 function getTargetInstForInputEventPolyfill(domEventName, targetInst) { 7255 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') { 7256 // On the selectionchange event, the target is just document which isn't 7257 // helpful for us so just check activeElement instead. 7258 // 7259 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire 7260 // propertychange on the first input event after setting `value` from a 7261 // script and fires only keydown, keypress, keyup. Catching keyup usually 7262 // gets it and catching keydown lets us fire an event for the first 7263 // keystroke if user does a key repeat (it'll be a little delayed: right 7264 // before the second keystroke). Other input methods (e.g., paste) seem to 7265 // fire selectionchange normally. 7266 return getInstIfValueChanged(activeElementInst); 7267 } 7268 } 7269 /** 7270 * SECTION: handle `click` event 7271 */ 7272 7273 7274 function shouldUseClickEvent(elem) { 7275 // Use the `click` event to detect changes to checkbox and radio inputs. 7276 // This approach works across all browsers, whereas `change` does not fire 7277 // until `blur` in IE8. 7278 var nodeName = elem.nodeName; 7279 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); 7280 } 7281 7282 function getTargetInstForClickEvent(domEventName, targetInst) { 7283 if (domEventName === 'click') { 7284 return getInstIfValueChanged(targetInst); 7285 } 7286 } 7287 7288 function getTargetInstForInputOrChangeEvent(domEventName, targetInst) { 7289 if (domEventName === 'input' || domEventName === 'change') { 7290 return getInstIfValueChanged(targetInst); 7291 } 7292 } 7293 7294 function handleControlledInputBlur(node) { 7295 var state = node._wrapperState; 7296 7297 if (!state || !state.controlled || node.type !== 'number') { 7298 return; 7299 } 7300 7301 { 7302 // If controlled, assign the value attribute to the current value on blur 7303 setDefaultValue(node, 'number', node.value); 7304 } 7305 } 7306 /** 7307 * This plugin creates an `onChange` event that normalizes change events 7308 * across form elements. This event fires at a time when it's possible to 7309 * change the element's value without seeing a flicker. 7310 * 7311 * Supported elements are: 7312 * - input (see `isTextInputElement`) 7313 * - textarea 7314 * - select 7315 */ 7316 7317 7318 function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 7319 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window; 7320 var getTargetInstFunc, handleEventFunc; 7321 7322 if (shouldUseChangeEvent(targetNode)) { 7323 getTargetInstFunc = getTargetInstForChangeEvent; 7324 } else if (isTextInputElement(targetNode)) { 7325 if (isInputEventSupported) { 7326 getTargetInstFunc = getTargetInstForInputOrChangeEvent; 7327 } else { 7328 getTargetInstFunc = getTargetInstForInputEventPolyfill; 7329 handleEventFunc = handleEventsForInputEventPolyfill; 7330 } 7331 } else if (shouldUseClickEvent(targetNode)) { 7332 getTargetInstFunc = getTargetInstForClickEvent; 7333 } 7334 7335 if (getTargetInstFunc) { 7336 var inst = getTargetInstFunc(domEventName, targetInst); 7337 7338 if (inst) { 7339 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget); 7340 return; 7341 } 7342 } 7343 7344 if (handleEventFunc) { 7345 handleEventFunc(domEventName, targetNode, targetInst); 7346 } // When blurring, set the value attribute for number inputs 7347 7348 7349 if (domEventName === 'focusout') { 7350 handleControlledInputBlur(targetNode); 7351 } 7352 } 7353 7354 function registerEvents$2() { 7355 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']); 7356 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']); 7357 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']); 7358 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']); 7359 } 7360 /** 7361 * For almost every interaction we care about, there will be both a top-level 7362 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that 7363 * we do not extract duplicate events. However, moving the mouse into the 7364 * browser from outside will not fire a `mouseout` event. In this case, we use 7365 * the `mouseover` top-level event. 7366 */ 7367 7368 7369 function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 7370 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover'; 7371 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout'; 7372 7373 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0) { 7374 // If this is an over event with a target, we might have already dispatched 7375 // the event in the out event of the other target. If this is replayed, 7376 // then it's because we couldn't dispatch against this target previously 7377 // so we have to do it now instead. 7378 var related = nativeEvent.relatedTarget || nativeEvent.fromElement; 7379 7380 if (related) { 7381 // If the related node is managed by React, we can assume that we have 7382 // already dispatched the corresponding events during its mouseout. 7383 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) { 7384 return; 7385 } 7386 } 7387 } 7388 7389 if (!isOutEvent && !isOverEvent) { 7390 // Must not be a mouse or pointer in or out - ignoring. 7391 return; 7392 } 7393 7394 var win; // TODO: why is this nullable in the types but we read from it? 7395 7396 if (nativeEventTarget.window === nativeEventTarget) { 7397 // `nativeEventTarget` is probably a window object. 7398 win = nativeEventTarget; 7399 } else { 7400 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. 7401 var doc = nativeEventTarget.ownerDocument; 7402 7403 if (doc) { 7404 win = doc.defaultView || doc.parentWindow; 7405 } else { 7406 win = window; 7407 } 7408 } 7409 7410 var from; 7411 var to; 7412 7413 if (isOutEvent) { 7414 var _related = nativeEvent.relatedTarget || nativeEvent.toElement; 7415 7416 from = targetInst; 7417 to = _related ? getClosestInstanceFromNode(_related) : null; 7418 7419 if (to !== null) { 7420 var nearestMounted = getNearestMountedFiber(to); 7421 7422 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) { 7423 to = null; 7424 } 7425 } 7426 } else { 7427 // Moving to a node from outside the window. 7428 from = null; 7429 to = targetInst; 7430 } 7431 7432 if (from === to) { 7433 // Nothing pertains to our managed components. 7434 return; 7435 } 7436 7437 var SyntheticEventCtor = SyntheticMouseEvent; 7438 var leaveEventType = 'onMouseLeave'; 7439 var enterEventType = 'onMouseEnter'; 7440 var eventTypePrefix = 'mouse'; 7441 7442 if (domEventName === 'pointerout' || domEventName === 'pointerover') { 7443 SyntheticEventCtor = SyntheticPointerEvent; 7444 leaveEventType = 'onPointerLeave'; 7445 enterEventType = 'onPointerEnter'; 7446 eventTypePrefix = 'pointer'; 7447 } 7448 7449 var fromNode = from == null ? win : getNodeFromInstance(from); 7450 var toNode = to == null ? win : getNodeFromInstance(to); 7451 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget); 7452 leave.target = fromNode; 7453 leave.relatedTarget = toNode; 7454 var enter = null; // We should only process this nativeEvent if we are processing 7455 // the first ancestor. Next time, we will ignore the event. 7456 7457 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget); 7458 7459 if (nativeTargetInst === targetInst) { 7460 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget); 7461 enterEvent.target = toNode; 7462 enterEvent.relatedTarget = fromNode; 7463 enter = enterEvent; 7464 } 7465 7466 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to); 7467 } 7468 7469 /** 7470 * inlined Object.is polyfill to avoid requiring consumers ship their own 7471 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 7472 */ 7473 function is(x, y) { 7474 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare 7475 ; 7476 } 7477 7478 var objectIs = typeof Object.is === 'function' ? Object.is : is; 7479 7480 var hasOwnProperty$2 = Object.prototype.hasOwnProperty; 7481 /** 7482 * Performs equality by iterating through keys on an object and returning false 7483 * when any key has values which are not strictly equal between the arguments. 7484 * Returns true when the values of all keys are strictly equal. 7485 */ 7486 7487 function shallowEqual(objA, objB) { 7488 if (objectIs(objA, objB)) { 7489 return true; 7490 } 7491 7492 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { 7493 return false; 7494 } 7495 7496 var keysA = Object.keys(objA); 7497 var keysB = Object.keys(objB); 7498 7499 if (keysA.length !== keysB.length) { 7500 return false; 7501 } // Test for A's keys different from B. 7502 7503 7504 for (var i = 0; i < keysA.length; i++) { 7505 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) { 7506 return false; 7507 } 7508 } 7509 7510 return true; 7511 } 7512 7513 /** 7514 * Given any node return the first leaf node without children. 7515 * 7516 * @param {DOMElement|DOMTextNode} node 7517 * @return {DOMElement|DOMTextNode} 7518 */ 7519 7520 function getLeafNode(node) { 7521 while (node && node.firstChild) { 7522 node = node.firstChild; 7523 } 7524 7525 return node; 7526 } 7527 /** 7528 * Get the next sibling within a container. This will walk up the 7529 * DOM if a node's siblings have been exhausted. 7530 * 7531 * @param {DOMElement|DOMTextNode} node 7532 * @return {?DOMElement|DOMTextNode} 7533 */ 7534 7535 7536 function getSiblingNode(node) { 7537 while (node) { 7538 if (node.nextSibling) { 7539 return node.nextSibling; 7540 } 7541 7542 node = node.parentNode; 7543 } 7544 } 7545 /** 7546 * Get object describing the nodes which contain characters at offset. 7547 * 7548 * @param {DOMElement|DOMTextNode} root 7549 * @param {number} offset 7550 * @return {?object} 7551 */ 7552 7553 7554 function getNodeForCharacterOffset(root, offset) { 7555 var node = getLeafNode(root); 7556 var nodeStart = 0; 7557 var nodeEnd = 0; 7558 7559 while (node) { 7560 if (node.nodeType === TEXT_NODE) { 7561 nodeEnd = nodeStart + node.textContent.length; 7562 7563 if (nodeStart <= offset && nodeEnd >= offset) { 7564 return { 7565 node: node, 7566 offset: offset - nodeStart 7567 }; 7568 } 7569 7570 nodeStart = nodeEnd; 7571 } 7572 7573 node = getLeafNode(getSiblingNode(node)); 7574 } 7575 } 7576 7577 /** 7578 * @param {DOMElement} outerNode 7579 * @return {?object} 7580 */ 7581 7582 function getOffsets(outerNode) { 7583 var ownerDocument = outerNode.ownerDocument; 7584 var win = ownerDocument && ownerDocument.defaultView || window; 7585 var selection = win.getSelection && win.getSelection(); 7586 7587 if (!selection || selection.rangeCount === 0) { 7588 return null; 7589 } 7590 7591 var anchorNode = selection.anchorNode, 7592 anchorOffset = selection.anchorOffset, 7593 focusNode = selection.focusNode, 7594 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the 7595 // up/down buttons on an <input type="number">. Anonymous divs do not seem to 7596 // expose properties, triggering a "Permission denied error" if any of its 7597 // properties are accessed. The only seemingly possible way to avoid erroring 7598 // is to access a property that typically works for non-anonymous divs and 7599 // catch any error that may otherwise arise. See 7600 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 7601 7602 try { 7603 /* eslint-disable no-unused-expressions */ 7604 anchorNode.nodeType; 7605 focusNode.nodeType; 7606 /* eslint-enable no-unused-expressions */ 7607 } catch (e) { 7608 return null; 7609 } 7610 7611 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset); 7612 } 7613 /** 7614 * Returns {start, end} where `start` is the character/codepoint index of 7615 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and 7616 * `end` is the index of (focusNode, focusOffset). 7617 * 7618 * Returns null if you pass in garbage input but we should probably just crash. 7619 * 7620 * Exported only for testing. 7621 */ 7622 7623 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { 7624 var length = 0; 7625 var start = -1; 7626 var end = -1; 7627 var indexWithinAnchor = 0; 7628 var indexWithinFocus = 0; 7629 var node = outerNode; 7630 var parentNode = null; 7631 7632 outer: while (true) { 7633 var next = null; 7634 7635 while (true) { 7636 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { 7637 start = length + anchorOffset; 7638 } 7639 7640 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { 7641 end = length + focusOffset; 7642 } 7643 7644 if (node.nodeType === TEXT_NODE) { 7645 length += node.nodeValue.length; 7646 } 7647 7648 if ((next = node.firstChild) === null) { 7649 break; 7650 } // Moving from `node` to its first child `next`. 7651 7652 7653 parentNode = node; 7654 node = next; 7655 } 7656 7657 while (true) { 7658 if (node === outerNode) { 7659 // If `outerNode` has children, this is always the second time visiting 7660 // it. If it has no children, this is still the first loop, and the only 7661 // valid selection is anchorNode and focusNode both equal to this node 7662 // and both offsets 0, in which case we will have handled above. 7663 break outer; 7664 } 7665 7666 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { 7667 start = length; 7668 } 7669 7670 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { 7671 end = length; 7672 } 7673 7674 if ((next = node.nextSibling) !== null) { 7675 break; 7676 } 7677 7678 node = parentNode; 7679 parentNode = node.parentNode; 7680 } // Moving from `node` to its next sibling `next`. 7681 7682 7683 node = next; 7684 } 7685 7686 if (start === -1 || end === -1) { 7687 // This should never happen. (Would happen if the anchor/focus nodes aren't 7688 // actually inside the passed-in node.) 7689 return null; 7690 } 7691 7692 return { 7693 start: start, 7694 end: end 7695 }; 7696 } 7697 /** 7698 * In modern non-IE browsers, we can support both forward and backward 7699 * selections. 7700 * 7701 * Note: IE10+ supports the Selection object, but it does not support 7702 * the `extend` method, which means that even in modern IE, it's not possible 7703 * to programmatically create a backward selection. Thus, for all IE 7704 * versions, we use the old IE API to create our selections. 7705 * 7706 * @param {DOMElement|DOMTextNode} node 7707 * @param {object} offsets 7708 */ 7709 7710 function setOffsets(node, offsets) { 7711 var doc = node.ownerDocument || document; 7712 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios. 7713 // (For instance: TinyMCE editor used in a list component that supports pasting to add more, 7714 // fails when pasting 100+ items) 7715 7716 if (!win.getSelection) { 7717 return; 7718 } 7719 7720 var selection = win.getSelection(); 7721 var length = node.textContent.length; 7722 var start = Math.min(offsets.start, length); 7723 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method. 7724 // Flip backward selections, so we can set with a single range. 7725 7726 if (!selection.extend && start > end) { 7727 var temp = end; 7728 end = start; 7729 start = temp; 7730 } 7731 7732 var startMarker = getNodeForCharacterOffset(node, start); 7733 var endMarker = getNodeForCharacterOffset(node, end); 7734 7735 if (startMarker && endMarker) { 7736 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) { 7737 return; 7738 } 7739 7740 var range = doc.createRange(); 7741 range.setStart(startMarker.node, startMarker.offset); 7742 selection.removeAllRanges(); 7743 7744 if (start > end) { 7745 selection.addRange(range); 7746 selection.extend(endMarker.node, endMarker.offset); 7747 } else { 7748 range.setEnd(endMarker.node, endMarker.offset); 7749 selection.addRange(range); 7750 } 7751 } 7752 } 7753 7754 function isTextNode(node) { 7755 return node && node.nodeType === TEXT_NODE; 7756 } 7757 7758 function containsNode(outerNode, innerNode) { 7759 if (!outerNode || !innerNode) { 7760 return false; 7761 } else if (outerNode === innerNode) { 7762 return true; 7763 } else if (isTextNode(outerNode)) { 7764 return false; 7765 } else if (isTextNode(innerNode)) { 7766 return containsNode(outerNode, innerNode.parentNode); 7767 } else if ('contains' in outerNode) { 7768 return outerNode.contains(innerNode); 7769 } else if (outerNode.compareDocumentPosition) { 7770 return !!(outerNode.compareDocumentPosition(innerNode) & 16); 7771 } else { 7772 return false; 7773 } 7774 } 7775 7776 function isInDocument(node) { 7777 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); 7778 } 7779 7780 function isSameOriginFrame(iframe) { 7781 try { 7782 // Accessing the contentDocument of a HTMLIframeElement can cause the browser 7783 // to throw, e.g. if it has a cross-origin src attribute. 7784 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g: 7785 // iframe.contentDocument.defaultView; 7786 // A safety way is to access one of the cross origin properties: Window or Location 7787 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari. 7788 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl 7789 return typeof iframe.contentWindow.location.href === 'string'; 7790 } catch (err) { 7791 return false; 7792 } 7793 } 7794 7795 function getActiveElementDeep() { 7796 var win = window; 7797 var element = getActiveElement(); 7798 7799 while (element instanceof win.HTMLIFrameElement) { 7800 if (isSameOriginFrame(element)) { 7801 win = element.contentWindow; 7802 } else { 7803 return element; 7804 } 7805 7806 element = getActiveElement(win.document); 7807 } 7808 7809 return element; 7810 } 7811 /** 7812 * @ReactInputSelection: React input selection module. Based on Selection.js, 7813 * but modified to be suitable for react and has a couple of bug fixes (doesn't 7814 * assume buttons have range selections allowed). 7815 * Input selection module for React. 7816 */ 7817 7818 /** 7819 * @hasSelectionCapabilities: we get the element types that support selection 7820 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart` 7821 * and `selectionEnd` rows. 7822 */ 7823 7824 7825 function hasSelectionCapabilities(elem) { 7826 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 7827 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true'); 7828 } 7829 function getSelectionInformation() { 7830 var focusedElem = getActiveElementDeep(); 7831 return { 7832 focusedElem: focusedElem, 7833 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null 7834 }; 7835 } 7836 /** 7837 * @restoreSelection: If any selection information was potentially lost, 7838 * restore it. This is useful when performing operations that could remove dom 7839 * nodes and place them back in, resulting in focus being lost. 7840 */ 7841 7842 function restoreSelection(priorSelectionInformation) { 7843 var curFocusedElem = getActiveElementDeep(); 7844 var priorFocusedElem = priorSelectionInformation.focusedElem; 7845 var priorSelectionRange = priorSelectionInformation.selectionRange; 7846 7847 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { 7848 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) { 7849 setSelection(priorFocusedElem, priorSelectionRange); 7850 } // Focusing a node can change the scroll position, which is undesirable 7851 7852 7853 var ancestors = []; 7854 var ancestor = priorFocusedElem; 7855 7856 while (ancestor = ancestor.parentNode) { 7857 if (ancestor.nodeType === ELEMENT_NODE) { 7858 ancestors.push({ 7859 element: ancestor, 7860 left: ancestor.scrollLeft, 7861 top: ancestor.scrollTop 7862 }); 7863 } 7864 } 7865 7866 if (typeof priorFocusedElem.focus === 'function') { 7867 priorFocusedElem.focus(); 7868 } 7869 7870 for (var i = 0; i < ancestors.length; i++) { 7871 var info = ancestors[i]; 7872 info.element.scrollLeft = info.left; 7873 info.element.scrollTop = info.top; 7874 } 7875 } 7876 } 7877 /** 7878 * @getSelection: Gets the selection bounds of a focused textarea, input or 7879 * contentEditable node. 7880 * -@input: Look up selection bounds of this input 7881 * -@return {start: selectionStart, end: selectionEnd} 7882 */ 7883 7884 function getSelection(input) { 7885 var selection; 7886 7887 if ('selectionStart' in input) { 7888 // Modern browser with input or textarea. 7889 selection = { 7890 start: input.selectionStart, 7891 end: input.selectionEnd 7892 }; 7893 } else { 7894 // Content editable or old IE textarea. 7895 selection = getOffsets(input); 7896 } 7897 7898 return selection || { 7899 start: 0, 7900 end: 0 7901 }; 7902 } 7903 /** 7904 * @setSelection: Sets the selection bounds of a textarea or input and focuses 7905 * the input. 7906 * -@input Set selection bounds of this input or textarea 7907 * -@offsets Object of same form that is returned from get* 7908 */ 7909 7910 function setSelection(input, offsets) { 7911 var start = offsets.start; 7912 var end = offsets.end; 7913 7914 if (end === undefined) { 7915 end = start; 7916 } 7917 7918 if ('selectionStart' in input) { 7919 input.selectionStart = start; 7920 input.selectionEnd = Math.min(end, input.value.length); 7921 } else { 7922 setOffsets(input, offsets); 7923 } 7924 } 7925 7926 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11; 7927 7928 function registerEvents$3() { 7929 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']); 7930 } 7931 7932 var activeElement$1 = null; 7933 var activeElementInst$1 = null; 7934 var lastSelection = null; 7935 var mouseDown = false; 7936 /** 7937 * Get an object which is a unique representation of the current selection. 7938 * 7939 * The return value will not be consistent across nodes or browsers, but 7940 * two identical selections on the same node will return identical objects. 7941 */ 7942 7943 function getSelection$1(node) { 7944 if ('selectionStart' in node && hasSelectionCapabilities(node)) { 7945 return { 7946 start: node.selectionStart, 7947 end: node.selectionEnd 7948 }; 7949 } else { 7950 var win = node.ownerDocument && node.ownerDocument.defaultView || window; 7951 var selection = win.getSelection(); 7952 return { 7953 anchorNode: selection.anchorNode, 7954 anchorOffset: selection.anchorOffset, 7955 focusNode: selection.focusNode, 7956 focusOffset: selection.focusOffset 7957 }; 7958 } 7959 } 7960 /** 7961 * Get document associated with the event target. 7962 */ 7963 7964 7965 function getEventTargetDocument(eventTarget) { 7966 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument; 7967 } 7968 /** 7969 * Poll selection to see whether it's changed. 7970 * 7971 * @param {object} nativeEvent 7972 * @param {object} nativeEventTarget 7973 * @return {?SyntheticEvent} 7974 */ 7975 7976 7977 function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) { 7978 // Ensure we have the right element, and that the user is not dragging a 7979 // selection (this matches native `select` event behavior). In HTML5, select 7980 // fires only on input and textarea thus if there's no focused element we 7981 // won't dispatch. 7982 var doc = getEventTargetDocument(nativeEventTarget); 7983 7984 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) { 7985 return; 7986 } // Only fire when selection has actually changed. 7987 7988 7989 var currentSelection = getSelection$1(activeElement$1); 7990 7991 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { 7992 lastSelection = currentSelection; 7993 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect'); 7994 7995 if (listeners.length > 0) { 7996 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget); 7997 dispatchQueue.push({ 7998 event: event, 7999 listeners: listeners 8000 }); 8001 event.target = activeElement$1; 8002 } 8003 } 8004 } 8005 /** 8006 * This plugin creates an `onSelect` event that normalizes select events 8007 * across form elements. 8008 * 8009 * Supported elements are: 8010 * - input (see `isTextInputElement`) 8011 * - textarea 8012 * - contentEditable 8013 * 8014 * This differs from native browser implementations in the following ways: 8015 * - Fires on contentEditable fields as well as inputs. 8016 * - Fires for collapsed selection. 8017 * - Fires after user input. 8018 */ 8019 8020 8021 function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8022 8023 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window; 8024 8025 switch (domEventName) { 8026 // Track the input node that has focus. 8027 case 'focusin': 8028 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { 8029 activeElement$1 = targetNode; 8030 activeElementInst$1 = targetInst; 8031 lastSelection = null; 8032 } 8033 8034 break; 8035 8036 case 'focusout': 8037 activeElement$1 = null; 8038 activeElementInst$1 = null; 8039 lastSelection = null; 8040 break; 8041 // Don't fire the event while the user is dragging. This matches the 8042 // semantics of the native select event. 8043 8044 case 'mousedown': 8045 mouseDown = true; 8046 break; 8047 8048 case 'contextmenu': 8049 case 'mouseup': 8050 case 'dragend': 8051 mouseDown = false; 8052 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget); 8053 break; 8054 // Chrome and IE fire non-standard event when selection is changed (and 8055 // sometimes when it hasn't). IE's event fires out of order with respect 8056 // to key and input events on deletion, so we discard it. 8057 // 8058 // Firefox doesn't support selectionchange, so check selection status 8059 // after each key entry. The selection changes after keydown and before 8060 // keyup, but we check on keydown as well in the case of holding down a 8061 // key, when multiple keydown events are fired but only one keyup is. 8062 // This is also our approach for IE handling, for the reason above. 8063 8064 case 'selectionchange': 8065 if (skipSelectionChangeEvent) { 8066 break; 8067 } 8068 8069 // falls through 8070 8071 case 'keydown': 8072 case 'keyup': 8073 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget); 8074 } 8075 } 8076 8077 function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8078 var reactName = topLevelEventsToReactNames.get(domEventName); 8079 8080 if (reactName === undefined) { 8081 return; 8082 } 8083 8084 var SyntheticEventCtor = SyntheticEvent; 8085 var reactEventType = domEventName; 8086 8087 switch (domEventName) { 8088 case 'keypress': 8089 // Firefox creates a keypress event for function keys too. This removes 8090 // the unwanted keypress events. Enter is however both printable and 8091 // non-printable. One would expect Tab to be as well (but it isn't). 8092 if (getEventCharCode(nativeEvent) === 0) { 8093 return; 8094 } 8095 8096 /* falls through */ 8097 8098 case 'keydown': 8099 case 'keyup': 8100 SyntheticEventCtor = SyntheticKeyboardEvent; 8101 break; 8102 8103 case 'focusin': 8104 reactEventType = 'focus'; 8105 SyntheticEventCtor = SyntheticFocusEvent; 8106 break; 8107 8108 case 'focusout': 8109 reactEventType = 'blur'; 8110 SyntheticEventCtor = SyntheticFocusEvent; 8111 break; 8112 8113 case 'beforeblur': 8114 case 'afterblur': 8115 SyntheticEventCtor = SyntheticFocusEvent; 8116 break; 8117 8118 case 'click': 8119 // Firefox creates a click event on right mouse clicks. This removes the 8120 // unwanted click events. 8121 if (nativeEvent.button === 2) { 8122 return; 8123 } 8124 8125 /* falls through */ 8126 8127 case 'auxclick': 8128 case 'dblclick': 8129 case 'mousedown': 8130 case 'mousemove': 8131 case 'mouseup': // TODO: Disabled elements should not respond to mouse events 8132 8133 /* falls through */ 8134 8135 case 'mouseout': 8136 case 'mouseover': 8137 case 'contextmenu': 8138 SyntheticEventCtor = SyntheticMouseEvent; 8139 break; 8140 8141 case 'drag': 8142 case 'dragend': 8143 case 'dragenter': 8144 case 'dragexit': 8145 case 'dragleave': 8146 case 'dragover': 8147 case 'dragstart': 8148 case 'drop': 8149 SyntheticEventCtor = SyntheticDragEvent; 8150 break; 8151 8152 case 'touchcancel': 8153 case 'touchend': 8154 case 'touchmove': 8155 case 'touchstart': 8156 SyntheticEventCtor = SyntheticTouchEvent; 8157 break; 8158 8159 case ANIMATION_END: 8160 case ANIMATION_ITERATION: 8161 case ANIMATION_START: 8162 SyntheticEventCtor = SyntheticAnimationEvent; 8163 break; 8164 8165 case TRANSITION_END: 8166 SyntheticEventCtor = SyntheticTransitionEvent; 8167 break; 8168 8169 case 'scroll': 8170 SyntheticEventCtor = SyntheticUIEvent; 8171 break; 8172 8173 case 'wheel': 8174 SyntheticEventCtor = SyntheticWheelEvent; 8175 break; 8176 8177 case 'copy': 8178 case 'cut': 8179 case 'paste': 8180 SyntheticEventCtor = SyntheticClipboardEvent; 8181 break; 8182 8183 case 'gotpointercapture': 8184 case 'lostpointercapture': 8185 case 'pointercancel': 8186 case 'pointerdown': 8187 case 'pointermove': 8188 case 'pointerout': 8189 case 'pointerover': 8190 case 'pointerup': 8191 SyntheticEventCtor = SyntheticPointerEvent; 8192 break; 8193 } 8194 8195 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0; 8196 8197 { 8198 // Some events don't bubble in the browser. 8199 // In the past, React has always bubbled them, but this can be surprising. 8200 // We're going to try aligning closer to the browser behavior by not bubbling 8201 // them in React either. We'll start by not bubbling onScroll, and then expand. 8202 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from 8203 // nonDelegatedEvents list in DOMPluginEventSystem. 8204 // Then we can remove this special list. 8205 // This is a breaking change that can wait until React 18. 8206 domEventName === 'scroll'; 8207 8208 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly); 8209 8210 if (_listeners.length > 0) { 8211 // Intentionally create event lazily. 8212 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget); 8213 8214 dispatchQueue.push({ 8215 event: _event, 8216 listeners: _listeners 8217 }); 8218 } 8219 } 8220 } 8221 8222 // TODO: remove top-level side effect. 8223 registerSimpleEvents(); 8224 registerEvents$2(); 8225 registerEvents$1(); 8226 registerEvents$3(); 8227 registerEvents(); 8228 8229 function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8230 // TODO: we should remove the concept of a "SimpleEventPlugin". 8231 // This is the basic functionality of the event system. All 8232 // the other plugins are essentially polyfills. So the plugin 8233 // should probably be inlined somewhere and have its logic 8234 // be core the to event system. This would potentially allow 8235 // us to ship builds of React without the polyfilled plugins below. 8236 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); 8237 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the 8238 // event's native "bubble" phase, which means that we're 8239 // not in the capture phase. That's because we emulate 8240 // the capture phase here still. This is a trade-off, 8241 // because in an ideal world we would not emulate and use 8242 // the phases properly, like we do with the SimpleEvent 8243 // plugin. However, the plugins below either expect 8244 // emulation (EnterLeave) or use state localized to that 8245 // plugin (BeforeInput, Change, Select). The state in 8246 // these modules complicates things, as you'll essentially 8247 // get the case where the capture phase event might change 8248 // state, only for the following bubble event to come in 8249 // later and not trigger anything as the state now 8250 // invalidates the heuristics of the event plugin. We 8251 // could alter all these plugins to work in such ways, but 8252 // that might cause other unknown side-effects that we 8253 // can't forsee right now. 8254 8255 if (shouldProcessPolyfillPlugins) { 8256 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); 8257 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 8258 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 8259 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 8260 } 8261 } // List of events that need to be individually attached to media elements. 8262 8263 8264 var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather 8265 // set them on the actual target element itself. This is primarily 8266 // because these events do not consistently bubble in the DOM. 8267 8268 var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes)); 8269 8270 function executeDispatch(event, listener, currentTarget) { 8271 var type = event.type || 'unknown-event'; 8272 event.currentTarget = currentTarget; 8273 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); 8274 event.currentTarget = null; 8275 } 8276 8277 function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) { 8278 var previousInstance; 8279 8280 if (inCapturePhase) { 8281 for (var i = dispatchListeners.length - 1; i >= 0; i--) { 8282 var _dispatchListeners$i = dispatchListeners[i], 8283 instance = _dispatchListeners$i.instance, 8284 currentTarget = _dispatchListeners$i.currentTarget, 8285 listener = _dispatchListeners$i.listener; 8286 8287 if (instance !== previousInstance && event.isPropagationStopped()) { 8288 return; 8289 } 8290 8291 executeDispatch(event, listener, currentTarget); 8292 previousInstance = instance; 8293 } 8294 } else { 8295 for (var _i = 0; _i < dispatchListeners.length; _i++) { 8296 var _dispatchListeners$_i = dispatchListeners[_i], 8297 _instance = _dispatchListeners$_i.instance, 8298 _currentTarget = _dispatchListeners$_i.currentTarget, 8299 _listener = _dispatchListeners$_i.listener; 8300 8301 if (_instance !== previousInstance && event.isPropagationStopped()) { 8302 return; 8303 } 8304 8305 executeDispatch(event, _listener, _currentTarget); 8306 previousInstance = _instance; 8307 } 8308 } 8309 } 8310 8311 function processDispatchQueue(dispatchQueue, eventSystemFlags) { 8312 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0; 8313 8314 for (var i = 0; i < dispatchQueue.length; i++) { 8315 var _dispatchQueue$i = dispatchQueue[i], 8316 event = _dispatchQueue$i.event, 8317 listeners = _dispatchQueue$i.listeners; 8318 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling. 8319 } // This would be a good time to rethrow if any of the event handlers threw. 8320 8321 8322 rethrowCaughtError(); 8323 } 8324 8325 function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) { 8326 var nativeEventTarget = getEventTarget(nativeEvent); 8327 var dispatchQueue = []; 8328 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); 8329 processDispatchQueue(dispatchQueue, eventSystemFlags); 8330 } 8331 8332 function listenToNonDelegatedEvent(domEventName, targetElement) { 8333 var isCapturePhaseListener = false; 8334 var listenerSet = getEventListenerSet(targetElement); 8335 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener); 8336 8337 if (!listenerSet.has(listenerSetKey)) { 8338 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener); 8339 listenerSet.add(listenerSetKey); 8340 } 8341 } 8342 var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2); 8343 function listenToAllSupportedEvents(rootContainerElement) { 8344 { 8345 if (rootContainerElement[listeningMarker]) { 8346 // Performance optimization: don't iterate through events 8347 // for the same portal container or root node more than once. 8348 // TODO: once we remove the flag, we may be able to also 8349 // remove some of the bookkeeping maps used for laziness. 8350 return; 8351 } 8352 8353 rootContainerElement[listeningMarker] = true; 8354 allNativeEvents.forEach(function (domEventName) { 8355 if (!nonDelegatedEvents.has(domEventName)) { 8356 listenToNativeEvent(domEventName, false, rootContainerElement, null); 8357 } 8358 8359 listenToNativeEvent(domEventName, true, rootContainerElement, null); 8360 }); 8361 } 8362 } 8363 function listenToNativeEvent(domEventName, isCapturePhaseListener, rootContainerElement, targetElement) { 8364 var eventSystemFlags = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; 8365 var target = rootContainerElement; // selectionchange needs to be attached to the document 8366 // otherwise it won't capture incoming events that are only 8367 // triggered on the document directly. 8368 8369 if (domEventName === 'selectionchange' && rootContainerElement.nodeType !== DOCUMENT_NODE) { 8370 target = rootContainerElement.ownerDocument; 8371 } // If the event can be delegated (or is capture phase), we can 8372 // register it to the root container. Otherwise, we should 8373 // register the event to the target element and mark it as 8374 // a non-delegated event. 8375 8376 8377 if (targetElement !== null && !isCapturePhaseListener && nonDelegatedEvents.has(domEventName)) { 8378 // For all non-delegated events, apart from scroll, we attach 8379 // their event listeners to the respective elements that their 8380 // events fire on. That means we can skip this step, as event 8381 // listener has already been added previously. However, we 8382 // special case the scroll event because the reality is that any 8383 // element can scroll. 8384 // TODO: ideally, we'd eventually apply the same logic to all 8385 // events from the nonDelegatedEvents list. Then we can remove 8386 // this special case and use the same logic for all events. 8387 if (domEventName !== 'scroll') { 8388 return; 8389 } 8390 8391 eventSystemFlags |= IS_NON_DELEGATED; 8392 target = targetElement; 8393 } 8394 8395 var listenerSet = getEventListenerSet(target); 8396 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener); // If the listener entry is empty or we should upgrade, then 8397 // we need to trap an event listener onto the target. 8398 8399 if (!listenerSet.has(listenerSetKey)) { 8400 if (isCapturePhaseListener) { 8401 eventSystemFlags |= IS_CAPTURE_PHASE; 8402 } 8403 8404 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener); 8405 listenerSet.add(listenerSetKey); 8406 } 8407 } 8408 8409 function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) { 8410 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be 8411 // active and not passive. 8412 8413 var isPassiveListener = undefined; 8414 8415 if (passiveBrowserEventsSupported) { 8416 // Browsers introduced an intervention, making these events 8417 // passive by default on document. React doesn't bind them 8418 // to document anymore, but changing this now would undo 8419 // the performance wins from the change. So we emulate 8420 // the existing behavior manually on the roots now. 8421 // https://github.com/facebook/react/issues/19651 8422 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') { 8423 isPassiveListener = true; 8424 } 8425 } 8426 8427 targetContainer = targetContainer; 8428 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we 8429 8430 8431 if (isCapturePhaseListener) { 8432 if (isPassiveListener !== undefined) { 8433 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener); 8434 } else { 8435 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener); 8436 } 8437 } else { 8438 if (isPassiveListener !== undefined) { 8439 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener); 8440 } else { 8441 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener); 8442 } 8443 } 8444 } 8445 8446 function isMatchingRootContainer(grandContainer, targetContainer) { 8447 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer; 8448 } 8449 8450 function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) { 8451 var ancestorInst = targetInst; 8452 8453 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) { 8454 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we 8455 8456 if (targetInst !== null) { 8457 // The below logic attempts to work out if we need to change 8458 // the target fiber to a different ancestor. We had similar logic 8459 // in the legacy event system, except the big difference between 8460 // systems is that the modern event system now has an event listener 8461 // attached to each React Root and React Portal Root. Together, 8462 // the DOM nodes representing these roots are the "rootContainer". 8463 // To figure out which ancestor instance we should use, we traverse 8464 // up the fiber tree from the target instance and attempt to find 8465 // root boundaries that match that of our current "rootContainer". 8466 // If we find that "rootContainer", we find the parent fiber 8467 // sub-tree for that root and make that our ancestor instance. 8468 var node = targetInst; 8469 8470 mainLoop: while (true) { 8471 if (node === null) { 8472 return; 8473 } 8474 8475 var nodeTag = node.tag; 8476 8477 if (nodeTag === HostRoot || nodeTag === HostPortal) { 8478 var container = node.stateNode.containerInfo; 8479 8480 if (isMatchingRootContainer(container, targetContainerNode)) { 8481 break; 8482 } 8483 8484 if (nodeTag === HostPortal) { 8485 // The target is a portal, but it's not the rootContainer we're looking for. 8486 // Normally portals handle their own events all the way down to the root. 8487 // So we should be able to stop now. However, we don't know if this portal 8488 // was part of *our* root. 8489 var grandNode = node.return; 8490 8491 while (grandNode !== null) { 8492 var grandTag = grandNode.tag; 8493 8494 if (grandTag === HostRoot || grandTag === HostPortal) { 8495 var grandContainer = grandNode.stateNode.containerInfo; 8496 8497 if (isMatchingRootContainer(grandContainer, targetContainerNode)) { 8498 // This is the rootContainer we're looking for and we found it as 8499 // a parent of the Portal. That means we can ignore it because the 8500 // Portal will bubble through to us. 8501 return; 8502 } 8503 } 8504 8505 grandNode = grandNode.return; 8506 } 8507 } // Now we need to find it's corresponding host fiber in the other 8508 // tree. To do this we can use getClosestInstanceFromNode, but we 8509 // need to validate that the fiber is a host instance, otherwise 8510 // we need to traverse up through the DOM till we find the correct 8511 // node that is from the other tree. 8512 8513 8514 while (container !== null) { 8515 var parentNode = getClosestInstanceFromNode(container); 8516 8517 if (parentNode === null) { 8518 return; 8519 } 8520 8521 var parentTag = parentNode.tag; 8522 8523 if (parentTag === HostComponent || parentTag === HostText) { 8524 node = ancestorInst = parentNode; 8525 continue mainLoop; 8526 } 8527 8528 container = container.parentNode; 8529 } 8530 } 8531 8532 node = node.return; 8533 } 8534 } 8535 } 8536 8537 batchedEventUpdates(function () { 8538 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst); 8539 }); 8540 } 8541 8542 function createDispatchListener(instance, listener, currentTarget) { 8543 return { 8544 instance: instance, 8545 listener: listener, 8546 currentTarget: currentTarget 8547 }; 8548 } 8549 8550 function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly) { 8551 var captureName = reactName !== null ? reactName + 'Capture' : null; 8552 var reactEventName = inCapturePhase ? captureName : reactName; 8553 var listeners = []; 8554 var instance = targetFiber; 8555 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path. 8556 8557 while (instance !== null) { 8558 var _instance2 = instance, 8559 stateNode = _instance2.stateNode, 8560 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>) 8561 8562 if (tag === HostComponent && stateNode !== null) { 8563 lastHostComponent = stateNode; // createEventHandle listeners 8564 8565 8566 if (reactEventName !== null) { 8567 var listener = getListener(instance, reactEventName); 8568 8569 if (listener != null) { 8570 listeners.push(createDispatchListener(instance, listener, lastHostComponent)); 8571 } 8572 } 8573 } // If we are only accumulating events for the target, then we don't 8574 // continue to propagate through the React fiber tree to find other 8575 // listeners. 8576 8577 8578 if (accumulateTargetOnly) { 8579 break; 8580 } 8581 8582 instance = instance.return; 8583 } 8584 8585 return listeners; 8586 } // We should only use this function for: 8587 // - BeforeInputEventPlugin 8588 // - ChangeEventPlugin 8589 // - SelectEventPlugin 8590 // This is because we only process these plugins 8591 // in the bubble phase, so we need to accumulate two 8592 // phase event listeners (via emulation). 8593 8594 function accumulateTwoPhaseListeners(targetFiber, reactName) { 8595 var captureName = reactName + 'Capture'; 8596 var listeners = []; 8597 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path. 8598 8599 while (instance !== null) { 8600 var _instance3 = instance, 8601 stateNode = _instance3.stateNode, 8602 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>) 8603 8604 if (tag === HostComponent && stateNode !== null) { 8605 var currentTarget = stateNode; 8606 var captureListener = getListener(instance, captureName); 8607 8608 if (captureListener != null) { 8609 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget)); 8610 } 8611 8612 var bubbleListener = getListener(instance, reactName); 8613 8614 if (bubbleListener != null) { 8615 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget)); 8616 } 8617 } 8618 8619 instance = instance.return; 8620 } 8621 8622 return listeners; 8623 } 8624 8625 function getParent(inst) { 8626 if (inst === null) { 8627 return null; 8628 } 8629 8630 do { 8631 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. 8632 // That is depending on if we want nested subtrees (layers) to bubble 8633 // events to their parent. We could also go through parentNode on the 8634 // host node but that wouldn't work for React Native and doesn't let us 8635 // do the portal feature. 8636 } while (inst && inst.tag !== HostComponent); 8637 8638 if (inst) { 8639 return inst; 8640 } 8641 8642 return null; 8643 } 8644 /** 8645 * Return the lowest common ancestor of A and B, or null if they are in 8646 * different trees. 8647 */ 8648 8649 8650 function getLowestCommonAncestor(instA, instB) { 8651 var nodeA = instA; 8652 var nodeB = instB; 8653 var depthA = 0; 8654 8655 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) { 8656 depthA++; 8657 } 8658 8659 var depthB = 0; 8660 8661 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) { 8662 depthB++; 8663 } // If A is deeper, crawl up. 8664 8665 8666 while (depthA - depthB > 0) { 8667 nodeA = getParent(nodeA); 8668 depthA--; 8669 } // If B is deeper, crawl up. 8670 8671 8672 while (depthB - depthA > 0) { 8673 nodeB = getParent(nodeB); 8674 depthB--; 8675 } // Walk in lockstep until we find a match. 8676 8677 8678 var depth = depthA; 8679 8680 while (depth--) { 8681 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) { 8682 return nodeA; 8683 } 8684 8685 nodeA = getParent(nodeA); 8686 nodeB = getParent(nodeB); 8687 } 8688 8689 return null; 8690 } 8691 8692 function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) { 8693 var registrationName = event._reactName; 8694 var listeners = []; 8695 var instance = target; 8696 8697 while (instance !== null) { 8698 if (instance === common) { 8699 break; 8700 } 8701 8702 var _instance4 = instance, 8703 alternate = _instance4.alternate, 8704 stateNode = _instance4.stateNode, 8705 tag = _instance4.tag; 8706 8707 if (alternate !== null && alternate === common) { 8708 break; 8709 } 8710 8711 if (tag === HostComponent && stateNode !== null) { 8712 var currentTarget = stateNode; 8713 8714 if (inCapturePhase) { 8715 var captureListener = getListener(instance, registrationName); 8716 8717 if (captureListener != null) { 8718 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget)); 8719 } 8720 } else if (!inCapturePhase) { 8721 var bubbleListener = getListener(instance, registrationName); 8722 8723 if (bubbleListener != null) { 8724 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget)); 8725 } 8726 } 8727 } 8728 8729 instance = instance.return; 8730 } 8731 8732 if (listeners.length !== 0) { 8733 dispatchQueue.push({ 8734 event: event, 8735 listeners: listeners 8736 }); 8737 } 8738 } // We should only use this function for: 8739 // - EnterLeaveEventPlugin 8740 // This is because we only process this plugin 8741 // in the bubble phase, so we need to accumulate two 8742 // phase event listeners. 8743 8744 8745 function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) { 8746 var common = from && to ? getLowestCommonAncestor(from, to) : null; 8747 8748 if (from !== null) { 8749 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false); 8750 } 8751 8752 if (to !== null && enterEvent !== null) { 8753 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true); 8754 } 8755 } 8756 function getListenerSetKey(domEventName, capture) { 8757 return domEventName + "__" + (capture ? 'capture' : 'bubble'); 8758 } 8759 8760 var didWarnInvalidHydration = false; 8761 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML'; 8762 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning'; 8763 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning'; 8764 var AUTOFOCUS = 'autoFocus'; 8765 var CHILDREN = 'children'; 8766 var STYLE = 'style'; 8767 var HTML$1 = '__html'; 8768 var HTML_NAMESPACE$1 = Namespaces.html; 8769 var warnedUnknownTags; 8770 var suppressHydrationWarning; 8771 var validatePropertiesInDevelopment; 8772 var warnForTextDifference; 8773 var warnForPropDifference; 8774 var warnForExtraAttributes; 8775 var warnForInvalidEventListener; 8776 var canDiffStyleForHydrationWarning; 8777 var normalizeMarkupForTextOrAttribute; 8778 var normalizeHTML; 8779 8780 { 8781 warnedUnknownTags = { 8782 // There are working polyfills for <dialog>. Let people use it. 8783 dialog: true, 8784 // Electron ships a custom <webview> tag to display external web content in 8785 // an isolated frame and process. 8786 // This tag is not present in non Electron environments such as JSDom which 8787 // is often used for testing purposes. 8788 // @see https://electronjs.org/docs/api/webview-tag 8789 webview: true 8790 }; 8791 8792 validatePropertiesInDevelopment = function (type, props) { 8793 validateProperties(type, props); 8794 validateProperties$1(type, props); 8795 validateProperties$2(type, props, { 8796 registrationNameDependencies: registrationNameDependencies, 8797 possibleRegistrationNames: possibleRegistrationNames 8798 }); 8799 }; // IE 11 parses & normalizes the style attribute as opposed to other 8800 // browsers. It adds spaces and sorts the properties in some 8801 // non-alphabetical order. Handling that would require sorting CSS 8802 // properties in the client & server versions or applying 8803 // `expectedStyle` to a temporary DOM node to read its `style` attribute 8804 // normalized. Since it only affects IE, we're skipping style warnings 8805 // in that browser completely in favor of doing all that work. 8806 // See https://github.com/facebook/react/issues/11807 8807 8808 8809 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF. 8810 // It also can turn \u0000 into \uFFFD inside attributes. 8811 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream 8812 // If we have a mismatch, it might be caused by that. 8813 // We will still patch up in this case but not fire the warning. 8814 8815 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g; 8816 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g; 8817 8818 normalizeMarkupForTextOrAttribute = function (markup) { 8819 var markupString = typeof markup === 'string' ? markup : '' + markup; 8820 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ''); 8821 }; 8822 8823 warnForTextDifference = function (serverText, clientText) { 8824 if (didWarnInvalidHydration) { 8825 return; 8826 } 8827 8828 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); 8829 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); 8830 8831 if (normalizedServerText === normalizedClientText) { 8832 return; 8833 } 8834 8835 didWarnInvalidHydration = true; 8836 8837 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText); 8838 }; 8839 8840 warnForPropDifference = function (propName, serverValue, clientValue) { 8841 if (didWarnInvalidHydration) { 8842 return; 8843 } 8844 8845 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue); 8846 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue); 8847 8848 if (normalizedServerValue === normalizedClientValue) { 8849 return; 8850 } 8851 8852 didWarnInvalidHydration = true; 8853 8854 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue)); 8855 }; 8856 8857 warnForExtraAttributes = function (attributeNames) { 8858 if (didWarnInvalidHydration) { 8859 return; 8860 } 8861 8862 didWarnInvalidHydration = true; 8863 var names = []; 8864 attributeNames.forEach(function (name) { 8865 names.push(name); 8866 }); 8867 8868 error('Extra attributes from the server: %s', names); 8869 }; 8870 8871 warnForInvalidEventListener = function (registrationName, listener) { 8872 if (listener === false) { 8873 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); 8874 } else { 8875 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener); 8876 } 8877 }; // Parse the HTML and read it back to normalize the HTML string so that it 8878 // can be used for comparison. 8879 8880 8881 normalizeHTML = function (parent, html) { 8882 // We could have created a separate document here to avoid 8883 // re-initializing custom elements if they exist. But this breaks 8884 // how <noscript> is being handled. So we use the same document. 8885 // See the discussion in https://github.com/facebook/react/pull/11157. 8886 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName); 8887 testElement.innerHTML = html; 8888 return testElement.innerHTML; 8889 }; 8890 } 8891 8892 function getOwnerDocumentFromRootContainer(rootContainerElement) { 8893 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument; 8894 } 8895 8896 function noop() {} 8897 8898 function trapClickOnNonInteractiveElement(node) { 8899 // Mobile Safari does not fire properly bubble click events on 8900 // non-interactive elements, which means delegated click listeners do not 8901 // fire. The workaround for this bug involves attaching an empty click 8902 // listener on the target node. 8903 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 8904 // Just set it using the onclick property so that we don't have to manage any 8905 // bookkeeping for it. Not sure if we need to clear it when the listener is 8906 // removed. 8907 // TODO: Only do this for the relevant Safaris maybe? 8908 node.onclick = noop; 8909 } 8910 8911 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) { 8912 for (var propKey in nextProps) { 8913 if (!nextProps.hasOwnProperty(propKey)) { 8914 continue; 8915 } 8916 8917 var nextProp = nextProps[propKey]; 8918 8919 if (propKey === STYLE) { 8920 { 8921 if (nextProp) { 8922 // Freeze the next style object so that we can assume it won't be 8923 // mutated. We have already warned for this in the past. 8924 Object.freeze(nextProp); 8925 } 8926 } // Relies on `updateStylesByID` not mutating `styleUpdates`. 8927 8928 8929 setValueForStyles(domElement, nextProp); 8930 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 8931 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 8932 8933 if (nextHtml != null) { 8934 setInnerHTML(domElement, nextHtml); 8935 } 8936 } else if (propKey === CHILDREN) { 8937 if (typeof nextProp === 'string') { 8938 // Avoid setting initial textContent when the text is empty. In IE11 setting 8939 // textContent on a <textarea> will cause the placeholder to not 8940 // show within the <textarea> until it has been focused and blurred again. 8941 // https://github.com/facebook/react/issues/6731#issuecomment-254874553 8942 var canSetTextContent = tag !== 'textarea' || nextProp !== ''; 8943 8944 if (canSetTextContent) { 8945 setTextContent(domElement, nextProp); 8946 } 8947 } else if (typeof nextProp === 'number') { 8948 setTextContent(domElement, '' + nextProp); 8949 } 8950 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) { 8951 if (nextProp != null) { 8952 if ( typeof nextProp !== 'function') { 8953 warnForInvalidEventListener(propKey, nextProp); 8954 } 8955 8956 if (propKey === 'onScroll') { 8957 listenToNonDelegatedEvent('scroll', domElement); 8958 } 8959 } 8960 } else if (nextProp != null) { 8961 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag); 8962 } 8963 } 8964 } 8965 8966 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) { 8967 // TODO: Handle wasCustomComponentTag 8968 for (var i = 0; i < updatePayload.length; i += 2) { 8969 var propKey = updatePayload[i]; 8970 var propValue = updatePayload[i + 1]; 8971 8972 if (propKey === STYLE) { 8973 setValueForStyles(domElement, propValue); 8974 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 8975 setInnerHTML(domElement, propValue); 8976 } else if (propKey === CHILDREN) { 8977 setTextContent(domElement, propValue); 8978 } else { 8979 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag); 8980 } 8981 } 8982 } 8983 8984 function createElement(type, props, rootContainerElement, parentNamespace) { 8985 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML 8986 // tags get no namespace. 8987 8988 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement); 8989 var domElement; 8990 var namespaceURI = parentNamespace; 8991 8992 if (namespaceURI === HTML_NAMESPACE$1) { 8993 namespaceURI = getIntrinsicNamespace(type); 8994 } 8995 8996 if (namespaceURI === HTML_NAMESPACE$1) { 8997 { 8998 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to 8999 // allow <SVG> or <mATH>. 9000 9001 if (!isCustomComponentTag && type !== type.toLowerCase()) { 9002 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type); 9003 } 9004 } 9005 9006 if (type === 'script') { 9007 // Create the script via .innerHTML so its "parser-inserted" flag is 9008 // set to true and it does not execute 9009 var div = ownerDocument.createElement('div'); 9010 9011 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line 9012 // This is guaranteed to yield a script element. 9013 9014 var firstChild = div.firstChild; 9015 domElement = div.removeChild(firstChild); 9016 } else if (typeof props.is === 'string') { 9017 // $FlowIssue `createElement` should be updated for Web Components 9018 domElement = ownerDocument.createElement(type, { 9019 is: props.is 9020 }); 9021 } else { 9022 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. 9023 // See discussion in https://github.com/facebook/react/pull/6896 9024 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 9025 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size` 9026 // attributes on `select`s needs to be added before `option`s are inserted. 9027 // This prevents: 9028 // - a bug where the `select` does not scroll to the correct option because singular 9029 // `select` elements automatically pick the first item #13222 9030 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239 9031 // See https://github.com/facebook/react/issues/13222 9032 // and https://github.com/facebook/react/issues/14239 9033 9034 if (type === 'select') { 9035 var node = domElement; 9036 9037 if (props.multiple) { 9038 node.multiple = true; 9039 } else if (props.size) { 9040 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where 9041 // it is possible that no option is selected. 9042 // 9043 // This is only necessary when a select in "single selection mode". 9044 node.size = props.size; 9045 } 9046 } 9047 } 9048 } else { 9049 domElement = ownerDocument.createElementNS(namespaceURI, type); 9050 } 9051 9052 { 9053 if (namespaceURI === HTML_NAMESPACE$1) { 9054 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) { 9055 warnedUnknownTags[type] = true; 9056 9057 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); 9058 } 9059 } 9060 } 9061 9062 return domElement; 9063 } 9064 function createTextNode(text, rootContainerElement) { 9065 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); 9066 } 9067 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) { 9068 var isCustomComponentTag = isCustomComponent(tag, rawProps); 9069 9070 { 9071 validatePropertiesInDevelopment(tag, rawProps); 9072 } // TODO: Make sure that we check isMounted before firing any of these events. 9073 9074 9075 var props; 9076 9077 switch (tag) { 9078 case 'dialog': 9079 listenToNonDelegatedEvent('cancel', domElement); 9080 listenToNonDelegatedEvent('close', domElement); 9081 props = rawProps; 9082 break; 9083 9084 case 'iframe': 9085 case 'object': 9086 case 'embed': 9087 // We listen to this event in case to ensure emulated bubble 9088 // listeners still fire for the load event. 9089 listenToNonDelegatedEvent('load', domElement); 9090 props = rawProps; 9091 break; 9092 9093 case 'video': 9094 case 'audio': 9095 // We listen to these events in case to ensure emulated bubble 9096 // listeners still fire for all the media events. 9097 for (var i = 0; i < mediaEventTypes.length; i++) { 9098 listenToNonDelegatedEvent(mediaEventTypes[i], domElement); 9099 } 9100 9101 props = rawProps; 9102 break; 9103 9104 case 'source': 9105 // We listen to this event in case to ensure emulated bubble 9106 // listeners still fire for the error event. 9107 listenToNonDelegatedEvent('error', domElement); 9108 props = rawProps; 9109 break; 9110 9111 case 'img': 9112 case 'image': 9113 case 'link': 9114 // We listen to these events in case to ensure emulated bubble 9115 // listeners still fire for error and load events. 9116 listenToNonDelegatedEvent('error', domElement); 9117 listenToNonDelegatedEvent('load', domElement); 9118 props = rawProps; 9119 break; 9120 9121 case 'details': 9122 // We listen to this event in case to ensure emulated bubble 9123 // listeners still fire for the toggle event. 9124 listenToNonDelegatedEvent('toggle', domElement); 9125 props = rawProps; 9126 break; 9127 9128 case 'input': 9129 initWrapperState(domElement, rawProps); 9130 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9131 // listeners still fire for the invalid event. 9132 9133 listenToNonDelegatedEvent('invalid', domElement); 9134 9135 break; 9136 9137 case 'option': 9138 validateProps(domElement, rawProps); 9139 props = getHostProps$1(domElement, rawProps); 9140 break; 9141 9142 case 'select': 9143 initWrapperState$1(domElement, rawProps); 9144 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9145 // listeners still fire for the invalid event. 9146 9147 listenToNonDelegatedEvent('invalid', domElement); 9148 9149 break; 9150 9151 case 'textarea': 9152 initWrapperState$2(domElement, rawProps); 9153 props = getHostProps$3(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9154 // listeners still fire for the invalid event. 9155 9156 listenToNonDelegatedEvent('invalid', domElement); 9157 9158 break; 9159 9160 default: 9161 props = rawProps; 9162 } 9163 9164 assertValidProps(tag, props); 9165 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag); 9166 9167 switch (tag) { 9168 case 'input': 9169 // TODO: Make sure we check if this is still unmounted or do any clean 9170 // up necessary since we never stop tracking anymore. 9171 track(domElement); 9172 postMountWrapper(domElement, rawProps, false); 9173 break; 9174 9175 case 'textarea': 9176 // TODO: Make sure we check if this is still unmounted or do any clean 9177 // up necessary since we never stop tracking anymore. 9178 track(domElement); 9179 postMountWrapper$3(domElement); 9180 break; 9181 9182 case 'option': 9183 postMountWrapper$1(domElement, rawProps); 9184 break; 9185 9186 case 'select': 9187 postMountWrapper$2(domElement, rawProps); 9188 break; 9189 9190 default: 9191 if (typeof props.onClick === 'function') { 9192 // TODO: This cast may not be sound for SVG, MathML or custom elements. 9193 trapClickOnNonInteractiveElement(domElement); 9194 } 9195 9196 break; 9197 } 9198 } // Calculate the diff between the two objects. 9199 9200 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { 9201 { 9202 validatePropertiesInDevelopment(tag, nextRawProps); 9203 } 9204 9205 var updatePayload = null; 9206 var lastProps; 9207 var nextProps; 9208 9209 switch (tag) { 9210 case 'input': 9211 lastProps = getHostProps(domElement, lastRawProps); 9212 nextProps = getHostProps(domElement, nextRawProps); 9213 updatePayload = []; 9214 break; 9215 9216 case 'option': 9217 lastProps = getHostProps$1(domElement, lastRawProps); 9218 nextProps = getHostProps$1(domElement, nextRawProps); 9219 updatePayload = []; 9220 break; 9221 9222 case 'select': 9223 lastProps = getHostProps$2(domElement, lastRawProps); 9224 nextProps = getHostProps$2(domElement, nextRawProps); 9225 updatePayload = []; 9226 break; 9227 9228 case 'textarea': 9229 lastProps = getHostProps$3(domElement, lastRawProps); 9230 nextProps = getHostProps$3(domElement, nextRawProps); 9231 updatePayload = []; 9232 break; 9233 9234 default: 9235 lastProps = lastRawProps; 9236 nextProps = nextRawProps; 9237 9238 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') { 9239 // TODO: This cast may not be sound for SVG, MathML or custom elements. 9240 trapClickOnNonInteractiveElement(domElement); 9241 } 9242 9243 break; 9244 } 9245 9246 assertValidProps(tag, nextProps); 9247 var propKey; 9248 var styleName; 9249 var styleUpdates = null; 9250 9251 for (propKey in lastProps) { 9252 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { 9253 continue; 9254 } 9255 9256 if (propKey === STYLE) { 9257 var lastStyle = lastProps[propKey]; 9258 9259 for (styleName in lastStyle) { 9260 if (lastStyle.hasOwnProperty(styleName)) { 9261 if (!styleUpdates) { 9262 styleUpdates = {}; 9263 } 9264 9265 styleUpdates[styleName] = ''; 9266 } 9267 } 9268 } 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)) { 9269 // This is a special case. If any listener updates we need to ensure 9270 // that the "current" fiber pointer gets updated so we need a commit 9271 // to update this element. 9272 if (!updatePayload) { 9273 updatePayload = []; 9274 } 9275 } else { 9276 // For all other deleted properties we add it to the queue. We use 9277 // the allowed property list in the commit phase instead. 9278 (updatePayload = updatePayload || []).push(propKey, null); 9279 } 9280 } 9281 9282 for (propKey in nextProps) { 9283 var nextProp = nextProps[propKey]; 9284 var lastProp = lastProps != null ? lastProps[propKey] : undefined; 9285 9286 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { 9287 continue; 9288 } 9289 9290 if (propKey === STYLE) { 9291 { 9292 if (nextProp) { 9293 // Freeze the next style object so that we can assume it won't be 9294 // mutated. We have already warned for this in the past. 9295 Object.freeze(nextProp); 9296 } 9297 } 9298 9299 if (lastProp) { 9300 // Unset styles on `lastProp` but not on `nextProp`. 9301 for (styleName in lastProp) { 9302 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { 9303 if (!styleUpdates) { 9304 styleUpdates = {}; 9305 } 9306 9307 styleUpdates[styleName] = ''; 9308 } 9309 } // Update styles that changed since `lastProp`. 9310 9311 9312 for (styleName in nextProp) { 9313 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { 9314 if (!styleUpdates) { 9315 styleUpdates = {}; 9316 } 9317 9318 styleUpdates[styleName] = nextProp[styleName]; 9319 } 9320 } 9321 } else { 9322 // Relies on `updateStylesByID` not mutating `styleUpdates`. 9323 if (!styleUpdates) { 9324 if (!updatePayload) { 9325 updatePayload = []; 9326 } 9327 9328 updatePayload.push(propKey, styleUpdates); 9329 } 9330 9331 styleUpdates = nextProp; 9332 } 9333 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 9334 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 9335 var lastHtml = lastProp ? lastProp[HTML$1] : undefined; 9336 9337 if (nextHtml != null) { 9338 if (lastHtml !== nextHtml) { 9339 (updatePayload = updatePayload || []).push(propKey, nextHtml); 9340 } 9341 } 9342 } else if (propKey === CHILDREN) { 9343 if (typeof nextProp === 'string' || typeof nextProp === 'number') { 9344 (updatePayload = updatePayload || []).push(propKey, '' + nextProp); 9345 } 9346 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) { 9347 if (nextProp != null) { 9348 // We eagerly listen to this even though we haven't committed yet. 9349 if ( typeof nextProp !== 'function') { 9350 warnForInvalidEventListener(propKey, nextProp); 9351 } 9352 9353 if (propKey === 'onScroll') { 9354 listenToNonDelegatedEvent('scroll', domElement); 9355 } 9356 } 9357 9358 if (!updatePayload && lastProp !== nextProp) { 9359 // This is a special case. If any listener updates we need to ensure 9360 // that the "current" props pointer gets updated so we need a commit 9361 // to update this element. 9362 updatePayload = []; 9363 } 9364 } else if (typeof nextProp === 'object' && nextProp !== null && nextProp.$$typeof === REACT_OPAQUE_ID_TYPE) { 9365 // If we encounter useOpaqueReference's opaque object, this means we are hydrating. 9366 // In this case, call the opaque object's toString function which generates a new client 9367 // ID so client and server IDs match and throws to rerender. 9368 nextProp.toString(); 9369 } else { 9370 // For any other property we always add it to the queue and then we 9371 // filter it out using the allowed property list during the commit. 9372 (updatePayload = updatePayload || []).push(propKey, nextProp); 9373 } 9374 } 9375 9376 if (styleUpdates) { 9377 { 9378 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]); 9379 } 9380 9381 (updatePayload = updatePayload || []).push(STYLE, styleUpdates); 9382 } 9383 9384 return updatePayload; 9385 } // Apply the diff. 9386 9387 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) { 9388 // Update checked *before* name. 9389 // In the middle of an update, it is possible to have multiple checked. 9390 // When a checked radio tries to change name, browser makes another radio's checked false. 9391 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) { 9392 updateChecked(domElement, nextRawProps); 9393 } 9394 9395 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps); 9396 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff. 9397 9398 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props 9399 // changed. 9400 9401 switch (tag) { 9402 case 'input': 9403 // Update the wrapper around inputs *after* updating props. This has to 9404 // happen after `updateDOMProperties`. Otherwise HTML5 input validations 9405 // raise warnings and prevent the new value from being assigned. 9406 updateWrapper(domElement, nextRawProps); 9407 break; 9408 9409 case 'textarea': 9410 updateWrapper$1(domElement, nextRawProps); 9411 break; 9412 9413 case 'select': 9414 // <select> value update needs to occur after <option> children 9415 // reconciliation 9416 postUpdateWrapper(domElement, nextRawProps); 9417 break; 9418 } 9419 } 9420 9421 function getPossibleStandardName(propName) { 9422 { 9423 var lowerCasedName = propName.toLowerCase(); 9424 9425 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) { 9426 return null; 9427 } 9428 9429 return possibleStandardNames[lowerCasedName] || null; 9430 } 9431 } 9432 9433 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) { 9434 var isCustomComponentTag; 9435 var extraAttributeNames; 9436 9437 { 9438 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true; 9439 isCustomComponentTag = isCustomComponent(tag, rawProps); 9440 validatePropertiesInDevelopment(tag, rawProps); 9441 } // TODO: Make sure that we check isMounted before firing any of these events. 9442 9443 9444 switch (tag) { 9445 case 'dialog': 9446 listenToNonDelegatedEvent('cancel', domElement); 9447 listenToNonDelegatedEvent('close', domElement); 9448 break; 9449 9450 case 'iframe': 9451 case 'object': 9452 case 'embed': 9453 // We listen to this event in case to ensure emulated bubble 9454 // listeners still fire for the load event. 9455 listenToNonDelegatedEvent('load', domElement); 9456 break; 9457 9458 case 'video': 9459 case 'audio': 9460 // We listen to these events in case to ensure emulated bubble 9461 // listeners still fire for all the media events. 9462 for (var i = 0; i < mediaEventTypes.length; i++) { 9463 listenToNonDelegatedEvent(mediaEventTypes[i], domElement); 9464 } 9465 9466 break; 9467 9468 case 'source': 9469 // We listen to this event in case to ensure emulated bubble 9470 // listeners still fire for the error event. 9471 listenToNonDelegatedEvent('error', domElement); 9472 break; 9473 9474 case 'img': 9475 case 'image': 9476 case 'link': 9477 // We listen to these events in case to ensure emulated bubble 9478 // listeners still fire for error and load events. 9479 listenToNonDelegatedEvent('error', domElement); 9480 listenToNonDelegatedEvent('load', domElement); 9481 break; 9482 9483 case 'details': 9484 // We listen to this event in case to ensure emulated bubble 9485 // listeners still fire for the toggle event. 9486 listenToNonDelegatedEvent('toggle', domElement); 9487 break; 9488 9489 case 'input': 9490 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9491 // listeners still fire for the invalid event. 9492 9493 listenToNonDelegatedEvent('invalid', domElement); 9494 9495 break; 9496 9497 case 'option': 9498 validateProps(domElement, rawProps); 9499 break; 9500 9501 case 'select': 9502 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9503 // listeners still fire for the invalid event. 9504 9505 listenToNonDelegatedEvent('invalid', domElement); 9506 9507 break; 9508 9509 case 'textarea': 9510 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9511 // listeners still fire for the invalid event. 9512 9513 listenToNonDelegatedEvent('invalid', domElement); 9514 9515 break; 9516 } 9517 9518 assertValidProps(tag, rawProps); 9519 9520 { 9521 extraAttributeNames = new Set(); 9522 var attributes = domElement.attributes; 9523 9524 for (var _i = 0; _i < attributes.length; _i++) { 9525 var name = attributes[_i].name.toLowerCase(); 9526 9527 switch (name) { 9528 // Built-in SSR attribute is allowed 9529 case 'data-reactroot': 9530 break; 9531 // Controlled attributes are not validated 9532 // TODO: Only ignore them on controlled tags. 9533 9534 case 'value': 9535 break; 9536 9537 case 'checked': 9538 break; 9539 9540 case 'selected': 9541 break; 9542 9543 default: 9544 // Intentionally use the original name. 9545 // See discussion in https://github.com/facebook/react/pull/10676. 9546 extraAttributeNames.add(attributes[_i].name); 9547 } 9548 } 9549 } 9550 9551 var updatePayload = null; 9552 9553 for (var propKey in rawProps) { 9554 if (!rawProps.hasOwnProperty(propKey)) { 9555 continue; 9556 } 9557 9558 var nextProp = rawProps[propKey]; 9559 9560 if (propKey === CHILDREN) { 9561 // For text content children we compare against textContent. This 9562 // might match additional HTML that is hidden when we read it using 9563 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still 9564 // satisfies our requirement. Our requirement is not to produce perfect 9565 // HTML and attributes. Ideally we should preserve structure but it's 9566 // ok not to if the visible content is still enough to indicate what 9567 // even listeners these nodes might be wired up to. 9568 // TODO: Warn if there is more than a single textNode as a child. 9569 // TODO: Should we use domElement.firstChild.nodeValue to compare? 9570 if (typeof nextProp === 'string') { 9571 if (domElement.textContent !== nextProp) { 9572 if ( !suppressHydrationWarning) { 9573 warnForTextDifference(domElement.textContent, nextProp); 9574 } 9575 9576 updatePayload = [CHILDREN, nextProp]; 9577 } 9578 } else if (typeof nextProp === 'number') { 9579 if (domElement.textContent !== '' + nextProp) { 9580 if ( !suppressHydrationWarning) { 9581 warnForTextDifference(domElement.textContent, nextProp); 9582 } 9583 9584 updatePayload = [CHILDREN, '' + nextProp]; 9585 } 9586 } 9587 } else if (registrationNameDependencies.hasOwnProperty(propKey)) { 9588 if (nextProp != null) { 9589 if ( typeof nextProp !== 'function') { 9590 warnForInvalidEventListener(propKey, nextProp); 9591 } 9592 9593 if (propKey === 'onScroll') { 9594 listenToNonDelegatedEvent('scroll', domElement); 9595 } 9596 } 9597 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.) 9598 typeof isCustomComponentTag === 'boolean') { 9599 // Validate that the properties correspond to their expected values. 9600 var serverValue = void 0; 9601 var propertyInfo = getPropertyInfo(propKey); 9602 9603 if (suppressHydrationWarning) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated 9604 // TODO: Only ignore them on controlled tags. 9605 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 9606 var serverHTML = domElement.innerHTML; 9607 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 9608 9609 if (nextHtml != null) { 9610 var expectedHTML = normalizeHTML(domElement, nextHtml); 9611 9612 if (expectedHTML !== serverHTML) { 9613 warnForPropDifference(propKey, serverHTML, expectedHTML); 9614 } 9615 } 9616 } else if (propKey === STYLE) { 9617 // $FlowFixMe - Should be inferred as not undefined. 9618 extraAttributeNames.delete(propKey); 9619 9620 if (canDiffStyleForHydrationWarning) { 9621 var expectedStyle = createDangerousStringForStyles(nextProp); 9622 serverValue = domElement.getAttribute('style'); 9623 9624 if (expectedStyle !== serverValue) { 9625 warnForPropDifference(propKey, serverValue, expectedStyle); 9626 } 9627 } 9628 } else if (isCustomComponentTag) { 9629 // $FlowFixMe - Should be inferred as not undefined. 9630 extraAttributeNames.delete(propKey.toLowerCase()); 9631 serverValue = getValueForAttribute(domElement, propKey, nextProp); 9632 9633 if (nextProp !== serverValue) { 9634 warnForPropDifference(propKey, serverValue, nextProp); 9635 } 9636 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) { 9637 var isMismatchDueToBadCasing = false; 9638 9639 if (propertyInfo !== null) { 9640 // $FlowFixMe - Should be inferred as not undefined. 9641 extraAttributeNames.delete(propertyInfo.attributeName); 9642 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo); 9643 } else { 9644 var ownNamespace = parentNamespace; 9645 9646 if (ownNamespace === HTML_NAMESPACE$1) { 9647 ownNamespace = getIntrinsicNamespace(tag); 9648 } 9649 9650 if (ownNamespace === HTML_NAMESPACE$1) { 9651 // $FlowFixMe - Should be inferred as not undefined. 9652 extraAttributeNames.delete(propKey.toLowerCase()); 9653 } else { 9654 var standardName = getPossibleStandardName(propKey); 9655 9656 if (standardName !== null && standardName !== propKey) { 9657 // If an SVG prop is supplied with bad casing, it will 9658 // be successfully parsed from HTML, but will produce a mismatch 9659 // (and would be incorrectly rendered on the client). 9660 // However, we already warn about bad casing elsewhere. 9661 // So we'll skip the misleading extra mismatch warning in this case. 9662 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined. 9663 9664 extraAttributeNames.delete(standardName); 9665 } // $FlowFixMe - Should be inferred as not undefined. 9666 9667 9668 extraAttributeNames.delete(propKey); 9669 } 9670 9671 serverValue = getValueForAttribute(domElement, propKey, nextProp); 9672 } 9673 9674 if (nextProp !== serverValue && !isMismatchDueToBadCasing) { 9675 warnForPropDifference(propKey, serverValue, nextProp); 9676 } 9677 } 9678 } 9679 } 9680 9681 { 9682 // $FlowFixMe - Should be inferred as not undefined. 9683 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) { 9684 // $FlowFixMe - Should be inferred as not undefined. 9685 warnForExtraAttributes(extraAttributeNames); 9686 } 9687 } 9688 9689 switch (tag) { 9690 case 'input': 9691 // TODO: Make sure we check if this is still unmounted or do any clean 9692 // up necessary since we never stop tracking anymore. 9693 track(domElement); 9694 postMountWrapper(domElement, rawProps, true); 9695 break; 9696 9697 case 'textarea': 9698 // TODO: Make sure we check if this is still unmounted or do any clean 9699 // up necessary since we never stop tracking anymore. 9700 track(domElement); 9701 postMountWrapper$3(domElement); 9702 break; 9703 9704 case 'select': 9705 case 'option': 9706 // For input and textarea we current always set the value property at 9707 // post mount to force it to diverge from attributes. However, for 9708 // option and select we don't quite do the same thing and select 9709 // is not resilient to the DOM state changing so we don't do that here. 9710 // TODO: Consider not doing this for input and textarea. 9711 break; 9712 9713 default: 9714 if (typeof rawProps.onClick === 'function') { 9715 // TODO: This cast may not be sound for SVG, MathML or custom elements. 9716 trapClickOnNonInteractiveElement(domElement); 9717 } 9718 9719 break; 9720 } 9721 9722 return updatePayload; 9723 } 9724 function diffHydratedText(textNode, text) { 9725 var isDifferent = textNode.nodeValue !== text; 9726 return isDifferent; 9727 } 9728 function warnForUnmatchedText(textNode, text) { 9729 { 9730 warnForTextDifference(textNode.nodeValue, text); 9731 } 9732 } 9733 function warnForDeletedHydratableElement(parentNode, child) { 9734 { 9735 if (didWarnInvalidHydration) { 9736 return; 9737 } 9738 9739 didWarnInvalidHydration = true; 9740 9741 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase()); 9742 } 9743 } 9744 function warnForDeletedHydratableText(parentNode, child) { 9745 { 9746 if (didWarnInvalidHydration) { 9747 return; 9748 } 9749 9750 didWarnInvalidHydration = true; 9751 9752 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase()); 9753 } 9754 } 9755 function warnForInsertedHydratedElement(parentNode, tag, props) { 9756 { 9757 if (didWarnInvalidHydration) { 9758 return; 9759 } 9760 9761 didWarnInvalidHydration = true; 9762 9763 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase()); 9764 } 9765 } 9766 function warnForInsertedHydratedText(parentNode, text) { 9767 { 9768 if (text === '') { 9769 // We expect to insert empty text nodes since they're not represented in 9770 // the HTML. 9771 // TODO: Remove this special case if we can just avoid inserting empty 9772 // text nodes. 9773 return; 9774 } 9775 9776 if (didWarnInvalidHydration) { 9777 return; 9778 } 9779 9780 didWarnInvalidHydration = true; 9781 9782 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase()); 9783 } 9784 } 9785 function restoreControlledState$3(domElement, tag, props) { 9786 switch (tag) { 9787 case 'input': 9788 restoreControlledState(domElement, props); 9789 return; 9790 9791 case 'textarea': 9792 restoreControlledState$2(domElement, props); 9793 return; 9794 9795 case 'select': 9796 restoreControlledState$1(domElement, props); 9797 return; 9798 } 9799 } 9800 9801 var validateDOMNesting = function () {}; 9802 9803 var updatedAncestorInfo = function () {}; 9804 9805 { 9806 // This validation code was written based on the HTML5 parsing spec: 9807 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 9808 // 9809 // Note: this does not catch all invalid nesting, nor does it try to (as it's 9810 // not clear what practical benefit doing so provides); instead, we warn only 9811 // for cases where the parser will give a parse tree differing from what React 9812 // intended. For example, <b><div></div></b> is invalid but we don't warn 9813 // because it still parses correctly; we do warn for other cases like nested 9814 // <p> tags where the beginning of the second element implicitly closes the 9815 // first, causing a confusing mess. 9816 // https://html.spec.whatwg.org/multipage/syntax.html#special 9817 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 9818 9819 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point 9820 // TODO: Distinguish by namespace here -- for <title>, including it here 9821 // errs on the side of fewer warnings 9822 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope 9823 9824 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags 9825 9826 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; 9827 var emptyAncestorInfo = { 9828 current: null, 9829 formTag: null, 9830 aTagInScope: null, 9831 buttonTagInScope: null, 9832 nobrTagInScope: null, 9833 pTagInButtonScope: null, 9834 listItemTagAutoclosing: null, 9835 dlItemTagAutoclosing: null 9836 }; 9837 9838 updatedAncestorInfo = function (oldInfo, tag) { 9839 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); 9840 9841 var info = { 9842 tag: tag 9843 }; 9844 9845 if (inScopeTags.indexOf(tag) !== -1) { 9846 ancestorInfo.aTagInScope = null; 9847 ancestorInfo.buttonTagInScope = null; 9848 ancestorInfo.nobrTagInScope = null; 9849 } 9850 9851 if (buttonScopeTags.indexOf(tag) !== -1) { 9852 ancestorInfo.pTagInButtonScope = null; 9853 } // See rules for 'li', 'dd', 'dt' start tags in 9854 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 9855 9856 9857 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { 9858 ancestorInfo.listItemTagAutoclosing = null; 9859 ancestorInfo.dlItemTagAutoclosing = null; 9860 } 9861 9862 ancestorInfo.current = info; 9863 9864 if (tag === 'form') { 9865 ancestorInfo.formTag = info; 9866 } 9867 9868 if (tag === 'a') { 9869 ancestorInfo.aTagInScope = info; 9870 } 9871 9872 if (tag === 'button') { 9873 ancestorInfo.buttonTagInScope = info; 9874 } 9875 9876 if (tag === 'nobr') { 9877 ancestorInfo.nobrTagInScope = info; 9878 } 9879 9880 if (tag === 'p') { 9881 ancestorInfo.pTagInButtonScope = info; 9882 } 9883 9884 if (tag === 'li') { 9885 ancestorInfo.listItemTagAutoclosing = info; 9886 } 9887 9888 if (tag === 'dd' || tag === 'dt') { 9889 ancestorInfo.dlItemTagAutoclosing = info; 9890 } 9891 9892 return ancestorInfo; 9893 }; 9894 /** 9895 * Returns whether 9896 */ 9897 9898 9899 var isTagValidWithParent = function (tag, parentTag) { 9900 // First, let's check if we're in an unusual parsing mode... 9901 switch (parentTag) { 9902 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect 9903 case 'select': 9904 return tag === 'option' || tag === 'optgroup' || tag === '#text'; 9905 9906 case 'optgroup': 9907 return tag === 'option' || tag === '#text'; 9908 // Strictly speaking, seeing an <option> doesn't mean we're in a <select> 9909 // but 9910 9911 case 'option': 9912 return tag === '#text'; 9913 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd 9914 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption 9915 // No special behavior since these rules fall back to "in body" mode for 9916 // all except special table nodes which cause bad parsing behavior anyway. 9917 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr 9918 9919 case 'tr': 9920 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; 9921 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody 9922 9923 case 'tbody': 9924 case 'thead': 9925 case 'tfoot': 9926 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; 9927 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup 9928 9929 case 'colgroup': 9930 return tag === 'col' || tag === 'template'; 9931 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable 9932 9933 case 'table': 9934 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; 9935 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead 9936 9937 case 'head': 9938 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; 9939 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element 9940 9941 case 'html': 9942 return tag === 'head' || tag === 'body' || tag === 'frameset'; 9943 9944 case 'frameset': 9945 return tag === 'frame'; 9946 9947 case '#document': 9948 return tag === 'html'; 9949 } // Probably in the "in body" parsing mode, so we outlaw only tag combos 9950 // where the parsing rules cause implicit opens or closes to be added. 9951 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 9952 9953 9954 switch (tag) { 9955 case 'h1': 9956 case 'h2': 9957 case 'h3': 9958 case 'h4': 9959 case 'h5': 9960 case 'h6': 9961 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; 9962 9963 case 'rp': 9964 case 'rt': 9965 return impliedEndTags.indexOf(parentTag) === -1; 9966 9967 case 'body': 9968 case 'caption': 9969 case 'col': 9970 case 'colgroup': 9971 case 'frameset': 9972 case 'frame': 9973 case 'head': 9974 case 'html': 9975 case 'tbody': 9976 case 'td': 9977 case 'tfoot': 9978 case 'th': 9979 case 'thead': 9980 case 'tr': 9981 // These tags are only valid with a few parents that have special child 9982 // parsing rules -- if we're down here, then none of those matched and 9983 // so we allow it only if we don't know what the parent is, as all other 9984 // cases are invalid. 9985 return parentTag == null; 9986 } 9987 9988 return true; 9989 }; 9990 /** 9991 * Returns whether 9992 */ 9993 9994 9995 var findInvalidAncestorForTag = function (tag, ancestorInfo) { 9996 switch (tag) { 9997 case 'address': 9998 case 'article': 9999 case 'aside': 10000 case 'blockquote': 10001 case 'center': 10002 case 'details': 10003 case 'dialog': 10004 case 'dir': 10005 case 'div': 10006 case 'dl': 10007 case 'fieldset': 10008 case 'figcaption': 10009 case 'figure': 10010 case 'footer': 10011 case 'header': 10012 case 'hgroup': 10013 case 'main': 10014 case 'menu': 10015 case 'nav': 10016 case 'ol': 10017 case 'p': 10018 case 'section': 10019 case 'summary': 10020 case 'ul': 10021 case 'pre': 10022 case 'listing': 10023 case 'table': 10024 case 'hr': 10025 case 'xmp': 10026 case 'h1': 10027 case 'h2': 10028 case 'h3': 10029 case 'h4': 10030 case 'h5': 10031 case 'h6': 10032 return ancestorInfo.pTagInButtonScope; 10033 10034 case 'form': 10035 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; 10036 10037 case 'li': 10038 return ancestorInfo.listItemTagAutoclosing; 10039 10040 case 'dd': 10041 case 'dt': 10042 return ancestorInfo.dlItemTagAutoclosing; 10043 10044 case 'button': 10045 return ancestorInfo.buttonTagInScope; 10046 10047 case 'a': 10048 // Spec says something about storing a list of markers, but it sounds 10049 // equivalent to this check. 10050 return ancestorInfo.aTagInScope; 10051 10052 case 'nobr': 10053 return ancestorInfo.nobrTagInScope; 10054 } 10055 10056 return null; 10057 }; 10058 10059 var didWarn$1 = {}; 10060 10061 validateDOMNesting = function (childTag, childText, ancestorInfo) { 10062 ancestorInfo = ancestorInfo || emptyAncestorInfo; 10063 var parentInfo = ancestorInfo.current; 10064 var parentTag = parentInfo && parentInfo.tag; 10065 10066 if (childText != null) { 10067 if (childTag != null) { 10068 error('validateDOMNesting: when childText is passed, childTag should be null'); 10069 } 10070 10071 childTag = '#text'; 10072 } 10073 10074 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; 10075 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); 10076 var invalidParentOrAncestor = invalidParent || invalidAncestor; 10077 10078 if (!invalidParentOrAncestor) { 10079 return; 10080 } 10081 10082 var ancestorTag = invalidParentOrAncestor.tag; 10083 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag; 10084 10085 if (didWarn$1[warnKey]) { 10086 return; 10087 } 10088 10089 didWarn$1[warnKey] = true; 10090 var tagDisplayName = childTag; 10091 var whitespaceInfo = ''; 10092 10093 if (childTag === '#text') { 10094 if (/\S/.test(childText)) { 10095 tagDisplayName = 'Text nodes'; 10096 } else { 10097 tagDisplayName = 'Whitespace text nodes'; 10098 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.'; 10099 } 10100 } else { 10101 tagDisplayName = '<' + childTag + '>'; 10102 } 10103 10104 if (invalidParent) { 10105 var info = ''; 10106 10107 if (ancestorTag === 'table' && childTag === 'tr') { 10108 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.'; 10109 } 10110 10111 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info); 10112 } else { 10113 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag); 10114 } 10115 }; 10116 } 10117 10118 var SUPPRESS_HYDRATION_WARNING$1; 10119 10120 { 10121 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning'; 10122 } 10123 10124 var SUSPENSE_START_DATA = '$'; 10125 var SUSPENSE_END_DATA = '/$'; 10126 var SUSPENSE_PENDING_START_DATA = '$?'; 10127 var SUSPENSE_FALLBACK_START_DATA = '$!'; 10128 var STYLE$1 = 'style'; 10129 var eventsEnabled = null; 10130 var selectionInformation = null; 10131 10132 function shouldAutoFocusHostComponent(type, props) { 10133 switch (type) { 10134 case 'button': 10135 case 'input': 10136 case 'select': 10137 case 'textarea': 10138 return !!props.autoFocus; 10139 } 10140 10141 return false; 10142 } 10143 function getRootHostContext(rootContainerInstance) { 10144 var type; 10145 var namespace; 10146 var nodeType = rootContainerInstance.nodeType; 10147 10148 switch (nodeType) { 10149 case DOCUMENT_NODE: 10150 case DOCUMENT_FRAGMENT_NODE: 10151 { 10152 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment'; 10153 var root = rootContainerInstance.documentElement; 10154 namespace = root ? root.namespaceURI : getChildNamespace(null, ''); 10155 break; 10156 } 10157 10158 default: 10159 { 10160 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; 10161 var ownNamespace = container.namespaceURI || null; 10162 type = container.tagName; 10163 namespace = getChildNamespace(ownNamespace, type); 10164 break; 10165 } 10166 } 10167 10168 { 10169 var validatedTag = type.toLowerCase(); 10170 var ancestorInfo = updatedAncestorInfo(null, validatedTag); 10171 return { 10172 namespace: namespace, 10173 ancestorInfo: ancestorInfo 10174 }; 10175 } 10176 } 10177 function getChildHostContext(parentHostContext, type, rootContainerInstance) { 10178 { 10179 var parentHostContextDev = parentHostContext; 10180 var namespace = getChildNamespace(parentHostContextDev.namespace, type); 10181 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type); 10182 return { 10183 namespace: namespace, 10184 ancestorInfo: ancestorInfo 10185 }; 10186 } 10187 } 10188 function getPublicInstance(instance) { 10189 return instance; 10190 } 10191 function prepareForCommit(containerInfo) { 10192 eventsEnabled = isEnabled(); 10193 selectionInformation = getSelectionInformation(); 10194 var activeInstance = null; 10195 10196 setEnabled(false); 10197 return activeInstance; 10198 } 10199 function resetAfterCommit(containerInfo) { 10200 restoreSelection(selectionInformation); 10201 setEnabled(eventsEnabled); 10202 eventsEnabled = null; 10203 selectionInformation = null; 10204 } 10205 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 10206 var parentNamespace; 10207 10208 { 10209 // TODO: take namespace into account when validating. 10210 var hostContextDev = hostContext; 10211 validateDOMNesting(type, null, hostContextDev.ancestorInfo); 10212 10213 if (typeof props.children === 'string' || typeof props.children === 'number') { 10214 var string = '' + props.children; 10215 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 10216 validateDOMNesting(null, string, ownAncestorInfo); 10217 } 10218 10219 parentNamespace = hostContextDev.namespace; 10220 } 10221 10222 var domElement = createElement(type, props, rootContainerInstance, parentNamespace); 10223 precacheFiberNode(internalInstanceHandle, domElement); 10224 updateFiberProps(domElement, props); 10225 return domElement; 10226 } 10227 function appendInitialChild(parentInstance, child) { 10228 parentInstance.appendChild(child); 10229 } 10230 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) { 10231 setInitialProperties(domElement, type, props, rootContainerInstance); 10232 return shouldAutoFocusHostComponent(type, props); 10233 } 10234 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { 10235 { 10236 var hostContextDev = hostContext; 10237 10238 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) { 10239 var string = '' + newProps.children; 10240 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 10241 validateDOMNesting(null, string, ownAncestorInfo); 10242 } 10243 } 10244 10245 return diffProperties(domElement, type, oldProps, newProps); 10246 } 10247 function shouldSetTextContent(type, props) { 10248 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null; 10249 } 10250 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) { 10251 { 10252 var hostContextDev = hostContext; 10253 validateDOMNesting(null, text, hostContextDev.ancestorInfo); 10254 } 10255 10256 var textNode = createTextNode(text, rootContainerInstance); 10257 precacheFiberNode(internalInstanceHandle, textNode); 10258 return textNode; 10259 } 10260 // if a component just imports ReactDOM (e.g. for findDOMNode). 10261 // Some environments might not have setTimeout or clearTimeout. 10262 10263 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined; 10264 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined; 10265 var noTimeout = -1; // ------------------- 10266 function commitMount(domElement, type, newProps, internalInstanceHandle) { 10267 // Despite the naming that might imply otherwise, this method only 10268 // fires if there is an `Update` effect scheduled during mounting. 10269 // This happens if `finalizeInitialChildren` returns `true` (which it 10270 // does to implement the `autoFocus` attribute on the client). But 10271 // there are also other cases when this might happen (such as patching 10272 // up text content during hydration mismatch). So we'll check this again. 10273 if (shouldAutoFocusHostComponent(type, newProps)) { 10274 domElement.focus(); 10275 } 10276 } 10277 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { 10278 // Update the props handle so that we know which props are the ones with 10279 // with current event handlers. 10280 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node. 10281 10282 updateProperties(domElement, updatePayload, type, oldProps, newProps); 10283 } 10284 function resetTextContent(domElement) { 10285 setTextContent(domElement, ''); 10286 } 10287 function commitTextUpdate(textInstance, oldText, newText) { 10288 textInstance.nodeValue = newText; 10289 } 10290 function appendChild(parentInstance, child) { 10291 parentInstance.appendChild(child); 10292 } 10293 function appendChildToContainer(container, child) { 10294 var parentNode; 10295 10296 if (container.nodeType === COMMENT_NODE) { 10297 parentNode = container.parentNode; 10298 parentNode.insertBefore(child, container); 10299 } else { 10300 parentNode = container; 10301 parentNode.appendChild(child); 10302 } // This container might be used for a portal. 10303 // If something inside a portal is clicked, that click should bubble 10304 // through the React tree. However, on Mobile Safari the click would 10305 // never bubble through the *DOM* tree unless an ancestor with onclick 10306 // event exists. So we wouldn't see it and dispatch it. 10307 // This is why we ensure that non React root containers have inline onclick 10308 // defined. 10309 // https://github.com/facebook/react/issues/11918 10310 10311 10312 var reactRootContainer = container._reactRootContainer; 10313 10314 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) { 10315 // TODO: This cast may not be sound for SVG, MathML or custom elements. 10316 trapClickOnNonInteractiveElement(parentNode); 10317 } 10318 } 10319 function insertBefore(parentInstance, child, beforeChild) { 10320 parentInstance.insertBefore(child, beforeChild); 10321 } 10322 function insertInContainerBefore(container, child, beforeChild) { 10323 if (container.nodeType === COMMENT_NODE) { 10324 container.parentNode.insertBefore(child, beforeChild); 10325 } else { 10326 container.insertBefore(child, beforeChild); 10327 } 10328 } 10329 10330 function removeChild(parentInstance, child) { 10331 parentInstance.removeChild(child); 10332 } 10333 function removeChildFromContainer(container, child) { 10334 if (container.nodeType === COMMENT_NODE) { 10335 container.parentNode.removeChild(child); 10336 } else { 10337 container.removeChild(child); 10338 } 10339 } 10340 function hideInstance(instance) { 10341 // TODO: Does this work for all element types? What about MathML? Should we 10342 // pass host context to this method? 10343 instance = instance; 10344 var style = instance.style; 10345 10346 if (typeof style.setProperty === 'function') { 10347 style.setProperty('display', 'none', 'important'); 10348 } else { 10349 style.display = 'none'; 10350 } 10351 } 10352 function hideTextInstance(textInstance) { 10353 textInstance.nodeValue = ''; 10354 } 10355 function unhideInstance(instance, props) { 10356 instance = instance; 10357 var styleProp = props[STYLE$1]; 10358 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null; 10359 instance.style.display = dangerousStyleValue('display', display); 10360 } 10361 function unhideTextInstance(textInstance, text) { 10362 textInstance.nodeValue = text; 10363 } 10364 function clearContainer(container) { 10365 if (container.nodeType === ELEMENT_NODE) { 10366 container.textContent = ''; 10367 } else if (container.nodeType === DOCUMENT_NODE) { 10368 var body = container.body; 10369 10370 if (body != null) { 10371 body.textContent = ''; 10372 } 10373 } 10374 } // ------------------- 10375 function canHydrateInstance(instance, type, props) { 10376 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) { 10377 return null; 10378 } // This has now been refined to an element node. 10379 10380 10381 return instance; 10382 } 10383 function canHydrateTextInstance(instance, text) { 10384 if (text === '' || instance.nodeType !== TEXT_NODE) { 10385 // Empty strings are not parsed by HTML so there won't be a correct match here. 10386 return null; 10387 } // This has now been refined to a text node. 10388 10389 10390 return instance; 10391 } 10392 function isSuspenseInstancePending(instance) { 10393 return instance.data === SUSPENSE_PENDING_START_DATA; 10394 } 10395 function isSuspenseInstanceFallback(instance) { 10396 return instance.data === SUSPENSE_FALLBACK_START_DATA; 10397 } 10398 10399 function getNextHydratable(node) { 10400 // Skip non-hydratable nodes. 10401 for (; node != null; node = node.nextSibling) { 10402 var nodeType = node.nodeType; 10403 10404 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) { 10405 break; 10406 } 10407 } 10408 10409 return node; 10410 } 10411 10412 function getNextHydratableSibling(instance) { 10413 return getNextHydratable(instance.nextSibling); 10414 } 10415 function getFirstHydratableChild(parentInstance) { 10416 return getNextHydratable(parentInstance.firstChild); 10417 } 10418 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 10419 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events 10420 // get attached. 10421 10422 updateFiberProps(instance, props); 10423 var parentNamespace; 10424 10425 { 10426 var hostContextDev = hostContext; 10427 parentNamespace = hostContextDev.namespace; 10428 } 10429 10430 return diffHydratedProperties(instance, type, props, parentNamespace); 10431 } 10432 function hydrateTextInstance(textInstance, text, internalInstanceHandle) { 10433 precacheFiberNode(internalInstanceHandle, textInstance); 10434 return diffHydratedText(textInstance, text); 10435 } 10436 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) { 10437 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary. 10438 // There might be nested nodes so we need to keep track of how 10439 // deep we are and only break out when we're back on top. 10440 10441 var depth = 0; 10442 10443 while (node) { 10444 if (node.nodeType === COMMENT_NODE) { 10445 var data = node.data; 10446 10447 if (data === SUSPENSE_END_DATA) { 10448 if (depth === 0) { 10449 return getNextHydratableSibling(node); 10450 } else { 10451 depth--; 10452 } 10453 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) { 10454 depth++; 10455 } 10456 } 10457 10458 node = node.nextSibling; 10459 } // TODO: Warn, we didn't find the end comment boundary. 10460 10461 10462 return null; 10463 } // Returns the SuspenseInstance if this node is a direct child of a 10464 // SuspenseInstance. I.e. if its previous sibling is a Comment with 10465 // SUSPENSE_x_START_DATA. Otherwise, null. 10466 10467 function getParentSuspenseInstance(targetInstance) { 10468 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary. 10469 // There might be nested nodes so we need to keep track of how 10470 // deep we are and only break out when we're back on top. 10471 10472 var depth = 0; 10473 10474 while (node) { 10475 if (node.nodeType === COMMENT_NODE) { 10476 var data = node.data; 10477 10478 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) { 10479 if (depth === 0) { 10480 return node; 10481 } else { 10482 depth--; 10483 } 10484 } else if (data === SUSPENSE_END_DATA) { 10485 depth++; 10486 } 10487 } 10488 10489 node = node.previousSibling; 10490 } 10491 10492 return null; 10493 } 10494 function commitHydratedContainer(container) { 10495 // Retry if any event replaying was blocked on this. 10496 retryIfBlockedOn(container); 10497 } 10498 function commitHydratedSuspenseInstance(suspenseInstance) { 10499 // Retry if any event replaying was blocked on this. 10500 retryIfBlockedOn(suspenseInstance); 10501 } 10502 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) { 10503 { 10504 warnForUnmatchedText(textInstance, text); 10505 } 10506 } 10507 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) { 10508 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 10509 warnForUnmatchedText(textInstance, text); 10510 } 10511 } 10512 function didNotHydrateContainerInstance(parentContainer, instance) { 10513 { 10514 if (instance.nodeType === ELEMENT_NODE) { 10515 warnForDeletedHydratableElement(parentContainer, instance); 10516 } else if (instance.nodeType === COMMENT_NODE) ; else { 10517 warnForDeletedHydratableText(parentContainer, instance); 10518 } 10519 } 10520 } 10521 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) { 10522 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 10523 if (instance.nodeType === ELEMENT_NODE) { 10524 warnForDeletedHydratableElement(parentInstance, instance); 10525 } else if (instance.nodeType === COMMENT_NODE) ; else { 10526 warnForDeletedHydratableText(parentInstance, instance); 10527 } 10528 } 10529 } 10530 function didNotFindHydratableContainerInstance(parentContainer, type, props) { 10531 { 10532 warnForInsertedHydratedElement(parentContainer, type); 10533 } 10534 } 10535 function didNotFindHydratableContainerTextInstance(parentContainer, text) { 10536 { 10537 warnForInsertedHydratedText(parentContainer, text); 10538 } 10539 } 10540 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) { 10541 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 10542 warnForInsertedHydratedElement(parentInstance, type); 10543 } 10544 } 10545 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) { 10546 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 10547 warnForInsertedHydratedText(parentInstance, text); 10548 } 10549 } 10550 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) { 10551 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ; 10552 } 10553 var clientId = 0; 10554 function makeClientIdInDEV(warnOnAccessInDEV) { 10555 var id = 'r:' + (clientId++).toString(36); 10556 return { 10557 toString: function () { 10558 warnOnAccessInDEV(); 10559 return id; 10560 }, 10561 valueOf: function () { 10562 warnOnAccessInDEV(); 10563 return id; 10564 } 10565 }; 10566 } 10567 function isOpaqueHydratingObject(value) { 10568 return value !== null && typeof value === 'object' && value.$$typeof === REACT_OPAQUE_ID_TYPE; 10569 } 10570 function makeOpaqueHydratingObject(attemptToReadValue) { 10571 return { 10572 $$typeof: REACT_OPAQUE_ID_TYPE, 10573 toString: attemptToReadValue, 10574 valueOf: attemptToReadValue 10575 }; 10576 } 10577 function preparePortalMount(portalInstance) { 10578 { 10579 listenToAllSupportedEvents(portalInstance); 10580 } 10581 } 10582 10583 var randomKey = Math.random().toString(36).slice(2); 10584 var internalInstanceKey = '__reactFiber$' + randomKey; 10585 var internalPropsKey = '__reactProps$' + randomKey; 10586 var internalContainerInstanceKey = '__reactContainer$' + randomKey; 10587 var internalEventHandlersKey = '__reactEvents$' + randomKey; 10588 function precacheFiberNode(hostInst, node) { 10589 node[internalInstanceKey] = hostInst; 10590 } 10591 function markContainerAsRoot(hostRoot, node) { 10592 node[internalContainerInstanceKey] = hostRoot; 10593 } 10594 function unmarkContainerAsRoot(node) { 10595 node[internalContainerInstanceKey] = null; 10596 } 10597 function isContainerMarkedAsRoot(node) { 10598 return !!node[internalContainerInstanceKey]; 10599 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor. 10600 // If the target node is part of a hydrated or not yet rendered subtree, then 10601 // this may also return a SuspenseComponent or HostRoot to indicate that. 10602 // Conceptually the HostRoot fiber is a child of the Container node. So if you 10603 // pass the Container node as the targetNode, you will not actually get the 10604 // HostRoot back. To get to the HostRoot, you need to pass a child of it. 10605 // The same thing applies to Suspense boundaries. 10606 10607 function getClosestInstanceFromNode(targetNode) { 10608 var targetInst = targetNode[internalInstanceKey]; 10609 10610 if (targetInst) { 10611 // Don't return HostRoot or SuspenseComponent here. 10612 return targetInst; 10613 } // If the direct event target isn't a React owned DOM node, we need to look 10614 // to see if one of its parents is a React owned DOM node. 10615 10616 10617 var parentNode = targetNode.parentNode; 10618 10619 while (parentNode) { 10620 // We'll check if this is a container root that could include 10621 // React nodes in the future. We need to check this first because 10622 // if we're a child of a dehydrated container, we need to first 10623 // find that inner container before moving on to finding the parent 10624 // instance. Note that we don't check this field on the targetNode 10625 // itself because the fibers are conceptually between the container 10626 // node and the first child. It isn't surrounding the container node. 10627 // If it's not a container, we check if it's an instance. 10628 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey]; 10629 10630 if (targetInst) { 10631 // Since this wasn't the direct target of the event, we might have 10632 // stepped past dehydrated DOM nodes to get here. However they could 10633 // also have been non-React nodes. We need to answer which one. 10634 // If we the instance doesn't have any children, then there can't be 10635 // a nested suspense boundary within it. So we can use this as a fast 10636 // bailout. Most of the time, when people add non-React children to 10637 // the tree, it is using a ref to a child-less DOM node. 10638 // Normally we'd only need to check one of the fibers because if it 10639 // has ever gone from having children to deleting them or vice versa 10640 // it would have deleted the dehydrated boundary nested inside already. 10641 // However, since the HostRoot starts out with an alternate it might 10642 // have one on the alternate so we need to check in case this was a 10643 // root. 10644 var alternate = targetInst.alternate; 10645 10646 if (targetInst.child !== null || alternate !== null && alternate.child !== null) { 10647 // Next we need to figure out if the node that skipped past is 10648 // nested within a dehydrated boundary and if so, which one. 10649 var suspenseInstance = getParentSuspenseInstance(targetNode); 10650 10651 while (suspenseInstance !== null) { 10652 // We found a suspense instance. That means that we haven't 10653 // hydrated it yet. Even though we leave the comments in the 10654 // DOM after hydrating, and there are boundaries in the DOM 10655 // that could already be hydrated, we wouldn't have found them 10656 // through this pass since if the target is hydrated it would 10657 // have had an internalInstanceKey on it. 10658 // Let's get the fiber associated with the SuspenseComponent 10659 // as the deepest instance. 10660 var targetSuspenseInst = suspenseInstance[internalInstanceKey]; 10661 10662 if (targetSuspenseInst) { 10663 return targetSuspenseInst; 10664 } // If we don't find a Fiber on the comment, it might be because 10665 // we haven't gotten to hydrate it yet. There might still be a 10666 // parent boundary that hasn't above this one so we need to find 10667 // the outer most that is known. 10668 10669 10670 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent 10671 // host component also hasn't hydrated yet. We can return it 10672 // below since it will bail out on the isMounted check later. 10673 } 10674 } 10675 10676 return targetInst; 10677 } 10678 10679 targetNode = parentNode; 10680 parentNode = targetNode.parentNode; 10681 } 10682 10683 return null; 10684 } 10685 /** 10686 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent 10687 * instance, or null if the node was not rendered by this React. 10688 */ 10689 10690 function getInstanceFromNode(node) { 10691 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey]; 10692 10693 if (inst) { 10694 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) { 10695 return inst; 10696 } else { 10697 return null; 10698 } 10699 } 10700 10701 return null; 10702 } 10703 /** 10704 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding 10705 * DOM node. 10706 */ 10707 10708 function getNodeFromInstance(inst) { 10709 if (inst.tag === HostComponent || inst.tag === HostText) { 10710 // In Fiber this, is just the state node right now. We assume it will be 10711 // a host component or host text. 10712 return inst.stateNode; 10713 } // Without this first invariant, passing a non-DOM-component triggers the next 10714 // invariant for a missing parent, which is super confusing. 10715 10716 10717 { 10718 { 10719 throw Error( "getNodeFromInstance: Invalid argument." ); 10720 } 10721 } 10722 } 10723 function getFiberCurrentPropsFromNode(node) { 10724 return node[internalPropsKey] || null; 10725 } 10726 function updateFiberProps(node, props) { 10727 node[internalPropsKey] = props; 10728 } 10729 function getEventListenerSet(node) { 10730 var elementListenerSet = node[internalEventHandlersKey]; 10731 10732 if (elementListenerSet === undefined) { 10733 elementListenerSet = node[internalEventHandlersKey] = new Set(); 10734 } 10735 10736 return elementListenerSet; 10737 } 10738 10739 var loggedTypeFailures = {}; 10740 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 10741 10742 function setCurrentlyValidatingElement(element) { 10743 { 10744 if (element) { 10745 var owner = element._owner; 10746 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); 10747 ReactDebugCurrentFrame$1.setExtraStackFrame(stack); 10748 } else { 10749 ReactDebugCurrentFrame$1.setExtraStackFrame(null); 10750 } 10751 } 10752 } 10753 10754 function checkPropTypes(typeSpecs, values, location, componentName, element) { 10755 { 10756 // $FlowFixMe This is okay but Flow doesn't know it. 10757 var has = Function.call.bind(Object.prototype.hasOwnProperty); 10758 10759 for (var typeSpecName in typeSpecs) { 10760 if (has(typeSpecs, typeSpecName)) { 10761 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to 10762 // fail the render phase where it didn't fail before. So we log it. 10763 // After these have been cleaned up, we'll let them throw. 10764 10765 try { 10766 // This is intentionally an invariant that gets caught. It's the same 10767 // behavior as without this statement except with a better message. 10768 if (typeof typeSpecs[typeSpecName] !== 'function') { 10769 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`.'); 10770 err.name = 'Invariant Violation'; 10771 throw err; 10772 } 10773 10774 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'); 10775 } catch (ex) { 10776 error$1 = ex; 10777 } 10778 10779 if (error$1 && !(error$1 instanceof Error)) { 10780 setCurrentlyValidatingElement(element); 10781 10782 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); 10783 10784 setCurrentlyValidatingElement(null); 10785 } 10786 10787 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { 10788 // Only monitor this failure once because there tends to be a lot of the 10789 // same error. 10790 loggedTypeFailures[error$1.message] = true; 10791 setCurrentlyValidatingElement(element); 10792 10793 error('Failed %s type: %s', location, error$1.message); 10794 10795 setCurrentlyValidatingElement(null); 10796 } 10797 } 10798 } 10799 } 10800 } 10801 10802 var valueStack = []; 10803 var fiberStack; 10804 10805 { 10806 fiberStack = []; 10807 } 10808 10809 var index = -1; 10810 10811 function createCursor(defaultValue) { 10812 return { 10813 current: defaultValue 10814 }; 10815 } 10816 10817 function pop(cursor, fiber) { 10818 if (index < 0) { 10819 { 10820 error('Unexpected pop.'); 10821 } 10822 10823 return; 10824 } 10825 10826 { 10827 if (fiber !== fiberStack[index]) { 10828 error('Unexpected Fiber popped.'); 10829 } 10830 } 10831 10832 cursor.current = valueStack[index]; 10833 valueStack[index] = null; 10834 10835 { 10836 fiberStack[index] = null; 10837 } 10838 10839 index--; 10840 } 10841 10842 function push(cursor, value, fiber) { 10843 index++; 10844 valueStack[index] = cursor.current; 10845 10846 { 10847 fiberStack[index] = fiber; 10848 } 10849 10850 cursor.current = value; 10851 } 10852 10853 var warnedAboutMissingGetChildContext; 10854 10855 { 10856 warnedAboutMissingGetChildContext = {}; 10857 } 10858 10859 var emptyContextObject = {}; 10860 10861 { 10862 Object.freeze(emptyContextObject); 10863 } // A cursor to the current merged context object on the stack. 10864 10865 10866 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. 10867 10868 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. 10869 // We use this to get access to the parent context after we have already 10870 // pushed the next context provider, and now need to merge their contexts. 10871 10872 var previousContext = emptyContextObject; 10873 10874 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) { 10875 { 10876 if (didPushOwnContextIfProvider && isContextProvider(Component)) { 10877 // If the fiber is a context provider itself, when we read its context 10878 // we may have already pushed its own child context on the stack. A context 10879 // provider should not "see" its own child context. Therefore we read the 10880 // previous (parent) context instead for a context provider. 10881 return previousContext; 10882 } 10883 10884 return contextStackCursor.current; 10885 } 10886 } 10887 10888 function cacheContext(workInProgress, unmaskedContext, maskedContext) { 10889 { 10890 var instance = workInProgress.stateNode; 10891 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; 10892 instance.__reactInternalMemoizedMaskedChildContext = maskedContext; 10893 } 10894 } 10895 10896 function getMaskedContext(workInProgress, unmaskedContext) { 10897 { 10898 var type = workInProgress.type; 10899 var contextTypes = type.contextTypes; 10900 10901 if (!contextTypes) { 10902 return emptyContextObject; 10903 } // Avoid recreating masked context unless unmasked context has changed. 10904 // Failing to do this will result in unnecessary calls to componentWillReceiveProps. 10905 // This may trigger infinite loops if componentWillReceiveProps calls setState. 10906 10907 10908 var instance = workInProgress.stateNode; 10909 10910 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) { 10911 return instance.__reactInternalMemoizedMaskedChildContext; 10912 } 10913 10914 var context = {}; 10915 10916 for (var key in contextTypes) { 10917 context[key] = unmaskedContext[key]; 10918 } 10919 10920 { 10921 var name = getComponentName(type) || 'Unknown'; 10922 checkPropTypes(contextTypes, context, 'context', name); 10923 } // Cache unmasked context so we can avoid recreating masked context unless necessary. 10924 // Context is created before the class component is instantiated so check for instance. 10925 10926 10927 if (instance) { 10928 cacheContext(workInProgress, unmaskedContext, context); 10929 } 10930 10931 return context; 10932 } 10933 } 10934 10935 function hasContextChanged() { 10936 { 10937 return didPerformWorkStackCursor.current; 10938 } 10939 } 10940 10941 function isContextProvider(type) { 10942 { 10943 var childContextTypes = type.childContextTypes; 10944 return childContextTypes !== null && childContextTypes !== undefined; 10945 } 10946 } 10947 10948 function popContext(fiber) { 10949 { 10950 pop(didPerformWorkStackCursor, fiber); 10951 pop(contextStackCursor, fiber); 10952 } 10953 } 10954 10955 function popTopLevelContextObject(fiber) { 10956 { 10957 pop(didPerformWorkStackCursor, fiber); 10958 pop(contextStackCursor, fiber); 10959 } 10960 } 10961 10962 function pushTopLevelContextObject(fiber, context, didChange) { 10963 { 10964 if (!(contextStackCursor.current === emptyContextObject)) { 10965 { 10966 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); 10967 } 10968 } 10969 10970 push(contextStackCursor, context, fiber); 10971 push(didPerformWorkStackCursor, didChange, fiber); 10972 } 10973 } 10974 10975 function processChildContext(fiber, type, parentContext) { 10976 { 10977 var instance = fiber.stateNode; 10978 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. 10979 // It has only been added in Fiber to match the (unintentional) behavior in Stack. 10980 10981 if (typeof instance.getChildContext !== 'function') { 10982 { 10983 var componentName = getComponentName(type) || 'Unknown'; 10984 10985 if (!warnedAboutMissingGetChildContext[componentName]) { 10986 warnedAboutMissingGetChildContext[componentName] = true; 10987 10988 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); 10989 } 10990 } 10991 10992 return parentContext; 10993 } 10994 10995 var childContext = instance.getChildContext(); 10996 10997 for (var contextKey in childContext) { 10998 if (!(contextKey in childContextTypes)) { 10999 { 11000 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." ); 11001 } 11002 } 11003 } 11004 11005 { 11006 var name = getComponentName(type) || 'Unknown'; 11007 checkPropTypes(childContextTypes, childContext, 'child context', name); 11008 } 11009 11010 return _assign({}, parentContext, childContext); 11011 } 11012 } 11013 11014 function pushContextProvider(workInProgress) { 11015 { 11016 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. 11017 // If the instance does not exist yet, we will push null at first, 11018 // and replace it on the stack later when invalidating the context. 11019 11020 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later. 11021 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. 11022 11023 previousContext = contextStackCursor.current; 11024 push(contextStackCursor, memoizedMergedChildContext, workInProgress); 11025 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); 11026 return true; 11027 } 11028 } 11029 11030 function invalidateContextProvider(workInProgress, type, didChange) { 11031 { 11032 var instance = workInProgress.stateNode; 11033 11034 if (!instance) { 11035 { 11036 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." ); 11037 } 11038 } 11039 11040 if (didChange) { 11041 // Merge parent and own context. 11042 // Skip this if we're not updating due to sCU. 11043 // This avoids unnecessarily recomputing memoized values. 11044 var mergedContext = processChildContext(workInProgress, type, previousContext); 11045 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. 11046 // It is important to unwind the context in the reverse order. 11047 11048 pop(didPerformWorkStackCursor, workInProgress); 11049 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. 11050 11051 push(contextStackCursor, mergedContext, workInProgress); 11052 push(didPerformWorkStackCursor, didChange, workInProgress); 11053 } else { 11054 pop(didPerformWorkStackCursor, workInProgress); 11055 push(didPerformWorkStackCursor, didChange, workInProgress); 11056 } 11057 } 11058 } 11059 11060 function findCurrentUnmaskedContext(fiber) { 11061 { 11062 // Currently this is only used with renderSubtreeIntoContainer; not sure if it 11063 // makes sense elsewhere 11064 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { 11065 { 11066 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." ); 11067 } 11068 } 11069 11070 var node = fiber; 11071 11072 do { 11073 switch (node.tag) { 11074 case HostRoot: 11075 return node.stateNode.context; 11076 11077 case ClassComponent: 11078 { 11079 var Component = node.type; 11080 11081 if (isContextProvider(Component)) { 11082 return node.stateNode.__reactInternalMemoizedMergedChildContext; 11083 } 11084 11085 break; 11086 } 11087 } 11088 11089 node = node.return; 11090 } while (node !== null); 11091 11092 { 11093 { 11094 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." ); 11095 } 11096 } 11097 } 11098 } 11099 11100 var LegacyRoot = 0; 11101 var BlockingRoot = 1; 11102 var ConcurrentRoot = 2; 11103 11104 var rendererID = null; 11105 var injectedHook = null; 11106 var hasLoggedError = false; 11107 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'; 11108 function injectInternals(internals) { 11109 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { 11110 // No DevTools 11111 return false; 11112 } 11113 11114 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; 11115 11116 if (hook.isDisabled) { 11117 // This isn't a real property on the hook, but it can be set to opt out 11118 // of DevTools integration and associated warnings and logs. 11119 // https://github.com/facebook/react/issues/3877 11120 return true; 11121 } 11122 11123 if (!hook.supportsFiber) { 11124 { 11125 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'); 11126 } // DevTools exists, even though it doesn't support Fiber. 11127 11128 11129 return true; 11130 } 11131 11132 try { 11133 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. 11134 11135 injectedHook = hook; 11136 } catch (err) { 11137 // Catch all errors because it is unsafe to throw during initialization. 11138 { 11139 error('React instrumentation encountered an error: %s.', err); 11140 } 11141 } // DevTools exists 11142 11143 11144 return true; 11145 } 11146 function onScheduleRoot(root, children) { 11147 { 11148 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') { 11149 try { 11150 injectedHook.onScheduleFiberRoot(rendererID, root, children); 11151 } catch (err) { 11152 if ( !hasLoggedError) { 11153 hasLoggedError = true; 11154 11155 error('React instrumentation encountered an error: %s', err); 11156 } 11157 } 11158 } 11159 } 11160 } 11161 function onCommitRoot(root, priorityLevel) { 11162 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') { 11163 try { 11164 var didError = (root.current.flags & DidCapture) === DidCapture; 11165 11166 if (enableProfilerTimer) { 11167 injectedHook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); 11168 } else { 11169 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); 11170 } 11171 } catch (err) { 11172 { 11173 if (!hasLoggedError) { 11174 hasLoggedError = true; 11175 11176 error('React instrumentation encountered an error: %s', err); 11177 } 11178 } 11179 } 11180 } 11181 } 11182 function onCommitUnmount(fiber) { 11183 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') { 11184 try { 11185 injectedHook.onCommitFiberUnmount(rendererID, fiber); 11186 } catch (err) { 11187 { 11188 if (!hasLoggedError) { 11189 hasLoggedError = true; 11190 11191 error('React instrumentation encountered an error: %s', err); 11192 } 11193 } 11194 } 11195 } 11196 } 11197 11198 var Scheduler_runWithPriority = unstable_runWithPriority, 11199 Scheduler_scheduleCallback = unstable_scheduleCallback, 11200 Scheduler_cancelCallback = unstable_cancelCallback, 11201 Scheduler_shouldYield = unstable_shouldYield, 11202 Scheduler_requestPaint = unstable_requestPaint, 11203 Scheduler_now$1 = unstable_now, 11204 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel, 11205 Scheduler_ImmediatePriority = unstable_ImmediatePriority, 11206 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority, 11207 Scheduler_NormalPriority = unstable_NormalPriority, 11208 Scheduler_LowPriority = unstable_LowPriority, 11209 Scheduler_IdlePriority = unstable_IdlePriority; 11210 11211 { 11212 // Provide explicit error message when production+profiling bundle of e.g. 11213 // react-dom is used with production (non-profiling) bundle of 11214 // scheduler/tracing 11215 if (!(__interactionsRef != null && __interactionsRef.current != null)) { 11216 { 11217 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); 11218 } 11219 } 11220 } 11221 11222 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use 11223 // ascending numbers so we can compare them like numbers. They start at 90 to 11224 // avoid clashing with Scheduler's priorities. 11225 11226 var ImmediatePriority$1 = 99; 11227 var UserBlockingPriority$2 = 98; 11228 var NormalPriority$1 = 97; 11229 var LowPriority$1 = 96; 11230 var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. 11231 11232 var NoPriority$1 = 90; 11233 var shouldYield = Scheduler_shouldYield; 11234 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. 11235 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {}; 11236 var syncQueue = null; 11237 var immediateQueueCallbackNode = null; 11238 var isFlushingSyncQueue = false; 11239 var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. 11240 // This will be the case for modern browsers that support `performance.now`. In 11241 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix 11242 // timestamp. In that case, subtract the module initialization time to simulate 11243 // the behavior of performance.now and keep our times small enough to fit 11244 // within 32 bits. 11245 // TODO: Consider lifting this into Scheduler. 11246 11247 var now = initialTimeMs$1 < 10000 ? Scheduler_now$1 : function () { 11248 return Scheduler_now$1() - initialTimeMs$1; 11249 }; 11250 function getCurrentPriorityLevel() { 11251 switch (Scheduler_getCurrentPriorityLevel()) { 11252 case Scheduler_ImmediatePriority: 11253 return ImmediatePriority$1; 11254 11255 case Scheduler_UserBlockingPriority: 11256 return UserBlockingPriority$2; 11257 11258 case Scheduler_NormalPriority: 11259 return NormalPriority$1; 11260 11261 case Scheduler_LowPriority: 11262 return LowPriority$1; 11263 11264 case Scheduler_IdlePriority: 11265 return IdlePriority$1; 11266 11267 default: 11268 { 11269 { 11270 throw Error( "Unknown priority level." ); 11271 } 11272 } 11273 11274 } 11275 } 11276 11277 function reactPriorityToSchedulerPriority(reactPriorityLevel) { 11278 switch (reactPriorityLevel) { 11279 case ImmediatePriority$1: 11280 return Scheduler_ImmediatePriority; 11281 11282 case UserBlockingPriority$2: 11283 return Scheduler_UserBlockingPriority; 11284 11285 case NormalPriority$1: 11286 return Scheduler_NormalPriority; 11287 11288 case LowPriority$1: 11289 return Scheduler_LowPriority; 11290 11291 case IdlePriority$1: 11292 return Scheduler_IdlePriority; 11293 11294 default: 11295 { 11296 { 11297 throw Error( "Unknown priority level." ); 11298 } 11299 } 11300 11301 } 11302 } 11303 11304 function runWithPriority$1(reactPriorityLevel, fn) { 11305 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); 11306 return Scheduler_runWithPriority(priorityLevel, fn); 11307 } 11308 function scheduleCallback(reactPriorityLevel, callback, options) { 11309 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); 11310 return Scheduler_scheduleCallback(priorityLevel, callback, options); 11311 } 11312 function scheduleSyncCallback(callback) { 11313 // Push this callback into an internal queue. We'll flush these either in 11314 // the next tick, or earlier if something calls `flushSyncCallbackQueue`. 11315 if (syncQueue === null) { 11316 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. 11317 11318 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl); 11319 } else { 11320 // Push onto existing queue. Don't need to schedule a callback because 11321 // we already scheduled one when we created the queue. 11322 syncQueue.push(callback); 11323 } 11324 11325 return fakeCallbackNode; 11326 } 11327 function cancelCallback(callbackNode) { 11328 if (callbackNode !== fakeCallbackNode) { 11329 Scheduler_cancelCallback(callbackNode); 11330 } 11331 } 11332 function flushSyncCallbackQueue() { 11333 if (immediateQueueCallbackNode !== null) { 11334 var node = immediateQueueCallbackNode; 11335 immediateQueueCallbackNode = null; 11336 Scheduler_cancelCallback(node); 11337 } 11338 11339 flushSyncCallbackQueueImpl(); 11340 } 11341 11342 function flushSyncCallbackQueueImpl() { 11343 if (!isFlushingSyncQueue && syncQueue !== null) { 11344 // Prevent re-entrancy. 11345 isFlushingSyncQueue = true; 11346 var i = 0; 11347 11348 { 11349 try { 11350 var _isSync2 = true; 11351 var _queue = syncQueue; 11352 runWithPriority$1(ImmediatePriority$1, function () { 11353 for (; i < _queue.length; i++) { 11354 var callback = _queue[i]; 11355 11356 do { 11357 callback = callback(_isSync2); 11358 } while (callback !== null); 11359 } 11360 }); 11361 syncQueue = null; 11362 } catch (error) { 11363 // If something throws, leave the remaining callbacks on the queue. 11364 if (syncQueue !== null) { 11365 syncQueue = syncQueue.slice(i + 1); 11366 } // Resume flushing in the next tick 11367 11368 11369 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue); 11370 throw error; 11371 } finally { 11372 isFlushingSyncQueue = false; 11373 } 11374 } 11375 } 11376 } 11377 11378 // TODO: this is special because it gets imported during build. 11379 var ReactVersion = '17.0.2'; 11380 11381 var NoMode = 0; 11382 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root 11383 // tag instead 11384 11385 var BlockingMode = 2; 11386 var ConcurrentMode = 4; 11387 var ProfileMode = 8; 11388 var DebugTracingMode = 16; 11389 11390 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; 11391 var NoTransition = 0; 11392 function requestCurrentTransition() { 11393 return ReactCurrentBatchConfig.transition; 11394 } 11395 11396 var ReactStrictModeWarnings = { 11397 recordUnsafeLifecycleWarnings: function (fiber, instance) {}, 11398 flushPendingUnsafeLifecycleWarnings: function () {}, 11399 recordLegacyContextWarning: function (fiber, instance) {}, 11400 flushLegacyContextWarning: function () {}, 11401 discardPendingWarnings: function () {} 11402 }; 11403 11404 { 11405 var findStrictRoot = function (fiber) { 11406 var maybeStrictRoot = null; 11407 var node = fiber; 11408 11409 while (node !== null) { 11410 if (node.mode & StrictMode) { 11411 maybeStrictRoot = node; 11412 } 11413 11414 node = node.return; 11415 } 11416 11417 return maybeStrictRoot; 11418 }; 11419 11420 var setToSortedString = function (set) { 11421 var array = []; 11422 set.forEach(function (value) { 11423 array.push(value); 11424 }); 11425 return array.sort().join(', '); 11426 }; 11427 11428 var pendingComponentWillMountWarnings = []; 11429 var pendingUNSAFE_ComponentWillMountWarnings = []; 11430 var pendingComponentWillReceivePropsWarnings = []; 11431 var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 11432 var pendingComponentWillUpdateWarnings = []; 11433 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. 11434 11435 var didWarnAboutUnsafeLifecycles = new Set(); 11436 11437 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) { 11438 // Dedup strategy: Warn once per component. 11439 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { 11440 return; 11441 } 11442 11443 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components. 11444 instance.componentWillMount.__suppressDeprecationWarning !== true) { 11445 pendingComponentWillMountWarnings.push(fiber); 11446 } 11447 11448 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') { 11449 pendingUNSAFE_ComponentWillMountWarnings.push(fiber); 11450 } 11451 11452 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 11453 pendingComponentWillReceivePropsWarnings.push(fiber); 11454 } 11455 11456 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 11457 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); 11458 } 11459 11460 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 11461 pendingComponentWillUpdateWarnings.push(fiber); 11462 } 11463 11464 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') { 11465 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); 11466 } 11467 }; 11468 11469 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { 11470 // We do an initial pass to gather component names 11471 var componentWillMountUniqueNames = new Set(); 11472 11473 if (pendingComponentWillMountWarnings.length > 0) { 11474 pendingComponentWillMountWarnings.forEach(function (fiber) { 11475 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11476 didWarnAboutUnsafeLifecycles.add(fiber.type); 11477 }); 11478 pendingComponentWillMountWarnings = []; 11479 } 11480 11481 var UNSAFE_componentWillMountUniqueNames = new Set(); 11482 11483 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { 11484 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { 11485 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11486 didWarnAboutUnsafeLifecycles.add(fiber.type); 11487 }); 11488 pendingUNSAFE_ComponentWillMountWarnings = []; 11489 } 11490 11491 var componentWillReceivePropsUniqueNames = new Set(); 11492 11493 if (pendingComponentWillReceivePropsWarnings.length > 0) { 11494 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { 11495 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11496 didWarnAboutUnsafeLifecycles.add(fiber.type); 11497 }); 11498 pendingComponentWillReceivePropsWarnings = []; 11499 } 11500 11501 var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); 11502 11503 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { 11504 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) { 11505 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11506 didWarnAboutUnsafeLifecycles.add(fiber.type); 11507 }); 11508 pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 11509 } 11510 11511 var componentWillUpdateUniqueNames = new Set(); 11512 11513 if (pendingComponentWillUpdateWarnings.length > 0) { 11514 pendingComponentWillUpdateWarnings.forEach(function (fiber) { 11515 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11516 didWarnAboutUnsafeLifecycles.add(fiber.type); 11517 }); 11518 pendingComponentWillUpdateWarnings = []; 11519 } 11520 11521 var UNSAFE_componentWillUpdateUniqueNames = new Set(); 11522 11523 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { 11524 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { 11525 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component'); 11526 didWarnAboutUnsafeLifecycles.add(fiber.type); 11527 }); 11528 pendingUNSAFE_ComponentWillUpdateWarnings = []; 11529 } // Finally, we flush all the warnings 11530 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' 11531 11532 11533 if (UNSAFE_componentWillMountUniqueNames.size > 0) { 11534 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); 11535 11536 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); 11537 } 11538 11539 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { 11540 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames); 11541 11542 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); 11543 } 11544 11545 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { 11546 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames); 11547 11548 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); 11549 } 11550 11551 if (componentWillMountUniqueNames.size > 0) { 11552 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); 11553 11554 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); 11555 } 11556 11557 if (componentWillReceivePropsUniqueNames.size > 0) { 11558 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames); 11559 11560 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); 11561 } 11562 11563 if (componentWillUpdateUniqueNames.size > 0) { 11564 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); 11565 11566 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); 11567 } 11568 }; 11569 11570 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. 11571 11572 var didWarnAboutLegacyContext = new Set(); 11573 11574 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) { 11575 var strictRoot = findStrictRoot(fiber); 11576 11577 if (strictRoot === null) { 11578 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.'); 11579 11580 return; 11581 } // Dedup strategy: Warn once per component. 11582 11583 11584 if (didWarnAboutLegacyContext.has(fiber.type)) { 11585 return; 11586 } 11587 11588 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); 11589 11590 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') { 11591 if (warningsForRoot === undefined) { 11592 warningsForRoot = []; 11593 pendingLegacyContextWarning.set(strictRoot, warningsForRoot); 11594 } 11595 11596 warningsForRoot.push(fiber); 11597 } 11598 }; 11599 11600 ReactStrictModeWarnings.flushLegacyContextWarning = function () { 11601 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { 11602 if (fiberArray.length === 0) { 11603 return; 11604 } 11605 11606 var firstFiber = fiberArray[0]; 11607 var uniqueNames = new Set(); 11608 fiberArray.forEach(function (fiber) { 11609 uniqueNames.add(getComponentName(fiber.type) || 'Component'); 11610 didWarnAboutLegacyContext.add(fiber.type); 11611 }); 11612 var sortedNames = setToSortedString(uniqueNames); 11613 11614 try { 11615 setCurrentFiber(firstFiber); 11616 11617 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); 11618 } finally { 11619 resetCurrentFiber(); 11620 } 11621 }); 11622 }; 11623 11624 ReactStrictModeWarnings.discardPendingWarnings = function () { 11625 pendingComponentWillMountWarnings = []; 11626 pendingUNSAFE_ComponentWillMountWarnings = []; 11627 pendingComponentWillReceivePropsWarnings = []; 11628 pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 11629 pendingComponentWillUpdateWarnings = []; 11630 pendingUNSAFE_ComponentWillUpdateWarnings = []; 11631 pendingLegacyContextWarning = new Map(); 11632 }; 11633 } 11634 11635 function resolveDefaultProps(Component, baseProps) { 11636 if (Component && Component.defaultProps) { 11637 // Resolve default props. Taken from ReactElement 11638 var props = _assign({}, baseProps); 11639 11640 var defaultProps = Component.defaultProps; 11641 11642 for (var propName in defaultProps) { 11643 if (props[propName] === undefined) { 11644 props[propName] = defaultProps[propName]; 11645 } 11646 } 11647 11648 return props; 11649 } 11650 11651 return baseProps; 11652 } 11653 11654 // Max 31 bit integer. The max integer size in V8 for 32-bit systems. 11655 // Math.pow(2, 30) - 1 11656 // 0b111111111111111111111111111111 11657 var MAX_SIGNED_31_BIT_INT = 1073741823; 11658 11659 var valueCursor = createCursor(null); 11660 var rendererSigil; 11661 11662 { 11663 // Use this to detect multiple renderers using the same context 11664 rendererSigil = {}; 11665 } 11666 11667 var currentlyRenderingFiber = null; 11668 var lastContextDependency = null; 11669 var lastContextWithAllBitsObserved = null; 11670 var isDisallowedContextReadInDEV = false; 11671 function resetContextDependencies() { 11672 // This is called right before React yields execution, to ensure `readContext` 11673 // cannot be called outside the render phase. 11674 currentlyRenderingFiber = null; 11675 lastContextDependency = null; 11676 lastContextWithAllBitsObserved = null; 11677 11678 { 11679 isDisallowedContextReadInDEV = false; 11680 } 11681 } 11682 function enterDisallowedContextReadInDEV() { 11683 { 11684 isDisallowedContextReadInDEV = true; 11685 } 11686 } 11687 function exitDisallowedContextReadInDEV() { 11688 { 11689 isDisallowedContextReadInDEV = false; 11690 } 11691 } 11692 function pushProvider(providerFiber, nextValue) { 11693 var context = providerFiber.type._context; 11694 11695 { 11696 push(valueCursor, context._currentValue, providerFiber); 11697 context._currentValue = nextValue; 11698 11699 { 11700 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) { 11701 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 11702 } 11703 11704 context._currentRenderer = rendererSigil; 11705 } 11706 } 11707 } 11708 function popProvider(providerFiber) { 11709 var currentValue = valueCursor.current; 11710 pop(valueCursor, providerFiber); 11711 var context = providerFiber.type._context; 11712 11713 { 11714 context._currentValue = currentValue; 11715 } 11716 } 11717 function calculateChangedBits(context, newValue, oldValue) { 11718 if (objectIs(oldValue, newValue)) { 11719 // No change 11720 return 0; 11721 } else { 11722 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT; 11723 11724 { 11725 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { 11726 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits); 11727 } 11728 } 11729 11730 return changedBits | 0; 11731 } 11732 } 11733 function scheduleWorkOnParentPath(parent, renderLanes) { 11734 // Update the child lanes of all the ancestors, including the alternates. 11735 var node = parent; 11736 11737 while (node !== null) { 11738 var alternate = node.alternate; 11739 11740 if (!isSubsetOfLanes(node.childLanes, renderLanes)) { 11741 node.childLanes = mergeLanes(node.childLanes, renderLanes); 11742 11743 if (alternate !== null) { 11744 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); 11745 } 11746 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) { 11747 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); 11748 } else { 11749 // Neither alternate was updated, which means the rest of the 11750 // ancestor path already has sufficient priority. 11751 break; 11752 } 11753 11754 node = node.return; 11755 } 11756 } 11757 function propagateContextChange(workInProgress, context, changedBits, renderLanes) { 11758 var fiber = workInProgress.child; 11759 11760 if (fiber !== null) { 11761 // Set the return pointer of the child to the work-in-progress fiber. 11762 fiber.return = workInProgress; 11763 } 11764 11765 while (fiber !== null) { 11766 var nextFiber = void 0; // Visit this fiber. 11767 11768 var list = fiber.dependencies; 11769 11770 if (list !== null) { 11771 nextFiber = fiber.child; 11772 var dependency = list.firstContext; 11773 11774 while (dependency !== null) { 11775 // Check if the context matches. 11776 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) { 11777 // Match! Schedule an update on this fiber. 11778 if (fiber.tag === ClassComponent) { 11779 // Schedule a force update on the work-in-progress. 11780 var update = createUpdate(NoTimestamp, pickArbitraryLane(renderLanes)); 11781 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the 11782 // update to the current fiber, too, which means it will persist even if 11783 // this render is thrown away. Since it's a race condition, not sure it's 11784 // worth fixing. 11785 11786 enqueueUpdate(fiber, update); 11787 } 11788 11789 fiber.lanes = mergeLanes(fiber.lanes, renderLanes); 11790 var alternate = fiber.alternate; 11791 11792 if (alternate !== null) { 11793 alternate.lanes = mergeLanes(alternate.lanes, renderLanes); 11794 } 11795 11796 scheduleWorkOnParentPath(fiber.return, renderLanes); // Mark the updated lanes on the list, too. 11797 11798 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the 11799 // dependency list. 11800 11801 break; 11802 } 11803 11804 dependency = dependency.next; 11805 } 11806 } else if (fiber.tag === ContextProvider) { 11807 // Don't scan deeper if this is a matching provider 11808 nextFiber = fiber.type === workInProgress.type ? null : fiber.child; 11809 } else { 11810 // Traverse down. 11811 nextFiber = fiber.child; 11812 } 11813 11814 if (nextFiber !== null) { 11815 // Set the return pointer of the child to the work-in-progress fiber. 11816 nextFiber.return = fiber; 11817 } else { 11818 // No child. Traverse to next sibling. 11819 nextFiber = fiber; 11820 11821 while (nextFiber !== null) { 11822 if (nextFiber === workInProgress) { 11823 // We're back to the root of this subtree. Exit. 11824 nextFiber = null; 11825 break; 11826 } 11827 11828 var sibling = nextFiber.sibling; 11829 11830 if (sibling !== null) { 11831 // Set the return pointer of the sibling to the work-in-progress fiber. 11832 sibling.return = nextFiber.return; 11833 nextFiber = sibling; 11834 break; 11835 } // No more siblings. Traverse up. 11836 11837 11838 nextFiber = nextFiber.return; 11839 } 11840 } 11841 11842 fiber = nextFiber; 11843 } 11844 } 11845 function prepareToReadContext(workInProgress, renderLanes) { 11846 currentlyRenderingFiber = workInProgress; 11847 lastContextDependency = null; 11848 lastContextWithAllBitsObserved = null; 11849 var dependencies = workInProgress.dependencies; 11850 11851 if (dependencies !== null) { 11852 var firstContext = dependencies.firstContext; 11853 11854 if (firstContext !== null) { 11855 if (includesSomeLane(dependencies.lanes, renderLanes)) { 11856 // Context list has a pending update. Mark that this fiber performed work. 11857 markWorkInProgressReceivedUpdate(); 11858 } // Reset the work-in-progress list 11859 11860 11861 dependencies.firstContext = null; 11862 } 11863 } 11864 } 11865 function readContext(context, observedBits) { 11866 { 11867 // This warning would fire if you read context inside a Hook like useMemo. 11868 // Unlike the class check below, it's not enforced in production for perf. 11869 if (isDisallowedContextReadInDEV) { 11870 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().'); 11871 } 11872 } 11873 11874 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else { 11875 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. 11876 11877 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) { 11878 // Observe all updates. 11879 lastContextWithAllBitsObserved = context; 11880 resolvedObservedBits = MAX_SIGNED_31_BIT_INT; 11881 } else { 11882 resolvedObservedBits = observedBits; 11883 } 11884 11885 var contextItem = { 11886 context: context, 11887 observedBits: resolvedObservedBits, 11888 next: null 11889 }; 11890 11891 if (lastContextDependency === null) { 11892 if (!(currentlyRenderingFiber !== null)) { 11893 { 11894 throw 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()." ); 11895 } 11896 } // This is the first dependency for this component. Create a new list. 11897 11898 11899 lastContextDependency = contextItem; 11900 currentlyRenderingFiber.dependencies = { 11901 lanes: NoLanes, 11902 firstContext: contextItem, 11903 responders: null 11904 }; 11905 } else { 11906 // Append a new context item. 11907 lastContextDependency = lastContextDependency.next = contextItem; 11908 } 11909 } 11910 11911 return context._currentValue ; 11912 } 11913 11914 var UpdateState = 0; 11915 var ReplaceState = 1; 11916 var ForceUpdate = 2; 11917 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. 11918 // It should only be read right after calling `processUpdateQueue`, via 11919 // `checkHasForceUpdateAfterProcessing`. 11920 11921 var hasForceUpdate = false; 11922 var didWarnUpdateInsideUpdate; 11923 var currentlyProcessingQueue; 11924 11925 { 11926 didWarnUpdateInsideUpdate = false; 11927 currentlyProcessingQueue = null; 11928 } 11929 11930 function initializeUpdateQueue(fiber) { 11931 var queue = { 11932 baseState: fiber.memoizedState, 11933 firstBaseUpdate: null, 11934 lastBaseUpdate: null, 11935 shared: { 11936 pending: null 11937 }, 11938 effects: null 11939 }; 11940 fiber.updateQueue = queue; 11941 } 11942 function cloneUpdateQueue(current, workInProgress) { 11943 // Clone the update queue from current. Unless it's already a clone. 11944 var queue = workInProgress.updateQueue; 11945 var currentQueue = current.updateQueue; 11946 11947 if (queue === currentQueue) { 11948 var clone = { 11949 baseState: currentQueue.baseState, 11950 firstBaseUpdate: currentQueue.firstBaseUpdate, 11951 lastBaseUpdate: currentQueue.lastBaseUpdate, 11952 shared: currentQueue.shared, 11953 effects: currentQueue.effects 11954 }; 11955 workInProgress.updateQueue = clone; 11956 } 11957 } 11958 function createUpdate(eventTime, lane) { 11959 var update = { 11960 eventTime: eventTime, 11961 lane: lane, 11962 tag: UpdateState, 11963 payload: null, 11964 callback: null, 11965 next: null 11966 }; 11967 return update; 11968 } 11969 function enqueueUpdate(fiber, update) { 11970 var updateQueue = fiber.updateQueue; 11971 11972 if (updateQueue === null) { 11973 // Only occurs if the fiber has been unmounted. 11974 return; 11975 } 11976 11977 var sharedQueue = updateQueue.shared; 11978 var pending = sharedQueue.pending; 11979 11980 if (pending === null) { 11981 // This is the first update. Create a circular list. 11982 update.next = update; 11983 } else { 11984 update.next = pending.next; 11985 pending.next = update; 11986 } 11987 11988 sharedQueue.pending = update; 11989 11990 { 11991 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) { 11992 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.'); 11993 11994 didWarnUpdateInsideUpdate = true; 11995 } 11996 } 11997 } 11998 function enqueueCapturedUpdate(workInProgress, capturedUpdate) { 11999 // Captured updates are updates that are thrown by a child during the render 12000 // phase. They should be discarded if the render is aborted. Therefore, 12001 // we should only put them on the work-in-progress queue, not the current one. 12002 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. 12003 12004 var current = workInProgress.alternate; 12005 12006 if (current !== null) { 12007 var currentQueue = current.updateQueue; 12008 12009 if (queue === currentQueue) { 12010 // The work-in-progress queue is the same as current. This happens when 12011 // we bail out on a parent fiber that then captures an error thrown by 12012 // a child. Since we want to append the update only to the work-in 12013 // -progress queue, we need to clone the updates. We usually clone during 12014 // processUpdateQueue, but that didn't happen in this case because we 12015 // skipped over the parent when we bailed out. 12016 var newFirst = null; 12017 var newLast = null; 12018 var firstBaseUpdate = queue.firstBaseUpdate; 12019 12020 if (firstBaseUpdate !== null) { 12021 // Loop through the updates and clone them. 12022 var update = firstBaseUpdate; 12023 12024 do { 12025 var clone = { 12026 eventTime: update.eventTime, 12027 lane: update.lane, 12028 tag: update.tag, 12029 payload: update.payload, 12030 callback: update.callback, 12031 next: null 12032 }; 12033 12034 if (newLast === null) { 12035 newFirst = newLast = clone; 12036 } else { 12037 newLast.next = clone; 12038 newLast = clone; 12039 } 12040 12041 update = update.next; 12042 } while (update !== null); // Append the captured update the end of the cloned list. 12043 12044 12045 if (newLast === null) { 12046 newFirst = newLast = capturedUpdate; 12047 } else { 12048 newLast.next = capturedUpdate; 12049 newLast = capturedUpdate; 12050 } 12051 } else { 12052 // There are no base updates. 12053 newFirst = newLast = capturedUpdate; 12054 } 12055 12056 queue = { 12057 baseState: currentQueue.baseState, 12058 firstBaseUpdate: newFirst, 12059 lastBaseUpdate: newLast, 12060 shared: currentQueue.shared, 12061 effects: currentQueue.effects 12062 }; 12063 workInProgress.updateQueue = queue; 12064 return; 12065 } 12066 } // Append the update to the end of the list. 12067 12068 12069 var lastBaseUpdate = queue.lastBaseUpdate; 12070 12071 if (lastBaseUpdate === null) { 12072 queue.firstBaseUpdate = capturedUpdate; 12073 } else { 12074 lastBaseUpdate.next = capturedUpdate; 12075 } 12076 12077 queue.lastBaseUpdate = capturedUpdate; 12078 } 12079 12080 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) { 12081 switch (update.tag) { 12082 case ReplaceState: 12083 { 12084 var payload = update.payload; 12085 12086 if (typeof payload === 'function') { 12087 // Updater function 12088 { 12089 enterDisallowedContextReadInDEV(); 12090 } 12091 12092 var nextState = payload.call(instance, prevState, nextProps); 12093 12094 { 12095 if ( workInProgress.mode & StrictMode) { 12096 disableLogs(); 12097 12098 try { 12099 payload.call(instance, prevState, nextProps); 12100 } finally { 12101 reenableLogs(); 12102 } 12103 } 12104 12105 exitDisallowedContextReadInDEV(); 12106 } 12107 12108 return nextState; 12109 } // State object 12110 12111 12112 return payload; 12113 } 12114 12115 case CaptureUpdate: 12116 { 12117 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture; 12118 } 12119 // Intentional fallthrough 12120 12121 case UpdateState: 12122 { 12123 var _payload = update.payload; 12124 var partialState; 12125 12126 if (typeof _payload === 'function') { 12127 // Updater function 12128 { 12129 enterDisallowedContextReadInDEV(); 12130 } 12131 12132 partialState = _payload.call(instance, prevState, nextProps); 12133 12134 { 12135 if ( workInProgress.mode & StrictMode) { 12136 disableLogs(); 12137 12138 try { 12139 _payload.call(instance, prevState, nextProps); 12140 } finally { 12141 reenableLogs(); 12142 } 12143 } 12144 12145 exitDisallowedContextReadInDEV(); 12146 } 12147 } else { 12148 // Partial state object 12149 partialState = _payload; 12150 } 12151 12152 if (partialState === null || partialState === undefined) { 12153 // Null and undefined are treated as no-ops. 12154 return prevState; 12155 } // Merge the partial state and the previous state. 12156 12157 12158 return _assign({}, prevState, partialState); 12159 } 12160 12161 case ForceUpdate: 12162 { 12163 hasForceUpdate = true; 12164 return prevState; 12165 } 12166 } 12167 12168 return prevState; 12169 } 12170 12171 function processUpdateQueue(workInProgress, props, instance, renderLanes) { 12172 // This is always non-null on a ClassComponent or HostRoot 12173 var queue = workInProgress.updateQueue; 12174 hasForceUpdate = false; 12175 12176 { 12177 currentlyProcessingQueue = queue.shared; 12178 } 12179 12180 var firstBaseUpdate = queue.firstBaseUpdate; 12181 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. 12182 12183 var pendingQueue = queue.shared.pending; 12184 12185 if (pendingQueue !== null) { 12186 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first 12187 // and last so that it's non-circular. 12188 12189 var lastPendingUpdate = pendingQueue; 12190 var firstPendingUpdate = lastPendingUpdate.next; 12191 lastPendingUpdate.next = null; // Append pending updates to base queue 12192 12193 if (lastBaseUpdate === null) { 12194 firstBaseUpdate = firstPendingUpdate; 12195 } else { 12196 lastBaseUpdate.next = firstPendingUpdate; 12197 } 12198 12199 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then 12200 // we need to transfer the updates to that queue, too. Because the base 12201 // queue is a singly-linked list with no cycles, we can append to both 12202 // lists and take advantage of structural sharing. 12203 // TODO: Pass `current` as argument 12204 12205 var current = workInProgress.alternate; 12206 12207 if (current !== null) { 12208 // This is always non-null on a ClassComponent or HostRoot 12209 var currentQueue = current.updateQueue; 12210 var currentLastBaseUpdate = currentQueue.lastBaseUpdate; 12211 12212 if (currentLastBaseUpdate !== lastBaseUpdate) { 12213 if (currentLastBaseUpdate === null) { 12214 currentQueue.firstBaseUpdate = firstPendingUpdate; 12215 } else { 12216 currentLastBaseUpdate.next = firstPendingUpdate; 12217 } 12218 12219 currentQueue.lastBaseUpdate = lastPendingUpdate; 12220 } 12221 } 12222 } // These values may change as we process the queue. 12223 12224 12225 if (firstBaseUpdate !== null) { 12226 // Iterate through the list of updates to compute the result. 12227 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes 12228 // from the original lanes. 12229 12230 var newLanes = NoLanes; 12231 var newBaseState = null; 12232 var newFirstBaseUpdate = null; 12233 var newLastBaseUpdate = null; 12234 var update = firstBaseUpdate; 12235 12236 do { 12237 var updateLane = update.lane; 12238 var updateEventTime = update.eventTime; 12239 12240 if (!isSubsetOfLanes(renderLanes, updateLane)) { 12241 // Priority is insufficient. Skip this update. If this is the first 12242 // skipped update, the previous update/state is the new base 12243 // update/state. 12244 var clone = { 12245 eventTime: updateEventTime, 12246 lane: updateLane, 12247 tag: update.tag, 12248 payload: update.payload, 12249 callback: update.callback, 12250 next: null 12251 }; 12252 12253 if (newLastBaseUpdate === null) { 12254 newFirstBaseUpdate = newLastBaseUpdate = clone; 12255 newBaseState = newState; 12256 } else { 12257 newLastBaseUpdate = newLastBaseUpdate.next = clone; 12258 } // Update the remaining priority in the queue. 12259 12260 12261 newLanes = mergeLanes(newLanes, updateLane); 12262 } else { 12263 // This update does have sufficient priority. 12264 if (newLastBaseUpdate !== null) { 12265 var _clone = { 12266 eventTime: updateEventTime, 12267 // This update is going to be committed so we never want uncommit 12268 // it. Using NoLane works because 0 is a subset of all bitmasks, so 12269 // this will never be skipped by the check above. 12270 lane: NoLane, 12271 tag: update.tag, 12272 payload: update.payload, 12273 callback: update.callback, 12274 next: null 12275 }; 12276 newLastBaseUpdate = newLastBaseUpdate.next = _clone; 12277 } // Process this update. 12278 12279 12280 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance); 12281 var callback = update.callback; 12282 12283 if (callback !== null) { 12284 workInProgress.flags |= Callback; 12285 var effects = queue.effects; 12286 12287 if (effects === null) { 12288 queue.effects = [update]; 12289 } else { 12290 effects.push(update); 12291 } 12292 } 12293 } 12294 12295 update = update.next; 12296 12297 if (update === null) { 12298 pendingQueue = queue.shared.pending; 12299 12300 if (pendingQueue === null) { 12301 break; 12302 } else { 12303 // An update was scheduled from inside a reducer. Add the new 12304 // pending updates to the end of the list and keep processing. 12305 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we 12306 // unravel them when transferring them to the base queue. 12307 12308 var _firstPendingUpdate = _lastPendingUpdate.next; 12309 _lastPendingUpdate.next = null; 12310 update = _firstPendingUpdate; 12311 queue.lastBaseUpdate = _lastPendingUpdate; 12312 queue.shared.pending = null; 12313 } 12314 } 12315 } while (true); 12316 12317 if (newLastBaseUpdate === null) { 12318 newBaseState = newState; 12319 } 12320 12321 queue.baseState = newBaseState; 12322 queue.firstBaseUpdate = newFirstBaseUpdate; 12323 queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. 12324 // This should be fine because the only two other things that contribute to 12325 // expiration time are props and context. We're already in the middle of the 12326 // begin phase by the time we start processing the queue, so we've already 12327 // dealt with the props. Context in components that specify 12328 // shouldComponentUpdate is tricky; but we'll have to account for 12329 // that regardless. 12330 12331 markSkippedUpdateLanes(newLanes); 12332 workInProgress.lanes = newLanes; 12333 workInProgress.memoizedState = newState; 12334 } 12335 12336 { 12337 currentlyProcessingQueue = null; 12338 } 12339 } 12340 12341 function callCallback(callback, context) { 12342 if (!(typeof callback === 'function')) { 12343 { 12344 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback ); 12345 } 12346 } 12347 12348 callback.call(context); 12349 } 12350 12351 function resetHasForceUpdateBeforeProcessing() { 12352 hasForceUpdate = false; 12353 } 12354 function checkHasForceUpdateAfterProcessing() { 12355 return hasForceUpdate; 12356 } 12357 function commitUpdateQueue(finishedWork, finishedQueue, instance) { 12358 // Commit the effects 12359 var effects = finishedQueue.effects; 12360 finishedQueue.effects = null; 12361 12362 if (effects !== null) { 12363 for (var i = 0; i < effects.length; i++) { 12364 var effect = effects[i]; 12365 var callback = effect.callback; 12366 12367 if (callback !== null) { 12368 effect.callback = null; 12369 callCallback(callback, instance); 12370 } 12371 } 12372 } 12373 } 12374 12375 var fakeInternalInstance = {}; 12376 var isArray = Array.isArray; // React.Component uses a shared frozen object by default. 12377 // We'll use it to determine whether we need to initialize legacy refs. 12378 12379 var emptyRefsObject = new React.Component().refs; 12380 var didWarnAboutStateAssignmentForComponent; 12381 var didWarnAboutUninitializedState; 12382 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; 12383 var didWarnAboutLegacyLifecyclesAndDerivedState; 12384 var didWarnAboutUndefinedDerivedState; 12385 var warnOnUndefinedDerivedState; 12386 var warnOnInvalidCallback; 12387 var didWarnAboutDirectlyAssigningPropsToState; 12388 var didWarnAboutContextTypeAndContextTypes; 12389 var didWarnAboutInvalidateContextType; 12390 12391 { 12392 didWarnAboutStateAssignmentForComponent = new Set(); 12393 didWarnAboutUninitializedState = new Set(); 12394 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); 12395 didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); 12396 didWarnAboutDirectlyAssigningPropsToState = new Set(); 12397 didWarnAboutUndefinedDerivedState = new Set(); 12398 didWarnAboutContextTypeAndContextTypes = new Set(); 12399 didWarnAboutInvalidateContextType = new Set(); 12400 var didWarnOnInvalidCallback = new Set(); 12401 12402 warnOnInvalidCallback = function (callback, callerName) { 12403 if (callback === null || typeof callback === 'function') { 12404 return; 12405 } 12406 12407 var key = callerName + '_' + callback; 12408 12409 if (!didWarnOnInvalidCallback.has(key)) { 12410 didWarnOnInvalidCallback.add(key); 12411 12412 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 12413 } 12414 }; 12415 12416 warnOnUndefinedDerivedState = function (type, partialState) { 12417 if (partialState === undefined) { 12418 var componentName = getComponentName(type) || 'Component'; 12419 12420 if (!didWarnAboutUndefinedDerivedState.has(componentName)) { 12421 didWarnAboutUndefinedDerivedState.add(componentName); 12422 12423 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName); 12424 } 12425 } 12426 }; // This is so gross but it's at least non-critical and can be removed if 12427 // it causes problems. This is meant to give a nicer error message for 12428 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, 12429 // ...)) which otherwise throws a "_processChildContext is not a function" 12430 // exception. 12431 12432 12433 Object.defineProperty(fakeInternalInstance, '_processChildContext', { 12434 enumerable: false, 12435 value: function () { 12436 { 12437 { 12438 throw 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)." ); 12439 } 12440 } 12441 } 12442 }); 12443 Object.freeze(fakeInternalInstance); 12444 } 12445 12446 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) { 12447 var prevState = workInProgress.memoizedState; 12448 12449 { 12450 if ( workInProgress.mode & StrictMode) { 12451 disableLogs(); 12452 12453 try { 12454 // Invoke the function an extra time to help detect side-effects. 12455 getDerivedStateFromProps(nextProps, prevState); 12456 } finally { 12457 reenableLogs(); 12458 } 12459 } 12460 } 12461 12462 var partialState = getDerivedStateFromProps(nextProps, prevState); 12463 12464 { 12465 warnOnUndefinedDerivedState(ctor, partialState); 12466 } // Merge the partial state and the previous state. 12467 12468 12469 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState); 12470 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the 12471 // base state. 12472 12473 if (workInProgress.lanes === NoLanes) { 12474 // Queue is always non-null for classes 12475 var updateQueue = workInProgress.updateQueue; 12476 updateQueue.baseState = memoizedState; 12477 } 12478 } 12479 var classComponentUpdater = { 12480 isMounted: isMounted, 12481 enqueueSetState: function (inst, payload, callback) { 12482 var fiber = get(inst); 12483 var eventTime = requestEventTime(); 12484 var lane = requestUpdateLane(fiber); 12485 var update = createUpdate(eventTime, lane); 12486 update.payload = payload; 12487 12488 if (callback !== undefined && callback !== null) { 12489 { 12490 warnOnInvalidCallback(callback, 'setState'); 12491 } 12492 12493 update.callback = callback; 12494 } 12495 12496 enqueueUpdate(fiber, update); 12497 scheduleUpdateOnFiber(fiber, lane, eventTime); 12498 }, 12499 enqueueReplaceState: function (inst, payload, callback) { 12500 var fiber = get(inst); 12501 var eventTime = requestEventTime(); 12502 var lane = requestUpdateLane(fiber); 12503 var update = createUpdate(eventTime, lane); 12504 update.tag = ReplaceState; 12505 update.payload = payload; 12506 12507 if (callback !== undefined && callback !== null) { 12508 { 12509 warnOnInvalidCallback(callback, 'replaceState'); 12510 } 12511 12512 update.callback = callback; 12513 } 12514 12515 enqueueUpdate(fiber, update); 12516 scheduleUpdateOnFiber(fiber, lane, eventTime); 12517 }, 12518 enqueueForceUpdate: function (inst, callback) { 12519 var fiber = get(inst); 12520 var eventTime = requestEventTime(); 12521 var lane = requestUpdateLane(fiber); 12522 var update = createUpdate(eventTime, lane); 12523 update.tag = ForceUpdate; 12524 12525 if (callback !== undefined && callback !== null) { 12526 { 12527 warnOnInvalidCallback(callback, 'forceUpdate'); 12528 } 12529 12530 update.callback = callback; 12531 } 12532 12533 enqueueUpdate(fiber, update); 12534 scheduleUpdateOnFiber(fiber, lane, eventTime); 12535 } 12536 }; 12537 12538 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) { 12539 var instance = workInProgress.stateNode; 12540 12541 if (typeof instance.shouldComponentUpdate === 'function') { 12542 { 12543 if ( workInProgress.mode & StrictMode) { 12544 disableLogs(); 12545 12546 try { 12547 // Invoke the function an extra time to help detect side-effects. 12548 instance.shouldComponentUpdate(newProps, newState, nextContext); 12549 } finally { 12550 reenableLogs(); 12551 } 12552 } 12553 } 12554 12555 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); 12556 12557 { 12558 if (shouldUpdate === undefined) { 12559 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component'); 12560 } 12561 } 12562 12563 return shouldUpdate; 12564 } 12565 12566 if (ctor.prototype && ctor.prototype.isPureReactComponent) { 12567 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); 12568 } 12569 12570 return true; 12571 } 12572 12573 function checkClassInstance(workInProgress, ctor, newProps) { 12574 var instance = workInProgress.stateNode; 12575 12576 { 12577 var name = getComponentName(ctor) || 'Component'; 12578 var renderPresent = instance.render; 12579 12580 if (!renderPresent) { 12581 if (ctor.prototype && typeof ctor.prototype.render === 'function') { 12582 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name); 12583 } else { 12584 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); 12585 } 12586 } 12587 12588 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) { 12589 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); 12590 } 12591 12592 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) { 12593 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); 12594 } 12595 12596 if (instance.propTypes) { 12597 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name); 12598 } 12599 12600 if (instance.contextType) { 12601 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name); 12602 } 12603 12604 { 12605 if (instance.contextTypes) { 12606 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name); 12607 } 12608 12609 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) { 12610 didWarnAboutContextTypeAndContextTypes.add(ctor); 12611 12612 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name); 12613 } 12614 } 12615 12616 if (typeof instance.componentShouldUpdate === 'function') { 12617 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); 12618 } 12619 12620 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { 12621 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component'); 12622 } 12623 12624 if (typeof instance.componentDidUnmount === 'function') { 12625 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name); 12626 } 12627 12628 if (typeof instance.componentDidReceiveProps === 'function') { 12629 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); 12630 } 12631 12632 if (typeof instance.componentWillRecieveProps === 'function') { 12633 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name); 12634 } 12635 12636 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') { 12637 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name); 12638 } 12639 12640 var hasMutatedProps = instance.props !== newProps; 12641 12642 if (instance.props !== undefined && hasMutatedProps) { 12643 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name); 12644 } 12645 12646 if (instance.defaultProps) { 12647 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); 12648 } 12649 12650 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { 12651 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); 12652 12653 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor)); 12654 } 12655 12656 if (typeof instance.getDerivedStateFromProps === 'function') { 12657 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 12658 } 12659 12660 if (typeof instance.getDerivedStateFromError === 'function') { 12661 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 12662 } 12663 12664 if (typeof ctor.getSnapshotBeforeUpdate === 'function') { 12665 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name); 12666 } 12667 12668 var _state = instance.state; 12669 12670 if (_state && (typeof _state !== 'object' || isArray(_state))) { 12671 error('%s.state: must be set to an object or null', name); 12672 } 12673 12674 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') { 12675 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name); 12676 } 12677 } 12678 } 12679 12680 function adoptClassInstance(workInProgress, instance) { 12681 instance.updater = classComponentUpdater; 12682 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates 12683 12684 set(instance, workInProgress); 12685 12686 { 12687 instance._reactInternalInstance = fakeInternalInstance; 12688 } 12689 } 12690 12691 function constructClassInstance(workInProgress, ctor, props) { 12692 var isLegacyContextConsumer = false; 12693 var unmaskedContext = emptyContextObject; 12694 var context = emptyContextObject; 12695 var contextType = ctor.contextType; 12696 12697 { 12698 if ('contextType' in ctor) { 12699 var isValid = // Allow null for conditional declaration 12700 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer> 12701 12702 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { 12703 didWarnAboutInvalidateContextType.add(ctor); 12704 var addendum = ''; 12705 12706 if (contextType === undefined) { 12707 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.'; 12708 } else if (typeof contextType !== 'object') { 12709 addendum = ' However, it is set to a ' + typeof contextType + '.'; 12710 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) { 12711 addendum = ' Did you accidentally pass the Context.Provider instead?'; 12712 } else if (contextType._context !== undefined) { 12713 // <Context.Consumer> 12714 addendum = ' Did you accidentally pass the Context.Consumer instead?'; 12715 } else { 12716 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.'; 12717 } 12718 12719 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum); 12720 } 12721 } 12722 } 12723 12724 if (typeof contextType === 'object' && contextType !== null) { 12725 context = readContext(contextType); 12726 } else { 12727 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 12728 var contextTypes = ctor.contextTypes; 12729 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined; 12730 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; 12731 } // Instantiate twice to help detect side-effects. 12732 12733 12734 { 12735 if ( workInProgress.mode & StrictMode) { 12736 disableLogs(); 12737 12738 try { 12739 new ctor(props, context); // eslint-disable-line no-new 12740 } finally { 12741 reenableLogs(); 12742 } 12743 } 12744 } 12745 12746 var instance = new ctor(props, context); 12747 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null; 12748 adoptClassInstance(workInProgress, instance); 12749 12750 { 12751 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) { 12752 var componentName = getComponentName(ctor) || 'Component'; 12753 12754 if (!didWarnAboutUninitializedState.has(componentName)) { 12755 didWarnAboutUninitializedState.add(componentName); 12756 12757 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); 12758 } 12759 } // If new component APIs are defined, "unsafe" lifecycles won't be called. 12760 // Warn about these lifecycles if they are present. 12761 // Don't warn about react-lifecycles-compat polyfilled methods though. 12762 12763 12764 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') { 12765 var foundWillMountName = null; 12766 var foundWillReceivePropsName = null; 12767 var foundWillUpdateName = null; 12768 12769 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 12770 foundWillMountName = 'componentWillMount'; 12771 } else if (typeof instance.UNSAFE_componentWillMount === 'function') { 12772 foundWillMountName = 'UNSAFE_componentWillMount'; 12773 } 12774 12775 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 12776 foundWillReceivePropsName = 'componentWillReceiveProps'; 12777 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 12778 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; 12779 } 12780 12781 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 12782 foundWillUpdateName = 'componentWillUpdate'; 12783 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 12784 foundWillUpdateName = 'UNSAFE_componentWillUpdate'; 12785 } 12786 12787 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { 12788 var _componentName = getComponentName(ctor) || 'Component'; 12789 12790 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; 12791 12792 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { 12793 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); 12794 12795 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 : ''); 12796 } 12797 } 12798 } 12799 } // Cache unmasked context so we can avoid recreating masked context unless necessary. 12800 // ReactFiberContext usually updates this cache but can't for newly-created instances. 12801 12802 12803 if (isLegacyContextConsumer) { 12804 cacheContext(workInProgress, unmaskedContext, context); 12805 } 12806 12807 return instance; 12808 } 12809 12810 function callComponentWillMount(workInProgress, instance) { 12811 var oldState = instance.state; 12812 12813 if (typeof instance.componentWillMount === 'function') { 12814 instance.componentWillMount(); 12815 } 12816 12817 if (typeof instance.UNSAFE_componentWillMount === 'function') { 12818 instance.UNSAFE_componentWillMount(); 12819 } 12820 12821 if (oldState !== instance.state) { 12822 { 12823 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component'); 12824 } 12825 12826 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 12827 } 12828 } 12829 12830 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) { 12831 var oldState = instance.state; 12832 12833 if (typeof instance.componentWillReceiveProps === 'function') { 12834 instance.componentWillReceiveProps(newProps, nextContext); 12835 } 12836 12837 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 12838 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); 12839 } 12840 12841 if (instance.state !== oldState) { 12842 { 12843 var componentName = getComponentName(workInProgress.type) || 'Component'; 12844 12845 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { 12846 didWarnAboutStateAssignmentForComponent.add(componentName); 12847 12848 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName); 12849 } 12850 } 12851 12852 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 12853 } 12854 } // Invokes the mount life-cycles on a previously never rendered instance. 12855 12856 12857 function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { 12858 { 12859 checkClassInstance(workInProgress, ctor, newProps); 12860 } 12861 12862 var instance = workInProgress.stateNode; 12863 instance.props = newProps; 12864 instance.state = workInProgress.memoizedState; 12865 instance.refs = emptyRefsObject; 12866 initializeUpdateQueue(workInProgress); 12867 var contextType = ctor.contextType; 12868 12869 if (typeof contextType === 'object' && contextType !== null) { 12870 instance.context = readContext(contextType); 12871 } else { 12872 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 12873 instance.context = getMaskedContext(workInProgress, unmaskedContext); 12874 } 12875 12876 { 12877 if (instance.state === newProps) { 12878 var componentName = getComponentName(ctor) || 'Component'; 12879 12880 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { 12881 didWarnAboutDirectlyAssigningPropsToState.add(componentName); 12882 12883 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); 12884 } 12885 } 12886 12887 if (workInProgress.mode & StrictMode) { 12888 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance); 12889 } 12890 12891 { 12892 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance); 12893 } 12894 } 12895 12896 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 12897 instance.state = workInProgress.memoizedState; 12898 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 12899 12900 if (typeof getDerivedStateFromProps === 'function') { 12901 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 12902 instance.state = workInProgress.memoizedState; 12903 } // In order to support react-lifecycles-compat polyfilled components, 12904 // Unsafe lifecycles should not be invoked for components using the new APIs. 12905 12906 12907 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 12908 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's 12909 // process them now. 12910 12911 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 12912 instance.state = workInProgress.memoizedState; 12913 } 12914 12915 if (typeof instance.componentDidMount === 'function') { 12916 workInProgress.flags |= Update; 12917 } 12918 } 12919 12920 function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { 12921 var instance = workInProgress.stateNode; 12922 var oldProps = workInProgress.memoizedProps; 12923 instance.props = oldProps; 12924 var oldContext = instance.context; 12925 var contextType = ctor.contextType; 12926 var nextContext = emptyContextObject; 12927 12928 if (typeof contextType === 'object' && contextType !== null) { 12929 nextContext = readContext(contextType); 12930 } else { 12931 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 12932 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); 12933 } 12934 12935 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 12936 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what 12937 // ever the previously attempted to render - not the "current". However, 12938 // during componentDidUpdate we pass the "current" props. 12939 // In order to support react-lifecycles-compat polyfilled components, 12940 // Unsafe lifecycles should not be invoked for components using the new APIs. 12941 12942 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 12943 if (oldProps !== newProps || oldContext !== nextContext) { 12944 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 12945 } 12946 } 12947 12948 resetHasForceUpdateBeforeProcessing(); 12949 var oldState = workInProgress.memoizedState; 12950 var newState = instance.state = oldState; 12951 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 12952 newState = workInProgress.memoizedState; 12953 12954 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 12955 // If an update was already in progress, we should schedule an Update 12956 // effect even though we're bailing out, so that cWU/cDU are called. 12957 if (typeof instance.componentDidMount === 'function') { 12958 workInProgress.flags |= Update; 12959 } 12960 12961 return false; 12962 } 12963 12964 if (typeof getDerivedStateFromProps === 'function') { 12965 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 12966 newState = workInProgress.memoizedState; 12967 } 12968 12969 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); 12970 12971 if (shouldUpdate) { 12972 // In order to support react-lifecycles-compat polyfilled components, 12973 // Unsafe lifecycles should not be invoked for components using the new APIs. 12974 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 12975 if (typeof instance.componentWillMount === 'function') { 12976 instance.componentWillMount(); 12977 } 12978 12979 if (typeof instance.UNSAFE_componentWillMount === 'function') { 12980 instance.UNSAFE_componentWillMount(); 12981 } 12982 } 12983 12984 if (typeof instance.componentDidMount === 'function') { 12985 workInProgress.flags |= Update; 12986 } 12987 } else { 12988 // If an update was already in progress, we should schedule an Update 12989 // effect even though we're bailing out, so that cWU/cDU are called. 12990 if (typeof instance.componentDidMount === 'function') { 12991 workInProgress.flags |= Update; 12992 } // If shouldComponentUpdate returned false, we should still update the 12993 // memoized state to indicate that this work can be reused. 12994 12995 12996 workInProgress.memoizedProps = newProps; 12997 workInProgress.memoizedState = newState; 12998 } // Update the existing instance's state, props, and context pointers even 12999 // if shouldComponentUpdate returns false. 13000 13001 13002 instance.props = newProps; 13003 instance.state = newState; 13004 instance.context = nextContext; 13005 return shouldUpdate; 13006 } // Invokes the update life-cycles and returns false if it shouldn't rerender. 13007 13008 13009 function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) { 13010 var instance = workInProgress.stateNode; 13011 cloneUpdateQueue(current, workInProgress); 13012 var unresolvedOldProps = workInProgress.memoizedProps; 13013 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps); 13014 instance.props = oldProps; 13015 var unresolvedNewProps = workInProgress.pendingProps; 13016 var oldContext = instance.context; 13017 var contextType = ctor.contextType; 13018 var nextContext = emptyContextObject; 13019 13020 if (typeof contextType === 'object' && contextType !== null) { 13021 nextContext = readContext(contextType); 13022 } else { 13023 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 13024 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); 13025 } 13026 13027 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 13028 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what 13029 // ever the previously attempted to render - not the "current". However, 13030 // during componentDidUpdate we pass the "current" props. 13031 // In order to support react-lifecycles-compat polyfilled components, 13032 // Unsafe lifecycles should not be invoked for components using the new APIs. 13033 13034 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 13035 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) { 13036 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 13037 } 13038 } 13039 13040 resetHasForceUpdateBeforeProcessing(); 13041 var oldState = workInProgress.memoizedState; 13042 var newState = instance.state = oldState; 13043 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 13044 newState = workInProgress.memoizedState; 13045 13046 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 13047 // If an update was already in progress, we should schedule an Update 13048 // effect even though we're bailing out, so that cWU/cDU are called. 13049 if (typeof instance.componentDidUpdate === 'function') { 13050 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 13051 workInProgress.flags |= Update; 13052 } 13053 } 13054 13055 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 13056 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 13057 workInProgress.flags |= Snapshot; 13058 } 13059 } 13060 13061 return false; 13062 } 13063 13064 if (typeof getDerivedStateFromProps === 'function') { 13065 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 13066 newState = workInProgress.memoizedState; 13067 } 13068 13069 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); 13070 13071 if (shouldUpdate) { 13072 // In order to support react-lifecycles-compat polyfilled components, 13073 // Unsafe lifecycles should not be invoked for components using the new APIs. 13074 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) { 13075 if (typeof instance.componentWillUpdate === 'function') { 13076 instance.componentWillUpdate(newProps, newState, nextContext); 13077 } 13078 13079 if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 13080 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext); 13081 } 13082 } 13083 13084 if (typeof instance.componentDidUpdate === 'function') { 13085 workInProgress.flags |= Update; 13086 } 13087 13088 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 13089 workInProgress.flags |= Snapshot; 13090 } 13091 } else { 13092 // If an update was already in progress, we should schedule an Update 13093 // effect even though we're bailing out, so that cWU/cDU are called. 13094 if (typeof instance.componentDidUpdate === 'function') { 13095 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 13096 workInProgress.flags |= Update; 13097 } 13098 } 13099 13100 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 13101 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 13102 workInProgress.flags |= Snapshot; 13103 } 13104 } // If shouldComponentUpdate returned false, we should still update the 13105 // memoized props/state to indicate that this work can be reused. 13106 13107 13108 workInProgress.memoizedProps = newProps; 13109 workInProgress.memoizedState = newState; 13110 } // Update the existing instance's state, props, and context pointers even 13111 // if shouldComponentUpdate returns false. 13112 13113 13114 instance.props = newProps; 13115 instance.state = newState; 13116 instance.context = nextContext; 13117 return shouldUpdate; 13118 } 13119 13120 var didWarnAboutMaps; 13121 var didWarnAboutGenerators; 13122 var didWarnAboutStringRefs; 13123 var ownerHasKeyUseWarning; 13124 var ownerHasFunctionTypeWarning; 13125 13126 var warnForMissingKey = function (child, returnFiber) {}; 13127 13128 { 13129 didWarnAboutMaps = false; 13130 didWarnAboutGenerators = false; 13131 didWarnAboutStringRefs = {}; 13132 /** 13133 * Warn if there's no key explicitly set on dynamic arrays of children or 13134 * object keys are not valid. This allows us to keep track of children between 13135 * updates. 13136 */ 13137 13138 ownerHasKeyUseWarning = {}; 13139 ownerHasFunctionTypeWarning = {}; 13140 13141 warnForMissingKey = function (child, returnFiber) { 13142 if (child === null || typeof child !== 'object') { 13143 return; 13144 } 13145 13146 if (!child._store || child._store.validated || child.key != null) { 13147 return; 13148 } 13149 13150 if (!(typeof child._store === 'object')) { 13151 { 13152 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." ); 13153 } 13154 } 13155 13156 child._store.validated = true; 13157 var componentName = getComponentName(returnFiber.type) || 'Component'; 13158 13159 if (ownerHasKeyUseWarning[componentName]) { 13160 return; 13161 } 13162 13163 ownerHasKeyUseWarning[componentName] = true; 13164 13165 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.'); 13166 }; 13167 } 13168 13169 var isArray$1 = Array.isArray; 13170 13171 function coerceRef(returnFiber, current, element) { 13172 var mixedRef = element.ref; 13173 13174 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') { 13175 { 13176 // TODO: Clean this up once we turn on the string ref warning for 13177 // everyone, because the strict mode case will no longer be relevant 13178 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs 13179 // because these cannot be automatically converted to an arrow function 13180 // using a codemod. Therefore, we don't have to warn about string refs again. 13181 !(element._owner && element._self && element._owner.stateNode !== element._self)) { 13182 var componentName = getComponentName(returnFiber.type) || 'Component'; 13183 13184 if (!didWarnAboutStringRefs[componentName]) { 13185 { 13186 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); 13187 } 13188 13189 didWarnAboutStringRefs[componentName] = true; 13190 } 13191 } 13192 } 13193 13194 if (element._owner) { 13195 var owner = element._owner; 13196 var inst; 13197 13198 if (owner) { 13199 var ownerFiber = owner; 13200 13201 if (!(ownerFiber.tag === ClassComponent)) { 13202 { 13203 throw 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" ); 13204 } 13205 } 13206 13207 inst = ownerFiber.stateNode; 13208 } 13209 13210 if (!inst) { 13211 { 13212 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." ); 13213 } 13214 } 13215 13216 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref 13217 13218 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) { 13219 return current.ref; 13220 } 13221 13222 var ref = function (value) { 13223 var refs = inst.refs; 13224 13225 if (refs === emptyRefsObject) { 13226 // This is a lazy pooled frozen object, so we need to initialize. 13227 refs = inst.refs = {}; 13228 } 13229 13230 if (value === null) { 13231 delete refs[stringRef]; 13232 } else { 13233 refs[stringRef] = value; 13234 } 13235 }; 13236 13237 ref._stringRef = stringRef; 13238 return ref; 13239 } else { 13240 if (!(typeof mixedRef === 'string')) { 13241 { 13242 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." ); 13243 } 13244 } 13245 13246 if (!element._owner) { 13247 { 13248 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information." ); 13249 } 13250 } 13251 } 13252 } 13253 13254 return mixedRef; 13255 } 13256 13257 function throwOnInvalidObjectType(returnFiber, newChild) { 13258 if (returnFiber.type !== 'textarea') { 13259 { 13260 { 13261 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + "). If you meant to render a collection of children, use an array instead." ); 13262 } 13263 } 13264 } 13265 } 13266 13267 function warnOnFunctionType(returnFiber) { 13268 { 13269 var componentName = getComponentName(returnFiber.type) || 'Component'; 13270 13271 if (ownerHasFunctionTypeWarning[componentName]) { 13272 return; 13273 } 13274 13275 ownerHasFunctionTypeWarning[componentName] = true; 13276 13277 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.'); 13278 } 13279 } // We avoid inlining this to avoid potential deopts from using try/catch. 13280 // to be able to optimize each path individually by branching early. This needs 13281 // a compiler or we can do it manually. Helpers that don't need this branching 13282 // live outside of this function. 13283 13284 13285 function ChildReconciler(shouldTrackSideEffects) { 13286 function deleteChild(returnFiber, childToDelete) { 13287 if (!shouldTrackSideEffects) { 13288 // Noop. 13289 return; 13290 } // Deletions are added in reversed order so we add it to the front. 13291 // At this point, the return fiber's effect list is empty except for 13292 // deletions, so we can just append the deletion to the list. The remaining 13293 // effects aren't added until the complete phase. Once we implement 13294 // resuming, this may not be true. 13295 13296 13297 var last = returnFiber.lastEffect; 13298 13299 if (last !== null) { 13300 last.nextEffect = childToDelete; 13301 returnFiber.lastEffect = childToDelete; 13302 } else { 13303 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 13304 } 13305 13306 childToDelete.nextEffect = null; 13307 childToDelete.flags = Deletion; 13308 } 13309 13310 function deleteRemainingChildren(returnFiber, currentFirstChild) { 13311 if (!shouldTrackSideEffects) { 13312 // Noop. 13313 return null; 13314 } // TODO: For the shouldClone case, this could be micro-optimized a bit by 13315 // assuming that after the first child we've already added everything. 13316 13317 13318 var childToDelete = currentFirstChild; 13319 13320 while (childToDelete !== null) { 13321 deleteChild(returnFiber, childToDelete); 13322 childToDelete = childToDelete.sibling; 13323 } 13324 13325 return null; 13326 } 13327 13328 function mapRemainingChildren(returnFiber, currentFirstChild) { 13329 // Add the remaining children to a temporary map so that we can find them by 13330 // keys quickly. Implicit (null) keys get added to this set with their index 13331 // instead. 13332 var existingChildren = new Map(); 13333 var existingChild = currentFirstChild; 13334 13335 while (existingChild !== null) { 13336 if (existingChild.key !== null) { 13337 existingChildren.set(existingChild.key, existingChild); 13338 } else { 13339 existingChildren.set(existingChild.index, existingChild); 13340 } 13341 13342 existingChild = existingChild.sibling; 13343 } 13344 13345 return existingChildren; 13346 } 13347 13348 function useFiber(fiber, pendingProps) { 13349 // We currently set sibling to null and index to 0 here because it is easy 13350 // to forget to do before returning it. E.g. for the single child case. 13351 var clone = createWorkInProgress(fiber, pendingProps); 13352 clone.index = 0; 13353 clone.sibling = null; 13354 return clone; 13355 } 13356 13357 function placeChild(newFiber, lastPlacedIndex, newIndex) { 13358 newFiber.index = newIndex; 13359 13360 if (!shouldTrackSideEffects) { 13361 // Noop. 13362 return lastPlacedIndex; 13363 } 13364 13365 var current = newFiber.alternate; 13366 13367 if (current !== null) { 13368 var oldIndex = current.index; 13369 13370 if (oldIndex < lastPlacedIndex) { 13371 // This is a move. 13372 newFiber.flags = Placement; 13373 return lastPlacedIndex; 13374 } else { 13375 // This item can stay in place. 13376 return oldIndex; 13377 } 13378 } else { 13379 // This is an insertion. 13380 newFiber.flags = Placement; 13381 return lastPlacedIndex; 13382 } 13383 } 13384 13385 function placeSingleChild(newFiber) { 13386 // This is simpler for the single child case. We only need to do a 13387 // placement for inserting new children. 13388 if (shouldTrackSideEffects && newFiber.alternate === null) { 13389 newFiber.flags = Placement; 13390 } 13391 13392 return newFiber; 13393 } 13394 13395 function updateTextNode(returnFiber, current, textContent, lanes) { 13396 if (current === null || current.tag !== HostText) { 13397 // Insert 13398 var created = createFiberFromText(textContent, returnFiber.mode, lanes); 13399 created.return = returnFiber; 13400 return created; 13401 } else { 13402 // Update 13403 var existing = useFiber(current, textContent); 13404 existing.return = returnFiber; 13405 return existing; 13406 } 13407 } 13408 13409 function updateElement(returnFiber, current, element, lanes) { 13410 if (current !== null) { 13411 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path: 13412 isCompatibleFamilyForHotReloading(current, element) )) { 13413 // Move based on index 13414 var existing = useFiber(current, element.props); 13415 existing.ref = coerceRef(returnFiber, current, element); 13416 existing.return = returnFiber; 13417 13418 { 13419 existing._debugSource = element._source; 13420 existing._debugOwner = element._owner; 13421 } 13422 13423 return existing; 13424 } 13425 } // Insert 13426 13427 13428 var created = createFiberFromElement(element, returnFiber.mode, lanes); 13429 created.ref = coerceRef(returnFiber, current, element); 13430 created.return = returnFiber; 13431 return created; 13432 } 13433 13434 function updatePortal(returnFiber, current, portal, lanes) { 13435 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) { 13436 // Insert 13437 var created = createFiberFromPortal(portal, returnFiber.mode, lanes); 13438 created.return = returnFiber; 13439 return created; 13440 } else { 13441 // Update 13442 var existing = useFiber(current, portal.children || []); 13443 existing.return = returnFiber; 13444 return existing; 13445 } 13446 } 13447 13448 function updateFragment(returnFiber, current, fragment, lanes, key) { 13449 if (current === null || current.tag !== Fragment) { 13450 // Insert 13451 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key); 13452 created.return = returnFiber; 13453 return created; 13454 } else { 13455 // Update 13456 var existing = useFiber(current, fragment); 13457 existing.return = returnFiber; 13458 return existing; 13459 } 13460 } 13461 13462 function createChild(returnFiber, newChild, lanes) { 13463 if (typeof newChild === 'string' || typeof newChild === 'number') { 13464 // Text nodes don't have keys. If the previous node is implicitly keyed 13465 // we can continue to replace it without aborting even if it is not a text 13466 // node. 13467 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes); 13468 created.return = returnFiber; 13469 return created; 13470 } 13471 13472 if (typeof newChild === 'object' && newChild !== null) { 13473 switch (newChild.$$typeof) { 13474 case REACT_ELEMENT_TYPE: 13475 { 13476 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes); 13477 13478 _created.ref = coerceRef(returnFiber, null, newChild); 13479 _created.return = returnFiber; 13480 return _created; 13481 } 13482 13483 case REACT_PORTAL_TYPE: 13484 { 13485 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes); 13486 13487 _created2.return = returnFiber; 13488 return _created2; 13489 } 13490 } 13491 13492 if (isArray$1(newChild) || getIteratorFn(newChild)) { 13493 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null); 13494 13495 _created3.return = returnFiber; 13496 return _created3; 13497 } 13498 13499 throwOnInvalidObjectType(returnFiber, newChild); 13500 } 13501 13502 { 13503 if (typeof newChild === 'function') { 13504 warnOnFunctionType(returnFiber); 13505 } 13506 } 13507 13508 return null; 13509 } 13510 13511 function updateSlot(returnFiber, oldFiber, newChild, lanes) { 13512 // Update the fiber if the keys match, otherwise return null. 13513 var key = oldFiber !== null ? oldFiber.key : null; 13514 13515 if (typeof newChild === 'string' || typeof newChild === 'number') { 13516 // Text nodes don't have keys. If the previous node is implicitly keyed 13517 // we can continue to replace it without aborting even if it is not a text 13518 // node. 13519 if (key !== null) { 13520 return null; 13521 } 13522 13523 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes); 13524 } 13525 13526 if (typeof newChild === 'object' && newChild !== null) { 13527 switch (newChild.$$typeof) { 13528 case REACT_ELEMENT_TYPE: 13529 { 13530 if (newChild.key === key) { 13531 if (newChild.type === REACT_FRAGMENT_TYPE) { 13532 return updateFragment(returnFiber, oldFiber, newChild.props.children, lanes, key); 13533 } 13534 13535 return updateElement(returnFiber, oldFiber, newChild, lanes); 13536 } else { 13537 return null; 13538 } 13539 } 13540 13541 case REACT_PORTAL_TYPE: 13542 { 13543 if (newChild.key === key) { 13544 return updatePortal(returnFiber, oldFiber, newChild, lanes); 13545 } else { 13546 return null; 13547 } 13548 } 13549 } 13550 13551 if (isArray$1(newChild) || getIteratorFn(newChild)) { 13552 if (key !== null) { 13553 return null; 13554 } 13555 13556 return updateFragment(returnFiber, oldFiber, newChild, lanes, null); 13557 } 13558 13559 throwOnInvalidObjectType(returnFiber, newChild); 13560 } 13561 13562 { 13563 if (typeof newChild === 'function') { 13564 warnOnFunctionType(returnFiber); 13565 } 13566 } 13567 13568 return null; 13569 } 13570 13571 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) { 13572 if (typeof newChild === 'string' || typeof newChild === 'number') { 13573 // Text nodes don't have keys, so we neither have to check the old nor 13574 // new node for the key. If both are text nodes, they match. 13575 var matchedFiber = existingChildren.get(newIdx) || null; 13576 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes); 13577 } 13578 13579 if (typeof newChild === 'object' && newChild !== null) { 13580 switch (newChild.$$typeof) { 13581 case REACT_ELEMENT_TYPE: 13582 { 13583 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 13584 13585 if (newChild.type === REACT_FRAGMENT_TYPE) { 13586 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, lanes, newChild.key); 13587 } 13588 13589 return updateElement(returnFiber, _matchedFiber, newChild, lanes); 13590 } 13591 13592 case REACT_PORTAL_TYPE: 13593 { 13594 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 13595 13596 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes); 13597 } 13598 13599 } 13600 13601 if (isArray$1(newChild) || getIteratorFn(newChild)) { 13602 var _matchedFiber3 = existingChildren.get(newIdx) || null; 13603 13604 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null); 13605 } 13606 13607 throwOnInvalidObjectType(returnFiber, newChild); 13608 } 13609 13610 { 13611 if (typeof newChild === 'function') { 13612 warnOnFunctionType(returnFiber); 13613 } 13614 } 13615 13616 return null; 13617 } 13618 /** 13619 * Warns if there is a duplicate or missing key 13620 */ 13621 13622 13623 function warnOnInvalidKey(child, knownKeys, returnFiber) { 13624 { 13625 if (typeof child !== 'object' || child === null) { 13626 return knownKeys; 13627 } 13628 13629 switch (child.$$typeof) { 13630 case REACT_ELEMENT_TYPE: 13631 case REACT_PORTAL_TYPE: 13632 warnForMissingKey(child, returnFiber); 13633 var key = child.key; 13634 13635 if (typeof key !== 'string') { 13636 break; 13637 } 13638 13639 if (knownKeys === null) { 13640 knownKeys = new Set(); 13641 knownKeys.add(key); 13642 break; 13643 } 13644 13645 if (!knownKeys.has(key)) { 13646 knownKeys.add(key); 13647 break; 13648 } 13649 13650 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); 13651 13652 break; 13653 } 13654 } 13655 13656 return knownKeys; 13657 } 13658 13659 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) { 13660 // This algorithm can't optimize by searching from both ends since we 13661 // don't have backpointers on fibers. I'm trying to see how far we can get 13662 // with that model. If it ends up not being worth the tradeoffs, we can 13663 // add it later. 13664 // Even with a two ended optimization, we'd want to optimize for the case 13665 // where there are few changes and brute force the comparison instead of 13666 // going for the Map. It'd like to explore hitting that path first in 13667 // forward-only mode and only go for the Map once we notice that we need 13668 // lots of look ahead. This doesn't handle reversal as well as two ended 13669 // search but that's unusual. Besides, for the two ended optimization to 13670 // work on Iterables, we'd need to copy the whole set. 13671 // In this first iteration, we'll just live with hitting the bad case 13672 // (adding everything to a Map) in for every insert/move. 13673 // If you change this code, also update reconcileChildrenIterator() which 13674 // uses the same algorithm. 13675 { 13676 // First, validate keys. 13677 var knownKeys = null; 13678 13679 for (var i = 0; i < newChildren.length; i++) { 13680 var child = newChildren[i]; 13681 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); 13682 } 13683 } 13684 13685 var resultingFirstChild = null; 13686 var previousNewFiber = null; 13687 var oldFiber = currentFirstChild; 13688 var lastPlacedIndex = 0; 13689 var newIdx = 0; 13690 var nextOldFiber = null; 13691 13692 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { 13693 if (oldFiber.index > newIdx) { 13694 nextOldFiber = oldFiber; 13695 oldFiber = null; 13696 } else { 13697 nextOldFiber = oldFiber.sibling; 13698 } 13699 13700 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes); 13701 13702 if (newFiber === null) { 13703 // TODO: This breaks on empty slots like null children. That's 13704 // unfortunate because it triggers the slow path all the time. We need 13705 // a better way to communicate whether this was a miss or null, 13706 // boolean, undefined, etc. 13707 if (oldFiber === null) { 13708 oldFiber = nextOldFiber; 13709 } 13710 13711 break; 13712 } 13713 13714 if (shouldTrackSideEffects) { 13715 if (oldFiber && newFiber.alternate === null) { 13716 // We matched the slot, but we didn't reuse the existing fiber, so we 13717 // need to delete the existing child. 13718 deleteChild(returnFiber, oldFiber); 13719 } 13720 } 13721 13722 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 13723 13724 if (previousNewFiber === null) { 13725 // TODO: Move out of the loop. This only happens for the first run. 13726 resultingFirstChild = newFiber; 13727 } else { 13728 // TODO: Defer siblings if we're not at the right index for this slot. 13729 // I.e. if we had null values before, then we want to defer this 13730 // for each null value. However, we also don't want to call updateSlot 13731 // with the previous one. 13732 previousNewFiber.sibling = newFiber; 13733 } 13734 13735 previousNewFiber = newFiber; 13736 oldFiber = nextOldFiber; 13737 } 13738 13739 if (newIdx === newChildren.length) { 13740 // We've reached the end of the new children. We can delete the rest. 13741 deleteRemainingChildren(returnFiber, oldFiber); 13742 return resultingFirstChild; 13743 } 13744 13745 if (oldFiber === null) { 13746 // If we don't have any more existing children we can choose a fast path 13747 // since the rest will all be insertions. 13748 for (; newIdx < newChildren.length; newIdx++) { 13749 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes); 13750 13751 if (_newFiber === null) { 13752 continue; 13753 } 13754 13755 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); 13756 13757 if (previousNewFiber === null) { 13758 // TODO: Move out of the loop. This only happens for the first run. 13759 resultingFirstChild = _newFiber; 13760 } else { 13761 previousNewFiber.sibling = _newFiber; 13762 } 13763 13764 previousNewFiber = _newFiber; 13765 } 13766 13767 return resultingFirstChild; 13768 } // Add all children to a key map for quick lookups. 13769 13770 13771 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. 13772 13773 for (; newIdx < newChildren.length; newIdx++) { 13774 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes); 13775 13776 if (_newFiber2 !== null) { 13777 if (shouldTrackSideEffects) { 13778 if (_newFiber2.alternate !== null) { 13779 // The new fiber is a work in progress, but if there exists a 13780 // current, that means that we reused the fiber. We need to delete 13781 // it from the child list so that we don't add it to the deletion 13782 // list. 13783 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key); 13784 } 13785 } 13786 13787 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); 13788 13789 if (previousNewFiber === null) { 13790 resultingFirstChild = _newFiber2; 13791 } else { 13792 previousNewFiber.sibling = _newFiber2; 13793 } 13794 13795 previousNewFiber = _newFiber2; 13796 } 13797 } 13798 13799 if (shouldTrackSideEffects) { 13800 // Any existing children that weren't consumed above were deleted. We need 13801 // to add them to the deletion list. 13802 existingChildren.forEach(function (child) { 13803 return deleteChild(returnFiber, child); 13804 }); 13805 } 13806 13807 return resultingFirstChild; 13808 } 13809 13810 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) { 13811 // This is the same implementation as reconcileChildrenArray(), 13812 // but using the iterator instead. 13813 var iteratorFn = getIteratorFn(newChildrenIterable); 13814 13815 if (!(typeof iteratorFn === 'function')) { 13816 { 13817 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." ); 13818 } 13819 } 13820 13821 { 13822 // We don't support rendering Generators because it's a mutation. 13823 // See https://github.com/facebook/react/issues/12995 13824 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag 13825 newChildrenIterable[Symbol.toStringTag] === 'Generator') { 13826 if (!didWarnAboutGenerators) { 13827 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.'); 13828 } 13829 13830 didWarnAboutGenerators = true; 13831 } // Warn about using Maps as children 13832 13833 13834 if (newChildrenIterable.entries === iteratorFn) { 13835 if (!didWarnAboutMaps) { 13836 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.'); 13837 } 13838 13839 didWarnAboutMaps = true; 13840 } // First, validate keys. 13841 // We'll get a different iterator later for the main pass. 13842 13843 13844 var _newChildren = iteratorFn.call(newChildrenIterable); 13845 13846 if (_newChildren) { 13847 var knownKeys = null; 13848 13849 var _step = _newChildren.next(); 13850 13851 for (; !_step.done; _step = _newChildren.next()) { 13852 var child = _step.value; 13853 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); 13854 } 13855 } 13856 } 13857 13858 var newChildren = iteratorFn.call(newChildrenIterable); 13859 13860 if (!(newChildren != null)) { 13861 { 13862 throw Error( "An iterable object provided no iterator." ); 13863 } 13864 } 13865 13866 var resultingFirstChild = null; 13867 var previousNewFiber = null; 13868 var oldFiber = currentFirstChild; 13869 var lastPlacedIndex = 0; 13870 var newIdx = 0; 13871 var nextOldFiber = null; 13872 var step = newChildren.next(); 13873 13874 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { 13875 if (oldFiber.index > newIdx) { 13876 nextOldFiber = oldFiber; 13877 oldFiber = null; 13878 } else { 13879 nextOldFiber = oldFiber.sibling; 13880 } 13881 13882 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes); 13883 13884 if (newFiber === null) { 13885 // TODO: This breaks on empty slots like null children. That's 13886 // unfortunate because it triggers the slow path all the time. We need 13887 // a better way to communicate whether this was a miss or null, 13888 // boolean, undefined, etc. 13889 if (oldFiber === null) { 13890 oldFiber = nextOldFiber; 13891 } 13892 13893 break; 13894 } 13895 13896 if (shouldTrackSideEffects) { 13897 if (oldFiber && newFiber.alternate === null) { 13898 // We matched the slot, but we didn't reuse the existing fiber, so we 13899 // need to delete the existing child. 13900 deleteChild(returnFiber, oldFiber); 13901 } 13902 } 13903 13904 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 13905 13906 if (previousNewFiber === null) { 13907 // TODO: Move out of the loop. This only happens for the first run. 13908 resultingFirstChild = newFiber; 13909 } else { 13910 // TODO: Defer siblings if we're not at the right index for this slot. 13911 // I.e. if we had null values before, then we want to defer this 13912 // for each null value. However, we also don't want to call updateSlot 13913 // with the previous one. 13914 previousNewFiber.sibling = newFiber; 13915 } 13916 13917 previousNewFiber = newFiber; 13918 oldFiber = nextOldFiber; 13919 } 13920 13921 if (step.done) { 13922 // We've reached the end of the new children. We can delete the rest. 13923 deleteRemainingChildren(returnFiber, oldFiber); 13924 return resultingFirstChild; 13925 } 13926 13927 if (oldFiber === null) { 13928 // If we don't have any more existing children we can choose a fast path 13929 // since the rest will all be insertions. 13930 for (; !step.done; newIdx++, step = newChildren.next()) { 13931 var _newFiber3 = createChild(returnFiber, step.value, lanes); 13932 13933 if (_newFiber3 === null) { 13934 continue; 13935 } 13936 13937 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); 13938 13939 if (previousNewFiber === null) { 13940 // TODO: Move out of the loop. This only happens for the first run. 13941 resultingFirstChild = _newFiber3; 13942 } else { 13943 previousNewFiber.sibling = _newFiber3; 13944 } 13945 13946 previousNewFiber = _newFiber3; 13947 } 13948 13949 return resultingFirstChild; 13950 } // Add all children to a key map for quick lookups. 13951 13952 13953 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. 13954 13955 for (; !step.done; newIdx++, step = newChildren.next()) { 13956 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes); 13957 13958 if (_newFiber4 !== null) { 13959 if (shouldTrackSideEffects) { 13960 if (_newFiber4.alternate !== null) { 13961 // The new fiber is a work in progress, but if there exists a 13962 // current, that means that we reused the fiber. We need to delete 13963 // it from the child list so that we don't add it to the deletion 13964 // list. 13965 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key); 13966 } 13967 } 13968 13969 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); 13970 13971 if (previousNewFiber === null) { 13972 resultingFirstChild = _newFiber4; 13973 } else { 13974 previousNewFiber.sibling = _newFiber4; 13975 } 13976 13977 previousNewFiber = _newFiber4; 13978 } 13979 } 13980 13981 if (shouldTrackSideEffects) { 13982 // Any existing children that weren't consumed above were deleted. We need 13983 // to add them to the deletion list. 13984 existingChildren.forEach(function (child) { 13985 return deleteChild(returnFiber, child); 13986 }); 13987 } 13988 13989 return resultingFirstChild; 13990 } 13991 13992 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) { 13993 // There's no need to check for keys on text nodes since we don't have a 13994 // way to define them. 13995 if (currentFirstChild !== null && currentFirstChild.tag === HostText) { 13996 // We already have an existing node so let's just update it and delete 13997 // the rest. 13998 deleteRemainingChildren(returnFiber, currentFirstChild.sibling); 13999 var existing = useFiber(currentFirstChild, textContent); 14000 existing.return = returnFiber; 14001 return existing; 14002 } // The existing first child is not a text node so we need to create one 14003 // and delete the existing ones. 14004 14005 14006 deleteRemainingChildren(returnFiber, currentFirstChild); 14007 var created = createFiberFromText(textContent, returnFiber.mode, lanes); 14008 created.return = returnFiber; 14009 return created; 14010 } 14011 14012 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) { 14013 var key = element.key; 14014 var child = currentFirstChild; 14015 14016 while (child !== null) { 14017 // TODO: If key === null and child.key === null, then this only applies to 14018 // the first item in the list. 14019 if (child.key === key) { 14020 switch (child.tag) { 14021 case Fragment: 14022 { 14023 if (element.type === REACT_FRAGMENT_TYPE) { 14024 deleteRemainingChildren(returnFiber, child.sibling); 14025 var existing = useFiber(child, element.props.children); 14026 existing.return = returnFiber; 14027 14028 { 14029 existing._debugSource = element._source; 14030 existing._debugOwner = element._owner; 14031 } 14032 14033 return existing; 14034 } 14035 14036 break; 14037 } 14038 14039 case Block: 14040 14041 // We intentionally fallthrough here if enableBlocksAPI is not on. 14042 // eslint-disable-next-lined no-fallthrough 14043 14044 default: 14045 { 14046 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path: 14047 isCompatibleFamilyForHotReloading(child, element) )) { 14048 deleteRemainingChildren(returnFiber, child.sibling); 14049 14050 var _existing3 = useFiber(child, element.props); 14051 14052 _existing3.ref = coerceRef(returnFiber, child, element); 14053 _existing3.return = returnFiber; 14054 14055 { 14056 _existing3._debugSource = element._source; 14057 _existing3._debugOwner = element._owner; 14058 } 14059 14060 return _existing3; 14061 } 14062 14063 break; 14064 } 14065 } // Didn't match. 14066 14067 14068 deleteRemainingChildren(returnFiber, child); 14069 break; 14070 } else { 14071 deleteChild(returnFiber, child); 14072 } 14073 14074 child = child.sibling; 14075 } 14076 14077 if (element.type === REACT_FRAGMENT_TYPE) { 14078 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key); 14079 created.return = returnFiber; 14080 return created; 14081 } else { 14082 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); 14083 14084 _created4.ref = coerceRef(returnFiber, currentFirstChild, element); 14085 _created4.return = returnFiber; 14086 return _created4; 14087 } 14088 } 14089 14090 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) { 14091 var key = portal.key; 14092 var child = currentFirstChild; 14093 14094 while (child !== null) { 14095 // TODO: If key === null and child.key === null, then this only applies to 14096 // the first item in the list. 14097 if (child.key === key) { 14098 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { 14099 deleteRemainingChildren(returnFiber, child.sibling); 14100 var existing = useFiber(child, portal.children || []); 14101 existing.return = returnFiber; 14102 return existing; 14103 } else { 14104 deleteRemainingChildren(returnFiber, child); 14105 break; 14106 } 14107 } else { 14108 deleteChild(returnFiber, child); 14109 } 14110 14111 child = child.sibling; 14112 } 14113 14114 var created = createFiberFromPortal(portal, returnFiber.mode, lanes); 14115 created.return = returnFiber; 14116 return created; 14117 } // This API will tag the children with the side-effect of the reconciliation 14118 // itself. They will be added to the side-effect list as we pass through the 14119 // children and the parent. 14120 14121 14122 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) { 14123 // This function is not recursive. 14124 // If the top level item is an array, we treat it as a set of children, 14125 // not as a fragment. Nested arrays on the other hand will be treated as 14126 // fragment nodes. Recursion happens at the normal flow. 14127 // Handle top level unkeyed fragments as if they were arrays. 14128 // This leads to an ambiguity between <>{[...]}</> and <>...</>. 14129 // We treat the ambiguous cases above the same. 14130 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; 14131 14132 if (isUnkeyedTopLevelFragment) { 14133 newChild = newChild.props.children; 14134 } // Handle object types 14135 14136 14137 var isObject = typeof newChild === 'object' && newChild !== null; 14138 14139 if (isObject) { 14140 switch (newChild.$$typeof) { 14141 case REACT_ELEMENT_TYPE: 14142 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes)); 14143 14144 case REACT_PORTAL_TYPE: 14145 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes)); 14146 14147 } 14148 } 14149 14150 if (typeof newChild === 'string' || typeof newChild === 'number') { 14151 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes)); 14152 } 14153 14154 if (isArray$1(newChild)) { 14155 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes); 14156 } 14157 14158 if (getIteratorFn(newChild)) { 14159 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes); 14160 } 14161 14162 if (isObject) { 14163 throwOnInvalidObjectType(returnFiber, newChild); 14164 } 14165 14166 { 14167 if (typeof newChild === 'function') { 14168 warnOnFunctionType(returnFiber); 14169 } 14170 } 14171 14172 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) { 14173 // If the new child is undefined, and the return fiber is a composite 14174 // component, throw an error. If Fiber return types are disabled, 14175 // we already threw above. 14176 switch (returnFiber.tag) { 14177 case ClassComponent: 14178 { 14179 { 14180 var instance = returnFiber.stateNode; 14181 14182 if (instance.render._isMockFunction) { 14183 // We allow auto-mocks to proceed as if they're returning null. 14184 break; 14185 } 14186 } 14187 } 14188 // Intentionally fall through to the next case, which handles both 14189 // functions and classes 14190 // eslint-disable-next-lined no-fallthrough 14191 14192 case Block: 14193 case FunctionComponent: 14194 case ForwardRef: 14195 case SimpleMemoComponent: 14196 { 14197 { 14198 { 14199 throw Error( (getComponentName(returnFiber.type) || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); 14200 } 14201 } 14202 } 14203 } 14204 } // Remaining cases are all treated as empty. 14205 14206 14207 return deleteRemainingChildren(returnFiber, currentFirstChild); 14208 } 14209 14210 return reconcileChildFibers; 14211 } 14212 14213 var reconcileChildFibers = ChildReconciler(true); 14214 var mountChildFibers = ChildReconciler(false); 14215 function cloneChildFibers(current, workInProgress) { 14216 if (!(current === null || workInProgress.child === current.child)) { 14217 { 14218 throw Error( "Resuming work not yet implemented." ); 14219 } 14220 } 14221 14222 if (workInProgress.child === null) { 14223 return; 14224 } 14225 14226 var currentChild = workInProgress.child; 14227 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); 14228 workInProgress.child = newChild; 14229 newChild.return = workInProgress; 14230 14231 while (currentChild.sibling !== null) { 14232 currentChild = currentChild.sibling; 14233 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps); 14234 newChild.return = workInProgress; 14235 } 14236 14237 newChild.sibling = null; 14238 } // Reset a workInProgress child set to prepare it for a second pass. 14239 14240 function resetChildFibers(workInProgress, lanes) { 14241 var child = workInProgress.child; 14242 14243 while (child !== null) { 14244 resetWorkInProgress(child, lanes); 14245 child = child.sibling; 14246 } 14247 } 14248 14249 var NO_CONTEXT = {}; 14250 var contextStackCursor$1 = createCursor(NO_CONTEXT); 14251 var contextFiberStackCursor = createCursor(NO_CONTEXT); 14252 var rootInstanceStackCursor = createCursor(NO_CONTEXT); 14253 14254 function requiredContext(c) { 14255 if (!(c !== NO_CONTEXT)) { 14256 { 14257 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." ); 14258 } 14259 } 14260 14261 return c; 14262 } 14263 14264 function getRootHostContainer() { 14265 var rootInstance = requiredContext(rootInstanceStackCursor.current); 14266 return rootInstance; 14267 } 14268 14269 function pushHostContainer(fiber, nextRootInstance) { 14270 // Push current root instance onto the stack; 14271 // This allows us to reset root when portals are popped. 14272 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. 14273 // This enables us to pop only Fibers that provide unique contexts. 14274 14275 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. 14276 // However, we can't just call getRootHostContext() and push it because 14277 // we'd have a different number of entries on the stack depending on 14278 // whether getRootHostContext() throws somewhere in renderer code or not. 14279 // So we push an empty value first. This lets us safely unwind on errors. 14280 14281 push(contextStackCursor$1, NO_CONTEXT, fiber); 14282 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. 14283 14284 pop(contextStackCursor$1, fiber); 14285 push(contextStackCursor$1, nextRootContext, fiber); 14286 } 14287 14288 function popHostContainer(fiber) { 14289 pop(contextStackCursor$1, fiber); 14290 pop(contextFiberStackCursor, fiber); 14291 pop(rootInstanceStackCursor, fiber); 14292 } 14293 14294 function getHostContext() { 14295 var context = requiredContext(contextStackCursor$1.current); 14296 return context; 14297 } 14298 14299 function pushHostContext(fiber) { 14300 var rootInstance = requiredContext(rootInstanceStackCursor.current); 14301 var context = requiredContext(contextStackCursor$1.current); 14302 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. 14303 14304 if (context === nextContext) { 14305 return; 14306 } // Track the context and the Fiber that provided it. 14307 // This enables us to pop only Fibers that provide unique contexts. 14308 14309 14310 push(contextFiberStackCursor, fiber, fiber); 14311 push(contextStackCursor$1, nextContext, fiber); 14312 } 14313 14314 function popHostContext(fiber) { 14315 // Do not pop unless this Fiber provided the current context. 14316 // pushHostContext() only pushes Fibers that provide unique contexts. 14317 if (contextFiberStackCursor.current !== fiber) { 14318 return; 14319 } 14320 14321 pop(contextStackCursor$1, fiber); 14322 pop(contextFiberStackCursor, fiber); 14323 } 14324 14325 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is 14326 // inherited deeply down the subtree. The upper bits only affect 14327 // this immediate suspense boundary and gets reset each new 14328 // boundary or suspense list. 14329 14330 var SubtreeSuspenseContextMask = 1; // Subtree Flags: 14331 // InvisibleParentSuspenseContext indicates that one of our parent Suspense 14332 // boundaries is not currently showing visible main content. 14333 // Either because it is already showing a fallback or is not mounted at all. 14334 // We can use this to determine if it is desirable to trigger a fallback at 14335 // the parent. If not, then we might need to trigger undesirable boundaries 14336 // and/or suspend the commit to avoid hiding the parent content. 14337 14338 var InvisibleParentSuspenseContext = 1; // Shallow Flags: 14339 // ForceSuspenseFallback can be used by SuspenseList to force newly added 14340 // items into their fallback state during one of the render passes. 14341 14342 var ForceSuspenseFallback = 2; 14343 var suspenseStackCursor = createCursor(DefaultSuspenseContext); 14344 function hasSuspenseContext(parentContext, flag) { 14345 return (parentContext & flag) !== 0; 14346 } 14347 function setDefaultShallowSuspenseContext(parentContext) { 14348 return parentContext & SubtreeSuspenseContextMask; 14349 } 14350 function setShallowSuspenseContext(parentContext, shallowContext) { 14351 return parentContext & SubtreeSuspenseContextMask | shallowContext; 14352 } 14353 function addSubtreeSuspenseContext(parentContext, subtreeContext) { 14354 return parentContext | subtreeContext; 14355 } 14356 function pushSuspenseContext(fiber, newContext) { 14357 push(suspenseStackCursor, newContext, fiber); 14358 } 14359 function popSuspenseContext(fiber) { 14360 pop(suspenseStackCursor, fiber); 14361 } 14362 14363 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { 14364 // If it was the primary children that just suspended, capture and render the 14365 // fallback. Otherwise, don't capture and bubble to the next boundary. 14366 var nextState = workInProgress.memoizedState; 14367 14368 if (nextState !== null) { 14369 if (nextState.dehydrated !== null) { 14370 // A dehydrated boundary always captures. 14371 return true; 14372 } 14373 14374 return false; 14375 } 14376 14377 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop. 14378 14379 if (props.fallback === undefined) { 14380 return false; 14381 } // Regular boundaries always capture. 14382 14383 14384 if (props.unstable_avoidThisFallback !== true) { 14385 return true; 14386 } // If it's a boundary we should avoid, then we prefer to bubble up to the 14387 // parent boundary if it is currently invisible. 14388 14389 14390 if (hasInvisibleParent) { 14391 return false; 14392 } // If the parent is not able to handle it, we must handle it. 14393 14394 14395 return true; 14396 } 14397 function findFirstSuspended(row) { 14398 var node = row; 14399 14400 while (node !== null) { 14401 if (node.tag === SuspenseComponent) { 14402 var state = node.memoizedState; 14403 14404 if (state !== null) { 14405 var dehydrated = state.dehydrated; 14406 14407 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) { 14408 return node; 14409 } 14410 } 14411 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't 14412 // keep track of whether it suspended or not. 14413 node.memoizedProps.revealOrder !== undefined) { 14414 var didSuspend = (node.flags & DidCapture) !== NoFlags; 14415 14416 if (didSuspend) { 14417 return node; 14418 } 14419 } else if (node.child !== null) { 14420 node.child.return = node; 14421 node = node.child; 14422 continue; 14423 } 14424 14425 if (node === row) { 14426 return null; 14427 } 14428 14429 while (node.sibling === null) { 14430 if (node.return === null || node.return === row) { 14431 return null; 14432 } 14433 14434 node = node.return; 14435 } 14436 14437 node.sibling.return = node.return; 14438 node = node.sibling; 14439 } 14440 14441 return null; 14442 } 14443 14444 var NoFlags$1 = 14445 /* */ 14446 0; // Represents whether effect should fire. 14447 14448 var HasEffect = 14449 /* */ 14450 1; // Represents the phase in which the effect (not the clean-up) fires. 14451 14452 var Layout = 14453 /* */ 14454 2; 14455 var Passive$1 = 14456 /* */ 14457 4; 14458 14459 // This may have been an insertion or a hydration. 14460 14461 var hydrationParentFiber = null; 14462 var nextHydratableInstance = null; 14463 var isHydrating = false; 14464 14465 function enterHydrationState(fiber) { 14466 14467 var parentInstance = fiber.stateNode.containerInfo; 14468 nextHydratableInstance = getFirstHydratableChild(parentInstance); 14469 hydrationParentFiber = fiber; 14470 isHydrating = true; 14471 return true; 14472 } 14473 14474 function deleteHydratableInstance(returnFiber, instance) { 14475 { 14476 switch (returnFiber.tag) { 14477 case HostRoot: 14478 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance); 14479 break; 14480 14481 case HostComponent: 14482 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance); 14483 break; 14484 } 14485 } 14486 14487 var childToDelete = createFiberFromHostInstanceForDeletion(); 14488 childToDelete.stateNode = instance; 14489 childToDelete.return = returnFiber; 14490 childToDelete.flags = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, 14491 // these children are not part of the reconciliation list of children. 14492 // Even if we abort and rereconcile the children, that will try to hydrate 14493 // again and the nodes are still in the host tree so these will be 14494 // recreated. 14495 14496 if (returnFiber.lastEffect !== null) { 14497 returnFiber.lastEffect.nextEffect = childToDelete; 14498 returnFiber.lastEffect = childToDelete; 14499 } else { 14500 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 14501 } 14502 } 14503 14504 function insertNonHydratedInstance(returnFiber, fiber) { 14505 fiber.flags = fiber.flags & ~Hydrating | Placement; 14506 14507 { 14508 switch (returnFiber.tag) { 14509 case HostRoot: 14510 { 14511 var parentContainer = returnFiber.stateNode.containerInfo; 14512 14513 switch (fiber.tag) { 14514 case HostComponent: 14515 var type = fiber.type; 14516 var props = fiber.pendingProps; 14517 didNotFindHydratableContainerInstance(parentContainer, type); 14518 break; 14519 14520 case HostText: 14521 var text = fiber.pendingProps; 14522 didNotFindHydratableContainerTextInstance(parentContainer, text); 14523 break; 14524 } 14525 14526 break; 14527 } 14528 14529 case HostComponent: 14530 { 14531 var parentType = returnFiber.type; 14532 var parentProps = returnFiber.memoizedProps; 14533 var parentInstance = returnFiber.stateNode; 14534 14535 switch (fiber.tag) { 14536 case HostComponent: 14537 var _type = fiber.type; 14538 var _props = fiber.pendingProps; 14539 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type); 14540 break; 14541 14542 case HostText: 14543 var _text = fiber.pendingProps; 14544 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text); 14545 break; 14546 14547 case SuspenseComponent: 14548 didNotFindHydratableSuspenseInstance(parentType, parentProps); 14549 break; 14550 } 14551 14552 break; 14553 } 14554 14555 default: 14556 return; 14557 } 14558 } 14559 } 14560 14561 function tryHydrate(fiber, nextInstance) { 14562 switch (fiber.tag) { 14563 case HostComponent: 14564 { 14565 var type = fiber.type; 14566 var props = fiber.pendingProps; 14567 var instance = canHydrateInstance(nextInstance, type); 14568 14569 if (instance !== null) { 14570 fiber.stateNode = instance; 14571 return true; 14572 } 14573 14574 return false; 14575 } 14576 14577 case HostText: 14578 { 14579 var text = fiber.pendingProps; 14580 var textInstance = canHydrateTextInstance(nextInstance, text); 14581 14582 if (textInstance !== null) { 14583 fiber.stateNode = textInstance; 14584 return true; 14585 } 14586 14587 return false; 14588 } 14589 14590 case SuspenseComponent: 14591 { 14592 14593 return false; 14594 } 14595 14596 default: 14597 return false; 14598 } 14599 } 14600 14601 function tryToClaimNextHydratableInstance(fiber) { 14602 if (!isHydrating) { 14603 return; 14604 } 14605 14606 var nextInstance = nextHydratableInstance; 14607 14608 if (!nextInstance) { 14609 // Nothing to hydrate. Make it an insertion. 14610 insertNonHydratedInstance(hydrationParentFiber, fiber); 14611 isHydrating = false; 14612 hydrationParentFiber = fiber; 14613 return; 14614 } 14615 14616 var firstAttemptedInstance = nextInstance; 14617 14618 if (!tryHydrate(fiber, nextInstance)) { 14619 // If we can't hydrate this instance let's try the next one. 14620 // We use this as a heuristic. It's based on intuition and not data so it 14621 // might be flawed or unnecessary. 14622 nextInstance = getNextHydratableSibling(firstAttemptedInstance); 14623 14624 if (!nextInstance || !tryHydrate(fiber, nextInstance)) { 14625 // Nothing to hydrate. Make it an insertion. 14626 insertNonHydratedInstance(hydrationParentFiber, fiber); 14627 isHydrating = false; 14628 hydrationParentFiber = fiber; 14629 return; 14630 } // We matched the next one, we'll now assume that the first one was 14631 // superfluous and we'll delete it. Since we can't eagerly delete it 14632 // we'll have to schedule a deletion. To do that, this node needs a dummy 14633 // fiber associated with it. 14634 14635 14636 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); 14637 } 14638 14639 hydrationParentFiber = fiber; 14640 nextHydratableInstance = getFirstHydratableChild(nextInstance); 14641 } 14642 14643 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { 14644 14645 var instance = fiber.stateNode; 14646 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component. 14647 14648 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there 14649 // is a new ref we mark this as an update. 14650 14651 if (updatePayload !== null) { 14652 return true; 14653 } 14654 14655 return false; 14656 } 14657 14658 function prepareToHydrateHostTextInstance(fiber) { 14659 14660 var textInstance = fiber.stateNode; 14661 var textContent = fiber.memoizedProps; 14662 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); 14663 14664 { 14665 if (shouldUpdate) { 14666 // We assume that prepareToHydrateHostTextInstance is called in a context where the 14667 // hydration parent is the parent host component of this host text. 14668 var returnFiber = hydrationParentFiber; 14669 14670 if (returnFiber !== null) { 14671 switch (returnFiber.tag) { 14672 case HostRoot: 14673 { 14674 var parentContainer = returnFiber.stateNode.containerInfo; 14675 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent); 14676 break; 14677 } 14678 14679 case HostComponent: 14680 { 14681 var parentType = returnFiber.type; 14682 var parentProps = returnFiber.memoizedProps; 14683 var parentInstance = returnFiber.stateNode; 14684 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent); 14685 break; 14686 } 14687 } 14688 } 14689 } 14690 } 14691 14692 return shouldUpdate; 14693 } 14694 14695 function skipPastDehydratedSuspenseInstance(fiber) { 14696 14697 var suspenseState = fiber.memoizedState; 14698 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null; 14699 14700 if (!suspenseInstance) { 14701 { 14702 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." ); 14703 } 14704 } 14705 14706 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); 14707 } 14708 14709 function popToNextHostParent(fiber) { 14710 var parent = fiber.return; 14711 14712 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) { 14713 parent = parent.return; 14714 } 14715 14716 hydrationParentFiber = parent; 14717 } 14718 14719 function popHydrationState(fiber) { 14720 14721 if (fiber !== hydrationParentFiber) { 14722 // We're deeper than the current hydration context, inside an inserted 14723 // tree. 14724 return false; 14725 } 14726 14727 if (!isHydrating) { 14728 // If we're not currently hydrating but we're in a hydration context, then 14729 // we were an insertion and now need to pop up reenter hydration of our 14730 // siblings. 14731 popToNextHostParent(fiber); 14732 isHydrating = true; 14733 return false; 14734 } 14735 14736 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. 14737 // We only do this deeper than head and body since they tend to have random 14738 // other nodes in them. We also ignore components with pure text content in 14739 // side of them. 14740 // TODO: Better heuristic. 14741 14742 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) { 14743 var nextInstance = nextHydratableInstance; 14744 14745 while (nextInstance) { 14746 deleteHydratableInstance(fiber, nextInstance); 14747 nextInstance = getNextHydratableSibling(nextInstance); 14748 } 14749 } 14750 14751 popToNextHostParent(fiber); 14752 14753 if (fiber.tag === SuspenseComponent) { 14754 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); 14755 } else { 14756 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; 14757 } 14758 14759 return true; 14760 } 14761 14762 function resetHydrationState() { 14763 14764 hydrationParentFiber = null; 14765 nextHydratableInstance = null; 14766 isHydrating = false; 14767 } 14768 14769 function getIsHydrating() { 14770 return isHydrating; 14771 } 14772 14773 // and should be reset before starting a new render. 14774 // This tracks which mutable sources need to be reset after a render. 14775 14776 var workInProgressSources = []; 14777 var rendererSigil$1; 14778 14779 { 14780 // Used to detect multiple renderers using the same mutable source. 14781 rendererSigil$1 = {}; 14782 } 14783 14784 function markSourceAsDirty(mutableSource) { 14785 workInProgressSources.push(mutableSource); 14786 } 14787 function resetWorkInProgressVersions() { 14788 for (var i = 0; i < workInProgressSources.length; i++) { 14789 var mutableSource = workInProgressSources[i]; 14790 14791 { 14792 mutableSource._workInProgressVersionPrimary = null; 14793 } 14794 } 14795 14796 workInProgressSources.length = 0; 14797 } 14798 function getWorkInProgressVersion(mutableSource) { 14799 { 14800 return mutableSource._workInProgressVersionPrimary; 14801 } 14802 } 14803 function setWorkInProgressVersion(mutableSource, version) { 14804 { 14805 mutableSource._workInProgressVersionPrimary = version; 14806 } 14807 14808 workInProgressSources.push(mutableSource); 14809 } 14810 function warnAboutMultipleRenderersDEV(mutableSource) { 14811 { 14812 { 14813 if (mutableSource._currentPrimaryRenderer == null) { 14814 mutableSource._currentPrimaryRenderer = rendererSigil$1; 14815 } else if (mutableSource._currentPrimaryRenderer !== rendererSigil$1) { 14816 error('Detected multiple renderers concurrently rendering the ' + 'same mutable source. This is currently unsupported.'); 14817 } 14818 } 14819 } 14820 } // Eager reads the version of a mutable source and stores it on the root. 14821 14822 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, 14823 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; 14824 var didWarnAboutMismatchedHooksForComponent; 14825 var didWarnAboutUseOpaqueIdentifier; 14826 14827 { 14828 didWarnAboutUseOpaqueIdentifier = {}; 14829 didWarnAboutMismatchedHooksForComponent = new Set(); 14830 } 14831 14832 // These are set right before calling the component. 14833 var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from 14834 // the work-in-progress hook. 14835 14836 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The 14837 // current hook list is the list that belongs to the current fiber. The 14838 // work-in-progress hook list is a new list that will be added to the 14839 // work-in-progress fiber. 14840 14841 var currentHook = null; 14842 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This 14843 // does not get reset if we do another render pass; only when we're completely 14844 // finished evaluating this component. This is an optimization so we know 14845 // whether we need to clear render phase updates after a throw. 14846 14847 var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This 14848 // gets reset after each attempt. 14849 // TODO: Maybe there's some way to consolidate this with 14850 // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`. 14851 14852 var didScheduleRenderPhaseUpdateDuringThisPass = false; 14853 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook 14854 14855 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. 14856 // The list stores the order of hooks used during the initial render (mount). 14857 // Subsequent renders (updates) reference this list. 14858 14859 var hookTypesDev = null; 14860 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore 14861 // the dependencies for Hooks that need them (e.g. useEffect or useMemo). 14862 // When true, such Hooks will always be "remounted". Only used during hot reload. 14863 14864 var ignorePreviousDependencies = false; 14865 14866 function mountHookTypesDev() { 14867 { 14868 var hookName = currentHookNameInDev; 14869 14870 if (hookTypesDev === null) { 14871 hookTypesDev = [hookName]; 14872 } else { 14873 hookTypesDev.push(hookName); 14874 } 14875 } 14876 } 14877 14878 function updateHookTypesDev() { 14879 { 14880 var hookName = currentHookNameInDev; 14881 14882 if (hookTypesDev !== null) { 14883 hookTypesUpdateIndexDev++; 14884 14885 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { 14886 warnOnHookMismatchInDev(hookName); 14887 } 14888 } 14889 } 14890 } 14891 14892 function checkDepsAreArrayDev(deps) { 14893 { 14894 if (deps !== undefined && deps !== null && !Array.isArray(deps)) { 14895 // Verify deps, but only on mount to avoid extra checks. 14896 // It's unlikely their type would change as usually you define them inline. 14897 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); 14898 } 14899 } 14900 } 14901 14902 function warnOnHookMismatchInDev(currentHookName) { 14903 { 14904 var componentName = getComponentName(currentlyRenderingFiber$1.type); 14905 14906 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { 14907 didWarnAboutMismatchedHooksForComponent.add(componentName); 14908 14909 if (hookTypesDev !== null) { 14910 var table = ''; 14911 var secondColumnStart = 30; 14912 14913 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) { 14914 var oldHookName = hookTypesDev[i]; 14915 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; 14916 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up 14917 // lol @ IE not supporting String#repeat 14918 14919 while (row.length < secondColumnStart) { 14920 row += ' '; 14921 } 14922 14923 row += newHookName + '\n'; 14924 table += row; 14925 } 14926 14927 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); 14928 } 14929 } 14930 } 14931 } 14932 14933 function throwInvalidHookError() { 14934 { 14935 { 14936 throw 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:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem." ); 14937 } 14938 } 14939 } 14940 14941 function areHookInputsEqual(nextDeps, prevDeps) { 14942 { 14943 if (ignorePreviousDependencies) { 14944 // Only true when this component is being hot reloaded. 14945 return false; 14946 } 14947 } 14948 14949 if (prevDeps === null) { 14950 { 14951 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); 14952 } 14953 14954 return false; 14955 } 14956 14957 { 14958 // Don't bother comparing lengths in prod because these arrays should be 14959 // passed inline. 14960 if (nextDeps.length !== prevDeps.length) { 14961 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(', ') + "]"); 14962 } 14963 } 14964 14965 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { 14966 if (objectIs(nextDeps[i], prevDeps[i])) { 14967 continue; 14968 } 14969 14970 return false; 14971 } 14972 14973 return true; 14974 } 14975 14976 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) { 14977 renderLanes = nextRenderLanes; 14978 currentlyRenderingFiber$1 = workInProgress; 14979 14980 { 14981 hookTypesDev = current !== null ? current._debugHookTypes : null; 14982 hookTypesUpdateIndexDev = -1; // Used for hot reloading: 14983 14984 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; 14985 } 14986 14987 workInProgress.memoizedState = null; 14988 workInProgress.updateQueue = null; 14989 workInProgress.lanes = NoLanes; // The following should have already been reset 14990 // currentHook = null; 14991 // workInProgressHook = null; 14992 // didScheduleRenderPhaseUpdate = false; 14993 // TODO Warn if no hooks are used at all during mount, then some are used during update. 14994 // Currently we will identify the update render as a mount because memoizedState === null. 14995 // This is tricky because it's valid for certain types of components (e.g. React.lazy) 14996 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. 14997 // Non-stateful hooks (e.g. context) don't get added to memoizedState, 14998 // so memoizedState would be null during updates and mounts. 14999 15000 { 15001 if (current !== null && current.memoizedState !== null) { 15002 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; 15003 } else if (hookTypesDev !== null) { 15004 // This dispatcher handles an edge case where a component is updating, 15005 // but no stateful hooks have been used. 15006 // We want to match the production code behavior (which will use HooksDispatcherOnMount), 15007 // but with the extra DEV validation to ensure hooks ordering hasn't changed. 15008 // This dispatcher does that. 15009 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; 15010 } else { 15011 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; 15012 } 15013 } 15014 15015 var children = Component(props, secondArg); // Check if there was a render phase update 15016 15017 if (didScheduleRenderPhaseUpdateDuringThisPass) { 15018 // Keep rendering in a loop for as long as render phase updates continue to 15019 // be scheduled. Use a counter to prevent infinite loops. 15020 var numberOfReRenders = 0; 15021 15022 do { 15023 didScheduleRenderPhaseUpdateDuringThisPass = false; 15024 15025 if (!(numberOfReRenders < RE_RENDER_LIMIT)) { 15026 { 15027 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." ); 15028 } 15029 } 15030 15031 numberOfReRenders += 1; 15032 15033 { 15034 // Even when hot reloading, allow dependencies to stabilize 15035 // after first render to prevent infinite render phase updates. 15036 ignorePreviousDependencies = false; 15037 } // Start over from the beginning of the list 15038 15039 15040 currentHook = null; 15041 workInProgressHook = null; 15042 workInProgress.updateQueue = null; 15043 15044 { 15045 // Also validate hook order for cascading updates. 15046 hookTypesUpdateIndexDev = -1; 15047 } 15048 15049 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ; 15050 children = Component(props, secondArg); 15051 } while (didScheduleRenderPhaseUpdateDuringThisPass); 15052 } // We can assume the previous dispatcher is always this one, since we set it 15053 // at the beginning of the render phase and there's no re-entrancy. 15054 15055 15056 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 15057 15058 { 15059 workInProgress._debugHookTypes = hookTypesDev; 15060 } // This check uses currentHook so that it works the same in DEV and prod bundles. 15061 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. 15062 15063 15064 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; 15065 renderLanes = NoLanes; 15066 currentlyRenderingFiber$1 = null; 15067 currentHook = null; 15068 workInProgressHook = null; 15069 15070 { 15071 currentHookNameInDev = null; 15072 hookTypesDev = null; 15073 hookTypesUpdateIndexDev = -1; 15074 } 15075 15076 didScheduleRenderPhaseUpdate = false; 15077 15078 if (!!didRenderTooFewHooks) { 15079 { 15080 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); 15081 } 15082 } 15083 15084 return children; 15085 } 15086 function bailoutHooks(current, workInProgress, lanes) { 15087 workInProgress.updateQueue = current.updateQueue; 15088 workInProgress.flags &= ~(Passive | Update); 15089 current.lanes = removeLanes(current.lanes, lanes); 15090 } 15091 function resetHooksAfterThrow() { 15092 // We can assume the previous dispatcher is always this one, since we set it 15093 // at the beginning of the render phase and there's no re-entrancy. 15094 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 15095 15096 if (didScheduleRenderPhaseUpdate) { 15097 // There were render phase updates. These are only valid for this render 15098 // phase, which we are now aborting. Remove the updates from the queues so 15099 // they do not persist to the next render. Do not remove updates from hooks 15100 // that weren't processed. 15101 // 15102 // Only reset the updates from the queue if it has a clone. If it does 15103 // not have a clone, that means it wasn't processed, and the updates were 15104 // scheduled before we entered the render phase. 15105 var hook = currentlyRenderingFiber$1.memoizedState; 15106 15107 while (hook !== null) { 15108 var queue = hook.queue; 15109 15110 if (queue !== null) { 15111 queue.pending = null; 15112 } 15113 15114 hook = hook.next; 15115 } 15116 15117 didScheduleRenderPhaseUpdate = false; 15118 } 15119 15120 renderLanes = NoLanes; 15121 currentlyRenderingFiber$1 = null; 15122 currentHook = null; 15123 workInProgressHook = null; 15124 15125 { 15126 hookTypesDev = null; 15127 hookTypesUpdateIndexDev = -1; 15128 currentHookNameInDev = null; 15129 isUpdatingOpaqueValueInRenderPhase = false; 15130 } 15131 15132 didScheduleRenderPhaseUpdateDuringThisPass = false; 15133 } 15134 15135 function mountWorkInProgressHook() { 15136 var hook = { 15137 memoizedState: null, 15138 baseState: null, 15139 baseQueue: null, 15140 queue: null, 15141 next: null 15142 }; 15143 15144 if (workInProgressHook === null) { 15145 // This is the first hook in the list 15146 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; 15147 } else { 15148 // Append to the end of the list 15149 workInProgressHook = workInProgressHook.next = hook; 15150 } 15151 15152 return workInProgressHook; 15153 } 15154 15155 function updateWorkInProgressHook() { 15156 // This function is used both for updates and for re-renders triggered by a 15157 // render phase update. It assumes there is either a current hook we can 15158 // clone, or a work-in-progress hook from a previous render pass that we can 15159 // use as a base. When we reach the end of the base list, we must switch to 15160 // the dispatcher used for mounts. 15161 var nextCurrentHook; 15162 15163 if (currentHook === null) { 15164 var current = currentlyRenderingFiber$1.alternate; 15165 15166 if (current !== null) { 15167 nextCurrentHook = current.memoizedState; 15168 } else { 15169 nextCurrentHook = null; 15170 } 15171 } else { 15172 nextCurrentHook = currentHook.next; 15173 } 15174 15175 var nextWorkInProgressHook; 15176 15177 if (workInProgressHook === null) { 15178 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; 15179 } else { 15180 nextWorkInProgressHook = workInProgressHook.next; 15181 } 15182 15183 if (nextWorkInProgressHook !== null) { 15184 // There's already a work-in-progress. Reuse it. 15185 workInProgressHook = nextWorkInProgressHook; 15186 nextWorkInProgressHook = workInProgressHook.next; 15187 currentHook = nextCurrentHook; 15188 } else { 15189 // Clone from the current hook. 15190 if (!(nextCurrentHook !== null)) { 15191 { 15192 throw Error( "Rendered more hooks than during the previous render." ); 15193 } 15194 } 15195 15196 currentHook = nextCurrentHook; 15197 var newHook = { 15198 memoizedState: currentHook.memoizedState, 15199 baseState: currentHook.baseState, 15200 baseQueue: currentHook.baseQueue, 15201 queue: currentHook.queue, 15202 next: null 15203 }; 15204 15205 if (workInProgressHook === null) { 15206 // This is the first hook in the list. 15207 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; 15208 } else { 15209 // Append to the end of the list. 15210 workInProgressHook = workInProgressHook.next = newHook; 15211 } 15212 } 15213 15214 return workInProgressHook; 15215 } 15216 15217 function createFunctionComponentUpdateQueue() { 15218 return { 15219 lastEffect: null 15220 }; 15221 } 15222 15223 function basicStateReducer(state, action) { 15224 // $FlowFixMe: Flow doesn't like mixed types 15225 return typeof action === 'function' ? action(state) : action; 15226 } 15227 15228 function mountReducer(reducer, initialArg, init) { 15229 var hook = mountWorkInProgressHook(); 15230 var initialState; 15231 15232 if (init !== undefined) { 15233 initialState = init(initialArg); 15234 } else { 15235 initialState = initialArg; 15236 } 15237 15238 hook.memoizedState = hook.baseState = initialState; 15239 var queue = hook.queue = { 15240 pending: null, 15241 dispatch: null, 15242 lastRenderedReducer: reducer, 15243 lastRenderedState: initialState 15244 }; 15245 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue); 15246 return [hook.memoizedState, dispatch]; 15247 } 15248 15249 function updateReducer(reducer, initialArg, init) { 15250 var hook = updateWorkInProgressHook(); 15251 var queue = hook.queue; 15252 15253 if (!(queue !== null)) { 15254 { 15255 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." ); 15256 } 15257 } 15258 15259 queue.lastRenderedReducer = reducer; 15260 var current = currentHook; // The last rebase update that is NOT part of the base state. 15261 15262 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. 15263 15264 var pendingQueue = queue.pending; 15265 15266 if (pendingQueue !== null) { 15267 // We have new updates that haven't been processed yet. 15268 // We'll add them to the base queue. 15269 if (baseQueue !== null) { 15270 // Merge the pending queue and the base queue. 15271 var baseFirst = baseQueue.next; 15272 var pendingFirst = pendingQueue.next; 15273 baseQueue.next = pendingFirst; 15274 pendingQueue.next = baseFirst; 15275 } 15276 15277 { 15278 if (current.baseQueue !== baseQueue) { 15279 // Internal invariant that should never happen, but feasibly could in 15280 // the future if we implement resuming, or some form of that. 15281 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.'); 15282 } 15283 } 15284 15285 current.baseQueue = baseQueue = pendingQueue; 15286 queue.pending = null; 15287 } 15288 15289 if (baseQueue !== null) { 15290 // We have a queue to process. 15291 var first = baseQueue.next; 15292 var newState = current.baseState; 15293 var newBaseState = null; 15294 var newBaseQueueFirst = null; 15295 var newBaseQueueLast = null; 15296 var update = first; 15297 15298 do { 15299 var updateLane = update.lane; 15300 15301 if (!isSubsetOfLanes(renderLanes, updateLane)) { 15302 // Priority is insufficient. Skip this update. If this is the first 15303 // skipped update, the previous update/state is the new base 15304 // update/state. 15305 var clone = { 15306 lane: updateLane, 15307 action: update.action, 15308 eagerReducer: update.eagerReducer, 15309 eagerState: update.eagerState, 15310 next: null 15311 }; 15312 15313 if (newBaseQueueLast === null) { 15314 newBaseQueueFirst = newBaseQueueLast = clone; 15315 newBaseState = newState; 15316 } else { 15317 newBaseQueueLast = newBaseQueueLast.next = clone; 15318 } // Update the remaining priority in the queue. 15319 // TODO: Don't need to accumulate this. Instead, we can remove 15320 // renderLanes from the original lanes. 15321 15322 15323 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane); 15324 markSkippedUpdateLanes(updateLane); 15325 } else { 15326 // This update does have sufficient priority. 15327 if (newBaseQueueLast !== null) { 15328 var _clone = { 15329 // This update is going to be committed so we never want uncommit 15330 // it. Using NoLane works because 0 is a subset of all bitmasks, so 15331 // this will never be skipped by the check above. 15332 lane: NoLane, 15333 action: update.action, 15334 eagerReducer: update.eagerReducer, 15335 eagerState: update.eagerState, 15336 next: null 15337 }; 15338 newBaseQueueLast = newBaseQueueLast.next = _clone; 15339 } // Process this update. 15340 15341 15342 if (update.eagerReducer === reducer) { 15343 // If this update was processed eagerly, and its reducer matches the 15344 // current reducer, we can use the eagerly computed state. 15345 newState = update.eagerState; 15346 } else { 15347 var action = update.action; 15348 newState = reducer(newState, action); 15349 } 15350 } 15351 15352 update = update.next; 15353 } while (update !== null && update !== first); 15354 15355 if (newBaseQueueLast === null) { 15356 newBaseState = newState; 15357 } else { 15358 newBaseQueueLast.next = newBaseQueueFirst; 15359 } // Mark that the fiber performed work, but only if the new state is 15360 // different from the current state. 15361 15362 15363 if (!objectIs(newState, hook.memoizedState)) { 15364 markWorkInProgressReceivedUpdate(); 15365 } 15366 15367 hook.memoizedState = newState; 15368 hook.baseState = newBaseState; 15369 hook.baseQueue = newBaseQueueLast; 15370 queue.lastRenderedState = newState; 15371 } 15372 15373 var dispatch = queue.dispatch; 15374 return [hook.memoizedState, dispatch]; 15375 } 15376 15377 function rerenderReducer(reducer, initialArg, init) { 15378 var hook = updateWorkInProgressHook(); 15379 var queue = hook.queue; 15380 15381 if (!(queue !== null)) { 15382 { 15383 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." ); 15384 } 15385 } 15386 15387 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous 15388 // work-in-progress hook. 15389 15390 var dispatch = queue.dispatch; 15391 var lastRenderPhaseUpdate = queue.pending; 15392 var newState = hook.memoizedState; 15393 15394 if (lastRenderPhaseUpdate !== null) { 15395 // The queue doesn't persist past this render pass. 15396 queue.pending = null; 15397 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; 15398 var update = firstRenderPhaseUpdate; 15399 15400 do { 15401 // Process this render phase update. We don't have to check the 15402 // priority because it will always be the same as the current 15403 // render's. 15404 var action = update.action; 15405 newState = reducer(newState, action); 15406 update = update.next; 15407 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is 15408 // different from the current state. 15409 15410 15411 if (!objectIs(newState, hook.memoizedState)) { 15412 markWorkInProgressReceivedUpdate(); 15413 } 15414 15415 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to 15416 // the base state unless the queue is empty. 15417 // TODO: Not sure if this is the desired semantics, but it's what we 15418 // do for gDSFP. I can't remember why. 15419 15420 if (hook.baseQueue === null) { 15421 hook.baseState = newState; 15422 } 15423 15424 queue.lastRenderedState = newState; 15425 } 15426 15427 return [newState, dispatch]; 15428 } 15429 15430 function readFromUnsubcribedMutableSource(root, source, getSnapshot) { 15431 { 15432 warnAboutMultipleRenderersDEV(source); 15433 } 15434 15435 var getVersion = source._getVersion; 15436 var version = getVersion(source._source); // Is it safe for this component to read from this source during the current render? 15437 15438 var isSafeToReadFromSource = false; // Check the version first. 15439 // If this render has already been started with a specific version, 15440 // we can use it alone to determine if we can safely read from the source. 15441 15442 var currentRenderVersion = getWorkInProgressVersion(source); 15443 15444 if (currentRenderVersion !== null) { 15445 // It's safe to read if the store hasn't been mutated since the last time 15446 // we read something. 15447 isSafeToReadFromSource = currentRenderVersion === version; 15448 } else { 15449 // If there's no version, then this is the first time we've read from the 15450 // source during the current render pass, so we need to do a bit more work. 15451 // What we need to determine is if there are any hooks that already 15452 // subscribed to the source, and if so, whether there are any pending 15453 // mutations that haven't been synchronized yet. 15454 // 15455 // If there are no pending mutations, then `root.mutableReadLanes` will be 15456 // empty, and we know we can safely read. 15457 // 15458 // If there *are* pending mutations, we may still be able to safely read 15459 // if the currently rendering lanes are inclusive of the pending mutation 15460 // lanes, since that guarantees that the value we're about to read from 15461 // the source is consistent with the values that we read during the most 15462 // recent mutation. 15463 isSafeToReadFromSource = isSubsetOfLanes(renderLanes, root.mutableReadLanes); 15464 15465 if (isSafeToReadFromSource) { 15466 // If it's safe to read from this source during the current render, 15467 // store the version in case other components read from it. 15468 // A changed version number will let those components know to throw and restart the render. 15469 setWorkInProgressVersion(source, version); 15470 } 15471 } 15472 15473 if (isSafeToReadFromSource) { 15474 var snapshot = getSnapshot(source._source); 15475 15476 { 15477 if (typeof snapshot === 'function') { 15478 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.'); 15479 } 15480 } 15481 15482 return snapshot; 15483 } else { 15484 // This handles the special case of a mutable source being shared between renderers. 15485 // In that case, if the source is mutated between the first and second renderer, 15486 // The second renderer don't know that it needs to reset the WIP version during unwind, 15487 // (because the hook only marks sources as dirty if it's written to their WIP version). 15488 // That would cause this tear check to throw again and eventually be visible to the user. 15489 // We can avoid this infinite loop by explicitly marking the source as dirty. 15490 // 15491 // This can lead to tearing in the first renderer when it resumes, 15492 // but there's nothing we can do about that (short of throwing here and refusing to continue the render). 15493 markSourceAsDirty(source); 15494 15495 { 15496 { 15497 throw Error( "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); 15498 } 15499 } 15500 } 15501 } 15502 15503 function useMutableSource(hook, source, getSnapshot, subscribe) { 15504 var root = getWorkInProgressRoot(); 15505 15506 if (!(root !== null)) { 15507 { 15508 throw Error( "Expected a work-in-progress root. This is a bug in React. Please file an issue." ); 15509 } 15510 } 15511 15512 var getVersion = source._getVersion; 15513 var version = getVersion(source._source); 15514 var dispatcher = ReactCurrentDispatcher$1.current; // eslint-disable-next-line prefer-const 15515 15516 var _dispatcher$useState = dispatcher.useState(function () { 15517 return readFromUnsubcribedMutableSource(root, source, getSnapshot); 15518 }), 15519 currentSnapshot = _dispatcher$useState[0], 15520 setSnapshot = _dispatcher$useState[1]; 15521 15522 var snapshot = currentSnapshot; // Grab a handle to the state hook as well. 15523 // We use it to clear the pending update queue if we have a new source. 15524 15525 var stateHook = workInProgressHook; 15526 var memoizedState = hook.memoizedState; 15527 var refs = memoizedState.refs; 15528 var prevGetSnapshot = refs.getSnapshot; 15529 var prevSource = memoizedState.source; 15530 var prevSubscribe = memoizedState.subscribe; 15531 var fiber = currentlyRenderingFiber$1; 15532 hook.memoizedState = { 15533 refs: refs, 15534 source: source, 15535 subscribe: subscribe 15536 }; // Sync the values needed by our subscription handler after each commit. 15537 15538 dispatcher.useEffect(function () { 15539 refs.getSnapshot = getSnapshot; // Normally the dispatch function for a state hook never changes, 15540 // but this hook recreates the queue in certain cases to avoid updates from stale sources. 15541 // handleChange() below needs to reference the dispatch function without re-subscribing, 15542 // so we use a ref to ensure that it always has the latest version. 15543 15544 refs.setSnapshot = setSnapshot; // Check for a possible change between when we last rendered now. 15545 15546 var maybeNewVersion = getVersion(source._source); 15547 15548 if (!objectIs(version, maybeNewVersion)) { 15549 var maybeNewSnapshot = getSnapshot(source._source); 15550 15551 { 15552 if (typeof maybeNewSnapshot === 'function') { 15553 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.'); 15554 } 15555 } 15556 15557 if (!objectIs(snapshot, maybeNewSnapshot)) { 15558 setSnapshot(maybeNewSnapshot); 15559 var lane = requestUpdateLane(fiber); 15560 markRootMutableRead(root, lane); 15561 } // If the source mutated between render and now, 15562 // there may be state updates already scheduled from the old source. 15563 // Entangle the updates so that they render in the same batch. 15564 15565 15566 markRootEntangled(root, root.mutableReadLanes); 15567 } 15568 }, [getSnapshot, source, subscribe]); // If we got a new source or subscribe function, re-subscribe in a passive effect. 15569 15570 dispatcher.useEffect(function () { 15571 var handleChange = function () { 15572 var latestGetSnapshot = refs.getSnapshot; 15573 var latestSetSnapshot = refs.setSnapshot; 15574 15575 try { 15576 latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time. 15577 15578 var lane = requestUpdateLane(fiber); 15579 markRootMutableRead(root, lane); 15580 } catch (error) { 15581 // A selector might throw after a source mutation. 15582 // e.g. it might try to read from a part of the store that no longer exists. 15583 // In this case we should still schedule an update with React. 15584 // Worst case the selector will throw again and then an error boundary will handle it. 15585 latestSetSnapshot(function () { 15586 throw error; 15587 }); 15588 } 15589 }; 15590 15591 var unsubscribe = subscribe(source._source, handleChange); 15592 15593 { 15594 if (typeof unsubscribe !== 'function') { 15595 error('Mutable source subscribe function must return an unsubscribe function.'); 15596 } 15597 } 15598 15599 return unsubscribe; 15600 }, [source, subscribe]); // If any of the inputs to useMutableSource change, reading is potentially unsafe. 15601 // 15602 // If either the source or the subscription have changed we can't can't trust the update queue. 15603 // Maybe the source changed in a way that the old subscription ignored but the new one depends on. 15604 // 15605 // If the getSnapshot function changed, we also shouldn't rely on the update queue. 15606 // It's possible that the underlying source was mutated between the when the last "change" event fired, 15607 // and when the current render (with the new getSnapshot function) is processed. 15608 // 15609 // In both cases, we need to throw away pending updates (since they are no longer relevant) 15610 // and treat reading from the source as we do in the mount case. 15611 15612 if (!objectIs(prevGetSnapshot, getSnapshot) || !objectIs(prevSource, source) || !objectIs(prevSubscribe, subscribe)) { 15613 // Create a new queue and setState method, 15614 // So if there are interleaved updates, they get pushed to the older queue. 15615 // When this becomes current, the previous queue and dispatch method will be discarded, 15616 // including any interleaving updates that occur. 15617 var newQueue = { 15618 pending: null, 15619 dispatch: null, 15620 lastRenderedReducer: basicStateReducer, 15621 lastRenderedState: snapshot 15622 }; 15623 newQueue.dispatch = setSnapshot = dispatchAction.bind(null, currentlyRenderingFiber$1, newQueue); 15624 stateHook.queue = newQueue; 15625 stateHook.baseQueue = null; 15626 snapshot = readFromUnsubcribedMutableSource(root, source, getSnapshot); 15627 stateHook.memoizedState = stateHook.baseState = snapshot; 15628 } 15629 15630 return snapshot; 15631 } 15632 15633 function mountMutableSource(source, getSnapshot, subscribe) { 15634 var hook = mountWorkInProgressHook(); 15635 hook.memoizedState = { 15636 refs: { 15637 getSnapshot: getSnapshot, 15638 setSnapshot: null 15639 }, 15640 source: source, 15641 subscribe: subscribe 15642 }; 15643 return useMutableSource(hook, source, getSnapshot, subscribe); 15644 } 15645 15646 function updateMutableSource(source, getSnapshot, subscribe) { 15647 var hook = updateWorkInProgressHook(); 15648 return useMutableSource(hook, source, getSnapshot, subscribe); 15649 } 15650 15651 function mountState(initialState) { 15652 var hook = mountWorkInProgressHook(); 15653 15654 if (typeof initialState === 'function') { 15655 // $FlowFixMe: Flow doesn't like mixed types 15656 initialState = initialState(); 15657 } 15658 15659 hook.memoizedState = hook.baseState = initialState; 15660 var queue = hook.queue = { 15661 pending: null, 15662 dispatch: null, 15663 lastRenderedReducer: basicStateReducer, 15664 lastRenderedState: initialState 15665 }; 15666 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue); 15667 return [hook.memoizedState, dispatch]; 15668 } 15669 15670 function updateState(initialState) { 15671 return updateReducer(basicStateReducer); 15672 } 15673 15674 function rerenderState(initialState) { 15675 return rerenderReducer(basicStateReducer); 15676 } 15677 15678 function pushEffect(tag, create, destroy, deps) { 15679 var effect = { 15680 tag: tag, 15681 create: create, 15682 destroy: destroy, 15683 deps: deps, 15684 // Circular 15685 next: null 15686 }; 15687 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; 15688 15689 if (componentUpdateQueue === null) { 15690 componentUpdateQueue = createFunctionComponentUpdateQueue(); 15691 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; 15692 componentUpdateQueue.lastEffect = effect.next = effect; 15693 } else { 15694 var lastEffect = componentUpdateQueue.lastEffect; 15695 15696 if (lastEffect === null) { 15697 componentUpdateQueue.lastEffect = effect.next = effect; 15698 } else { 15699 var firstEffect = lastEffect.next; 15700 lastEffect.next = effect; 15701 effect.next = firstEffect; 15702 componentUpdateQueue.lastEffect = effect; 15703 } 15704 } 15705 15706 return effect; 15707 } 15708 15709 function mountRef(initialValue) { 15710 var hook = mountWorkInProgressHook(); 15711 var ref = { 15712 current: initialValue 15713 }; 15714 15715 { 15716 Object.seal(ref); 15717 } 15718 15719 hook.memoizedState = ref; 15720 return ref; 15721 } 15722 15723 function updateRef(initialValue) { 15724 var hook = updateWorkInProgressHook(); 15725 return hook.memoizedState; 15726 } 15727 15728 function mountEffectImpl(fiberFlags, hookFlags, create, deps) { 15729 var hook = mountWorkInProgressHook(); 15730 var nextDeps = deps === undefined ? null : deps; 15731 currentlyRenderingFiber$1.flags |= fiberFlags; 15732 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps); 15733 } 15734 15735 function updateEffectImpl(fiberFlags, hookFlags, create, deps) { 15736 var hook = updateWorkInProgressHook(); 15737 var nextDeps = deps === undefined ? null : deps; 15738 var destroy = undefined; 15739 15740 if (currentHook !== null) { 15741 var prevEffect = currentHook.memoizedState; 15742 destroy = prevEffect.destroy; 15743 15744 if (nextDeps !== null) { 15745 var prevDeps = prevEffect.deps; 15746 15747 if (areHookInputsEqual(nextDeps, prevDeps)) { 15748 pushEffect(hookFlags, create, destroy, nextDeps); 15749 return; 15750 } 15751 } 15752 } 15753 15754 currentlyRenderingFiber$1.flags |= fiberFlags; 15755 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps); 15756 } 15757 15758 function mountEffect(create, deps) { 15759 { 15760 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests 15761 if ('undefined' !== typeof jest) { 15762 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); 15763 } 15764 } 15765 15766 return mountEffectImpl(Update | Passive, Passive$1, create, deps); 15767 } 15768 15769 function updateEffect(create, deps) { 15770 { 15771 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests 15772 if ('undefined' !== typeof jest) { 15773 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); 15774 } 15775 } 15776 15777 return updateEffectImpl(Update | Passive, Passive$1, create, deps); 15778 } 15779 15780 function mountLayoutEffect(create, deps) { 15781 return mountEffectImpl(Update, Layout, create, deps); 15782 } 15783 15784 function updateLayoutEffect(create, deps) { 15785 return updateEffectImpl(Update, Layout, create, deps); 15786 } 15787 15788 function imperativeHandleEffect(create, ref) { 15789 if (typeof ref === 'function') { 15790 var refCallback = ref; 15791 15792 var _inst = create(); 15793 15794 refCallback(_inst); 15795 return function () { 15796 refCallback(null); 15797 }; 15798 } else if (ref !== null && ref !== undefined) { 15799 var refObject = ref; 15800 15801 { 15802 if (!refObject.hasOwnProperty('current')) { 15803 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(', ') + '}'); 15804 } 15805 } 15806 15807 var _inst2 = create(); 15808 15809 refObject.current = _inst2; 15810 return function () { 15811 refObject.current = null; 15812 }; 15813 } 15814 } 15815 15816 function mountImperativeHandle(ref, create, deps) { 15817 { 15818 if (typeof create !== 'function') { 15819 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null'); 15820 } 15821 } // TODO: If deps are provided, should we skip comparing the ref itself? 15822 15823 15824 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 15825 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 15826 } 15827 15828 function updateImperativeHandle(ref, create, deps) { 15829 { 15830 if (typeof create !== 'function') { 15831 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null'); 15832 } 15833 } // TODO: If deps are provided, should we skip comparing the ref itself? 15834 15835 15836 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 15837 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 15838 } 15839 15840 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op. 15841 // The react-debug-hooks package injects its own implementation 15842 // so that e.g. DevTools can display custom hook values. 15843 } 15844 15845 var updateDebugValue = mountDebugValue; 15846 15847 function mountCallback(callback, deps) { 15848 var hook = mountWorkInProgressHook(); 15849 var nextDeps = deps === undefined ? null : deps; 15850 hook.memoizedState = [callback, nextDeps]; 15851 return callback; 15852 } 15853 15854 function updateCallback(callback, deps) { 15855 var hook = updateWorkInProgressHook(); 15856 var nextDeps = deps === undefined ? null : deps; 15857 var prevState = hook.memoizedState; 15858 15859 if (prevState !== null) { 15860 if (nextDeps !== null) { 15861 var prevDeps = prevState[1]; 15862 15863 if (areHookInputsEqual(nextDeps, prevDeps)) { 15864 return prevState[0]; 15865 } 15866 } 15867 } 15868 15869 hook.memoizedState = [callback, nextDeps]; 15870 return callback; 15871 } 15872 15873 function mountMemo(nextCreate, deps) { 15874 var hook = mountWorkInProgressHook(); 15875 var nextDeps = deps === undefined ? null : deps; 15876 var nextValue = nextCreate(); 15877 hook.memoizedState = [nextValue, nextDeps]; 15878 return nextValue; 15879 } 15880 15881 function updateMemo(nextCreate, deps) { 15882 var hook = updateWorkInProgressHook(); 15883 var nextDeps = deps === undefined ? null : deps; 15884 var prevState = hook.memoizedState; 15885 15886 if (prevState !== null) { 15887 // Assume these are defined. If they're not, areHookInputsEqual will warn. 15888 if (nextDeps !== null) { 15889 var prevDeps = prevState[1]; 15890 15891 if (areHookInputsEqual(nextDeps, prevDeps)) { 15892 return prevState[0]; 15893 } 15894 } 15895 } 15896 15897 var nextValue = nextCreate(); 15898 hook.memoizedState = [nextValue, nextDeps]; 15899 return nextValue; 15900 } 15901 15902 function mountDeferredValue(value) { 15903 var _mountState = mountState(value), 15904 prevValue = _mountState[0], 15905 setValue = _mountState[1]; 15906 15907 mountEffect(function () { 15908 var prevTransition = ReactCurrentBatchConfig$1.transition; 15909 ReactCurrentBatchConfig$1.transition = 1; 15910 15911 try { 15912 setValue(value); 15913 } finally { 15914 ReactCurrentBatchConfig$1.transition = prevTransition; 15915 } 15916 }, [value]); 15917 return prevValue; 15918 } 15919 15920 function updateDeferredValue(value) { 15921 var _updateState = updateState(), 15922 prevValue = _updateState[0], 15923 setValue = _updateState[1]; 15924 15925 updateEffect(function () { 15926 var prevTransition = ReactCurrentBatchConfig$1.transition; 15927 ReactCurrentBatchConfig$1.transition = 1; 15928 15929 try { 15930 setValue(value); 15931 } finally { 15932 ReactCurrentBatchConfig$1.transition = prevTransition; 15933 } 15934 }, [value]); 15935 return prevValue; 15936 } 15937 15938 function rerenderDeferredValue(value) { 15939 var _rerenderState = rerenderState(), 15940 prevValue = _rerenderState[0], 15941 setValue = _rerenderState[1]; 15942 15943 updateEffect(function () { 15944 var prevTransition = ReactCurrentBatchConfig$1.transition; 15945 ReactCurrentBatchConfig$1.transition = 1; 15946 15947 try { 15948 setValue(value); 15949 } finally { 15950 ReactCurrentBatchConfig$1.transition = prevTransition; 15951 } 15952 }, [value]); 15953 return prevValue; 15954 } 15955 15956 function startTransition(setPending, callback) { 15957 var priorityLevel = getCurrentPriorityLevel(); 15958 15959 { 15960 runWithPriority$1(priorityLevel < UserBlockingPriority$2 ? UserBlockingPriority$2 : priorityLevel, function () { 15961 setPending(true); 15962 }); 15963 runWithPriority$1(priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function () { 15964 var prevTransition = ReactCurrentBatchConfig$1.transition; 15965 ReactCurrentBatchConfig$1.transition = 1; 15966 15967 try { 15968 setPending(false); 15969 callback(); 15970 } finally { 15971 ReactCurrentBatchConfig$1.transition = prevTransition; 15972 } 15973 }); 15974 } 15975 } 15976 15977 function mountTransition() { 15978 var _mountState2 = mountState(false), 15979 isPending = _mountState2[0], 15980 setPending = _mountState2[1]; // The `start` method can be stored on a ref, since `setPending` 15981 // never changes. 15982 15983 15984 var start = startTransition.bind(null, setPending); 15985 mountRef(start); 15986 return [start, isPending]; 15987 } 15988 15989 function updateTransition() { 15990 var _updateState2 = updateState(), 15991 isPending = _updateState2[0]; 15992 15993 var startRef = updateRef(); 15994 var start = startRef.current; 15995 return [start, isPending]; 15996 } 15997 15998 function rerenderTransition() { 15999 var _rerenderState2 = rerenderState(), 16000 isPending = _rerenderState2[0]; 16001 16002 var startRef = updateRef(); 16003 var start = startRef.current; 16004 return [start, isPending]; 16005 } 16006 16007 var isUpdatingOpaqueValueInRenderPhase = false; 16008 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() { 16009 { 16010 return isUpdatingOpaqueValueInRenderPhase; 16011 } 16012 } 16013 16014 function warnOnOpaqueIdentifierAccessInDEV(fiber) { 16015 { 16016 // TODO: Should warn in effects and callbacks, too 16017 var name = getComponentName(fiber.type) || 'Unknown'; 16018 16019 if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) { 16020 error('The object passed back from useOpaqueIdentifier is meant to be ' + 'passed through to attributes only. Do not read the ' + 'value directly.'); 16021 16022 didWarnAboutUseOpaqueIdentifier[name] = true; 16023 } 16024 } 16025 } 16026 16027 function mountOpaqueIdentifier() { 16028 var makeId = makeClientIdInDEV.bind(null, warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber$1)) ; 16029 16030 if (getIsHydrating()) { 16031 var didUpgrade = false; 16032 var fiber = currentlyRenderingFiber$1; 16033 16034 var readValue = function () { 16035 if (!didUpgrade) { 16036 // Only upgrade once. This works even inside the render phase because 16037 // the update is added to a shared queue, which outlasts the 16038 // in-progress render. 16039 didUpgrade = true; 16040 16041 { 16042 isUpdatingOpaqueValueInRenderPhase = true; 16043 setId(makeId()); 16044 isUpdatingOpaqueValueInRenderPhase = false; 16045 warnOnOpaqueIdentifierAccessInDEV(fiber); 16046 } 16047 } 16048 16049 { 16050 { 16051 throw Error( "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly." ); 16052 } 16053 } 16054 }; 16055 16056 var id = makeOpaqueHydratingObject(readValue); 16057 var setId = mountState(id)[1]; 16058 16059 if ((currentlyRenderingFiber$1.mode & BlockingMode) === NoMode) { 16060 currentlyRenderingFiber$1.flags |= Update | Passive; 16061 pushEffect(HasEffect | Passive$1, function () { 16062 setId(makeId()); 16063 }, undefined, null); 16064 } 16065 16066 return id; 16067 } else { 16068 var _id = makeId(); 16069 16070 mountState(_id); 16071 return _id; 16072 } 16073 } 16074 16075 function updateOpaqueIdentifier() { 16076 var id = updateState()[0]; 16077 return id; 16078 } 16079 16080 function rerenderOpaqueIdentifier() { 16081 var id = rerenderState()[0]; 16082 return id; 16083 } 16084 16085 function dispatchAction(fiber, queue, action) { 16086 { 16087 if (typeof arguments[3] === 'function') { 16088 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().'); 16089 } 16090 } 16091 16092 var eventTime = requestEventTime(); 16093 var lane = requestUpdateLane(fiber); 16094 var update = { 16095 lane: lane, 16096 action: action, 16097 eagerReducer: null, 16098 eagerState: null, 16099 next: null 16100 }; // Append the update to the end of the list. 16101 16102 var pending = queue.pending; 16103 16104 if (pending === null) { 16105 // This is the first update. Create a circular list. 16106 update.next = update; 16107 } else { 16108 update.next = pending.next; 16109 pending.next = update; 16110 } 16111 16112 queue.pending = update; 16113 var alternate = fiber.alternate; 16114 16115 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) { 16116 // This is a render phase update. Stash it in a lazily-created map of 16117 // queue -> linked list of updates. After this render pass, we'll restart 16118 // and apply the stashed updates on top of the work-in-progress hook. 16119 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; 16120 } else { 16121 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) { 16122 // The queue is currently empty, which means we can eagerly compute the 16123 // next state before entering the render phase. If the new state is the 16124 // same as the current state, we may be able to bail out entirely. 16125 var lastRenderedReducer = queue.lastRenderedReducer; 16126 16127 if (lastRenderedReducer !== null) { 16128 var prevDispatcher; 16129 16130 { 16131 prevDispatcher = ReactCurrentDispatcher$1.current; 16132 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16133 } 16134 16135 try { 16136 var currentState = queue.lastRenderedState; 16137 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute 16138 // it, on the update object. If the reducer hasn't changed by the 16139 // time we enter the render phase, then the eager state can be used 16140 // without calling the reducer again. 16141 16142 update.eagerReducer = lastRenderedReducer; 16143 update.eagerState = eagerState; 16144 16145 if (objectIs(eagerState, currentState)) { 16146 // Fast path. We can bail out without scheduling React to re-render. 16147 // It's still possible that we'll need to rebase this update later, 16148 // if the component re-renders for a different reason and by that 16149 // time the reducer has changed. 16150 return; 16151 } 16152 } catch (error) {// Suppress the error. It will throw again in the render phase. 16153 } finally { 16154 { 16155 ReactCurrentDispatcher$1.current = prevDispatcher; 16156 } 16157 } 16158 } 16159 } 16160 16161 { 16162 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests 16163 if ('undefined' !== typeof jest) { 16164 warnIfNotScopedWithMatchingAct(fiber); 16165 warnIfNotCurrentlyActingUpdatesInDev(fiber); 16166 } 16167 } 16168 16169 scheduleUpdateOnFiber(fiber, lane, eventTime); 16170 } 16171 } 16172 16173 var ContextOnlyDispatcher = { 16174 readContext: readContext, 16175 useCallback: throwInvalidHookError, 16176 useContext: throwInvalidHookError, 16177 useEffect: throwInvalidHookError, 16178 useImperativeHandle: throwInvalidHookError, 16179 useLayoutEffect: throwInvalidHookError, 16180 useMemo: throwInvalidHookError, 16181 useReducer: throwInvalidHookError, 16182 useRef: throwInvalidHookError, 16183 useState: throwInvalidHookError, 16184 useDebugValue: throwInvalidHookError, 16185 useDeferredValue: throwInvalidHookError, 16186 useTransition: throwInvalidHookError, 16187 useMutableSource: throwInvalidHookError, 16188 useOpaqueIdentifier: throwInvalidHookError, 16189 unstable_isNewReconciler: enableNewReconciler 16190 }; 16191 var HooksDispatcherOnMountInDEV = null; 16192 var HooksDispatcherOnMountWithHookTypesInDEV = null; 16193 var HooksDispatcherOnUpdateInDEV = null; 16194 var HooksDispatcherOnRerenderInDEV = null; 16195 var InvalidNestedHooksDispatcherOnMountInDEV = null; 16196 var InvalidNestedHooksDispatcherOnUpdateInDEV = null; 16197 var InvalidNestedHooksDispatcherOnRerenderInDEV = null; 16198 16199 { 16200 var warnInvalidContextAccess = function () { 16201 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().'); 16202 }; 16203 16204 var warnInvalidHookAccess = function () { 16205 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'); 16206 }; 16207 16208 HooksDispatcherOnMountInDEV = { 16209 readContext: function (context, observedBits) { 16210 return readContext(context, observedBits); 16211 }, 16212 useCallback: function (callback, deps) { 16213 currentHookNameInDev = 'useCallback'; 16214 mountHookTypesDev(); 16215 checkDepsAreArrayDev(deps); 16216 return mountCallback(callback, deps); 16217 }, 16218 useContext: function (context, observedBits) { 16219 currentHookNameInDev = 'useContext'; 16220 mountHookTypesDev(); 16221 return readContext(context, observedBits); 16222 }, 16223 useEffect: function (create, deps) { 16224 currentHookNameInDev = 'useEffect'; 16225 mountHookTypesDev(); 16226 checkDepsAreArrayDev(deps); 16227 return mountEffect(create, deps); 16228 }, 16229 useImperativeHandle: function (ref, create, deps) { 16230 currentHookNameInDev = 'useImperativeHandle'; 16231 mountHookTypesDev(); 16232 checkDepsAreArrayDev(deps); 16233 return mountImperativeHandle(ref, create, deps); 16234 }, 16235 useLayoutEffect: function (create, deps) { 16236 currentHookNameInDev = 'useLayoutEffect'; 16237 mountHookTypesDev(); 16238 checkDepsAreArrayDev(deps); 16239 return mountLayoutEffect(create, deps); 16240 }, 16241 useMemo: function (create, deps) { 16242 currentHookNameInDev = 'useMemo'; 16243 mountHookTypesDev(); 16244 checkDepsAreArrayDev(deps); 16245 var prevDispatcher = ReactCurrentDispatcher$1.current; 16246 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16247 16248 try { 16249 return mountMemo(create, deps); 16250 } finally { 16251 ReactCurrentDispatcher$1.current = prevDispatcher; 16252 } 16253 }, 16254 useReducer: function (reducer, initialArg, init) { 16255 currentHookNameInDev = 'useReducer'; 16256 mountHookTypesDev(); 16257 var prevDispatcher = ReactCurrentDispatcher$1.current; 16258 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16259 16260 try { 16261 return mountReducer(reducer, initialArg, init); 16262 } finally { 16263 ReactCurrentDispatcher$1.current = prevDispatcher; 16264 } 16265 }, 16266 useRef: function (initialValue) { 16267 currentHookNameInDev = 'useRef'; 16268 mountHookTypesDev(); 16269 return mountRef(initialValue); 16270 }, 16271 useState: function (initialState) { 16272 currentHookNameInDev = 'useState'; 16273 mountHookTypesDev(); 16274 var prevDispatcher = ReactCurrentDispatcher$1.current; 16275 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16276 16277 try { 16278 return mountState(initialState); 16279 } finally { 16280 ReactCurrentDispatcher$1.current = prevDispatcher; 16281 } 16282 }, 16283 useDebugValue: function (value, formatterFn) { 16284 currentHookNameInDev = 'useDebugValue'; 16285 mountHookTypesDev(); 16286 return mountDebugValue(); 16287 }, 16288 useDeferredValue: function (value) { 16289 currentHookNameInDev = 'useDeferredValue'; 16290 mountHookTypesDev(); 16291 return mountDeferredValue(value); 16292 }, 16293 useTransition: function () { 16294 currentHookNameInDev = 'useTransition'; 16295 mountHookTypesDev(); 16296 return mountTransition(); 16297 }, 16298 useMutableSource: function (source, getSnapshot, subscribe) { 16299 currentHookNameInDev = 'useMutableSource'; 16300 mountHookTypesDev(); 16301 return mountMutableSource(source, getSnapshot, subscribe); 16302 }, 16303 useOpaqueIdentifier: function () { 16304 currentHookNameInDev = 'useOpaqueIdentifier'; 16305 mountHookTypesDev(); 16306 return mountOpaqueIdentifier(); 16307 }, 16308 unstable_isNewReconciler: enableNewReconciler 16309 }; 16310 HooksDispatcherOnMountWithHookTypesInDEV = { 16311 readContext: function (context, observedBits) { 16312 return readContext(context, observedBits); 16313 }, 16314 useCallback: function (callback, deps) { 16315 currentHookNameInDev = 'useCallback'; 16316 updateHookTypesDev(); 16317 return mountCallback(callback, deps); 16318 }, 16319 useContext: function (context, observedBits) { 16320 currentHookNameInDev = 'useContext'; 16321 updateHookTypesDev(); 16322 return readContext(context, observedBits); 16323 }, 16324 useEffect: function (create, deps) { 16325 currentHookNameInDev = 'useEffect'; 16326 updateHookTypesDev(); 16327 return mountEffect(create, deps); 16328 }, 16329 useImperativeHandle: function (ref, create, deps) { 16330 currentHookNameInDev = 'useImperativeHandle'; 16331 updateHookTypesDev(); 16332 return mountImperativeHandle(ref, create, deps); 16333 }, 16334 useLayoutEffect: function (create, deps) { 16335 currentHookNameInDev = 'useLayoutEffect'; 16336 updateHookTypesDev(); 16337 return mountLayoutEffect(create, deps); 16338 }, 16339 useMemo: function (create, deps) { 16340 currentHookNameInDev = 'useMemo'; 16341 updateHookTypesDev(); 16342 var prevDispatcher = ReactCurrentDispatcher$1.current; 16343 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16344 16345 try { 16346 return mountMemo(create, deps); 16347 } finally { 16348 ReactCurrentDispatcher$1.current = prevDispatcher; 16349 } 16350 }, 16351 useReducer: function (reducer, initialArg, init) { 16352 currentHookNameInDev = 'useReducer'; 16353 updateHookTypesDev(); 16354 var prevDispatcher = ReactCurrentDispatcher$1.current; 16355 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16356 16357 try { 16358 return mountReducer(reducer, initialArg, init); 16359 } finally { 16360 ReactCurrentDispatcher$1.current = prevDispatcher; 16361 } 16362 }, 16363 useRef: function (initialValue) { 16364 currentHookNameInDev = 'useRef'; 16365 updateHookTypesDev(); 16366 return mountRef(initialValue); 16367 }, 16368 useState: function (initialState) { 16369 currentHookNameInDev = 'useState'; 16370 updateHookTypesDev(); 16371 var prevDispatcher = ReactCurrentDispatcher$1.current; 16372 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16373 16374 try { 16375 return mountState(initialState); 16376 } finally { 16377 ReactCurrentDispatcher$1.current = prevDispatcher; 16378 } 16379 }, 16380 useDebugValue: function (value, formatterFn) { 16381 currentHookNameInDev = 'useDebugValue'; 16382 updateHookTypesDev(); 16383 return mountDebugValue(); 16384 }, 16385 useDeferredValue: function (value) { 16386 currentHookNameInDev = 'useDeferredValue'; 16387 updateHookTypesDev(); 16388 return mountDeferredValue(value); 16389 }, 16390 useTransition: function () { 16391 currentHookNameInDev = 'useTransition'; 16392 updateHookTypesDev(); 16393 return mountTransition(); 16394 }, 16395 useMutableSource: function (source, getSnapshot, subscribe) { 16396 currentHookNameInDev = 'useMutableSource'; 16397 updateHookTypesDev(); 16398 return mountMutableSource(source, getSnapshot, subscribe); 16399 }, 16400 useOpaqueIdentifier: function () { 16401 currentHookNameInDev = 'useOpaqueIdentifier'; 16402 updateHookTypesDev(); 16403 return mountOpaqueIdentifier(); 16404 }, 16405 unstable_isNewReconciler: enableNewReconciler 16406 }; 16407 HooksDispatcherOnUpdateInDEV = { 16408 readContext: function (context, observedBits) { 16409 return readContext(context, observedBits); 16410 }, 16411 useCallback: function (callback, deps) { 16412 currentHookNameInDev = 'useCallback'; 16413 updateHookTypesDev(); 16414 return updateCallback(callback, deps); 16415 }, 16416 useContext: function (context, observedBits) { 16417 currentHookNameInDev = 'useContext'; 16418 updateHookTypesDev(); 16419 return readContext(context, observedBits); 16420 }, 16421 useEffect: function (create, deps) { 16422 currentHookNameInDev = 'useEffect'; 16423 updateHookTypesDev(); 16424 return updateEffect(create, deps); 16425 }, 16426 useImperativeHandle: function (ref, create, deps) { 16427 currentHookNameInDev = 'useImperativeHandle'; 16428 updateHookTypesDev(); 16429 return updateImperativeHandle(ref, create, deps); 16430 }, 16431 useLayoutEffect: function (create, deps) { 16432 currentHookNameInDev = 'useLayoutEffect'; 16433 updateHookTypesDev(); 16434 return updateLayoutEffect(create, deps); 16435 }, 16436 useMemo: function (create, deps) { 16437 currentHookNameInDev = 'useMemo'; 16438 updateHookTypesDev(); 16439 var prevDispatcher = ReactCurrentDispatcher$1.current; 16440 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16441 16442 try { 16443 return updateMemo(create, deps); 16444 } finally { 16445 ReactCurrentDispatcher$1.current = prevDispatcher; 16446 } 16447 }, 16448 useReducer: function (reducer, initialArg, init) { 16449 currentHookNameInDev = 'useReducer'; 16450 updateHookTypesDev(); 16451 var prevDispatcher = ReactCurrentDispatcher$1.current; 16452 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16453 16454 try { 16455 return updateReducer(reducer, initialArg, init); 16456 } finally { 16457 ReactCurrentDispatcher$1.current = prevDispatcher; 16458 } 16459 }, 16460 useRef: function (initialValue) { 16461 currentHookNameInDev = 'useRef'; 16462 updateHookTypesDev(); 16463 return updateRef(); 16464 }, 16465 useState: function (initialState) { 16466 currentHookNameInDev = 'useState'; 16467 updateHookTypesDev(); 16468 var prevDispatcher = ReactCurrentDispatcher$1.current; 16469 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16470 16471 try { 16472 return updateState(initialState); 16473 } finally { 16474 ReactCurrentDispatcher$1.current = prevDispatcher; 16475 } 16476 }, 16477 useDebugValue: function (value, formatterFn) { 16478 currentHookNameInDev = 'useDebugValue'; 16479 updateHookTypesDev(); 16480 return updateDebugValue(); 16481 }, 16482 useDeferredValue: function (value) { 16483 currentHookNameInDev = 'useDeferredValue'; 16484 updateHookTypesDev(); 16485 return updateDeferredValue(value); 16486 }, 16487 useTransition: function () { 16488 currentHookNameInDev = 'useTransition'; 16489 updateHookTypesDev(); 16490 return updateTransition(); 16491 }, 16492 useMutableSource: function (source, getSnapshot, subscribe) { 16493 currentHookNameInDev = 'useMutableSource'; 16494 updateHookTypesDev(); 16495 return updateMutableSource(source, getSnapshot, subscribe); 16496 }, 16497 useOpaqueIdentifier: function () { 16498 currentHookNameInDev = 'useOpaqueIdentifier'; 16499 updateHookTypesDev(); 16500 return updateOpaqueIdentifier(); 16501 }, 16502 unstable_isNewReconciler: enableNewReconciler 16503 }; 16504 HooksDispatcherOnRerenderInDEV = { 16505 readContext: function (context, observedBits) { 16506 return readContext(context, observedBits); 16507 }, 16508 useCallback: function (callback, deps) { 16509 currentHookNameInDev = 'useCallback'; 16510 updateHookTypesDev(); 16511 return updateCallback(callback, deps); 16512 }, 16513 useContext: function (context, observedBits) { 16514 currentHookNameInDev = 'useContext'; 16515 updateHookTypesDev(); 16516 return readContext(context, observedBits); 16517 }, 16518 useEffect: function (create, deps) { 16519 currentHookNameInDev = 'useEffect'; 16520 updateHookTypesDev(); 16521 return updateEffect(create, deps); 16522 }, 16523 useImperativeHandle: function (ref, create, deps) { 16524 currentHookNameInDev = 'useImperativeHandle'; 16525 updateHookTypesDev(); 16526 return updateImperativeHandle(ref, create, deps); 16527 }, 16528 useLayoutEffect: function (create, deps) { 16529 currentHookNameInDev = 'useLayoutEffect'; 16530 updateHookTypesDev(); 16531 return updateLayoutEffect(create, deps); 16532 }, 16533 useMemo: function (create, deps) { 16534 currentHookNameInDev = 'useMemo'; 16535 updateHookTypesDev(); 16536 var prevDispatcher = ReactCurrentDispatcher$1.current; 16537 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 16538 16539 try { 16540 return updateMemo(create, deps); 16541 } finally { 16542 ReactCurrentDispatcher$1.current = prevDispatcher; 16543 } 16544 }, 16545 useReducer: function (reducer, initialArg, init) { 16546 currentHookNameInDev = 'useReducer'; 16547 updateHookTypesDev(); 16548 var prevDispatcher = ReactCurrentDispatcher$1.current; 16549 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 16550 16551 try { 16552 return rerenderReducer(reducer, initialArg, init); 16553 } finally { 16554 ReactCurrentDispatcher$1.current = prevDispatcher; 16555 } 16556 }, 16557 useRef: function (initialValue) { 16558 currentHookNameInDev = 'useRef'; 16559 updateHookTypesDev(); 16560 return updateRef(); 16561 }, 16562 useState: function (initialState) { 16563 currentHookNameInDev = 'useState'; 16564 updateHookTypesDev(); 16565 var prevDispatcher = ReactCurrentDispatcher$1.current; 16566 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 16567 16568 try { 16569 return rerenderState(initialState); 16570 } finally { 16571 ReactCurrentDispatcher$1.current = prevDispatcher; 16572 } 16573 }, 16574 useDebugValue: function (value, formatterFn) { 16575 currentHookNameInDev = 'useDebugValue'; 16576 updateHookTypesDev(); 16577 return updateDebugValue(); 16578 }, 16579 useDeferredValue: function (value) { 16580 currentHookNameInDev = 'useDeferredValue'; 16581 updateHookTypesDev(); 16582 return rerenderDeferredValue(value); 16583 }, 16584 useTransition: function () { 16585 currentHookNameInDev = 'useTransition'; 16586 updateHookTypesDev(); 16587 return rerenderTransition(); 16588 }, 16589 useMutableSource: function (source, getSnapshot, subscribe) { 16590 currentHookNameInDev = 'useMutableSource'; 16591 updateHookTypesDev(); 16592 return updateMutableSource(source, getSnapshot, subscribe); 16593 }, 16594 useOpaqueIdentifier: function () { 16595 currentHookNameInDev = 'useOpaqueIdentifier'; 16596 updateHookTypesDev(); 16597 return rerenderOpaqueIdentifier(); 16598 }, 16599 unstable_isNewReconciler: enableNewReconciler 16600 }; 16601 InvalidNestedHooksDispatcherOnMountInDEV = { 16602 readContext: function (context, observedBits) { 16603 warnInvalidContextAccess(); 16604 return readContext(context, observedBits); 16605 }, 16606 useCallback: function (callback, deps) { 16607 currentHookNameInDev = 'useCallback'; 16608 warnInvalidHookAccess(); 16609 mountHookTypesDev(); 16610 return mountCallback(callback, deps); 16611 }, 16612 useContext: function (context, observedBits) { 16613 currentHookNameInDev = 'useContext'; 16614 warnInvalidHookAccess(); 16615 mountHookTypesDev(); 16616 return readContext(context, observedBits); 16617 }, 16618 useEffect: function (create, deps) { 16619 currentHookNameInDev = 'useEffect'; 16620 warnInvalidHookAccess(); 16621 mountHookTypesDev(); 16622 return mountEffect(create, deps); 16623 }, 16624 useImperativeHandle: function (ref, create, deps) { 16625 currentHookNameInDev = 'useImperativeHandle'; 16626 warnInvalidHookAccess(); 16627 mountHookTypesDev(); 16628 return mountImperativeHandle(ref, create, deps); 16629 }, 16630 useLayoutEffect: function (create, deps) { 16631 currentHookNameInDev = 'useLayoutEffect'; 16632 warnInvalidHookAccess(); 16633 mountHookTypesDev(); 16634 return mountLayoutEffect(create, deps); 16635 }, 16636 useMemo: function (create, deps) { 16637 currentHookNameInDev = 'useMemo'; 16638 warnInvalidHookAccess(); 16639 mountHookTypesDev(); 16640 var prevDispatcher = ReactCurrentDispatcher$1.current; 16641 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16642 16643 try { 16644 return mountMemo(create, deps); 16645 } finally { 16646 ReactCurrentDispatcher$1.current = prevDispatcher; 16647 } 16648 }, 16649 useReducer: function (reducer, initialArg, init) { 16650 currentHookNameInDev = 'useReducer'; 16651 warnInvalidHookAccess(); 16652 mountHookTypesDev(); 16653 var prevDispatcher = ReactCurrentDispatcher$1.current; 16654 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16655 16656 try { 16657 return mountReducer(reducer, initialArg, init); 16658 } finally { 16659 ReactCurrentDispatcher$1.current = prevDispatcher; 16660 } 16661 }, 16662 useRef: function (initialValue) { 16663 currentHookNameInDev = 'useRef'; 16664 warnInvalidHookAccess(); 16665 mountHookTypesDev(); 16666 return mountRef(initialValue); 16667 }, 16668 useState: function (initialState) { 16669 currentHookNameInDev = 'useState'; 16670 warnInvalidHookAccess(); 16671 mountHookTypesDev(); 16672 var prevDispatcher = ReactCurrentDispatcher$1.current; 16673 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 16674 16675 try { 16676 return mountState(initialState); 16677 } finally { 16678 ReactCurrentDispatcher$1.current = prevDispatcher; 16679 } 16680 }, 16681 useDebugValue: function (value, formatterFn) { 16682 currentHookNameInDev = 'useDebugValue'; 16683 warnInvalidHookAccess(); 16684 mountHookTypesDev(); 16685 return mountDebugValue(); 16686 }, 16687 useDeferredValue: function (value) { 16688 currentHookNameInDev = 'useDeferredValue'; 16689 warnInvalidHookAccess(); 16690 mountHookTypesDev(); 16691 return mountDeferredValue(value); 16692 }, 16693 useTransition: function () { 16694 currentHookNameInDev = 'useTransition'; 16695 warnInvalidHookAccess(); 16696 mountHookTypesDev(); 16697 return mountTransition(); 16698 }, 16699 useMutableSource: function (source, getSnapshot, subscribe) { 16700 currentHookNameInDev = 'useMutableSource'; 16701 warnInvalidHookAccess(); 16702 mountHookTypesDev(); 16703 return mountMutableSource(source, getSnapshot, subscribe); 16704 }, 16705 useOpaqueIdentifier: function () { 16706 currentHookNameInDev = 'useOpaqueIdentifier'; 16707 warnInvalidHookAccess(); 16708 mountHookTypesDev(); 16709 return mountOpaqueIdentifier(); 16710 }, 16711 unstable_isNewReconciler: enableNewReconciler 16712 }; 16713 InvalidNestedHooksDispatcherOnUpdateInDEV = { 16714 readContext: function (context, observedBits) { 16715 warnInvalidContextAccess(); 16716 return readContext(context, observedBits); 16717 }, 16718 useCallback: function (callback, deps) { 16719 currentHookNameInDev = 'useCallback'; 16720 warnInvalidHookAccess(); 16721 updateHookTypesDev(); 16722 return updateCallback(callback, deps); 16723 }, 16724 useContext: function (context, observedBits) { 16725 currentHookNameInDev = 'useContext'; 16726 warnInvalidHookAccess(); 16727 updateHookTypesDev(); 16728 return readContext(context, observedBits); 16729 }, 16730 useEffect: function (create, deps) { 16731 currentHookNameInDev = 'useEffect'; 16732 warnInvalidHookAccess(); 16733 updateHookTypesDev(); 16734 return updateEffect(create, deps); 16735 }, 16736 useImperativeHandle: function (ref, create, deps) { 16737 currentHookNameInDev = 'useImperativeHandle'; 16738 warnInvalidHookAccess(); 16739 updateHookTypesDev(); 16740 return updateImperativeHandle(ref, create, deps); 16741 }, 16742 useLayoutEffect: function (create, deps) { 16743 currentHookNameInDev = 'useLayoutEffect'; 16744 warnInvalidHookAccess(); 16745 updateHookTypesDev(); 16746 return updateLayoutEffect(create, deps); 16747 }, 16748 useMemo: function (create, deps) { 16749 currentHookNameInDev = 'useMemo'; 16750 warnInvalidHookAccess(); 16751 updateHookTypesDev(); 16752 var prevDispatcher = ReactCurrentDispatcher$1.current; 16753 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16754 16755 try { 16756 return updateMemo(create, deps); 16757 } finally { 16758 ReactCurrentDispatcher$1.current = prevDispatcher; 16759 } 16760 }, 16761 useReducer: function (reducer, initialArg, init) { 16762 currentHookNameInDev = 'useReducer'; 16763 warnInvalidHookAccess(); 16764 updateHookTypesDev(); 16765 var prevDispatcher = ReactCurrentDispatcher$1.current; 16766 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16767 16768 try { 16769 return updateReducer(reducer, initialArg, init); 16770 } finally { 16771 ReactCurrentDispatcher$1.current = prevDispatcher; 16772 } 16773 }, 16774 useRef: function (initialValue) { 16775 currentHookNameInDev = 'useRef'; 16776 warnInvalidHookAccess(); 16777 updateHookTypesDev(); 16778 return updateRef(); 16779 }, 16780 useState: function (initialState) { 16781 currentHookNameInDev = 'useState'; 16782 warnInvalidHookAccess(); 16783 updateHookTypesDev(); 16784 var prevDispatcher = ReactCurrentDispatcher$1.current; 16785 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16786 16787 try { 16788 return updateState(initialState); 16789 } finally { 16790 ReactCurrentDispatcher$1.current = prevDispatcher; 16791 } 16792 }, 16793 useDebugValue: function (value, formatterFn) { 16794 currentHookNameInDev = 'useDebugValue'; 16795 warnInvalidHookAccess(); 16796 updateHookTypesDev(); 16797 return updateDebugValue(); 16798 }, 16799 useDeferredValue: function (value) { 16800 currentHookNameInDev = 'useDeferredValue'; 16801 warnInvalidHookAccess(); 16802 updateHookTypesDev(); 16803 return updateDeferredValue(value); 16804 }, 16805 useTransition: function () { 16806 currentHookNameInDev = 'useTransition'; 16807 warnInvalidHookAccess(); 16808 updateHookTypesDev(); 16809 return updateTransition(); 16810 }, 16811 useMutableSource: function (source, getSnapshot, subscribe) { 16812 currentHookNameInDev = 'useMutableSource'; 16813 warnInvalidHookAccess(); 16814 updateHookTypesDev(); 16815 return updateMutableSource(source, getSnapshot, subscribe); 16816 }, 16817 useOpaqueIdentifier: function () { 16818 currentHookNameInDev = 'useOpaqueIdentifier'; 16819 warnInvalidHookAccess(); 16820 updateHookTypesDev(); 16821 return updateOpaqueIdentifier(); 16822 }, 16823 unstable_isNewReconciler: enableNewReconciler 16824 }; 16825 InvalidNestedHooksDispatcherOnRerenderInDEV = { 16826 readContext: function (context, observedBits) { 16827 warnInvalidContextAccess(); 16828 return readContext(context, observedBits); 16829 }, 16830 useCallback: function (callback, deps) { 16831 currentHookNameInDev = 'useCallback'; 16832 warnInvalidHookAccess(); 16833 updateHookTypesDev(); 16834 return updateCallback(callback, deps); 16835 }, 16836 useContext: function (context, observedBits) { 16837 currentHookNameInDev = 'useContext'; 16838 warnInvalidHookAccess(); 16839 updateHookTypesDev(); 16840 return readContext(context, observedBits); 16841 }, 16842 useEffect: function (create, deps) { 16843 currentHookNameInDev = 'useEffect'; 16844 warnInvalidHookAccess(); 16845 updateHookTypesDev(); 16846 return updateEffect(create, deps); 16847 }, 16848 useImperativeHandle: function (ref, create, deps) { 16849 currentHookNameInDev = 'useImperativeHandle'; 16850 warnInvalidHookAccess(); 16851 updateHookTypesDev(); 16852 return updateImperativeHandle(ref, create, deps); 16853 }, 16854 useLayoutEffect: function (create, deps) { 16855 currentHookNameInDev = 'useLayoutEffect'; 16856 warnInvalidHookAccess(); 16857 updateHookTypesDev(); 16858 return updateLayoutEffect(create, deps); 16859 }, 16860 useMemo: function (create, deps) { 16861 currentHookNameInDev = 'useMemo'; 16862 warnInvalidHookAccess(); 16863 updateHookTypesDev(); 16864 var prevDispatcher = ReactCurrentDispatcher$1.current; 16865 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16866 16867 try { 16868 return updateMemo(create, deps); 16869 } finally { 16870 ReactCurrentDispatcher$1.current = prevDispatcher; 16871 } 16872 }, 16873 useReducer: function (reducer, initialArg, init) { 16874 currentHookNameInDev = 'useReducer'; 16875 warnInvalidHookAccess(); 16876 updateHookTypesDev(); 16877 var prevDispatcher = ReactCurrentDispatcher$1.current; 16878 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16879 16880 try { 16881 return rerenderReducer(reducer, initialArg, init); 16882 } finally { 16883 ReactCurrentDispatcher$1.current = prevDispatcher; 16884 } 16885 }, 16886 useRef: function (initialValue) { 16887 currentHookNameInDev = 'useRef'; 16888 warnInvalidHookAccess(); 16889 updateHookTypesDev(); 16890 return updateRef(); 16891 }, 16892 useState: function (initialState) { 16893 currentHookNameInDev = 'useState'; 16894 warnInvalidHookAccess(); 16895 updateHookTypesDev(); 16896 var prevDispatcher = ReactCurrentDispatcher$1.current; 16897 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 16898 16899 try { 16900 return rerenderState(initialState); 16901 } finally { 16902 ReactCurrentDispatcher$1.current = prevDispatcher; 16903 } 16904 }, 16905 useDebugValue: function (value, formatterFn) { 16906 currentHookNameInDev = 'useDebugValue'; 16907 warnInvalidHookAccess(); 16908 updateHookTypesDev(); 16909 return updateDebugValue(); 16910 }, 16911 useDeferredValue: function (value) { 16912 currentHookNameInDev = 'useDeferredValue'; 16913 warnInvalidHookAccess(); 16914 updateHookTypesDev(); 16915 return rerenderDeferredValue(value); 16916 }, 16917 useTransition: function () { 16918 currentHookNameInDev = 'useTransition'; 16919 warnInvalidHookAccess(); 16920 updateHookTypesDev(); 16921 return rerenderTransition(); 16922 }, 16923 useMutableSource: function (source, getSnapshot, subscribe) { 16924 currentHookNameInDev = 'useMutableSource'; 16925 warnInvalidHookAccess(); 16926 updateHookTypesDev(); 16927 return updateMutableSource(source, getSnapshot, subscribe); 16928 }, 16929 useOpaqueIdentifier: function () { 16930 currentHookNameInDev = 'useOpaqueIdentifier'; 16931 warnInvalidHookAccess(); 16932 updateHookTypesDev(); 16933 return rerenderOpaqueIdentifier(); 16934 }, 16935 unstable_isNewReconciler: enableNewReconciler 16936 }; 16937 } 16938 16939 var now$1 = unstable_now; 16940 var commitTime = 0; 16941 var profilerStartTime = -1; 16942 16943 function getCommitTime() { 16944 return commitTime; 16945 } 16946 16947 function recordCommitTime() { 16948 16949 commitTime = now$1(); 16950 } 16951 16952 function startProfilerTimer(fiber) { 16953 16954 profilerStartTime = now$1(); 16955 16956 if (fiber.actualStartTime < 0) { 16957 fiber.actualStartTime = now$1(); 16958 } 16959 } 16960 16961 function stopProfilerTimerIfRunning(fiber) { 16962 16963 profilerStartTime = -1; 16964 } 16965 16966 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { 16967 16968 if (profilerStartTime >= 0) { 16969 var elapsedTime = now$1() - profilerStartTime; 16970 fiber.actualDuration += elapsedTime; 16971 16972 if (overrideBaseTime) { 16973 fiber.selfBaseDuration = elapsedTime; 16974 } 16975 16976 profilerStartTime = -1; 16977 } 16978 } 16979 16980 function transferActualDuration(fiber) { 16981 // Transfer time spent rendering these children so we don't lose it 16982 // after we rerender. This is used as a helper in special cases 16983 // where we should count the work of multiple passes. 16984 var child = fiber.child; 16985 16986 while (child) { 16987 fiber.actualDuration += child.actualDuration; 16988 child = child.sibling; 16989 } 16990 } 16991 16992 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; 16993 var didReceiveUpdate = false; 16994 var didWarnAboutBadClass; 16995 var didWarnAboutModulePatternComponent; 16996 var didWarnAboutContextTypeOnFunctionComponent; 16997 var didWarnAboutGetDerivedStateOnFunctionComponent; 16998 var didWarnAboutFunctionRefs; 16999 var didWarnAboutReassigningProps; 17000 var didWarnAboutRevealOrder; 17001 var didWarnAboutTailOptions; 17002 17003 { 17004 didWarnAboutBadClass = {}; 17005 didWarnAboutModulePatternComponent = {}; 17006 didWarnAboutContextTypeOnFunctionComponent = {}; 17007 didWarnAboutGetDerivedStateOnFunctionComponent = {}; 17008 didWarnAboutFunctionRefs = {}; 17009 didWarnAboutReassigningProps = false; 17010 didWarnAboutRevealOrder = {}; 17011 didWarnAboutTailOptions = {}; 17012 } 17013 17014 function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { 17015 if (current === null) { 17016 // If this is a fresh new component that hasn't been rendered yet, we 17017 // won't update its child set by applying minimal side-effects. Instead, 17018 // we will add them all to the child before it gets rendered. That means 17019 // we can optimize this reconciliation pass by not tracking side-effects. 17020 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); 17021 } else { 17022 // If the current child is the same as the work in progress, it means that 17023 // we haven't yet started any work on these children. Therefore, we use 17024 // the clone algorithm to create a copy of all the current children. 17025 // If we had any progressed work already, that is invalid at this point so 17026 // let's throw it out. 17027 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes); 17028 } 17029 } 17030 17031 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) { 17032 // This function is fork of reconcileChildren. It's used in cases where we 17033 // want to reconcile without matching against the existing set. This has the 17034 // effect of all current children being unmounted; even if the type and key 17035 // are the same, the old child is unmounted and a new child is created. 17036 // 17037 // To do this, we're going to go through the reconcile algorithm twice. In 17038 // the first pass, we schedule a deletion for all the current children by 17039 // passing null. 17040 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we 17041 // pass null in place of where we usually pass the current child set. This has 17042 // the effect of remounting all children regardless of whether their 17043 // identities match. 17044 17045 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); 17046 } 17047 17048 function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) { 17049 // TODO: current can be non-null here even if the component 17050 // hasn't yet mounted. This happens after the first render suspends. 17051 // We'll need to figure out if this is fine or can cause issues. 17052 { 17053 if (workInProgress.type !== workInProgress.elementType) { 17054 // Lazy component props can't be validated in createElement 17055 // because they're only guaranteed to be resolved here. 17056 var innerPropTypes = Component.propTypes; 17057 17058 if (innerPropTypes) { 17059 checkPropTypes(innerPropTypes, nextProps, // Resolved props 17060 'prop', getComponentName(Component)); 17061 } 17062 } 17063 } 17064 17065 var render = Component.render; 17066 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent 17067 17068 var nextChildren; 17069 prepareToReadContext(workInProgress, renderLanes); 17070 17071 { 17072 ReactCurrentOwner$1.current = workInProgress; 17073 setIsRendering(true); 17074 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); 17075 17076 if ( workInProgress.mode & StrictMode) { 17077 disableLogs(); 17078 17079 try { 17080 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); 17081 } finally { 17082 reenableLogs(); 17083 } 17084 } 17085 17086 setIsRendering(false); 17087 } 17088 17089 if (current !== null && !didReceiveUpdate) { 17090 bailoutHooks(current, workInProgress, renderLanes); 17091 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17092 } // React DevTools reads this flag. 17093 17094 17095 workInProgress.flags |= PerformedWork; 17096 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17097 return workInProgress.child; 17098 } 17099 17100 function updateMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) { 17101 if (current === null) { 17102 var type = Component.type; 17103 17104 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. 17105 Component.defaultProps === undefined) { 17106 var resolvedType = type; 17107 17108 { 17109 resolvedType = resolveFunctionForHotReloading(type); 17110 } // If this is a plain function component without default props, 17111 // and with only the default shallow comparison, we upgrade it 17112 // to a SimpleMemoComponent to allow fast path updates. 17113 17114 17115 workInProgress.tag = SimpleMemoComponent; 17116 workInProgress.type = resolvedType; 17117 17118 { 17119 validateFunctionComponentInDev(workInProgress, type); 17120 } 17121 17122 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateLanes, renderLanes); 17123 } 17124 17125 { 17126 var innerPropTypes = type.propTypes; 17127 17128 if (innerPropTypes) { 17129 // Inner memo component props aren't currently validated in createElement. 17130 // We could move it there, but we'd still need this for lazy code path. 17131 checkPropTypes(innerPropTypes, nextProps, // Resolved props 17132 'prop', getComponentName(type)); 17133 } 17134 } 17135 17136 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes); 17137 child.ref = workInProgress.ref; 17138 child.return = workInProgress; 17139 workInProgress.child = child; 17140 return child; 17141 } 17142 17143 { 17144 var _type = Component.type; 17145 var _innerPropTypes = _type.propTypes; 17146 17147 if (_innerPropTypes) { 17148 // Inner memo component props aren't currently validated in createElement. 17149 // We could move it there, but we'd still need this for lazy code path. 17150 checkPropTypes(_innerPropTypes, nextProps, // Resolved props 17151 'prop', getComponentName(_type)); 17152 } 17153 } 17154 17155 var currentChild = current.child; // This is always exactly one child 17156 17157 if (!includesSomeLane(updateLanes, renderLanes)) { 17158 // This will be the props with resolved defaultProps, 17159 // unlike current.memoizedProps which will be the unresolved ones. 17160 var prevProps = currentChild.memoizedProps; // Default to shallow comparison 17161 17162 var compare = Component.compare; 17163 compare = compare !== null ? compare : shallowEqual; 17164 17165 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { 17166 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17167 } 17168 } // React DevTools reads this flag. 17169 17170 17171 workInProgress.flags |= PerformedWork; 17172 var newChild = createWorkInProgress(currentChild, nextProps); 17173 newChild.ref = workInProgress.ref; 17174 newChild.return = workInProgress; 17175 workInProgress.child = newChild; 17176 return newChild; 17177 } 17178 17179 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) { 17180 // TODO: current can be non-null here even if the component 17181 // hasn't yet mounted. This happens when the inner render suspends. 17182 // We'll need to figure out if this is fine or can cause issues. 17183 { 17184 if (workInProgress.type !== workInProgress.elementType) { 17185 // Lazy component props can't be validated in createElement 17186 // because they're only guaranteed to be resolved here. 17187 var outerMemoType = workInProgress.elementType; 17188 17189 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { 17190 // We warn when you define propTypes on lazy() 17191 // so let's just skip over it to find memo() outer wrapper. 17192 // Inner props for memo are validated later. 17193 var lazyComponent = outerMemoType; 17194 var payload = lazyComponent._payload; 17195 var init = lazyComponent._init; 17196 17197 try { 17198 outerMemoType = init(payload); 17199 } catch (x) { 17200 outerMemoType = null; 17201 } // Inner propTypes will be validated in the function component path. 17202 17203 17204 var outerPropTypes = outerMemoType && outerMemoType.propTypes; 17205 17206 if (outerPropTypes) { 17207 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) 17208 'prop', getComponentName(outerMemoType)); 17209 } 17210 } 17211 } 17212 } 17213 17214 if (current !== null) { 17215 var prevProps = current.memoizedProps; 17216 17217 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload. 17218 workInProgress.type === current.type )) { 17219 didReceiveUpdate = false; 17220 17221 if (!includesSomeLane(renderLanes, updateLanes)) { 17222 // The pending lanes were cleared at the beginning of beginWork. We're 17223 // about to bail out, but there might be other lanes that weren't 17224 // included in the current render. Usually, the priority level of the 17225 // remaining updates is accumlated during the evaluation of the 17226 // component (i.e. when processing the update queue). But since since 17227 // we're bailing out early *without* evaluating the component, we need 17228 // to account for it here, too. Reset to the value of the current fiber. 17229 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, 17230 // because a MemoComponent fiber does not have hooks or an update queue; 17231 // rather, it wraps around an inner component, which may or may not 17232 // contains hooks. 17233 // TODO: Move the reset at in beginWork out of the common path so that 17234 // this is no longer necessary. 17235 workInProgress.lanes = current.lanes; 17236 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17237 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { 17238 // This is a special case that only exists for legacy mode. 17239 // See https://github.com/facebook/react/pull/19216. 17240 didReceiveUpdate = true; 17241 } 17242 } 17243 } 17244 17245 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes); 17246 } 17247 17248 function updateOffscreenComponent(current, workInProgress, renderLanes) { 17249 var nextProps = workInProgress.pendingProps; 17250 var nextChildren = nextProps.children; 17251 var prevState = current !== null ? current.memoizedState : null; 17252 17253 if (nextProps.mode === 'hidden' || nextProps.mode === 'unstable-defer-without-hiding') { 17254 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 17255 // In legacy sync mode, don't defer the subtree. Render it now. 17256 // TODO: Figure out what we should do in Blocking mode. 17257 var nextState = { 17258 baseLanes: NoLanes 17259 }; 17260 workInProgress.memoizedState = nextState; 17261 pushRenderLanes(workInProgress, renderLanes); 17262 } else if (!includesSomeLane(renderLanes, OffscreenLane)) { 17263 var nextBaseLanes; 17264 17265 if (prevState !== null) { 17266 var prevBaseLanes = prevState.baseLanes; 17267 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); 17268 } else { 17269 nextBaseLanes = renderLanes; 17270 } // Schedule this fiber to re-render at offscreen priority. Then bailout. 17271 17272 17273 { 17274 markSpawnedWork(OffscreenLane); 17275 } 17276 17277 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane); 17278 var _nextState = { 17279 baseLanes: nextBaseLanes 17280 }; 17281 workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway 17282 // to avoid a push/pop misalignment. 17283 17284 pushRenderLanes(workInProgress, nextBaseLanes); 17285 return null; 17286 } else { 17287 // Rendering at offscreen, so we can clear the base lanes. 17288 var _nextState2 = { 17289 baseLanes: NoLanes 17290 }; 17291 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. 17292 17293 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes; 17294 pushRenderLanes(workInProgress, subtreeRenderLanes); 17295 } 17296 } else { 17297 var _subtreeRenderLanes; 17298 17299 if (prevState !== null) { 17300 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state 17301 17302 workInProgress.memoizedState = null; 17303 } else { 17304 // We weren't previously hidden, and we still aren't, so there's nothing 17305 // special to do. Need to push to the stack regardless, though, to avoid 17306 // a push/pop misalignment. 17307 _subtreeRenderLanes = renderLanes; 17308 } 17309 17310 pushRenderLanes(workInProgress, _subtreeRenderLanes); 17311 } 17312 17313 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17314 return workInProgress.child; 17315 } // Note: These happen to have identical begin phases, for now. We shouldn't hold 17316 // ourselves to this constraint, though. If the behavior diverges, we should 17317 // fork the function. 17318 17319 17320 var updateLegacyHiddenComponent = updateOffscreenComponent; 17321 17322 function updateFragment(current, workInProgress, renderLanes) { 17323 var nextChildren = workInProgress.pendingProps; 17324 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17325 return workInProgress.child; 17326 } 17327 17328 function updateMode(current, workInProgress, renderLanes) { 17329 var nextChildren = workInProgress.pendingProps.children; 17330 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17331 return workInProgress.child; 17332 } 17333 17334 function updateProfiler(current, workInProgress, renderLanes) { 17335 { 17336 workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. 17337 // These are reset during render to allow the DevTools commit hook a chance to read them, 17338 17339 var stateNode = workInProgress.stateNode; 17340 stateNode.effectDuration = 0; 17341 stateNode.passiveEffectDuration = 0; 17342 } 17343 17344 var nextProps = workInProgress.pendingProps; 17345 var nextChildren = nextProps.children; 17346 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17347 return workInProgress.child; 17348 } 17349 17350 function markRef(current, workInProgress) { 17351 var ref = workInProgress.ref; 17352 17353 if (current === null && ref !== null || current !== null && current.ref !== ref) { 17354 // Schedule a Ref effect 17355 workInProgress.flags |= Ref; 17356 } 17357 } 17358 17359 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) { 17360 { 17361 if (workInProgress.type !== workInProgress.elementType) { 17362 // Lazy component props can't be validated in createElement 17363 // because they're only guaranteed to be resolved here. 17364 var innerPropTypes = Component.propTypes; 17365 17366 if (innerPropTypes) { 17367 checkPropTypes(innerPropTypes, nextProps, // Resolved props 17368 'prop', getComponentName(Component)); 17369 } 17370 } 17371 } 17372 17373 var context; 17374 17375 { 17376 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); 17377 context = getMaskedContext(workInProgress, unmaskedContext); 17378 } 17379 17380 var nextChildren; 17381 prepareToReadContext(workInProgress, renderLanes); 17382 17383 { 17384 ReactCurrentOwner$1.current = workInProgress; 17385 setIsRendering(true); 17386 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); 17387 17388 if ( workInProgress.mode & StrictMode) { 17389 disableLogs(); 17390 17391 try { 17392 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); 17393 } finally { 17394 reenableLogs(); 17395 } 17396 } 17397 17398 setIsRendering(false); 17399 } 17400 17401 if (current !== null && !didReceiveUpdate) { 17402 bailoutHooks(current, workInProgress, renderLanes); 17403 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17404 } // React DevTools reads this flag. 17405 17406 17407 workInProgress.flags |= PerformedWork; 17408 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17409 return workInProgress.child; 17410 } 17411 17412 function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) { 17413 { 17414 if (workInProgress.type !== workInProgress.elementType) { 17415 // Lazy component props can't be validated in createElement 17416 // because they're only guaranteed to be resolved here. 17417 var innerPropTypes = Component.propTypes; 17418 17419 if (innerPropTypes) { 17420 checkPropTypes(innerPropTypes, nextProps, // Resolved props 17421 'prop', getComponentName(Component)); 17422 } 17423 } 17424 } // Push context providers early to prevent context stack mismatches. 17425 // During mounting we don't know the child context yet as the instance doesn't exist. 17426 // We will invalidate the child context in finishClassComponent() right after rendering. 17427 17428 17429 var hasContext; 17430 17431 if (isContextProvider(Component)) { 17432 hasContext = true; 17433 pushContextProvider(workInProgress); 17434 } else { 17435 hasContext = false; 17436 } 17437 17438 prepareToReadContext(workInProgress, renderLanes); 17439 var instance = workInProgress.stateNode; 17440 var shouldUpdate; 17441 17442 if (instance === null) { 17443 if (current !== null) { 17444 // A class component without an instance only mounts if it suspended 17445 // inside a non-concurrent tree, in an inconsistent state. We want to 17446 // treat it like a new mount, even though an empty version of it already 17447 // committed. Disconnect the alternate pointers. 17448 current.alternate = null; 17449 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect 17450 17451 workInProgress.flags |= Placement; 17452 } // In the initial pass we might need to construct the instance. 17453 17454 17455 constructClassInstance(workInProgress, Component, nextProps); 17456 mountClassInstance(workInProgress, Component, nextProps, renderLanes); 17457 shouldUpdate = true; 17458 } else if (current === null) { 17459 // In a resume, we'll already have an instance we can reuse. 17460 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes); 17461 } else { 17462 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes); 17463 } 17464 17465 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes); 17466 17467 { 17468 var inst = workInProgress.stateNode; 17469 17470 if (shouldUpdate && inst.props !== nextProps) { 17471 if (!didWarnAboutReassigningProps) { 17472 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component'); 17473 } 17474 17475 didWarnAboutReassigningProps = true; 17476 } 17477 } 17478 17479 return nextUnitOfWork; 17480 } 17481 17482 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) { 17483 // Refs should update even if shouldComponentUpdate returns false 17484 markRef(current, workInProgress); 17485 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; 17486 17487 if (!shouldUpdate && !didCaptureError) { 17488 // Context providers should defer to sCU for rendering 17489 if (hasContext) { 17490 invalidateContextProvider(workInProgress, Component, false); 17491 } 17492 17493 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17494 } 17495 17496 var instance = workInProgress.stateNode; // Rerender 17497 17498 ReactCurrentOwner$1.current = workInProgress; 17499 var nextChildren; 17500 17501 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') { 17502 // If we captured an error, but getDerivedStateFromError is not defined, 17503 // unmount all the children. componentDidCatch will schedule an update to 17504 // re-render a fallback. This is temporary until we migrate everyone to 17505 // the new API. 17506 // TODO: Warn in a future release. 17507 nextChildren = null; 17508 17509 { 17510 stopProfilerTimerIfRunning(); 17511 } 17512 } else { 17513 { 17514 setIsRendering(true); 17515 nextChildren = instance.render(); 17516 17517 if ( workInProgress.mode & StrictMode) { 17518 disableLogs(); 17519 17520 try { 17521 instance.render(); 17522 } finally { 17523 reenableLogs(); 17524 } 17525 } 17526 17527 setIsRendering(false); 17528 } 17529 } // React DevTools reads this flag. 17530 17531 17532 workInProgress.flags |= PerformedWork; 17533 17534 if (current !== null && didCaptureError) { 17535 // If we're recovering from an error, reconcile without reusing any of 17536 // the existing children. Conceptually, the normal children and the children 17537 // that are shown on error are two different sets, so we shouldn't reuse 17538 // normal children even if their identities match. 17539 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes); 17540 } else { 17541 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17542 } // Memoize state using the values we just used to render. 17543 // TODO: Restructure so we never read values from the instance. 17544 17545 17546 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. 17547 17548 if (hasContext) { 17549 invalidateContextProvider(workInProgress, Component, true); 17550 } 17551 17552 return workInProgress.child; 17553 } 17554 17555 function pushHostRootContext(workInProgress) { 17556 var root = workInProgress.stateNode; 17557 17558 if (root.pendingContext) { 17559 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context); 17560 } else if (root.context) { 17561 // Should always be set 17562 pushTopLevelContextObject(workInProgress, root.context, false); 17563 } 17564 17565 pushHostContainer(workInProgress, root.containerInfo); 17566 } 17567 17568 function updateHostRoot(current, workInProgress, renderLanes) { 17569 pushHostRootContext(workInProgress); 17570 var updateQueue = workInProgress.updateQueue; 17571 17572 if (!(current !== null && updateQueue !== null)) { 17573 { 17574 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); 17575 } 17576 } 17577 17578 var nextProps = workInProgress.pendingProps; 17579 var prevState = workInProgress.memoizedState; 17580 var prevChildren = prevState !== null ? prevState.element : null; 17581 cloneUpdateQueue(current, workInProgress); 17582 processUpdateQueue(workInProgress, nextProps, null, renderLanes); 17583 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property 17584 // being called "element". 17585 17586 var nextChildren = nextState.element; 17587 17588 if (nextChildren === prevChildren) { 17589 resetHydrationState(); 17590 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 17591 } 17592 17593 var root = workInProgress.stateNode; 17594 17595 if (root.hydrate && enterHydrationState(workInProgress)) { 17596 // If we don't have any current children this might be the first pass. 17597 // We always try to hydrate. If this isn't a hydration pass there won't 17598 // be any children to hydrate which is effectively the same thing as 17599 // not hydrating. 17600 { 17601 var mutableSourceEagerHydrationData = root.mutableSourceEagerHydrationData; 17602 17603 if (mutableSourceEagerHydrationData != null) { 17604 for (var i = 0; i < mutableSourceEagerHydrationData.length; i += 2) { 17605 var mutableSource = mutableSourceEagerHydrationData[i]; 17606 var version = mutableSourceEagerHydrationData[i + 1]; 17607 setWorkInProgressVersion(mutableSource, version); 17608 } 17609 } 17610 } 17611 17612 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); 17613 workInProgress.child = child; 17614 var node = child; 17615 17616 while (node) { 17617 // Mark each child as hydrating. This is a fast path to know whether this 17618 // tree is part of a hydrating tree. This is used to determine if a child 17619 // node has fully mounted yet, and for scheduling event replaying. 17620 // Conceptually this is similar to Placement in that a new subtree is 17621 // inserted into the React tree here. It just happens to not need DOM 17622 // mutations because it already exists. 17623 node.flags = node.flags & ~Placement | Hydrating; 17624 node = node.sibling; 17625 } 17626 } else { 17627 // Otherwise reset hydration state in case we aborted and resumed another 17628 // root. 17629 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17630 resetHydrationState(); 17631 } 17632 17633 return workInProgress.child; 17634 } 17635 17636 function updateHostComponent(current, workInProgress, renderLanes) { 17637 pushHostContext(workInProgress); 17638 17639 if (current === null) { 17640 tryToClaimNextHydratableInstance(workInProgress); 17641 } 17642 17643 var type = workInProgress.type; 17644 var nextProps = workInProgress.pendingProps; 17645 var prevProps = current !== null ? current.memoizedProps : null; 17646 var nextChildren = nextProps.children; 17647 var isDirectTextChild = shouldSetTextContent(type, nextProps); 17648 17649 if (isDirectTextChild) { 17650 // We special case a direct text child of a host node. This is a common 17651 // case. We won't handle it as a reified child. We will instead handle 17652 // this in the host environment that also has access to this prop. That 17653 // avoids allocating another HostText fiber and traversing it. 17654 nextChildren = null; 17655 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { 17656 // If we're switching from a direct text child to a normal child, or to 17657 // empty, we need to schedule the text content to be reset. 17658 workInProgress.flags |= ContentReset; 17659 } 17660 17661 markRef(current, workInProgress); 17662 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 17663 return workInProgress.child; 17664 } 17665 17666 function updateHostText(current, workInProgress) { 17667 if (current === null) { 17668 tryToClaimNextHydratableInstance(workInProgress); 17669 } // Nothing to do here. This is terminal. We'll do the completion step 17670 // immediately after. 17671 17672 17673 return null; 17674 } 17675 17676 function mountLazyComponent(_current, workInProgress, elementType, updateLanes, renderLanes) { 17677 if (_current !== null) { 17678 // A lazy component only mounts if it suspended inside a non- 17679 // concurrent tree, in an inconsistent state. We want to treat it like 17680 // a new mount, even though an empty version of it already committed. 17681 // Disconnect the alternate pointers. 17682 _current.alternate = null; 17683 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect 17684 17685 workInProgress.flags |= Placement; 17686 } 17687 17688 var props = workInProgress.pendingProps; 17689 var lazyComponent = elementType; 17690 var payload = lazyComponent._payload; 17691 var init = lazyComponent._init; 17692 var Component = init(payload); // Store the unwrapped component in the type. 17693 17694 workInProgress.type = Component; 17695 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component); 17696 var resolvedProps = resolveDefaultProps(Component, props); 17697 var child; 17698 17699 switch (resolvedTag) { 17700 case FunctionComponent: 17701 { 17702 { 17703 validateFunctionComponentInDev(workInProgress, Component); 17704 workInProgress.type = Component = resolveFunctionForHotReloading(Component); 17705 } 17706 17707 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes); 17708 return child; 17709 } 17710 17711 case ClassComponent: 17712 { 17713 { 17714 workInProgress.type = Component = resolveClassForHotReloading(Component); 17715 } 17716 17717 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes); 17718 return child; 17719 } 17720 17721 case ForwardRef: 17722 { 17723 { 17724 workInProgress.type = Component = resolveForwardRefForHotReloading(Component); 17725 } 17726 17727 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes); 17728 return child; 17729 } 17730 17731 case MemoComponent: 17732 { 17733 { 17734 if (workInProgress.type !== workInProgress.elementType) { 17735 var outerPropTypes = Component.propTypes; 17736 17737 if (outerPropTypes) { 17738 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only 17739 'prop', getComponentName(Component)); 17740 } 17741 } 17742 } 17743 17744 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too 17745 updateLanes, renderLanes); 17746 return child; 17747 } 17748 } 17749 17750 var hint = ''; 17751 17752 { 17753 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) { 17754 hint = ' Did you wrap a component in React.lazy() more than once?'; 17755 } 17756 } // This message intentionally doesn't mention ForwardRef or MemoComponent 17757 // because the fact that it's a separate type of work is an 17758 // implementation detail. 17759 17760 17761 { 17762 { 17763 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint ); 17764 } 17765 } 17766 } 17767 17768 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) { 17769 if (_current !== null) { 17770 // An incomplete component only mounts if it suspended inside a non- 17771 // concurrent tree, in an inconsistent state. We want to treat it like 17772 // a new mount, even though an empty version of it already committed. 17773 // Disconnect the alternate pointers. 17774 _current.alternate = null; 17775 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect 17776 17777 workInProgress.flags |= Placement; 17778 } // Promote the fiber to a class and try rendering again. 17779 17780 17781 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` 17782 // Push context providers early to prevent context stack mismatches. 17783 // During mounting we don't know the child context yet as the instance doesn't exist. 17784 // We will invalidate the child context in finishClassComponent() right after rendering. 17785 17786 var hasContext; 17787 17788 if (isContextProvider(Component)) { 17789 hasContext = true; 17790 pushContextProvider(workInProgress); 17791 } else { 17792 hasContext = false; 17793 } 17794 17795 prepareToReadContext(workInProgress, renderLanes); 17796 constructClassInstance(workInProgress, Component, nextProps); 17797 mountClassInstance(workInProgress, Component, nextProps, renderLanes); 17798 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); 17799 } 17800 17801 function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) { 17802 if (_current !== null) { 17803 // An indeterminate component only mounts if it suspended inside a non- 17804 // concurrent tree, in an inconsistent state. We want to treat it like 17805 // a new mount, even though an empty version of it already committed. 17806 // Disconnect the alternate pointers. 17807 _current.alternate = null; 17808 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect 17809 17810 workInProgress.flags |= Placement; 17811 } 17812 17813 var props = workInProgress.pendingProps; 17814 var context; 17815 17816 { 17817 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); 17818 context = getMaskedContext(workInProgress, unmaskedContext); 17819 } 17820 17821 prepareToReadContext(workInProgress, renderLanes); 17822 var value; 17823 17824 { 17825 if (Component.prototype && typeof Component.prototype.render === 'function') { 17826 var componentName = getComponentName(Component) || 'Unknown'; 17827 17828 if (!didWarnAboutBadClass[componentName]) { 17829 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); 17830 17831 didWarnAboutBadClass[componentName] = true; 17832 } 17833 } 17834 17835 if (workInProgress.mode & StrictMode) { 17836 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); 17837 } 17838 17839 setIsRendering(true); 17840 ReactCurrentOwner$1.current = workInProgress; 17841 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); 17842 setIsRendering(false); 17843 } // React DevTools reads this flag. 17844 17845 17846 workInProgress.flags |= PerformedWork; 17847 17848 { 17849 // Support for module components is deprecated and is removed behind a flag. 17850 // Whether or not it would crash later, we want to show a good message in DEV first. 17851 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 17852 var _componentName = getComponentName(Component) || 'Unknown'; 17853 17854 if (!didWarnAboutModulePatternComponent[_componentName]) { 17855 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); 17856 17857 didWarnAboutModulePatternComponent[_componentName] = true; 17858 } 17859 } 17860 } 17861 17862 if ( // Run these checks in production only if the flag is off. 17863 // Eventually we'll delete this branch altogether. 17864 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 17865 { 17866 var _componentName2 = getComponentName(Component) || 'Unknown'; 17867 17868 if (!didWarnAboutModulePatternComponent[_componentName2]) { 17869 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); 17870 17871 didWarnAboutModulePatternComponent[_componentName2] = true; 17872 } 17873 } // Proceed under the assumption that this is a class instance 17874 17875 17876 workInProgress.tag = ClassComponent; // Throw out any hooks that were used. 17877 17878 workInProgress.memoizedState = null; 17879 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. 17880 // During mounting we don't know the child context yet as the instance doesn't exist. 17881 // We will invalidate the child context in finishClassComponent() right after rendering. 17882 17883 var hasContext = false; 17884 17885 if (isContextProvider(Component)) { 17886 hasContext = true; 17887 pushContextProvider(workInProgress); 17888 } else { 17889 hasContext = false; 17890 } 17891 17892 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; 17893 initializeUpdateQueue(workInProgress); 17894 var getDerivedStateFromProps = Component.getDerivedStateFromProps; 17895 17896 if (typeof getDerivedStateFromProps === 'function') { 17897 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props); 17898 } 17899 17900 adoptClassInstance(workInProgress, value); 17901 mountClassInstance(workInProgress, Component, props, renderLanes); 17902 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); 17903 } else { 17904 // Proceed under the assumption that this is a function component 17905 workInProgress.tag = FunctionComponent; 17906 17907 { 17908 17909 if ( workInProgress.mode & StrictMode) { 17910 disableLogs(); 17911 17912 try { 17913 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); 17914 } finally { 17915 reenableLogs(); 17916 } 17917 } 17918 } 17919 17920 reconcileChildren(null, workInProgress, value, renderLanes); 17921 17922 { 17923 validateFunctionComponentInDev(workInProgress, Component); 17924 } 17925 17926 return workInProgress.child; 17927 } 17928 } 17929 17930 function validateFunctionComponentInDev(workInProgress, Component) { 17931 { 17932 if (Component) { 17933 if (Component.childContextTypes) { 17934 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component'); 17935 } 17936 } 17937 17938 if (workInProgress.ref !== null) { 17939 var info = ''; 17940 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 17941 17942 if (ownerName) { 17943 info += '\n\nCheck the render method of `' + ownerName + '`.'; 17944 } 17945 17946 var warningKey = ownerName || workInProgress._debugID || ''; 17947 var debugSource = workInProgress._debugSource; 17948 17949 if (debugSource) { 17950 warningKey = debugSource.fileName + ':' + debugSource.lineNumber; 17951 } 17952 17953 if (!didWarnAboutFunctionRefs[warningKey]) { 17954 didWarnAboutFunctionRefs[warningKey] = true; 17955 17956 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info); 17957 } 17958 } 17959 17960 if (typeof Component.getDerivedStateFromProps === 'function') { 17961 var _componentName3 = getComponentName(Component) || 'Unknown'; 17962 17963 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { 17964 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3); 17965 17966 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; 17967 } 17968 } 17969 17970 if (typeof Component.contextType === 'object' && Component.contextType !== null) { 17971 var _componentName4 = getComponentName(Component) || 'Unknown'; 17972 17973 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { 17974 error('%s: Function components do not support contextType.', _componentName4); 17975 17976 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; 17977 } 17978 } 17979 } 17980 } 17981 17982 var SUSPENDED_MARKER = { 17983 dehydrated: null, 17984 retryLane: NoLane 17985 }; 17986 17987 function mountSuspenseOffscreenState(renderLanes) { 17988 return { 17989 baseLanes: renderLanes 17990 }; 17991 } 17992 17993 function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { 17994 return { 17995 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) 17996 }; 17997 } // TODO: Probably should inline this back 17998 17999 18000 function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) { 18001 // If we're already showing a fallback, there are cases where we need to 18002 // remain on that fallback regardless of whether the content has resolved. 18003 // For example, SuspenseList coordinates when nested content appears. 18004 if (current !== null) { 18005 var suspenseState = current.memoizedState; 18006 18007 if (suspenseState === null) { 18008 // Currently showing content. Don't hide it, even if ForceSuspenseFallack 18009 // is true. More precise name might be "ForceRemainSuspenseFallback". 18010 // Note: This is a factoring smell. Can't remain on a fallback if there's 18011 // no fallback to remain on. 18012 return false; 18013 } 18014 } // Not currently showing content. Consult the Suspense context. 18015 18016 18017 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); 18018 } 18019 18020 function getRemainingWorkInPrimaryTree(current, renderLanes) { 18021 // TODO: Should not remove render lanes that were pinged during this render 18022 return removeLanes(current.childLanes, renderLanes); 18023 } 18024 18025 function updateSuspenseComponent(current, workInProgress, renderLanes) { 18026 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. 18027 18028 { 18029 if (shouldSuspend(workInProgress)) { 18030 workInProgress.flags |= DidCapture; 18031 } 18032 } 18033 18034 var suspenseContext = suspenseStackCursor.current; 18035 var showFallback = false; 18036 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; 18037 18038 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { 18039 // Something in this boundary's subtree already suspended. Switch to 18040 // rendering the fallback children. 18041 showFallback = true; 18042 workInProgress.flags &= ~DidCapture; 18043 } else { 18044 // Attempting the main content 18045 if (current === null || current.memoizedState !== null) { 18046 // This is a new mount or this boundary is already showing a fallback state. 18047 // Mark this subtree context as having at least one invisible parent that could 18048 // handle the fallback state. 18049 // Boundaries without fallbacks or should be avoided are not considered since 18050 // they cannot handle preferred fallback states. 18051 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) { 18052 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext); 18053 } 18054 } 18055 } 18056 18057 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 18058 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense 18059 // boundary's children. This involves some custom reconcilation logic. Two 18060 // main reasons this is so complicated. 18061 // 18062 // First, Legacy Mode has different semantics for backwards compatibility. The 18063 // primary tree will commit in an inconsistent state, so when we do the 18064 // second pass to render the fallback, we do some exceedingly, uh, clever 18065 // hacks to make that not totally break. Like transferring effects and 18066 // deletions from hidden tree. In Concurrent Mode, it's much simpler, 18067 // because we bailout on the primary tree completely and leave it in its old 18068 // state, no effects. Same as what we do for Offscreen (except that 18069 // Offscreen doesn't have the first render pass). 18070 // 18071 // Second is hydration. During hydration, the Suspense fiber has a slightly 18072 // different layout, where the child points to a dehydrated fragment, which 18073 // contains the DOM rendered by the server. 18074 // 18075 // Third, even if you set all that aside, Suspense is like error boundaries in 18076 // that we first we try to render one tree, and if that fails, we render again 18077 // and switch to a different tree. Like a try/catch block. So we have to track 18078 // which branch we're currently rendering. Ideally we would model this using 18079 // a stack. 18080 18081 if (current === null) { 18082 // Initial mount 18083 // If we're currently hydrating, try to hydrate this boundary. 18084 // But only if this has a fallback. 18085 if (nextProps.fallback !== undefined) { 18086 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. 18087 } 18088 18089 var nextPrimaryChildren = nextProps.children; 18090 var nextFallbackChildren = nextProps.fallback; 18091 18092 if (showFallback) { 18093 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); 18094 var primaryChildFragment = workInProgress.child; 18095 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes); 18096 workInProgress.memoizedState = SUSPENDED_MARKER; 18097 return fallbackFragment; 18098 } else if (typeof nextProps.unstable_expectedLoadTime === 'number') { 18099 // This is a CPU-bound tree. Skip this tree and show a placeholder to 18100 // unblock the surrounding content. Then immediately retry after the 18101 // initial commit. 18102 var _fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); 18103 18104 var _primaryChildFragment = workInProgress.child; 18105 _primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes); 18106 workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to 18107 // get it started back up to attempt the next item. While in terms of 18108 // priority this work has the same priority as this current render, it's 18109 // not part of the same transition once the transition has committed. If 18110 // it's sync, we still want to yield so that it can be painted. 18111 // Conceptually, this is really the same as pinging. We can use any 18112 // RetryLane even if it's the one currently rendering since we're leaving 18113 // it behind on this node. 18114 18115 workInProgress.lanes = SomeRetryLane; 18116 18117 { 18118 markSpawnedWork(SomeRetryLane); 18119 } 18120 18121 return _fallbackFragment; 18122 } else { 18123 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren, renderLanes); 18124 } 18125 } else { 18126 // This is an update. 18127 // If the current fiber has a SuspenseState, that means it's already showing 18128 // a fallback. 18129 var prevState = current.memoizedState; 18130 18131 if (prevState !== null) { 18132 18133 if (showFallback) { 18134 var _nextFallbackChildren2 = nextProps.fallback; 18135 var _nextPrimaryChildren2 = nextProps.children; 18136 18137 var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes); 18138 18139 var _primaryChildFragment3 = workInProgress.child; 18140 var prevOffscreenState = current.child.memoizedState; 18141 _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); 18142 _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); 18143 workInProgress.memoizedState = SUSPENDED_MARKER; 18144 return _fallbackChildFragment; 18145 } else { 18146 var _nextPrimaryChildren3 = nextProps.children; 18147 18148 var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes); 18149 18150 workInProgress.memoizedState = null; 18151 return _primaryChildFragment4; 18152 } 18153 } else { 18154 // The current tree is not already showing a fallback. 18155 if (showFallback) { 18156 // Timed out. 18157 var _nextFallbackChildren3 = nextProps.fallback; 18158 var _nextPrimaryChildren4 = nextProps.children; 18159 18160 var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes); 18161 18162 var _primaryChildFragment5 = workInProgress.child; 18163 var _prevOffscreenState = current.child.memoizedState; 18164 _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); 18165 _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the 18166 // fallback children. 18167 18168 workInProgress.memoizedState = SUSPENDED_MARKER; 18169 return _fallbackChildFragment2; 18170 } else { 18171 // Still haven't timed out. Continue rendering the children, like we 18172 // normally do. 18173 var _nextPrimaryChildren5 = nextProps.children; 18174 18175 var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes); 18176 18177 workInProgress.memoizedState = null; 18178 return _primaryChildFragment6; 18179 } 18180 } 18181 } 18182 } 18183 18184 function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) { 18185 var mode = workInProgress.mode; 18186 var primaryChildProps = { 18187 mode: 'visible', 18188 children: primaryChildren 18189 }; 18190 var primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, renderLanes, null); 18191 primaryChildFragment.return = workInProgress; 18192 workInProgress.child = primaryChildFragment; 18193 return primaryChildFragment; 18194 } 18195 18196 function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) { 18197 var mode = workInProgress.mode; 18198 var progressedPrimaryFragment = workInProgress.child; 18199 var primaryChildProps = { 18200 mode: 'hidden', 18201 children: primaryChildren 18202 }; 18203 var primaryChildFragment; 18204 var fallbackChildFragment; 18205 18206 if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { 18207 // In legacy mode, we commit the primary tree as if it successfully 18208 // completed, even though it's in an inconsistent state. 18209 primaryChildFragment = progressedPrimaryFragment; 18210 primaryChildFragment.childLanes = NoLanes; 18211 primaryChildFragment.pendingProps = primaryChildProps; 18212 18213 if ( workInProgress.mode & ProfileMode) { 18214 // Reset the durations from the first pass so they aren't included in the 18215 // final amounts. This seems counterintuitive, since we're intentionally 18216 // not measuring part of the render phase, but this makes it match what we 18217 // do in Concurrent Mode. 18218 primaryChildFragment.actualDuration = 0; 18219 primaryChildFragment.actualStartTime = -1; 18220 primaryChildFragment.selfBaseDuration = 0; 18221 primaryChildFragment.treeBaseDuration = 0; 18222 } 18223 18224 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); 18225 } else { 18226 primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, NoLanes, null); 18227 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); 18228 } 18229 18230 primaryChildFragment.return = workInProgress; 18231 fallbackChildFragment.return = workInProgress; 18232 primaryChildFragment.sibling = fallbackChildFragment; 18233 workInProgress.child = primaryChildFragment; 18234 return fallbackChildFragment; 18235 } 18236 18237 function createWorkInProgressOffscreenFiber(current, offscreenProps) { 18238 // The props argument to `createWorkInProgress` is `any` typed, so we use this 18239 // wrapper function to constrain it. 18240 return createWorkInProgress(current, offscreenProps); 18241 } 18242 18243 function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) { 18244 var currentPrimaryChildFragment = current.child; 18245 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; 18246 var primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, { 18247 mode: 'visible', 18248 children: primaryChildren 18249 }); 18250 18251 if ((workInProgress.mode & BlockingMode) === NoMode) { 18252 primaryChildFragment.lanes = renderLanes; 18253 } 18254 18255 primaryChildFragment.return = workInProgress; 18256 primaryChildFragment.sibling = null; 18257 18258 if (currentFallbackChildFragment !== null) { 18259 // Delete the fallback child fragment 18260 currentFallbackChildFragment.nextEffect = null; 18261 currentFallbackChildFragment.flags = Deletion; 18262 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; 18263 } 18264 18265 workInProgress.child = primaryChildFragment; 18266 return primaryChildFragment; 18267 } 18268 18269 function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) { 18270 var mode = workInProgress.mode; 18271 var currentPrimaryChildFragment = current.child; 18272 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; 18273 var primaryChildProps = { 18274 mode: 'hidden', 18275 children: primaryChildren 18276 }; 18277 var primaryChildFragment; 18278 18279 if ( // In legacy mode, we commit the primary tree as if it successfully 18280 // completed, even though it's in an inconsistent state. 18281 (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was 18282 // already cloned. In legacy mode, the only case where this isn't true is 18283 // when DevTools forces us to display a fallback; we skip the first render 18284 // pass entirely and go straight to rendering the fallback. (In Concurrent 18285 // Mode, SuspenseList can also trigger this scenario, but this is a legacy- 18286 // only codepath.) 18287 workInProgress.child !== currentPrimaryChildFragment) { 18288 var progressedPrimaryFragment = workInProgress.child; 18289 primaryChildFragment = progressedPrimaryFragment; 18290 primaryChildFragment.childLanes = NoLanes; 18291 primaryChildFragment.pendingProps = primaryChildProps; 18292 18293 if ( workInProgress.mode & ProfileMode) { 18294 // Reset the durations from the first pass so they aren't included in the 18295 // final amounts. This seems counterintuitive, since we're intentionally 18296 // not measuring part of the render phase, but this makes it match what we 18297 // do in Concurrent Mode. 18298 primaryChildFragment.actualDuration = 0; 18299 primaryChildFragment.actualStartTime = -1; 18300 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration; 18301 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; 18302 } // The fallback fiber was added as a deletion effect during the first pass. 18303 // However, since we're going to remain on the fallback, we no longer want 18304 // to delete it. So we need to remove it from the list. Deletions are stored 18305 // on the same list as effects. We want to keep the effects from the primary 18306 // tree. So we copy the primary child fragment's effect list, which does not 18307 // include the fallback deletion effect. 18308 18309 18310 var progressedLastEffect = primaryChildFragment.lastEffect; 18311 18312 if (progressedLastEffect !== null) { 18313 workInProgress.firstEffect = primaryChildFragment.firstEffect; 18314 workInProgress.lastEffect = progressedLastEffect; 18315 progressedLastEffect.nextEffect = null; 18316 } else { 18317 // TODO: Reset this somewhere else? Lol legacy mode is so weird. 18318 workInProgress.firstEffect = workInProgress.lastEffect = null; 18319 } 18320 } else { 18321 primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); 18322 } 18323 18324 var fallbackChildFragment; 18325 18326 if (currentFallbackChildFragment !== null) { 18327 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren); 18328 } else { 18329 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already 18330 // mounted but this is a new fiber. 18331 18332 fallbackChildFragment.flags |= Placement; 18333 } 18334 18335 fallbackChildFragment.return = workInProgress; 18336 primaryChildFragment.return = workInProgress; 18337 primaryChildFragment.sibling = fallbackChildFragment; 18338 workInProgress.child = primaryChildFragment; 18339 return fallbackChildFragment; 18340 } 18341 18342 function scheduleWorkOnFiber(fiber, renderLanes) { 18343 fiber.lanes = mergeLanes(fiber.lanes, renderLanes); 18344 var alternate = fiber.alternate; 18345 18346 if (alternate !== null) { 18347 alternate.lanes = mergeLanes(alternate.lanes, renderLanes); 18348 } 18349 18350 scheduleWorkOnParentPath(fiber.return, renderLanes); 18351 } 18352 18353 function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) { 18354 // Mark any Suspense boundaries with fallbacks as having work to do. 18355 // If they were previously forced into fallbacks, they may now be able 18356 // to unblock. 18357 var node = firstChild; 18358 18359 while (node !== null) { 18360 if (node.tag === SuspenseComponent) { 18361 var state = node.memoizedState; 18362 18363 if (state !== null) { 18364 scheduleWorkOnFiber(node, renderLanes); 18365 } 18366 } else if (node.tag === SuspenseListComponent) { 18367 // If the tail is hidden there might not be an Suspense boundaries 18368 // to schedule work on. In this case we have to schedule it on the 18369 // list itself. 18370 // We don't have to traverse to the children of the list since 18371 // the list will propagate the change when it rerenders. 18372 scheduleWorkOnFiber(node, renderLanes); 18373 } else if (node.child !== null) { 18374 node.child.return = node; 18375 node = node.child; 18376 continue; 18377 } 18378 18379 if (node === workInProgress) { 18380 return; 18381 } 18382 18383 while (node.sibling === null) { 18384 if (node.return === null || node.return === workInProgress) { 18385 return; 18386 } 18387 18388 node = node.return; 18389 } 18390 18391 node.sibling.return = node.return; 18392 node = node.sibling; 18393 } 18394 } 18395 18396 function findLastContentRow(firstChild) { 18397 // This is going to find the last row among these children that is already 18398 // showing content on the screen, as opposed to being in fallback state or 18399 // new. If a row has multiple Suspense boundaries, any of them being in the 18400 // fallback state, counts as the whole row being in a fallback state. 18401 // Note that the "rows" will be workInProgress, but any nested children 18402 // will still be current since we haven't rendered them yet. The mounted 18403 // order may not be the same as the new order. We use the new order. 18404 var row = firstChild; 18405 var lastContentRow = null; 18406 18407 while (row !== null) { 18408 var currentRow = row.alternate; // New rows can't be content rows. 18409 18410 if (currentRow !== null && findFirstSuspended(currentRow) === null) { 18411 lastContentRow = row; 18412 } 18413 18414 row = row.sibling; 18415 } 18416 18417 return lastContentRow; 18418 } 18419 18420 function validateRevealOrder(revealOrder) { 18421 { 18422 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) { 18423 didWarnAboutRevealOrder[revealOrder] = true; 18424 18425 if (typeof revealOrder === 'string') { 18426 switch (revealOrder.toLowerCase()) { 18427 case 'together': 18428 case 'forwards': 18429 case 'backwards': 18430 { 18431 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase()); 18432 18433 break; 18434 } 18435 18436 case 'forward': 18437 case 'backward': 18438 { 18439 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()); 18440 18441 break; 18442 } 18443 18444 default: 18445 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder); 18446 18447 break; 18448 } 18449 } else { 18450 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder); 18451 } 18452 } 18453 } 18454 } 18455 18456 function validateTailOptions(tailMode, revealOrder) { 18457 { 18458 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { 18459 if (tailMode !== 'collapsed' && tailMode !== 'hidden') { 18460 didWarnAboutTailOptions[tailMode] = true; 18461 18462 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode); 18463 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') { 18464 didWarnAboutTailOptions[tailMode] = true; 18465 18466 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode); 18467 } 18468 } 18469 } 18470 } 18471 18472 function validateSuspenseListNestedChild(childSlot, index) { 18473 { 18474 var isArray = Array.isArray(childSlot); 18475 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function'; 18476 18477 if (isArray || isIterable) { 18478 var type = isArray ? 'array' : 'iterable'; 18479 18480 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); 18481 18482 return false; 18483 } 18484 } 18485 18486 return true; 18487 } 18488 18489 function validateSuspenseListChildren(children, revealOrder) { 18490 { 18491 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) { 18492 if (Array.isArray(children)) { 18493 for (var i = 0; i < children.length; i++) { 18494 if (!validateSuspenseListNestedChild(children[i], i)) { 18495 return; 18496 } 18497 } 18498 } else { 18499 var iteratorFn = getIteratorFn(children); 18500 18501 if (typeof iteratorFn === 'function') { 18502 var childrenIterator = iteratorFn.call(children); 18503 18504 if (childrenIterator) { 18505 var step = childrenIterator.next(); 18506 var _i = 0; 18507 18508 for (; !step.done; step = childrenIterator.next()) { 18509 if (!validateSuspenseListNestedChild(step.value, _i)) { 18510 return; 18511 } 18512 18513 _i++; 18514 } 18515 } 18516 } else { 18517 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); 18518 } 18519 } 18520 } 18521 } 18522 } 18523 18524 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) { 18525 var renderState = workInProgress.memoizedState; 18526 18527 if (renderState === null) { 18528 workInProgress.memoizedState = { 18529 isBackwards: isBackwards, 18530 rendering: null, 18531 renderingStartTime: 0, 18532 last: lastContentRow, 18533 tail: tail, 18534 tailMode: tailMode, 18535 lastEffect: lastEffectBeforeRendering 18536 }; 18537 } else { 18538 // We can reuse the existing object from previous renders. 18539 renderState.isBackwards = isBackwards; 18540 renderState.rendering = null; 18541 renderState.renderingStartTime = 0; 18542 renderState.last = lastContentRow; 18543 renderState.tail = tail; 18544 renderState.tailMode = tailMode; 18545 renderState.lastEffect = lastEffectBeforeRendering; 18546 } 18547 } // This can end up rendering this component multiple passes. 18548 // The first pass splits the children fibers into two sets. A head and tail. 18549 // We first render the head. If anything is in fallback state, we do another 18550 // pass through beginWork to rerender all children (including the tail) with 18551 // the force suspend context. If the first render didn't have anything in 18552 // in fallback state. Then we render each row in the tail one-by-one. 18553 // That happens in the completeWork phase without going back to beginWork. 18554 18555 18556 function updateSuspenseListComponent(current, workInProgress, renderLanes) { 18557 var nextProps = workInProgress.pendingProps; 18558 var revealOrder = nextProps.revealOrder; 18559 var tailMode = nextProps.tail; 18560 var newChildren = nextProps.children; 18561 validateRevealOrder(revealOrder); 18562 validateTailOptions(tailMode, revealOrder); 18563 validateSuspenseListChildren(newChildren, revealOrder); 18564 reconcileChildren(current, workInProgress, newChildren, renderLanes); 18565 var suspenseContext = suspenseStackCursor.current; 18566 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback); 18567 18568 if (shouldForceFallback) { 18569 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); 18570 workInProgress.flags |= DidCapture; 18571 } else { 18572 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags; 18573 18574 if (didSuspendBefore) { 18575 // If we previously forced a fallback, we need to schedule work 18576 // on any nested boundaries to let them know to try to render 18577 // again. This is the same as context updating. 18578 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes); 18579 } 18580 18581 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 18582 } 18583 18584 pushSuspenseContext(workInProgress, suspenseContext); 18585 18586 if ((workInProgress.mode & BlockingMode) === NoMode) { 18587 // In legacy mode, SuspenseList doesn't work so we just 18588 // use make it a noop by treating it as the default revealOrder. 18589 workInProgress.memoizedState = null; 18590 } else { 18591 switch (revealOrder) { 18592 case 'forwards': 18593 { 18594 var lastContentRow = findLastContentRow(workInProgress.child); 18595 var tail; 18596 18597 if (lastContentRow === null) { 18598 // The whole list is part of the tail. 18599 // TODO: We could fast path by just rendering the tail now. 18600 tail = workInProgress.child; 18601 workInProgress.child = null; 18602 } else { 18603 // Disconnect the tail rows after the content row. 18604 // We're going to render them separately later. 18605 tail = lastContentRow.sibling; 18606 lastContentRow.sibling = null; 18607 } 18608 18609 initSuspenseListRenderState(workInProgress, false, // isBackwards 18610 tail, lastContentRow, tailMode, workInProgress.lastEffect); 18611 break; 18612 } 18613 18614 case 'backwards': 18615 { 18616 // We're going to find the first row that has existing content. 18617 // At the same time we're going to reverse the list of everything 18618 // we pass in the meantime. That's going to be our tail in reverse 18619 // order. 18620 var _tail = null; 18621 var row = workInProgress.child; 18622 workInProgress.child = null; 18623 18624 while (row !== null) { 18625 var currentRow = row.alternate; // New rows can't be content rows. 18626 18627 if (currentRow !== null && findFirstSuspended(currentRow) === null) { 18628 // This is the beginning of the main content. 18629 workInProgress.child = row; 18630 break; 18631 } 18632 18633 var nextRow = row.sibling; 18634 row.sibling = _tail; 18635 _tail = row; 18636 row = nextRow; 18637 } // TODO: If workInProgress.child is null, we can continue on the tail immediately. 18638 18639 18640 initSuspenseListRenderState(workInProgress, true, // isBackwards 18641 _tail, null, // last 18642 tailMode, workInProgress.lastEffect); 18643 break; 18644 } 18645 18646 case 'together': 18647 { 18648 initSuspenseListRenderState(workInProgress, false, // isBackwards 18649 null, // tail 18650 null, // last 18651 undefined, workInProgress.lastEffect); 18652 break; 18653 } 18654 18655 default: 18656 { 18657 // The default reveal order is the same as not having 18658 // a boundary. 18659 workInProgress.memoizedState = null; 18660 } 18661 } 18662 } 18663 18664 return workInProgress.child; 18665 } 18666 18667 function updatePortalComponent(current, workInProgress, renderLanes) { 18668 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 18669 var nextChildren = workInProgress.pendingProps; 18670 18671 if (current === null) { 18672 // Portals are special because we don't append the children during mount 18673 // but at commit. Therefore we need to track insertions which the normal 18674 // flow doesn't do during mount. This doesn't happen at the root because 18675 // the root always starts with a "current" with a null child. 18676 // TODO: Consider unifying this with how the root works. 18677 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); 18678 } else { 18679 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 18680 } 18681 18682 return workInProgress.child; 18683 } 18684 18685 var hasWarnedAboutUsingNoValuePropOnContextProvider = false; 18686 18687 function updateContextProvider(current, workInProgress, renderLanes) { 18688 var providerType = workInProgress.type; 18689 var context = providerType._context; 18690 var newProps = workInProgress.pendingProps; 18691 var oldProps = workInProgress.memoizedProps; 18692 var newValue = newProps.value; 18693 18694 { 18695 if (!('value' in newProps)) { 18696 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { 18697 hasWarnedAboutUsingNoValuePropOnContextProvider = true; 18698 18699 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?'); 18700 } 18701 } 18702 18703 var providerPropTypes = workInProgress.type.propTypes; 18704 18705 if (providerPropTypes) { 18706 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider'); 18707 } 18708 } 18709 18710 pushProvider(workInProgress, newValue); 18711 18712 if (oldProps !== null) { 18713 var oldValue = oldProps.value; 18714 var changedBits = calculateChangedBits(context, newValue, oldValue); 18715 18716 if (changedBits === 0) { 18717 // No change. Bailout early if children are the same. 18718 if (oldProps.children === newProps.children && !hasContextChanged()) { 18719 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 18720 } 18721 } else { 18722 // The context value changed. Search for matching consumers and schedule 18723 // them to update. 18724 propagateContextChange(workInProgress, context, changedBits, renderLanes); 18725 } 18726 } 18727 18728 var newChildren = newProps.children; 18729 reconcileChildren(current, workInProgress, newChildren, renderLanes); 18730 return workInProgress.child; 18731 } 18732 18733 var hasWarnedAboutUsingContextAsConsumer = false; 18734 18735 function updateContextConsumer(current, workInProgress, renderLanes) { 18736 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In 18737 // DEV mode, we create a separate object for Context.Consumer that acts 18738 // like a proxy to Context. This proxy object adds unnecessary code in PROD 18739 // so we use the old behaviour (Context.Consumer references Context) to 18740 // reduce size and overhead. The separate object references context via 18741 // a property called "_context", which also gives us the ability to check 18742 // in DEV mode if this property exists or not and warn if it does not. 18743 18744 { 18745 if (context._context === undefined) { 18746 // This may be because it's a Context (rather than a Consumer). 18747 // Or it may be because it's older React where they're the same thing. 18748 // We only want to warn if we're sure it's a new React. 18749 if (context !== context.Consumer) { 18750 if (!hasWarnedAboutUsingContextAsConsumer) { 18751 hasWarnedAboutUsingContextAsConsumer = true; 18752 18753 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?'); 18754 } 18755 } 18756 } else { 18757 context = context._context; 18758 } 18759 } 18760 18761 var newProps = workInProgress.pendingProps; 18762 var render = newProps.children; 18763 18764 { 18765 if (typeof render !== 'function') { 18766 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.'); 18767 } 18768 } 18769 18770 prepareToReadContext(workInProgress, renderLanes); 18771 var newValue = readContext(context, newProps.unstable_observedBits); 18772 var newChildren; 18773 18774 { 18775 ReactCurrentOwner$1.current = workInProgress; 18776 setIsRendering(true); 18777 newChildren = render(newValue); 18778 setIsRendering(false); 18779 } // React DevTools reads this flag. 18780 18781 18782 workInProgress.flags |= PerformedWork; 18783 reconcileChildren(current, workInProgress, newChildren, renderLanes); 18784 return workInProgress.child; 18785 } 18786 18787 function markWorkInProgressReceivedUpdate() { 18788 didReceiveUpdate = true; 18789 } 18790 18791 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { 18792 if (current !== null) { 18793 // Reuse previous dependencies 18794 workInProgress.dependencies = current.dependencies; 18795 } 18796 18797 { 18798 // Don't update "base" render times for bailouts. 18799 stopProfilerTimerIfRunning(); 18800 } 18801 18802 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. 18803 18804 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { 18805 // The children don't have any work either. We can skip them. 18806 // TODO: Once we add back resuming, we should check if the children are 18807 // a work-in-progress set. If so, we need to transfer their effects. 18808 return null; 18809 } else { 18810 // This fiber doesn't have work, but its subtree does. Clone the child 18811 // fibers and continue. 18812 cloneChildFibers(current, workInProgress); 18813 return workInProgress.child; 18814 } 18815 } 18816 18817 function remountFiber(current, oldWorkInProgress, newWorkInProgress) { 18818 { 18819 var returnFiber = oldWorkInProgress.return; 18820 18821 if (returnFiber === null) { 18822 throw new Error('Cannot swap the root fiber.'); 18823 } // Disconnect from the old current. 18824 // It will get deleted. 18825 18826 18827 current.alternate = null; 18828 oldWorkInProgress.alternate = null; // Connect to the new tree. 18829 18830 newWorkInProgress.index = oldWorkInProgress.index; 18831 newWorkInProgress.sibling = oldWorkInProgress.sibling; 18832 newWorkInProgress.return = oldWorkInProgress.return; 18833 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. 18834 18835 if (oldWorkInProgress === returnFiber.child) { 18836 returnFiber.child = newWorkInProgress; 18837 } else { 18838 var prevSibling = returnFiber.child; 18839 18840 if (prevSibling === null) { 18841 throw new Error('Expected parent to have a child.'); 18842 } 18843 18844 while (prevSibling.sibling !== oldWorkInProgress) { 18845 prevSibling = prevSibling.sibling; 18846 18847 if (prevSibling === null) { 18848 throw new Error('Expected to find the previous sibling.'); 18849 } 18850 } 18851 18852 prevSibling.sibling = newWorkInProgress; 18853 } // Delete the old fiber and place the new one. 18854 // Since the old fiber is disconnected, we have to schedule it manually. 18855 18856 18857 var last = returnFiber.lastEffect; 18858 18859 if (last !== null) { 18860 last.nextEffect = current; 18861 returnFiber.lastEffect = current; 18862 } else { 18863 returnFiber.firstEffect = returnFiber.lastEffect = current; 18864 } 18865 18866 current.nextEffect = null; 18867 current.flags = Deletion; 18868 newWorkInProgress.flags |= Placement; // Restart work from the new fiber. 18869 18870 return newWorkInProgress; 18871 } 18872 } 18873 18874 function beginWork(current, workInProgress, renderLanes) { 18875 var updateLanes = workInProgress.lanes; 18876 18877 { 18878 if (workInProgress._debugNeedsRemount && current !== null) { 18879 // This will restart the begin phase with a new fiber. 18880 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes)); 18881 } 18882 } 18883 18884 if (current !== null) { 18885 var oldProps = current.memoizedProps; 18886 var newProps = workInProgress.pendingProps; 18887 18888 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload: 18889 workInProgress.type !== current.type )) { 18890 // If props or context changed, mark the fiber as having performed work. 18891 // This may be unset if the props are determined to be equal later (memo). 18892 didReceiveUpdate = true; 18893 } else if (!includesSomeLane(renderLanes, updateLanes)) { 18894 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering 18895 // the begin phase. There's still some bookkeeping we that needs to be done 18896 // in this optimized path, mostly pushing stuff onto the stack. 18897 18898 switch (workInProgress.tag) { 18899 case HostRoot: 18900 pushHostRootContext(workInProgress); 18901 resetHydrationState(); 18902 break; 18903 18904 case HostComponent: 18905 pushHostContext(workInProgress); 18906 break; 18907 18908 case ClassComponent: 18909 { 18910 var Component = workInProgress.type; 18911 18912 if (isContextProvider(Component)) { 18913 pushContextProvider(workInProgress); 18914 } 18915 18916 break; 18917 } 18918 18919 case HostPortal: 18920 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 18921 break; 18922 18923 case ContextProvider: 18924 { 18925 var newValue = workInProgress.memoizedProps.value; 18926 pushProvider(workInProgress, newValue); 18927 break; 18928 } 18929 18930 case Profiler: 18931 { 18932 // Profiler should only call onRender when one of its descendants actually rendered. 18933 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); 18934 18935 if (hasChildWork) { 18936 workInProgress.flags |= Update; 18937 } // Reset effect durations for the next eventual effect phase. 18938 // These are reset during render to allow the DevTools commit hook a chance to read them, 18939 18940 18941 var stateNode = workInProgress.stateNode; 18942 stateNode.effectDuration = 0; 18943 stateNode.passiveEffectDuration = 0; 18944 } 18945 18946 break; 18947 18948 case SuspenseComponent: 18949 { 18950 var state = workInProgress.memoizedState; 18951 18952 if (state !== null) { 18953 // whether to retry the primary children, or to skip over it and 18954 // go straight to the fallback. Check the priority of the primary 18955 // child fragment. 18956 18957 18958 var primaryChildFragment = workInProgress.child; 18959 var primaryChildLanes = primaryChildFragment.childLanes; 18960 18961 if (includesSomeLane(renderLanes, primaryChildLanes)) { 18962 // The primary children have pending work. Use the normal path 18963 // to attempt to render the primary children again. 18964 return updateSuspenseComponent(current, workInProgress, renderLanes); 18965 } else { 18966 // The primary child fragment does not have pending work marked 18967 // on it 18968 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient 18969 // priority. Bailout. 18970 18971 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 18972 18973 if (child !== null) { 18974 // The fallback children have pending work. Skip over the 18975 // primary children and work on the fallback. 18976 return child.sibling; 18977 } else { 18978 return null; 18979 } 18980 } 18981 } else { 18982 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); 18983 } 18984 18985 break; 18986 } 18987 18988 case SuspenseListComponent: 18989 { 18990 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; 18991 18992 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); 18993 18994 if (didSuspendBefore) { 18995 if (_hasChildWork) { 18996 // If something was in fallback state last time, and we have all the 18997 // same children then we're still in progressive loading state. 18998 // Something might get unblocked by state updates or retries in the 18999 // tree which will affect the tail. So we need to use the normal 19000 // path to compute the correct tail. 19001 return updateSuspenseListComponent(current, workInProgress, renderLanes); 19002 } // If none of the children had any work, that means that none of 19003 // them got retried so they'll still be blocked in the same way 19004 // as before. We can fast bail out. 19005 19006 19007 workInProgress.flags |= DidCapture; 19008 } // If nothing suspended before and we're rendering the same children, 19009 // then the tail doesn't matter. Anything new that suspends will work 19010 // in the "together" mode, so we can continue from the state we had. 19011 19012 19013 var renderState = workInProgress.memoizedState; 19014 19015 if (renderState !== null) { 19016 // Reset to the "together" mode in case we've started a different 19017 // update in the past but didn't complete it. 19018 renderState.rendering = null; 19019 renderState.tail = null; 19020 renderState.lastEffect = null; 19021 } 19022 19023 pushSuspenseContext(workInProgress, suspenseStackCursor.current); 19024 19025 if (_hasChildWork) { 19026 break; 19027 } else { 19028 // If none of the children had any work, that means that none of 19029 // them got retried so they'll still be blocked in the same way 19030 // as before. We can fast bail out. 19031 return null; 19032 } 19033 } 19034 19035 case OffscreenComponent: 19036 case LegacyHiddenComponent: 19037 { 19038 // Need to check if the tree still needs to be deferred. This is 19039 // almost identical to the logic used in the normal update path, 19040 // so we'll just enter that. The only difference is we'll bail out 19041 // at the next level instead of this one, because the child props 19042 // have not changed. Which is fine. 19043 // TODO: Probably should refactor `beginWork` to split the bailout 19044 // path from the normal path. I'm tempted to do a labeled break here 19045 // but I won't :) 19046 workInProgress.lanes = NoLanes; 19047 return updateOffscreenComponent(current, workInProgress, renderLanes); 19048 } 19049 } 19050 19051 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19052 } else { 19053 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { 19054 // This is a special case that only exists for legacy mode. 19055 // See https://github.com/facebook/react/pull/19216. 19056 didReceiveUpdate = true; 19057 } else { 19058 // An update was scheduled on this fiber, but there are no new props 19059 // nor legacy context. Set this to false. If an update queue or context 19060 // consumer produces a changed value, it will set this to true. Otherwise, 19061 // the component will assume the children have not changed and bail out. 19062 didReceiveUpdate = false; 19063 } 19064 } 19065 } else { 19066 didReceiveUpdate = false; 19067 } // Before entering the begin phase, clear pending update priority. 19068 // TODO: This assumes that we're about to evaluate the component and process 19069 // the update queue. However, there's an exception: SimpleMemoComponent 19070 // sometimes bails out later in the begin phase. This indicates that we should 19071 // move this assignment out of the common path and into each branch. 19072 19073 19074 workInProgress.lanes = NoLanes; 19075 19076 switch (workInProgress.tag) { 19077 case IndeterminateComponent: 19078 { 19079 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes); 19080 } 19081 19082 case LazyComponent: 19083 { 19084 var elementType = workInProgress.elementType; 19085 return mountLazyComponent(current, workInProgress, elementType, updateLanes, renderLanes); 19086 } 19087 19088 case FunctionComponent: 19089 { 19090 var _Component = workInProgress.type; 19091 var unresolvedProps = workInProgress.pendingProps; 19092 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); 19093 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderLanes); 19094 } 19095 19096 case ClassComponent: 19097 { 19098 var _Component2 = workInProgress.type; 19099 var _unresolvedProps = workInProgress.pendingProps; 19100 19101 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps); 19102 19103 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderLanes); 19104 } 19105 19106 case HostRoot: 19107 return updateHostRoot(current, workInProgress, renderLanes); 19108 19109 case HostComponent: 19110 return updateHostComponent(current, workInProgress, renderLanes); 19111 19112 case HostText: 19113 return updateHostText(current, workInProgress); 19114 19115 case SuspenseComponent: 19116 return updateSuspenseComponent(current, workInProgress, renderLanes); 19117 19118 case HostPortal: 19119 return updatePortalComponent(current, workInProgress, renderLanes); 19120 19121 case ForwardRef: 19122 { 19123 var type = workInProgress.type; 19124 var _unresolvedProps2 = workInProgress.pendingProps; 19125 19126 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2); 19127 19128 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes); 19129 } 19130 19131 case Fragment: 19132 return updateFragment(current, workInProgress, renderLanes); 19133 19134 case Mode: 19135 return updateMode(current, workInProgress, renderLanes); 19136 19137 case Profiler: 19138 return updateProfiler(current, workInProgress, renderLanes); 19139 19140 case ContextProvider: 19141 return updateContextProvider(current, workInProgress, renderLanes); 19142 19143 case ContextConsumer: 19144 return updateContextConsumer(current, workInProgress, renderLanes); 19145 19146 case MemoComponent: 19147 { 19148 var _type2 = workInProgress.type; 19149 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. 19150 19151 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); 19152 19153 { 19154 if (workInProgress.type !== workInProgress.elementType) { 19155 var outerPropTypes = _type2.propTypes; 19156 19157 if (outerPropTypes) { 19158 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only 19159 'prop', getComponentName(_type2)); 19160 } 19161 } 19162 } 19163 19164 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); 19165 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateLanes, renderLanes); 19166 } 19167 19168 case SimpleMemoComponent: 19169 { 19170 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateLanes, renderLanes); 19171 } 19172 19173 case IncompleteClassComponent: 19174 { 19175 var _Component3 = workInProgress.type; 19176 var _unresolvedProps4 = workInProgress.pendingProps; 19177 19178 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4); 19179 19180 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderLanes); 19181 } 19182 19183 case SuspenseListComponent: 19184 { 19185 return updateSuspenseListComponent(current, workInProgress, renderLanes); 19186 } 19187 19188 case FundamentalComponent: 19189 { 19190 19191 break; 19192 } 19193 19194 case ScopeComponent: 19195 { 19196 19197 break; 19198 } 19199 19200 case Block: 19201 { 19202 19203 break; 19204 } 19205 19206 case OffscreenComponent: 19207 { 19208 return updateOffscreenComponent(current, workInProgress, renderLanes); 19209 } 19210 19211 case LegacyHiddenComponent: 19212 { 19213 return updateLegacyHiddenComponent(current, workInProgress, renderLanes); 19214 } 19215 } 19216 19217 { 19218 { 19219 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." ); 19220 } 19221 } 19222 } 19223 19224 function markUpdate(workInProgress) { 19225 // Tag the fiber with an update effect. This turns a Placement into 19226 // a PlacementAndUpdate. 19227 workInProgress.flags |= Update; 19228 } 19229 19230 function markRef$1(workInProgress) { 19231 workInProgress.flags |= Ref; 19232 } 19233 19234 var appendAllChildren; 19235 var updateHostContainer; 19236 var updateHostComponent$1; 19237 var updateHostText$1; 19238 19239 { 19240 // Mutation mode 19241 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) { 19242 // We only have the top Fiber that was created but we need recurse down its 19243 // children to find all the terminal nodes. 19244 var node = workInProgress.child; 19245 19246 while (node !== null) { 19247 if (node.tag === HostComponent || node.tag === HostText) { 19248 appendInitialChild(parent, node.stateNode); 19249 } else if (node.tag === HostPortal) ; else if (node.child !== null) { 19250 node.child.return = node; 19251 node = node.child; 19252 continue; 19253 } 19254 19255 if (node === workInProgress) { 19256 return; 19257 } 19258 19259 while (node.sibling === null) { 19260 if (node.return === null || node.return === workInProgress) { 19261 return; 19262 } 19263 19264 node = node.return; 19265 } 19266 19267 node.sibling.return = node.return; 19268 node = node.sibling; 19269 } 19270 }; 19271 19272 updateHostContainer = function (workInProgress) {// Noop 19273 }; 19274 19275 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 19276 // If we have an alternate, that means this is an update and we need to 19277 // schedule a side-effect to do the updates. 19278 var oldProps = current.memoizedProps; 19279 19280 if (oldProps === newProps) { 19281 // In mutation mode, this is sufficient for a bailout because 19282 // we won't touch this node even if children changed. 19283 return; 19284 } // If we get updated because one of our children updated, we don't 19285 // have newProps so we'll have to reuse them. 19286 // TODO: Split the update API as separate for the props vs. children. 19287 // Even better would be if children weren't special cased at all tho. 19288 19289 19290 var instance = workInProgress.stateNode; 19291 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host 19292 // component is hitting the resume path. Figure out why. Possibly 19293 // related to `hidden`. 19294 19295 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component. 19296 19297 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there 19298 // is a new ref we mark this as an update. All the work is done in commitWork. 19299 19300 if (updatePayload) { 19301 markUpdate(workInProgress); 19302 } 19303 }; 19304 19305 updateHostText$1 = function (current, workInProgress, oldText, newText) { 19306 // If the text differs, mark it as an update. All the work in done in commitWork. 19307 if (oldText !== newText) { 19308 markUpdate(workInProgress); 19309 } 19310 }; 19311 } 19312 19313 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { 19314 if (getIsHydrating()) { 19315 // If we're hydrating, we should consume as many items as we can 19316 // so we don't leave any behind. 19317 return; 19318 } 19319 19320 switch (renderState.tailMode) { 19321 case 'hidden': 19322 { 19323 // Any insertions at the end of the tail list after this point 19324 // should be invisible. If there are already mounted boundaries 19325 // anything before them are not considered for collapsing. 19326 // Therefore we need to go through the whole tail to find if 19327 // there are any. 19328 var tailNode = renderState.tail; 19329 var lastTailNode = null; 19330 19331 while (tailNode !== null) { 19332 if (tailNode.alternate !== null) { 19333 lastTailNode = tailNode; 19334 } 19335 19336 tailNode = tailNode.sibling; 19337 } // Next we're simply going to delete all insertions after the 19338 // last rendered item. 19339 19340 19341 if (lastTailNode === null) { 19342 // All remaining items in the tail are insertions. 19343 renderState.tail = null; 19344 } else { 19345 // Detach the insertion after the last node that was already 19346 // inserted. 19347 lastTailNode.sibling = null; 19348 } 19349 19350 break; 19351 } 19352 19353 case 'collapsed': 19354 { 19355 // Any insertions at the end of the tail list after this point 19356 // should be invisible. If there are already mounted boundaries 19357 // anything before them are not considered for collapsing. 19358 // Therefore we need to go through the whole tail to find if 19359 // there are any. 19360 var _tailNode = renderState.tail; 19361 var _lastTailNode = null; 19362 19363 while (_tailNode !== null) { 19364 if (_tailNode.alternate !== null) { 19365 _lastTailNode = _tailNode; 19366 } 19367 19368 _tailNode = _tailNode.sibling; 19369 } // Next we're simply going to delete all insertions after the 19370 // last rendered item. 19371 19372 19373 if (_lastTailNode === null) { 19374 // All remaining items in the tail are insertions. 19375 if (!hasRenderedATailFallback && renderState.tail !== null) { 19376 // We suspended during the head. We want to show at least one 19377 // row at the tail. So we'll keep on and cut off the rest. 19378 renderState.tail.sibling = null; 19379 } else { 19380 renderState.tail = null; 19381 } 19382 } else { 19383 // Detach the insertion after the last node that was already 19384 // inserted. 19385 _lastTailNode.sibling = null; 19386 } 19387 19388 break; 19389 } 19390 } 19391 } 19392 19393 function completeWork(current, workInProgress, renderLanes) { 19394 var newProps = workInProgress.pendingProps; 19395 19396 switch (workInProgress.tag) { 19397 case IndeterminateComponent: 19398 case LazyComponent: 19399 case SimpleMemoComponent: 19400 case FunctionComponent: 19401 case ForwardRef: 19402 case Fragment: 19403 case Mode: 19404 case Profiler: 19405 case ContextConsumer: 19406 case MemoComponent: 19407 return null; 19408 19409 case ClassComponent: 19410 { 19411 var Component = workInProgress.type; 19412 19413 if (isContextProvider(Component)) { 19414 popContext(workInProgress); 19415 } 19416 19417 return null; 19418 } 19419 19420 case HostRoot: 19421 { 19422 popHostContainer(workInProgress); 19423 popTopLevelContextObject(workInProgress); 19424 resetWorkInProgressVersions(); 19425 var fiberRoot = workInProgress.stateNode; 19426 19427 if (fiberRoot.pendingContext) { 19428 fiberRoot.context = fiberRoot.pendingContext; 19429 fiberRoot.pendingContext = null; 19430 } 19431 19432 if (current === null || current.child === null) { 19433 // If we hydrated, pop so that we can delete any remaining children 19434 // that weren't hydrated. 19435 var wasHydrated = popHydrationState(workInProgress); 19436 19437 if (wasHydrated) { 19438 // If we hydrated, then we'll need to schedule an update for 19439 // the commit side-effects on the root. 19440 markUpdate(workInProgress); 19441 } else if (!fiberRoot.hydrate) { 19442 // Schedule an effect to clear this container at the start of the next commit. 19443 // This handles the case of React rendering into a container with previous children. 19444 // It's also safe to do for updates too, because current.child would only be null 19445 // if the previous render was null (so the the container would already be empty). 19446 workInProgress.flags |= Snapshot; 19447 } 19448 } 19449 19450 updateHostContainer(workInProgress); 19451 return null; 19452 } 19453 19454 case HostComponent: 19455 { 19456 popHostContext(workInProgress); 19457 var rootContainerInstance = getRootHostContainer(); 19458 var type = workInProgress.type; 19459 19460 if (current !== null && workInProgress.stateNode != null) { 19461 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance); 19462 19463 if (current.ref !== workInProgress.ref) { 19464 markRef$1(workInProgress); 19465 } 19466 } else { 19467 if (!newProps) { 19468 if (!(workInProgress.stateNode !== null)) { 19469 { 19470 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); 19471 } 19472 } // This can happen when we abort work. 19473 19474 19475 return null; 19476 } 19477 19478 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context 19479 // "stack" as the parent. Then append children as we go in beginWork 19480 // or completeWork depending on whether we want to add them top->down or 19481 // bottom->up. Top->down is faster in IE11. 19482 19483 var _wasHydrated = popHydrationState(workInProgress); 19484 19485 if (_wasHydrated) { 19486 // TODO: Move this and createInstance step into the beginPhase 19487 // to consolidate. 19488 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) { 19489 // If changes to the hydrated node need to be applied at the 19490 // commit-phase we mark this as such. 19491 markUpdate(workInProgress); 19492 } 19493 } else { 19494 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress); 19495 appendAllChildren(instance, workInProgress, false, false); 19496 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. 19497 // (eg DOM renderer supports auto-focus for certain elements). 19498 // Make sure such renderers get scheduled for later work. 19499 19500 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) { 19501 markUpdate(workInProgress); 19502 } 19503 } 19504 19505 if (workInProgress.ref !== null) { 19506 // If there is a ref on a host node we need to schedule a callback 19507 markRef$1(workInProgress); 19508 } 19509 } 19510 19511 return null; 19512 } 19513 19514 case HostText: 19515 { 19516 var newText = newProps; 19517 19518 if (current && workInProgress.stateNode != null) { 19519 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need 19520 // to schedule a side-effect to do the updates. 19521 19522 updateHostText$1(current, workInProgress, oldText, newText); 19523 } else { 19524 if (typeof newText !== 'string') { 19525 if (!(workInProgress.stateNode !== null)) { 19526 { 19527 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); 19528 } 19529 } // This can happen when we abort work. 19530 19531 } 19532 19533 var _rootContainerInstance = getRootHostContainer(); 19534 19535 var _currentHostContext = getHostContext(); 19536 19537 var _wasHydrated2 = popHydrationState(workInProgress); 19538 19539 if (_wasHydrated2) { 19540 if (prepareToHydrateHostTextInstance(workInProgress)) { 19541 markUpdate(workInProgress); 19542 } 19543 } else { 19544 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress); 19545 } 19546 } 19547 19548 return null; 19549 } 19550 19551 case SuspenseComponent: 19552 { 19553 popSuspenseContext(workInProgress); 19554 var nextState = workInProgress.memoizedState; 19555 19556 if ((workInProgress.flags & DidCapture) !== NoFlags) { 19557 // Something suspended. Re-render with the fallback children. 19558 workInProgress.lanes = renderLanes; // Do not reset the effect list. 19559 19560 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 19561 transferActualDuration(workInProgress); 19562 } 19563 19564 return workInProgress; 19565 } 19566 19567 var nextDidTimeout = nextState !== null; 19568 var prevDidTimeout = false; 19569 19570 if (current === null) { 19571 if (workInProgress.memoizedProps.fallback !== undefined) { 19572 popHydrationState(workInProgress); 19573 } 19574 } else { 19575 var prevState = current.memoizedState; 19576 prevDidTimeout = prevState !== null; 19577 } 19578 19579 if (nextDidTimeout && !prevDidTimeout) { 19580 // If this subtreee is running in blocking mode we can suspend, 19581 // otherwise we won't suspend. 19582 // TODO: This will still suspend a synchronous tree if anything 19583 // in the concurrent tree already suspended during this render. 19584 // This is a known bug. 19585 if ((workInProgress.mode & BlockingMode) !== NoMode) { 19586 // TODO: Move this back to throwException because this is too late 19587 // if this is a large tree which is common for initial loads. We 19588 // don't know if we should restart a render or not until we get 19589 // this marker, and this is too late. 19590 // If this render already had a ping or lower pri updates, 19591 // and this is the first time we know we're going to suspend we 19592 // should be able to immediately restart from within throwException. 19593 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true; 19594 19595 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) { 19596 // If this was in an invisible tree or a new render, then showing 19597 // this boundary is ok. 19598 renderDidSuspend(); 19599 } else { 19600 // Otherwise, we're going to have to hide content so we should 19601 // suspend for longer if possible. 19602 renderDidSuspendDelayIfPossible(); 19603 } 19604 } 19605 } 19606 19607 { 19608 // TODO: Only schedule updates if these values are non equal, i.e. it changed. 19609 if (nextDidTimeout || prevDidTimeout) { 19610 // If this boundary just timed out, schedule an effect to attach a 19611 // retry listener to the promise. This flag is also used to hide the 19612 // primary children. In mutation mode, we also need the flag to 19613 // *unhide* children that were previously hidden, so check if this 19614 // is currently timed out, too. 19615 workInProgress.flags |= Update; 19616 } 19617 } 19618 19619 return null; 19620 } 19621 19622 case HostPortal: 19623 popHostContainer(workInProgress); 19624 updateHostContainer(workInProgress); 19625 19626 if (current === null) { 19627 preparePortalMount(workInProgress.stateNode.containerInfo); 19628 } 19629 19630 return null; 19631 19632 case ContextProvider: 19633 // Pop provider fiber 19634 popProvider(workInProgress); 19635 return null; 19636 19637 case IncompleteClassComponent: 19638 { 19639 // Same as class component case. I put it down here so that the tags are 19640 // sequential to ensure this switch is compiled to a jump table. 19641 var _Component = workInProgress.type; 19642 19643 if (isContextProvider(_Component)) { 19644 popContext(workInProgress); 19645 } 19646 19647 return null; 19648 } 19649 19650 case SuspenseListComponent: 19651 { 19652 popSuspenseContext(workInProgress); 19653 var renderState = workInProgress.memoizedState; 19654 19655 if (renderState === null) { 19656 // We're running in the default, "independent" mode. 19657 // We don't do anything in this mode. 19658 return null; 19659 } 19660 19661 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; 19662 var renderedTail = renderState.rendering; 19663 19664 if (renderedTail === null) { 19665 // We just rendered the head. 19666 if (!didSuspendAlready) { 19667 // This is the first pass. We need to figure out if anything is still 19668 // suspended in the rendered set. 19669 // If new content unsuspended, but there's still some content that 19670 // didn't. Then we need to do a second pass that forces everything 19671 // to keep showing their fallbacks. 19672 // We might be suspended if something in this render pass suspended, or 19673 // something in the previous committed pass suspended. Otherwise, 19674 // there's no chance so we can skip the expensive call to 19675 // findFirstSuspended. 19676 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags); 19677 19678 if (!cannotBeSuspended) { 19679 var row = workInProgress.child; 19680 19681 while (row !== null) { 19682 var suspended = findFirstSuspended(row); 19683 19684 if (suspended !== null) { 19685 didSuspendAlready = true; 19686 workInProgress.flags |= DidCapture; 19687 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as 19688 // part of the second pass. In that case nothing will subscribe to 19689 // its thennables. Instead, we'll transfer its thennables to the 19690 // SuspenseList so that it can retry if they resolve. 19691 // There might be multiple of these in the list but since we're 19692 // going to wait for all of them anyway, it doesn't really matter 19693 // which ones gets to ping. In theory we could get clever and keep 19694 // track of how many dependencies remain but it gets tricky because 19695 // in the meantime, we can add/remove/change items and dependencies. 19696 // We might bail out of the loop before finding any but that 19697 // doesn't matter since that means that the other boundaries that 19698 // we did find already has their listeners attached. 19699 19700 var newThennables = suspended.updateQueue; 19701 19702 if (newThennables !== null) { 19703 workInProgress.updateQueue = newThennables; 19704 workInProgress.flags |= Update; 19705 } // Rerender the whole list, but this time, we'll force fallbacks 19706 // to stay in place. 19707 // Reset the effect list before doing the second pass since that's now invalid. 19708 19709 19710 if (renderState.lastEffect === null) { 19711 workInProgress.firstEffect = null; 19712 } 19713 19714 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. 19715 19716 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately 19717 // rerender the children. 19718 19719 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); 19720 return workInProgress.child; 19721 } 19722 19723 row = row.sibling; 19724 } 19725 } 19726 19727 if (renderState.tail !== null && now() > getRenderTargetTime()) { 19728 // We have already passed our CPU deadline but we still have rows 19729 // left in the tail. We'll just give up further attempts to render 19730 // the main content and only render fallbacks. 19731 workInProgress.flags |= DidCapture; 19732 didSuspendAlready = true; 19733 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this 19734 // to get it started back up to attempt the next item. While in terms 19735 // of priority this work has the same priority as this current render, 19736 // it's not part of the same transition once the transition has 19737 // committed. If it's sync, we still want to yield so that it can be 19738 // painted. Conceptually, this is really the same as pinging. 19739 // We can use any RetryLane even if it's the one currently rendering 19740 // since we're leaving it behind on this node. 19741 19742 workInProgress.lanes = SomeRetryLane; 19743 19744 { 19745 markSpawnedWork(SomeRetryLane); 19746 } 19747 } 19748 } else { 19749 cutOffTailIfNeeded(renderState, false); 19750 } // Next we're going to render the tail. 19751 19752 } else { 19753 // Append the rendered row to the child list. 19754 if (!didSuspendAlready) { 19755 var _suspended = findFirstSuspended(renderedTail); 19756 19757 if (_suspended !== null) { 19758 workInProgress.flags |= DidCapture; 19759 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't 19760 // get lost if this row ends up dropped during a second pass. 19761 19762 var _newThennables = _suspended.updateQueue; 19763 19764 if (_newThennables !== null) { 19765 workInProgress.updateQueue = _newThennables; 19766 workInProgress.flags |= Update; 19767 } 19768 19769 cutOffTailIfNeeded(renderState, true); // This might have been modified. 19770 19771 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating. 19772 ) { 19773 // We need to delete the row we just rendered. 19774 // Reset the effect list to what it was before we rendered this 19775 // child. The nested children have already appended themselves. 19776 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point. 19777 19778 if (lastEffect !== null) { 19779 lastEffect.nextEffect = null; 19780 } // We're done. 19781 19782 19783 return null; 19784 } 19785 } else if ( // The time it took to render last row is greater than the remaining 19786 // time we have to render. So rendering one more row would likely 19787 // exceed it. 19788 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) { 19789 // We have now passed our CPU deadline and we'll just give up further 19790 // attempts to render the main content and only render fallbacks. 19791 // The assumption is that this is usually faster. 19792 workInProgress.flags |= DidCapture; 19793 didSuspendAlready = true; 19794 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this 19795 // to get it started back up to attempt the next item. While in terms 19796 // of priority this work has the same priority as this current render, 19797 // it's not part of the same transition once the transition has 19798 // committed. If it's sync, we still want to yield so that it can be 19799 // painted. Conceptually, this is really the same as pinging. 19800 // We can use any RetryLane even if it's the one currently rendering 19801 // since we're leaving it behind on this node. 19802 19803 workInProgress.lanes = SomeRetryLane; 19804 19805 { 19806 markSpawnedWork(SomeRetryLane); 19807 } 19808 } 19809 } 19810 19811 if (renderState.isBackwards) { 19812 // The effect list of the backwards tail will have been added 19813 // to the end. This breaks the guarantee that life-cycles fire in 19814 // sibling order but that isn't a strong guarantee promised by React. 19815 // Especially since these might also just pop in during future commits. 19816 // Append to the beginning of the list. 19817 renderedTail.sibling = workInProgress.child; 19818 workInProgress.child = renderedTail; 19819 } else { 19820 var previousSibling = renderState.last; 19821 19822 if (previousSibling !== null) { 19823 previousSibling.sibling = renderedTail; 19824 } else { 19825 workInProgress.child = renderedTail; 19826 } 19827 19828 renderState.last = renderedTail; 19829 } 19830 } 19831 19832 if (renderState.tail !== null) { 19833 // We still have tail rows to render. 19834 // Pop a row. 19835 var next = renderState.tail; 19836 renderState.rendering = next; 19837 renderState.tail = next.sibling; 19838 renderState.lastEffect = workInProgress.lastEffect; 19839 renderState.renderingStartTime = now(); 19840 next.sibling = null; // Restore the context. 19841 // TODO: We can probably just avoid popping it instead and only 19842 // setting it the first time we go from not suspended to suspended. 19843 19844 var suspenseContext = suspenseStackCursor.current; 19845 19846 if (didSuspendAlready) { 19847 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); 19848 } else { 19849 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 19850 } 19851 19852 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. 19853 19854 return next; 19855 } 19856 19857 return null; 19858 } 19859 19860 case FundamentalComponent: 19861 { 19862 19863 break; 19864 } 19865 19866 case ScopeComponent: 19867 { 19868 19869 break; 19870 } 19871 19872 case Block: 19873 19874 break; 19875 19876 case OffscreenComponent: 19877 case LegacyHiddenComponent: 19878 { 19879 popRenderLanes(workInProgress); 19880 19881 if (current !== null) { 19882 var _nextState = workInProgress.memoizedState; 19883 var _prevState = current.memoizedState; 19884 var prevIsHidden = _prevState !== null; 19885 var nextIsHidden = _nextState !== null; 19886 19887 if (prevIsHidden !== nextIsHidden && newProps.mode !== 'unstable-defer-without-hiding') { 19888 workInProgress.flags |= Update; 19889 } 19890 } 19891 19892 return null; 19893 } 19894 } 19895 19896 { 19897 { 19898 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." ); 19899 } 19900 } 19901 } 19902 19903 function unwindWork(workInProgress, renderLanes) { 19904 switch (workInProgress.tag) { 19905 case ClassComponent: 19906 { 19907 var Component = workInProgress.type; 19908 19909 if (isContextProvider(Component)) { 19910 popContext(workInProgress); 19911 } 19912 19913 var flags = workInProgress.flags; 19914 19915 if (flags & ShouldCapture) { 19916 workInProgress.flags = flags & ~ShouldCapture | DidCapture; 19917 19918 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 19919 transferActualDuration(workInProgress); 19920 } 19921 19922 return workInProgress; 19923 } 19924 19925 return null; 19926 } 19927 19928 case HostRoot: 19929 { 19930 popHostContainer(workInProgress); 19931 popTopLevelContextObject(workInProgress); 19932 resetWorkInProgressVersions(); 19933 var _flags = workInProgress.flags; 19934 19935 if (!((_flags & DidCapture) === NoFlags)) { 19936 { 19937 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); 19938 } 19939 } 19940 19941 workInProgress.flags = _flags & ~ShouldCapture | DidCapture; 19942 return workInProgress; 19943 } 19944 19945 case HostComponent: 19946 { 19947 // TODO: popHydrationState 19948 popHostContext(workInProgress); 19949 return null; 19950 } 19951 19952 case SuspenseComponent: 19953 { 19954 popSuspenseContext(workInProgress); 19955 19956 var _flags2 = workInProgress.flags; 19957 19958 if (_flags2 & ShouldCapture) { 19959 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary. 19960 19961 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 19962 transferActualDuration(workInProgress); 19963 } 19964 19965 return workInProgress; 19966 } 19967 19968 return null; 19969 } 19970 19971 case SuspenseListComponent: 19972 { 19973 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been 19974 // caught by a nested boundary. If not, it should bubble through. 19975 19976 return null; 19977 } 19978 19979 case HostPortal: 19980 popHostContainer(workInProgress); 19981 return null; 19982 19983 case ContextProvider: 19984 popProvider(workInProgress); 19985 return null; 19986 19987 case OffscreenComponent: 19988 case LegacyHiddenComponent: 19989 popRenderLanes(workInProgress); 19990 return null; 19991 19992 default: 19993 return null; 19994 } 19995 } 19996 19997 function unwindInterruptedWork(interruptedWork) { 19998 switch (interruptedWork.tag) { 19999 case ClassComponent: 20000 { 20001 var childContextTypes = interruptedWork.type.childContextTypes; 20002 20003 if (childContextTypes !== null && childContextTypes !== undefined) { 20004 popContext(interruptedWork); 20005 } 20006 20007 break; 20008 } 20009 20010 case HostRoot: 20011 { 20012 popHostContainer(interruptedWork); 20013 popTopLevelContextObject(interruptedWork); 20014 resetWorkInProgressVersions(); 20015 break; 20016 } 20017 20018 case HostComponent: 20019 { 20020 popHostContext(interruptedWork); 20021 break; 20022 } 20023 20024 case HostPortal: 20025 popHostContainer(interruptedWork); 20026 break; 20027 20028 case SuspenseComponent: 20029 popSuspenseContext(interruptedWork); 20030 break; 20031 20032 case SuspenseListComponent: 20033 popSuspenseContext(interruptedWork); 20034 break; 20035 20036 case ContextProvider: 20037 popProvider(interruptedWork); 20038 break; 20039 20040 case OffscreenComponent: 20041 case LegacyHiddenComponent: 20042 popRenderLanes(interruptedWork); 20043 break; 20044 } 20045 } 20046 20047 function createCapturedValue(value, source) { 20048 // If the value is an error, call this function immediately after it is thrown 20049 // so the stack is accurate. 20050 return { 20051 value: value, 20052 source: source, 20053 stack: getStackByFiberInDevAndProd(source) 20054 }; 20055 } 20056 20057 // This module is forked in different environments. 20058 // By default, return `true` to log errors to the console. 20059 // Forks can return `false` if this isn't desirable. 20060 function showErrorDialog(boundary, errorInfo) { 20061 return true; 20062 } 20063 20064 function logCapturedError(boundary, errorInfo) { 20065 try { 20066 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. 20067 // This enables renderers like ReactNative to better manage redbox behavior. 20068 20069 if (logError === false) { 20070 return; 20071 } 20072 20073 var error = errorInfo.value; 20074 20075 if (true) { 20076 var source = errorInfo.source; 20077 var stack = errorInfo.stack; 20078 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling 20079 // `preventDefault()` in window `error` handler. 20080 // We record this information as an expando on the error. 20081 20082 if (error != null && error._suppressLogging) { 20083 if (boundary.tag === ClassComponent) { 20084 // The error is recoverable and was silenced. 20085 // Ignore it and don't print the stack addendum. 20086 // This is handy for testing error boundaries without noise. 20087 return; 20088 } // The error is fatal. Since the silencing might have 20089 // been accidental, we'll surface it anyway. 20090 // However, the browser would have silenced the original error 20091 // so we'll print it first, and then print the stack addendum. 20092 20093 20094 console['error'](error); // Don't transform to our wrapper 20095 // For a more detailed description of this block, see: 20096 // https://github.com/facebook/react/pull/13384 20097 } 20098 20099 var componentName = source ? getComponentName(source.type) : null; 20100 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:'; 20101 var errorBoundaryMessage; 20102 var errorBoundaryName = getComponentName(boundary.type); 20103 20104 if (errorBoundaryName) { 20105 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + "."); 20106 } else { 20107 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.'; 20108 } 20109 20110 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. 20111 // We don't include the original error message and JS stack because the browser 20112 // has already printed it. Even if the application swallows the error, it is still 20113 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. 20114 20115 console['error'](combinedMessage); // Don't transform to our wrapper 20116 } else { 20117 // In production, we print the error directly. 20118 // This will include the message, the JS stack, and anything the browser wants to show. 20119 // We pass the error object instead of custom message so that the browser displays the error natively. 20120 console['error'](error); // Don't transform to our wrapper 20121 } 20122 } catch (e) { 20123 // This method must not throw, or React internal state will get messed up. 20124 // If console.error is overridden, or logCapturedError() shows a dialog that throws, 20125 // we want to report this error outside of the normal stack as a last resort. 20126 // https://github.com/facebook/react/issues/13188 20127 setTimeout(function () { 20128 throw e; 20129 }); 20130 } 20131 } 20132 20133 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map; 20134 20135 function createRootErrorUpdate(fiber, errorInfo, lane) { 20136 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. 20137 20138 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property 20139 // being called "element". 20140 20141 update.payload = { 20142 element: null 20143 }; 20144 var error = errorInfo.value; 20145 20146 update.callback = function () { 20147 onUncaughtError(error); 20148 logCapturedError(fiber, errorInfo); 20149 }; 20150 20151 return update; 20152 } 20153 20154 function createClassErrorUpdate(fiber, errorInfo, lane) { 20155 var update = createUpdate(NoTimestamp, lane); 20156 update.tag = CaptureUpdate; 20157 var getDerivedStateFromError = fiber.type.getDerivedStateFromError; 20158 20159 if (typeof getDerivedStateFromError === 'function') { 20160 var error$1 = errorInfo.value; 20161 20162 update.payload = function () { 20163 logCapturedError(fiber, errorInfo); 20164 return getDerivedStateFromError(error$1); 20165 }; 20166 } 20167 20168 var inst = fiber.stateNode; 20169 20170 if (inst !== null && typeof inst.componentDidCatch === 'function') { 20171 update.callback = function callback() { 20172 { 20173 markFailedErrorBoundaryForHotReloading(fiber); 20174 } 20175 20176 if (typeof getDerivedStateFromError !== 'function') { 20177 // To preserve the preexisting retry behavior of error boundaries, 20178 // we keep track of which ones already failed during this batch. 20179 // This gets reset before we yield back to the browser. 20180 // TODO: Warn in strict mode if getDerivedStateFromError is 20181 // not defined. 20182 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined 20183 20184 logCapturedError(fiber, errorInfo); 20185 } 20186 20187 var error$1 = errorInfo.value; 20188 var stack = errorInfo.stack; 20189 this.componentDidCatch(error$1, { 20190 componentStack: stack !== null ? stack : '' 20191 }); 20192 20193 { 20194 if (typeof getDerivedStateFromError !== 'function') { 20195 // If componentDidCatch is the only error boundary method defined, 20196 // then it needs to call setState to recover from errors. 20197 // If no state update is scheduled then the boundary will swallow the error. 20198 if (!includesSomeLane(fiber.lanes, SyncLane)) { 20199 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown'); 20200 } 20201 } 20202 } 20203 }; 20204 } else { 20205 update.callback = function () { 20206 markFailedErrorBoundaryForHotReloading(fiber); 20207 }; 20208 } 20209 20210 return update; 20211 } 20212 20213 function attachPingListener(root, wakeable, lanes) { 20214 // Attach a listener to the promise to "ping" the root and retry. But only if 20215 // one does not already exist for the lanes we're currently rendering (which 20216 // acts like a "thread ID" here). 20217 var pingCache = root.pingCache; 20218 var threadIDs; 20219 20220 if (pingCache === null) { 20221 pingCache = root.pingCache = new PossiblyWeakMap$1(); 20222 threadIDs = new Set(); 20223 pingCache.set(wakeable, threadIDs); 20224 } else { 20225 threadIDs = pingCache.get(wakeable); 20226 20227 if (threadIDs === undefined) { 20228 threadIDs = new Set(); 20229 pingCache.set(wakeable, threadIDs); 20230 } 20231 } 20232 20233 if (!threadIDs.has(lanes)) { 20234 // Memoize using the thread ID to prevent redundant listeners. 20235 threadIDs.add(lanes); 20236 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); 20237 wakeable.then(ping, ping); 20238 } 20239 } 20240 20241 function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) { 20242 // The source fiber did not complete. 20243 sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. 20244 20245 sourceFiber.firstEffect = sourceFiber.lastEffect = null; 20246 20247 if (value !== null && typeof value === 'object' && typeof value.then === 'function') { 20248 // This is a wakeable. 20249 var wakeable = value; 20250 20251 if ((sourceFiber.mode & BlockingMode) === NoMode) { 20252 // Reset the memoizedState to what it was before we attempted 20253 // to render it. 20254 var currentSource = sourceFiber.alternate; 20255 20256 if (currentSource) { 20257 sourceFiber.updateQueue = currentSource.updateQueue; 20258 sourceFiber.memoizedState = currentSource.memoizedState; 20259 sourceFiber.lanes = currentSource.lanes; 20260 } else { 20261 sourceFiber.updateQueue = null; 20262 sourceFiber.memoizedState = null; 20263 } 20264 } 20265 20266 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view. 20267 20268 var _workInProgress = returnFiber; 20269 20270 do { 20271 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) { 20272 // Found the nearest boundary. 20273 // Stash the promise on the boundary fiber. If the boundary times out, we'll 20274 // attach another listener to flip the boundary back to its normal state. 20275 var wakeables = _workInProgress.updateQueue; 20276 20277 if (wakeables === null) { 20278 var updateQueue = new Set(); 20279 updateQueue.add(wakeable); 20280 _workInProgress.updateQueue = updateQueue; 20281 } else { 20282 wakeables.add(wakeable); 20283 } // If the boundary is outside of blocking mode, we should *not* 20284 // suspend the commit. Pretend as if the suspended component rendered 20285 // null and keep rendering. In the commit phase, we'll schedule a 20286 // subsequent synchronous update to re-render the Suspense. 20287 // 20288 // Note: It doesn't matter whether the component that suspended was 20289 // inside a blocking mode tree. If the Suspense is outside of it, we 20290 // should *not* suspend the commit. 20291 20292 20293 if ((_workInProgress.mode & BlockingMode) === NoMode) { 20294 _workInProgress.flags |= DidCapture; 20295 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. 20296 // But we shouldn't call any lifecycle methods or callbacks. Remove 20297 // all lifecycle effect tags. 20298 20299 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); 20300 20301 if (sourceFiber.tag === ClassComponent) { 20302 var currentSourceFiber = sourceFiber.alternate; 20303 20304 if (currentSourceFiber === null) { 20305 // This is a new mount. Change the tag so it's not mistaken for a 20306 // completed class component. For example, we should not call 20307 // componentWillUnmount if it is deleted. 20308 sourceFiber.tag = IncompleteClassComponent; 20309 } else { 20310 // When we try rendering again, we should not reuse the current fiber, 20311 // since it's known to be in an inconsistent state. Use a force update to 20312 // prevent a bail out. 20313 var update = createUpdate(NoTimestamp, SyncLane); 20314 update.tag = ForceUpdate; 20315 enqueueUpdate(sourceFiber, update); 20316 } 20317 } // The source fiber did not complete. Mark it with Sync priority to 20318 // indicate that it still has pending work. 20319 20320 20321 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. 20322 20323 return; 20324 } // Confirmed that the boundary is in a concurrent mode tree. Continue 20325 // with the normal suspend path. 20326 // 20327 // After this we'll use a set of heuristics to determine whether this 20328 // render pass will run to completion or restart or "suspend" the commit. 20329 // The actual logic for this is spread out in different places. 20330 // 20331 // This first principle is that if we're going to suspend when we complete 20332 // a root, then we should also restart if we get an update or ping that 20333 // might unsuspend it, and vice versa. The only reason to suspend is 20334 // because you think you might want to restart before committing. However, 20335 // it doesn't make sense to restart only while in the period we're suspended. 20336 // 20337 // Restarting too aggressively is also not good because it starves out any 20338 // intermediate loading state. So we use heuristics to determine when. 20339 // Suspense Heuristics 20340 // 20341 // If nothing threw a Promise or all the same fallbacks are already showing, 20342 // then don't suspend/restart. 20343 // 20344 // If this is an initial render of a new tree of Suspense boundaries and 20345 // those trigger a fallback, then don't suspend/restart. We want to ensure 20346 // that we can show the initial loading state as quickly as possible. 20347 // 20348 // If we hit a "Delayed" case, such as when we'd switch from content back into 20349 // a fallback, then we should always suspend/restart. Transitions apply 20350 // to this case. If none is defined, JND is used instead. 20351 // 20352 // If we're already showing a fallback and it gets "retried", allowing us to show 20353 // another level, but there's still an inner boundary that would show a fallback, 20354 // then we suspend/restart for 500ms since the last time we showed a fallback 20355 // anywhere in the tree. This effectively throttles progressive loading into a 20356 // consistent train of commits. This also gives us an opportunity to restart to 20357 // get to the completed state slightly earlier. 20358 // 20359 // If there's ambiguity due to batching it's resolved in preference of: 20360 // 1) "delayed", 2) "initial render", 3) "retry". 20361 // 20362 // We want to ensure that a "busy" state doesn't get force committed. We want to 20363 // ensure that new initial loading states can commit as soon as possible. 20364 20365 20366 attachPingListener(root, wakeable, rootRenderLanes); 20367 _workInProgress.flags |= ShouldCapture; 20368 _workInProgress.lanes = rootRenderLanes; 20369 return; 20370 } // This boundary already captured during this render. Continue to the next 20371 // boundary. 20372 20373 20374 _workInProgress = _workInProgress.return; 20375 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. 20376 // TODO: Use invariant so the message is stripped in prod? 20377 20378 20379 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.'); 20380 } // We didn't find a boundary that could handle this type of exception. Start 20381 // over and traverse parent path again, this time treating the exception 20382 // as an error. 20383 20384 20385 renderDidError(); 20386 value = createCapturedValue(value, sourceFiber); 20387 var workInProgress = returnFiber; 20388 20389 do { 20390 switch (workInProgress.tag) { 20391 case HostRoot: 20392 { 20393 var _errorInfo = value; 20394 workInProgress.flags |= ShouldCapture; 20395 var lane = pickArbitraryLane(rootRenderLanes); 20396 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); 20397 20398 var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); 20399 20400 enqueueCapturedUpdate(workInProgress, _update); 20401 return; 20402 } 20403 20404 case ClassComponent: 20405 // Capture and retry 20406 var errorInfo = value; 20407 var ctor = workInProgress.type; 20408 var instance = workInProgress.stateNode; 20409 20410 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) { 20411 workInProgress.flags |= ShouldCapture; 20412 20413 var _lane = pickArbitraryLane(rootRenderLanes); 20414 20415 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state 20416 20417 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, _lane); 20418 20419 enqueueCapturedUpdate(workInProgress, _update2); 20420 return; 20421 } 20422 20423 break; 20424 } 20425 20426 workInProgress = workInProgress.return; 20427 } while (workInProgress !== null); 20428 } 20429 20430 var didWarnAboutUndefinedSnapshotBeforeUpdate = null; 20431 20432 { 20433 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); 20434 } 20435 20436 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set; 20437 20438 var callComponentWillUnmountWithTimer = function (current, instance) { 20439 instance.props = current.memoizedProps; 20440 instance.state = current.memoizedState; 20441 20442 { 20443 instance.componentWillUnmount(); 20444 } 20445 }; // Capture errors so they don't interrupt unmounting. 20446 20447 20448 function safelyCallComponentWillUnmount(current, instance) { 20449 { 20450 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance); 20451 20452 if (hasCaughtError()) { 20453 var unmountError = clearCaughtError(); 20454 captureCommitPhaseError(current, unmountError); 20455 } 20456 } 20457 } 20458 20459 function safelyDetachRef(current) { 20460 var ref = current.ref; 20461 20462 if (ref !== null) { 20463 if (typeof ref === 'function') { 20464 { 20465 invokeGuardedCallback(null, ref, null, null); 20466 20467 if (hasCaughtError()) { 20468 var refError = clearCaughtError(); 20469 captureCommitPhaseError(current, refError); 20470 } 20471 } 20472 } else { 20473 ref.current = null; 20474 } 20475 } 20476 } 20477 20478 function safelyCallDestroy(current, destroy) { 20479 { 20480 invokeGuardedCallback(null, destroy, null); 20481 20482 if (hasCaughtError()) { 20483 var error = clearCaughtError(); 20484 captureCommitPhaseError(current, error); 20485 } 20486 } 20487 } 20488 20489 function commitBeforeMutationLifeCycles(current, finishedWork) { 20490 switch (finishedWork.tag) { 20491 case FunctionComponent: 20492 case ForwardRef: 20493 case SimpleMemoComponent: 20494 case Block: 20495 { 20496 return; 20497 } 20498 20499 case ClassComponent: 20500 { 20501 if (finishedWork.flags & Snapshot) { 20502 if (current !== null) { 20503 var prevProps = current.memoizedProps; 20504 var prevState = current.memoizedState; 20505 var instance = finishedWork.stateNode; // We could update instance props and state here, 20506 // but instead we rely on them being set during last render. 20507 // TODO: revisit this when we implement resuming. 20508 20509 { 20510 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 20511 if (instance.props !== finishedWork.memoizedProps) { 20512 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.', getComponentName(finishedWork.type) || 'instance'); 20513 } 20514 20515 if (instance.state !== finishedWork.memoizedState) { 20516 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.', getComponentName(finishedWork.type) || 'instance'); 20517 } 20518 } 20519 } 20520 20521 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState); 20522 20523 { 20524 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; 20525 20526 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { 20527 didWarnSet.add(finishedWork.type); 20528 20529 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type)); 20530 } 20531 } 20532 20533 instance.__reactInternalSnapshotBeforeUpdate = snapshot; 20534 } 20535 } 20536 20537 return; 20538 } 20539 20540 case HostRoot: 20541 { 20542 { 20543 if (finishedWork.flags & Snapshot) { 20544 var root = finishedWork.stateNode; 20545 clearContainer(root.containerInfo); 20546 } 20547 } 20548 20549 return; 20550 } 20551 20552 case HostComponent: 20553 case HostText: 20554 case HostPortal: 20555 case IncompleteClassComponent: 20556 // Nothing to do for these component types 20557 return; 20558 } 20559 20560 { 20561 { 20562 throw 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." ); 20563 } 20564 } 20565 } 20566 20567 function commitHookEffectListUnmount(tag, finishedWork) { 20568 var updateQueue = finishedWork.updateQueue; 20569 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 20570 20571 if (lastEffect !== null) { 20572 var firstEffect = lastEffect.next; 20573 var effect = firstEffect; 20574 20575 do { 20576 if ((effect.tag & tag) === tag) { 20577 // Unmount 20578 var destroy = effect.destroy; 20579 effect.destroy = undefined; 20580 20581 if (destroy !== undefined) { 20582 destroy(); 20583 } 20584 } 20585 20586 effect = effect.next; 20587 } while (effect !== firstEffect); 20588 } 20589 } 20590 20591 function commitHookEffectListMount(tag, finishedWork) { 20592 var updateQueue = finishedWork.updateQueue; 20593 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 20594 20595 if (lastEffect !== null) { 20596 var firstEffect = lastEffect.next; 20597 var effect = firstEffect; 20598 20599 do { 20600 if ((effect.tag & tag) === tag) { 20601 // Mount 20602 var create = effect.create; 20603 effect.destroy = create(); 20604 20605 { 20606 var destroy = effect.destroy; 20607 20608 if (destroy !== undefined && typeof destroy !== 'function') { 20609 var addendum = void 0; 20610 20611 if (destroy === null) { 20612 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).'; 20613 } else if (typeof destroy.then === 'function') { 20614 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching'; 20615 } else { 20616 addendum = ' You returned: ' + destroy; 20617 } 20618 20619 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s', addendum); 20620 } 20621 } 20622 } 20623 20624 effect = effect.next; 20625 } while (effect !== firstEffect); 20626 } 20627 } 20628 20629 function schedulePassiveEffects(finishedWork) { 20630 var updateQueue = finishedWork.updateQueue; 20631 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 20632 20633 if (lastEffect !== null) { 20634 var firstEffect = lastEffect.next; 20635 var effect = firstEffect; 20636 20637 do { 20638 var _effect = effect, 20639 next = _effect.next, 20640 tag = _effect.tag; 20641 20642 if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { 20643 enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); 20644 enqueuePendingPassiveHookEffectMount(finishedWork, effect); 20645 } 20646 20647 effect = next; 20648 } while (effect !== firstEffect); 20649 } 20650 } 20651 20652 function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { 20653 switch (finishedWork.tag) { 20654 case FunctionComponent: 20655 case ForwardRef: 20656 case SimpleMemoComponent: 20657 case Block: 20658 { 20659 // At this point layout effects have already been destroyed (during mutation phase). 20660 // This is done to prevent sibling component effects from interfering with each other, 20661 // e.g. a destroy function in one component should never override a ref set 20662 // by a create function in another component during the same commit. 20663 { 20664 commitHookEffectListMount(Layout | HasEffect, finishedWork); 20665 } 20666 20667 schedulePassiveEffects(finishedWork); 20668 return; 20669 } 20670 20671 case ClassComponent: 20672 { 20673 var instance = finishedWork.stateNode; 20674 20675 if (finishedWork.flags & Update) { 20676 if (current === null) { 20677 // We could update instance props and state here, 20678 // but instead we rely on them being set during last render. 20679 // TODO: revisit this when we implement resuming. 20680 { 20681 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 20682 if (instance.props !== finishedWork.memoizedProps) { 20683 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.', getComponentName(finishedWork.type) || 'instance'); 20684 } 20685 20686 if (instance.state !== finishedWork.memoizedState) { 20687 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.', getComponentName(finishedWork.type) || 'instance'); 20688 } 20689 } 20690 } 20691 20692 { 20693 instance.componentDidMount(); 20694 } 20695 } else { 20696 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps); 20697 var prevState = current.memoizedState; // We could update instance props and state here, 20698 // but instead we rely on them being set during last render. 20699 // TODO: revisit this when we implement resuming. 20700 20701 { 20702 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 20703 if (instance.props !== finishedWork.memoizedProps) { 20704 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.', getComponentName(finishedWork.type) || 'instance'); 20705 } 20706 20707 if (instance.state !== finishedWork.memoizedState) { 20708 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.', getComponentName(finishedWork.type) || 'instance'); 20709 } 20710 } 20711 } 20712 20713 { 20714 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); 20715 } 20716 } 20717 } // TODO: I think this is now always non-null by the time it reaches the 20718 // commit phase. Consider removing the type check. 20719 20720 20721 var updateQueue = finishedWork.updateQueue; 20722 20723 if (updateQueue !== null) { 20724 { 20725 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 20726 if (instance.props !== finishedWork.memoizedProps) { 20727 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.', getComponentName(finishedWork.type) || 'instance'); 20728 } 20729 20730 if (instance.state !== finishedWork.memoizedState) { 20731 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.', getComponentName(finishedWork.type) || 'instance'); 20732 } 20733 } 20734 } // We could update instance props and state here, 20735 // but instead we rely on them being set during last render. 20736 // TODO: revisit this when we implement resuming. 20737 20738 20739 commitUpdateQueue(finishedWork, updateQueue, instance); 20740 } 20741 20742 return; 20743 } 20744 20745 case HostRoot: 20746 { 20747 // TODO: I think this is now always non-null by the time it reaches the 20748 // commit phase. Consider removing the type check. 20749 var _updateQueue = finishedWork.updateQueue; 20750 20751 if (_updateQueue !== null) { 20752 var _instance = null; 20753 20754 if (finishedWork.child !== null) { 20755 switch (finishedWork.child.tag) { 20756 case HostComponent: 20757 _instance = getPublicInstance(finishedWork.child.stateNode); 20758 break; 20759 20760 case ClassComponent: 20761 _instance = finishedWork.child.stateNode; 20762 break; 20763 } 20764 } 20765 20766 commitUpdateQueue(finishedWork, _updateQueue, _instance); 20767 } 20768 20769 return; 20770 } 20771 20772 case HostComponent: 20773 { 20774 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted 20775 // (eg DOM renderer may schedule auto-focus for inputs and form controls). 20776 // These effects should only be committed when components are first mounted, 20777 // aka when there is no current/alternate. 20778 20779 if (current === null && finishedWork.flags & Update) { 20780 var type = finishedWork.type; 20781 var props = finishedWork.memoizedProps; 20782 commitMount(_instance2, type, props); 20783 } 20784 20785 return; 20786 } 20787 20788 case HostText: 20789 { 20790 // We have no life-cycles associated with text. 20791 return; 20792 } 20793 20794 case HostPortal: 20795 { 20796 // We have no life-cycles associated with portals. 20797 return; 20798 } 20799 20800 case Profiler: 20801 { 20802 { 20803 var _finishedWork$memoize2 = finishedWork.memoizedProps, 20804 onCommit = _finishedWork$memoize2.onCommit, 20805 onRender = _finishedWork$memoize2.onRender; 20806 var effectDuration = finishedWork.stateNode.effectDuration; 20807 var commitTime = getCommitTime(); 20808 20809 if (typeof onRender === 'function') { 20810 { 20811 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime, finishedRoot.memoizedInteractions); 20812 } 20813 } 20814 } 20815 20816 return; 20817 } 20818 20819 case SuspenseComponent: 20820 { 20821 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); 20822 return; 20823 } 20824 20825 case SuspenseListComponent: 20826 case IncompleteClassComponent: 20827 case FundamentalComponent: 20828 case ScopeComponent: 20829 case OffscreenComponent: 20830 case LegacyHiddenComponent: 20831 return; 20832 } 20833 20834 { 20835 { 20836 throw 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." ); 20837 } 20838 } 20839 } 20840 20841 function hideOrUnhideAllChildren(finishedWork, isHidden) { 20842 { 20843 // We only have the top Fiber that was inserted but we need to recurse down its 20844 // children to find all the terminal nodes. 20845 var node = finishedWork; 20846 20847 while (true) { 20848 if (node.tag === HostComponent) { 20849 var instance = node.stateNode; 20850 20851 if (isHidden) { 20852 hideInstance(instance); 20853 } else { 20854 unhideInstance(node.stateNode, node.memoizedProps); 20855 } 20856 } else if (node.tag === HostText) { 20857 var _instance3 = node.stateNode; 20858 20859 if (isHidden) { 20860 hideTextInstance(_instance3); 20861 } else { 20862 unhideTextInstance(_instance3, node.memoizedProps); 20863 } 20864 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) { 20865 node.child.return = node; 20866 node = node.child; 20867 continue; 20868 } 20869 20870 if (node === finishedWork) { 20871 return; 20872 } 20873 20874 while (node.sibling === null) { 20875 if (node.return === null || node.return === finishedWork) { 20876 return; 20877 } 20878 20879 node = node.return; 20880 } 20881 20882 node.sibling.return = node.return; 20883 node = node.sibling; 20884 } 20885 } 20886 } 20887 20888 function commitAttachRef(finishedWork) { 20889 var ref = finishedWork.ref; 20890 20891 if (ref !== null) { 20892 var instance = finishedWork.stateNode; 20893 var instanceToUse; 20894 20895 switch (finishedWork.tag) { 20896 case HostComponent: 20897 instanceToUse = getPublicInstance(instance); 20898 break; 20899 20900 default: 20901 instanceToUse = instance; 20902 } // Moved outside to ensure DCE works with this flag 20903 20904 if (typeof ref === 'function') { 20905 ref(instanceToUse); 20906 } else { 20907 { 20908 if (!ref.hasOwnProperty('current')) { 20909 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentName(finishedWork.type)); 20910 } 20911 } 20912 20913 ref.current = instanceToUse; 20914 } 20915 } 20916 } 20917 20918 function commitDetachRef(current) { 20919 var currentRef = current.ref; 20920 20921 if (currentRef !== null) { 20922 if (typeof currentRef === 'function') { 20923 currentRef(null); 20924 } else { 20925 currentRef.current = null; 20926 } 20927 } 20928 } // User-originating errors (lifecycles and refs) should not interrupt 20929 // deletion, so don't let them throw. Host-originating errors should 20930 // interrupt deletion, so it's okay 20931 20932 20933 function commitUnmount(finishedRoot, current, renderPriorityLevel) { 20934 onCommitUnmount(current); 20935 20936 switch (current.tag) { 20937 case FunctionComponent: 20938 case ForwardRef: 20939 case MemoComponent: 20940 case SimpleMemoComponent: 20941 case Block: 20942 { 20943 var updateQueue = current.updateQueue; 20944 20945 if (updateQueue !== null) { 20946 var lastEffect = updateQueue.lastEffect; 20947 20948 if (lastEffect !== null) { 20949 var firstEffect = lastEffect.next; 20950 var effect = firstEffect; 20951 20952 do { 20953 var _effect2 = effect, 20954 destroy = _effect2.destroy, 20955 tag = _effect2.tag; 20956 20957 if (destroy !== undefined) { 20958 if ((tag & Passive$1) !== NoFlags$1) { 20959 enqueuePendingPassiveHookEffectUnmount(current, effect); 20960 } else { 20961 { 20962 safelyCallDestroy(current, destroy); 20963 } 20964 } 20965 } 20966 20967 effect = effect.next; 20968 } while (effect !== firstEffect); 20969 } 20970 } 20971 20972 return; 20973 } 20974 20975 case ClassComponent: 20976 { 20977 safelyDetachRef(current); 20978 var instance = current.stateNode; 20979 20980 if (typeof instance.componentWillUnmount === 'function') { 20981 safelyCallComponentWillUnmount(current, instance); 20982 } 20983 20984 return; 20985 } 20986 20987 case HostComponent: 20988 { 20989 safelyDetachRef(current); 20990 return; 20991 } 20992 20993 case HostPortal: 20994 { 20995 // TODO: this is recursive. 20996 // We are also not using this parent because 20997 // the portal will get pushed immediately. 20998 { 20999 unmountHostComponents(finishedRoot, current); 21000 } 21001 21002 return; 21003 } 21004 21005 case FundamentalComponent: 21006 { 21007 21008 return; 21009 } 21010 21011 case DehydratedFragment: 21012 { 21013 21014 return; 21015 } 21016 21017 case ScopeComponent: 21018 { 21019 21020 return; 21021 } 21022 } 21023 } 21024 21025 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { 21026 // While we're inside a removed host node we don't want to call 21027 // removeChild on the inner nodes because they're removed by the top 21028 // call anyway. We also want to call componentWillUnmount on all 21029 // composites before this host node is removed from the tree. Therefore 21030 // we do an inner loop while we're still inside the host node. 21031 var node = root; 21032 21033 while (true) { 21034 commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. 21035 // Skip portals because commitUnmount() currently visits them recursively. 21036 21037 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above. 21038 // If we don't use mutation we drill down into portals here instead. 21039 node.tag !== HostPortal)) { 21040 node.child.return = node; 21041 node = node.child; 21042 continue; 21043 } 21044 21045 if (node === root) { 21046 return; 21047 } 21048 21049 while (node.sibling === null) { 21050 if (node.return === null || node.return === root) { 21051 return; 21052 } 21053 21054 node = node.return; 21055 } 21056 21057 node.sibling.return = node.return; 21058 node = node.sibling; 21059 } 21060 } 21061 21062 function detachFiberMutation(fiber) { 21063 // Cut off the return pointers to disconnect it from the tree. Ideally, we 21064 // should clear the child pointer of the parent alternate to let this 21065 // get GC:ed but we don't know which for sure which parent is the current 21066 // one so we'll settle for GC:ing the subtree of this child. This child 21067 // itself will be GC:ed when the parent updates the next time. 21068 // Note: we cannot null out sibling here, otherwise it can cause issues 21069 // with findDOMNode and how it requires the sibling field to carry out 21070 // traversal in a later effect. See PR #16820. We now clear the sibling 21071 // field after effects, see: detachFiberAfterEffects. 21072 // 21073 // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. 21074 // It may be required if the current component is an error boundary, 21075 // and one of its descendants throws while unmounting a passive effect. 21076 fiber.alternate = null; 21077 fiber.child = null; 21078 fiber.dependencies = null; 21079 fiber.firstEffect = null; 21080 fiber.lastEffect = null; 21081 fiber.memoizedProps = null; 21082 fiber.memoizedState = null; 21083 fiber.pendingProps = null; 21084 fiber.return = null; 21085 fiber.updateQueue = null; 21086 21087 { 21088 fiber._debugOwner = null; 21089 } 21090 } 21091 21092 function getHostParentFiber(fiber) { 21093 var parent = fiber.return; 21094 21095 while (parent !== null) { 21096 if (isHostParent(parent)) { 21097 return parent; 21098 } 21099 21100 parent = parent.return; 21101 } 21102 21103 { 21104 { 21105 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." ); 21106 } 21107 } 21108 } 21109 21110 function isHostParent(fiber) { 21111 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal; 21112 } 21113 21114 function getHostSibling(fiber) { 21115 // We're going to search forward into the tree until we find a sibling host 21116 // node. Unfortunately, if multiple insertions are done in a row we have to 21117 // search past them. This leads to exponential search for the next sibling. 21118 // TODO: Find a more efficient way to do this. 21119 var node = fiber; 21120 21121 siblings: while (true) { 21122 // If we didn't find anything, let's try the next sibling. 21123 while (node.sibling === null) { 21124 if (node.return === null || isHostParent(node.return)) { 21125 // If we pop out of the root or hit the parent the fiber we are the 21126 // last sibling. 21127 return null; 21128 } 21129 21130 node = node.return; 21131 } 21132 21133 node.sibling.return = node.return; 21134 node = node.sibling; 21135 21136 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) { 21137 // If it is not host node and, we might have a host node inside it. 21138 // Try to search down until we find one. 21139 if (node.flags & Placement) { 21140 // If we don't have a child, try the siblings instead. 21141 continue siblings; 21142 } // If we don't have a child, try the siblings instead. 21143 // We also skip portals because they are not part of this host tree. 21144 21145 21146 if (node.child === null || node.tag === HostPortal) { 21147 continue siblings; 21148 } else { 21149 node.child.return = node; 21150 node = node.child; 21151 } 21152 } // Check if this host node is stable or about to be placed. 21153 21154 21155 if (!(node.flags & Placement)) { 21156 // Found it! 21157 return node.stateNode; 21158 } 21159 } 21160 } 21161 21162 function commitPlacement(finishedWork) { 21163 21164 21165 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. 21166 21167 var parent; 21168 var isContainer; 21169 var parentStateNode = parentFiber.stateNode; 21170 21171 switch (parentFiber.tag) { 21172 case HostComponent: 21173 parent = parentStateNode; 21174 isContainer = false; 21175 break; 21176 21177 case HostRoot: 21178 parent = parentStateNode.containerInfo; 21179 isContainer = true; 21180 break; 21181 21182 case HostPortal: 21183 parent = parentStateNode.containerInfo; 21184 isContainer = true; 21185 break; 21186 21187 case FundamentalComponent: 21188 21189 // eslint-disable-next-line-no-fallthrough 21190 21191 default: 21192 { 21193 { 21194 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); 21195 } 21196 } 21197 21198 } 21199 21200 if (parentFiber.flags & ContentReset) { 21201 // Reset the text content of the parent before doing any insertions 21202 resetTextContent(parent); // Clear ContentReset from the effect tag 21203 21204 parentFiber.flags &= ~ContentReset; 21205 } 21206 21207 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its 21208 // children to find all the terminal nodes. 21209 21210 if (isContainer) { 21211 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); 21212 } else { 21213 insertOrAppendPlacementNode(finishedWork, before, parent); 21214 } 21215 } 21216 21217 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { 21218 var tag = node.tag; 21219 var isHost = tag === HostComponent || tag === HostText; 21220 21221 if (isHost || enableFundamentalAPI ) { 21222 var stateNode = isHost ? node.stateNode : node.stateNode.instance; 21223 21224 if (before) { 21225 insertInContainerBefore(parent, stateNode, before); 21226 } else { 21227 appendChildToContainer(parent, stateNode); 21228 } 21229 } else if (tag === HostPortal) ; else { 21230 var child = node.child; 21231 21232 if (child !== null) { 21233 insertOrAppendPlacementNodeIntoContainer(child, before, parent); 21234 var sibling = child.sibling; 21235 21236 while (sibling !== null) { 21237 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); 21238 sibling = sibling.sibling; 21239 } 21240 } 21241 } 21242 } 21243 21244 function insertOrAppendPlacementNode(node, before, parent) { 21245 var tag = node.tag; 21246 var isHost = tag === HostComponent || tag === HostText; 21247 21248 if (isHost || enableFundamentalAPI ) { 21249 var stateNode = isHost ? node.stateNode : node.stateNode.instance; 21250 21251 if (before) { 21252 insertBefore(parent, stateNode, before); 21253 } else { 21254 appendChild(parent, stateNode); 21255 } 21256 } else if (tag === HostPortal) ; else { 21257 var child = node.child; 21258 21259 if (child !== null) { 21260 insertOrAppendPlacementNode(child, before, parent); 21261 var sibling = child.sibling; 21262 21263 while (sibling !== null) { 21264 insertOrAppendPlacementNode(sibling, before, parent); 21265 sibling = sibling.sibling; 21266 } 21267 } 21268 } 21269 } 21270 21271 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { 21272 // We only have the top Fiber that was deleted but we need to recurse down its 21273 // children to find all the terminal nodes. 21274 var node = current; // Each iteration, currentParent is populated with node's host parent if not 21275 // currentParentIsValid. 21276 21277 var currentParentIsValid = false; // Note: these two variables *must* always be updated together. 21278 21279 var currentParent; 21280 var currentParentIsContainer; 21281 21282 while (true) { 21283 if (!currentParentIsValid) { 21284 var parent = node.return; 21285 21286 findParent: while (true) { 21287 if (!(parent !== null)) { 21288 { 21289 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." ); 21290 } 21291 } 21292 21293 var parentStateNode = parent.stateNode; 21294 21295 switch (parent.tag) { 21296 case HostComponent: 21297 currentParent = parentStateNode; 21298 currentParentIsContainer = false; 21299 break findParent; 21300 21301 case HostRoot: 21302 currentParent = parentStateNode.containerInfo; 21303 currentParentIsContainer = true; 21304 break findParent; 21305 21306 case HostPortal: 21307 currentParent = parentStateNode.containerInfo; 21308 currentParentIsContainer = true; 21309 break findParent; 21310 21311 } 21312 21313 parent = parent.return; 21314 } 21315 21316 currentParentIsValid = true; 21317 } 21318 21319 if (node.tag === HostComponent || node.tag === HostText) { 21320 commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the 21321 // node from the tree. 21322 21323 if (currentParentIsContainer) { 21324 removeChildFromContainer(currentParent, node.stateNode); 21325 } else { 21326 removeChild(currentParent, node.stateNode); 21327 } // Don't visit children because we already visited them. 21328 21329 } else if (node.tag === HostPortal) { 21330 if (node.child !== null) { 21331 // When we go into a portal, it becomes the parent to remove from. 21332 // We will reassign it back when we pop the portal on the way up. 21333 currentParent = node.stateNode.containerInfo; 21334 currentParentIsContainer = true; // Visit children because portals might contain host components. 21335 21336 node.child.return = node; 21337 node = node.child; 21338 continue; 21339 } 21340 } else { 21341 commitUnmount(finishedRoot, node); // Visit children because we may find more host components below. 21342 21343 if (node.child !== null) { 21344 node.child.return = node; 21345 node = node.child; 21346 continue; 21347 } 21348 } 21349 21350 if (node === current) { 21351 return; 21352 } 21353 21354 while (node.sibling === null) { 21355 if (node.return === null || node.return === current) { 21356 return; 21357 } 21358 21359 node = node.return; 21360 21361 if (node.tag === HostPortal) { 21362 // When we go out of the portal, we need to restore the parent. 21363 // Since we don't keep a stack of them, we will search for it. 21364 currentParentIsValid = false; 21365 } 21366 } 21367 21368 node.sibling.return = node.return; 21369 node = node.sibling; 21370 } 21371 } 21372 21373 function commitDeletion(finishedRoot, current, renderPriorityLevel) { 21374 { 21375 // Recursively delete all host nodes from the parent. 21376 // Detach refs and call componentWillUnmount() on the whole subtree. 21377 unmountHostComponents(finishedRoot, current); 21378 } 21379 21380 var alternate = current.alternate; 21381 detachFiberMutation(current); 21382 21383 if (alternate !== null) { 21384 detachFiberMutation(alternate); 21385 } 21386 } 21387 21388 function commitWork(current, finishedWork) { 21389 21390 switch (finishedWork.tag) { 21391 case FunctionComponent: 21392 case ForwardRef: 21393 case MemoComponent: 21394 case SimpleMemoComponent: 21395 case Block: 21396 { 21397 // Layout effects are destroyed during the mutation phase so that all 21398 // destroy functions for all fibers are called before any create functions. 21399 // This prevents sibling component effects from interfering with each other, 21400 // e.g. a destroy function in one component should never override a ref set 21401 // by a create function in another component during the same commit. 21402 { 21403 commitHookEffectListUnmount(Layout | HasEffect, finishedWork); 21404 } 21405 21406 return; 21407 } 21408 21409 case ClassComponent: 21410 { 21411 return; 21412 } 21413 21414 case HostComponent: 21415 { 21416 var instance = finishedWork.stateNode; 21417 21418 if (instance != null) { 21419 // Commit the work prepared earlier. 21420 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps 21421 // as the newProps. The updatePayload will contain the real change in 21422 // this case. 21423 21424 var oldProps = current !== null ? current.memoizedProps : newProps; 21425 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. 21426 21427 var updatePayload = finishedWork.updateQueue; 21428 finishedWork.updateQueue = null; 21429 21430 if (updatePayload !== null) { 21431 commitUpdate(instance, updatePayload, type, oldProps, newProps); 21432 } 21433 } 21434 21435 return; 21436 } 21437 21438 case HostText: 21439 { 21440 if (!(finishedWork.stateNode !== null)) { 21441 { 21442 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." ); 21443 } 21444 } 21445 21446 var textInstance = finishedWork.stateNode; 21447 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps 21448 // as the newProps. The updatePayload will contain the real change in 21449 // this case. 21450 21451 var oldText = current !== null ? current.memoizedProps : newText; 21452 commitTextUpdate(textInstance, oldText, newText); 21453 return; 21454 } 21455 21456 case HostRoot: 21457 { 21458 { 21459 var _root = finishedWork.stateNode; 21460 21461 if (_root.hydrate) { 21462 // We've just hydrated. No need to hydrate again. 21463 _root.hydrate = false; 21464 commitHydratedContainer(_root.containerInfo); 21465 } 21466 } 21467 21468 return; 21469 } 21470 21471 case Profiler: 21472 { 21473 return; 21474 } 21475 21476 case SuspenseComponent: 21477 { 21478 commitSuspenseComponent(finishedWork); 21479 attachSuspenseRetryListeners(finishedWork); 21480 return; 21481 } 21482 21483 case SuspenseListComponent: 21484 { 21485 attachSuspenseRetryListeners(finishedWork); 21486 return; 21487 } 21488 21489 case IncompleteClassComponent: 21490 { 21491 return; 21492 } 21493 21494 case FundamentalComponent: 21495 { 21496 21497 break; 21498 } 21499 21500 case ScopeComponent: 21501 { 21502 21503 break; 21504 } 21505 21506 case OffscreenComponent: 21507 case LegacyHiddenComponent: 21508 { 21509 var newState = finishedWork.memoizedState; 21510 var isHidden = newState !== null; 21511 hideOrUnhideAllChildren(finishedWork, isHidden); 21512 return; 21513 } 21514 } 21515 21516 { 21517 { 21518 throw 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." ); 21519 } 21520 } 21521 } 21522 21523 function commitSuspenseComponent(finishedWork) { 21524 var newState = finishedWork.memoizedState; 21525 21526 if (newState !== null) { 21527 markCommitTimeOfFallback(); 21528 21529 { 21530 // Hide the Offscreen component that contains the primary children. TODO: 21531 // Ideally, this effect would have been scheduled on the Offscreen fiber 21532 // itself. That's how unhiding works: the Offscreen component schedules an 21533 // effect on itself. However, in this case, the component didn't complete, 21534 // so the fiber was never added to the effect list in the normal path. We 21535 // could have appended it to the effect list in the Suspense component's 21536 // second pass, but doing it this way is less complicated. This would be 21537 // simpler if we got rid of the effect list and traversed the tree, like 21538 // we're planning to do. 21539 var primaryChildParent = finishedWork.child; 21540 hideOrUnhideAllChildren(primaryChildParent, true); 21541 } 21542 } 21543 } 21544 21545 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { 21546 21547 var newState = finishedWork.memoizedState; 21548 21549 if (newState === null) { 21550 var current = finishedWork.alternate; 21551 21552 if (current !== null) { 21553 var prevState = current.memoizedState; 21554 21555 if (prevState !== null) { 21556 var suspenseInstance = prevState.dehydrated; 21557 21558 if (suspenseInstance !== null) { 21559 commitHydratedSuspenseInstance(suspenseInstance); 21560 } 21561 } 21562 } 21563 } 21564 } 21565 21566 function attachSuspenseRetryListeners(finishedWork) { 21567 // If this boundary just timed out, then it will have a set of wakeables. 21568 // For each wakeable, attach a listener so that when it resolves, React 21569 // attempts to re-render the boundary in the primary (pre-timeout) state. 21570 var wakeables = finishedWork.updateQueue; 21571 21572 if (wakeables !== null) { 21573 finishedWork.updateQueue = null; 21574 var retryCache = finishedWork.stateNode; 21575 21576 if (retryCache === null) { 21577 retryCache = finishedWork.stateNode = new PossiblyWeakSet(); 21578 } 21579 21580 wakeables.forEach(function (wakeable) { 21581 // Memoize using the boundary fiber to prevent redundant listeners. 21582 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); 21583 21584 if (!retryCache.has(wakeable)) { 21585 { 21586 if (wakeable.__reactDoNotTraceInteractions !== true) { 21587 retry = unstable_wrap(retry); 21588 } 21589 } 21590 21591 retryCache.add(wakeable); 21592 wakeable.then(retry, retry); 21593 } 21594 }); 21595 } 21596 } // This function detects when a Suspense boundary goes from visible to hidden. 21597 // It returns false if the boundary is already hidden. 21598 // TODO: Use an effect tag. 21599 21600 21601 function isSuspenseBoundaryBeingHidden(current, finishedWork) { 21602 if (current !== null) { 21603 var oldState = current.memoizedState; 21604 21605 if (oldState === null || oldState.dehydrated !== null) { 21606 var newState = finishedWork.memoizedState; 21607 return newState !== null && newState.dehydrated === null; 21608 } 21609 } 21610 21611 return false; 21612 } 21613 21614 function commitResetTextContent(current) { 21615 21616 resetTextContent(current.stateNode); 21617 } 21618 21619 var COMPONENT_TYPE = 0; 21620 var HAS_PSEUDO_CLASS_TYPE = 1; 21621 var ROLE_TYPE = 2; 21622 var TEST_NAME_TYPE = 3; 21623 var TEXT_TYPE = 4; 21624 21625 if (typeof Symbol === 'function' && Symbol.for) { 21626 var symbolFor$1 = Symbol.for; 21627 COMPONENT_TYPE = symbolFor$1('selector.component'); 21628 HAS_PSEUDO_CLASS_TYPE = symbolFor$1('selector.has_pseudo_class'); 21629 ROLE_TYPE = symbolFor$1('selector.role'); 21630 TEST_NAME_TYPE = symbolFor$1('selector.test_id'); 21631 TEXT_TYPE = symbolFor$1('selector.text'); 21632 } 21633 var commitHooks = []; 21634 function onCommitRoot$1() { 21635 { 21636 commitHooks.forEach(function (commitHook) { 21637 return commitHook(); 21638 }); 21639 } 21640 } 21641 21642 var ceil = Math.ceil; 21643 var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, 21644 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, 21645 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; 21646 var NoContext = 21647 /* */ 21648 0; 21649 var BatchedContext = 21650 /* */ 21651 1; 21652 var EventContext = 21653 /* */ 21654 2; 21655 var DiscreteEventContext = 21656 /* */ 21657 4; 21658 var LegacyUnbatchedContext = 21659 /* */ 21660 8; 21661 var RenderContext = 21662 /* */ 21663 16; 21664 var CommitContext = 21665 /* */ 21666 32; 21667 var RetryAfterError = 21668 /* */ 21669 64; 21670 var RootIncomplete = 0; 21671 var RootFatalErrored = 1; 21672 var RootErrored = 2; 21673 var RootSuspended = 3; 21674 var RootSuspendedWithDelay = 4; 21675 var RootCompleted = 5; // Describes where we are in the React execution stack 21676 21677 var executionContext = NoContext; // The root we're working on 21678 21679 var workInProgressRoot = null; // The fiber we're working on 21680 21681 var workInProgress = null; // The lanes we're rendering 21682 21683 var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree 21684 // This is a superset of the lanes we started working on at the root. The only 21685 // case where it's different from `workInProgressRootRenderLanes` is when we 21686 // enter a subtree that is hidden and needs to be unhidden: Suspense and 21687 // Offscreen component. 21688 // 21689 // Most things in the work loop should deal with workInProgressRootRenderLanes. 21690 // Most things in begin/complete phases should deal with subtreeRenderLanes. 21691 21692 var subtreeRenderLanes = NoLanes; 21693 var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc. 21694 21695 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown 21696 21697 var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's 21698 // slightly different than `renderLanes` because `renderLanes` can change as you 21699 // enter and exit an Offscreen tree. This value is the combination of all render 21700 // lanes for the entire render phase. 21701 21702 var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only 21703 // includes unprocessed updates, not work in bailed out children. 21704 21705 var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render. 21706 21707 var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. 21708 21709 var workInProgressRootPingedLanes = NoLanes; 21710 var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train 21711 // model where we don't commit new loading states in too quick succession. 21712 21713 var globalMostRecentFallbackTime = 0; 21714 var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering 21715 // more and prefer CPU suspense heuristics instead. 21716 21717 var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU 21718 // suspense heuristics and opt out of rendering more content. 21719 21720 var RENDER_TIMEOUT_MS = 500; 21721 21722 function resetRenderTimer() { 21723 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; 21724 } 21725 21726 function getRenderTargetTime() { 21727 return workInProgressRootRenderTargetTime; 21728 } 21729 var nextEffect = null; 21730 var hasUncaughtError = false; 21731 var firstUncaughtError = null; 21732 var legacyErrorBoundariesThatAlreadyFailed = null; 21733 var rootDoesHavePassiveEffects = false; 21734 var rootWithPendingPassiveEffects = null; 21735 var pendingPassiveEffectsRenderPriority = NoPriority$1; 21736 var pendingPassiveEffectsLanes = NoLanes; 21737 var pendingPassiveHookEffectsMount = []; 21738 var pendingPassiveHookEffectsUnmount = []; 21739 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates 21740 21741 var NESTED_UPDATE_LIMIT = 50; 21742 var nestedUpdateCount = 0; 21743 var rootWithNestedUpdates = null; 21744 var NESTED_PASSIVE_UPDATE_LIMIT = 50; 21745 var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes 21746 // during the commit phase. This enables them to be traced across components 21747 // that spawn new work during render. E.g. hidden boundaries, suspended SSR 21748 // hydration or SuspenseList. 21749 // TODO: Can use a bitmask instead of an array 21750 21751 var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their 21752 // event times as simultaneous, even if the actual clock time has advanced 21753 // between the first and second call. 21754 21755 var currentEventTime = NoTimestamp; 21756 var currentEventWipLanes = NoLanes; 21757 var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. 21758 // We warn about state updates for unmounted components differently in this case. 21759 21760 var isFlushingPassiveEffects = false; 21761 var focusedInstanceHandle = null; 21762 var shouldFireAfterActiveInstanceBlur = false; 21763 function getWorkInProgressRoot() { 21764 return workInProgressRoot; 21765 } 21766 function requestEventTime() { 21767 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 21768 // We're inside React, so it's fine to read the actual time. 21769 return now(); 21770 } // We're not inside React, so we may be in the middle of a browser event. 21771 21772 21773 if (currentEventTime !== NoTimestamp) { 21774 // Use the same start time for all updates until we enter React again. 21775 return currentEventTime; 21776 } // This is the first update since React yielded. Compute a new start time. 21777 21778 21779 currentEventTime = now(); 21780 return currentEventTime; 21781 } 21782 function requestUpdateLane(fiber) { 21783 // Special cases 21784 var mode = fiber.mode; 21785 21786 if ((mode & BlockingMode) === NoMode) { 21787 return SyncLane; 21788 } else if ((mode & ConcurrentMode) === NoMode) { 21789 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; 21790 } // The algorithm for assigning an update to a lane should be stable for all 21791 // updates at the same priority within the same event. To do this, the inputs 21792 // to the algorithm must be the same. For example, we use the `renderLanes` 21793 // to avoid choosing a lane that is already in the middle of rendering. 21794 // 21795 // However, the "included" lanes could be mutated in between updates in the 21796 // same event, like if you perform an update inside `flushSync`. Or any other 21797 // code path that might call `prepareFreshStack`. 21798 // 21799 // The trick we use is to cache the first of each of these inputs within an 21800 // event. Then reset the cached values once we can be sure the event is over. 21801 // Our heuristic for that is whenever we enter a concurrent work loop. 21802 // 21803 // We'll do the same for `currentEventPendingLanes` below. 21804 21805 21806 if (currentEventWipLanes === NoLanes) { 21807 currentEventWipLanes = workInProgressRootIncludedLanes; 21808 } 21809 21810 var isTransition = requestCurrentTransition() !== NoTransition; 21811 21812 if (isTransition) { 21813 if (currentEventPendingLanes !== NoLanes) { 21814 currentEventPendingLanes = mostRecentlyUpdatedRoot !== null ? mostRecentlyUpdatedRoot.pendingLanes : NoLanes; 21815 } 21816 21817 return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); 21818 } // TODO: Remove this dependency on the Scheduler priority. 21819 // To do that, we're replacing it with an update lane priority. 21820 21821 21822 var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. 21823 // This couples React to the Scheduler internals, so we're replacing it 21824 // with the currentUpdateLanePriority above. As an example of how this 21825 // could be problematic, if we're not inside `Scheduler.runWithPriority`, 21826 // then we'll get the priority of the current running Scheduler task, 21827 // which is probably not what we want. 21828 21829 var lane; 21830 21831 if ( // TODO: Temporary. We're removing the concept of discrete updates. 21832 (executionContext & DiscreteEventContext) !== NoContext && schedulerPriority === UserBlockingPriority$2) { 21833 lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); 21834 } else { 21835 var schedulerLanePriority = schedulerPriorityToLanePriority(schedulerPriority); 21836 21837 lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); 21838 } 21839 21840 return lane; 21841 } 21842 21843 function requestRetryLane(fiber) { 21844 // This is a fork of `requestUpdateLane` designed specifically for Suspense 21845 // "retries" — a special update that attempts to flip a Suspense boundary 21846 // from its placeholder state to its primary/resolved state. 21847 // Special cases 21848 var mode = fiber.mode; 21849 21850 if ((mode & BlockingMode) === NoMode) { 21851 return SyncLane; 21852 } else if ((mode & ConcurrentMode) === NoMode) { 21853 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; 21854 } // See `requestUpdateLane` for explanation of `currentEventWipLanes` 21855 21856 21857 if (currentEventWipLanes === NoLanes) { 21858 currentEventWipLanes = workInProgressRootIncludedLanes; 21859 } 21860 21861 return findRetryLane(currentEventWipLanes); 21862 } 21863 21864 function scheduleUpdateOnFiber(fiber, lane, eventTime) { 21865 checkForNestedUpdates(); 21866 warnAboutRenderPhaseUpdatesInDEV(fiber); 21867 var root = markUpdateLaneFromFiberToRoot(fiber, lane); 21868 21869 if (root === null) { 21870 warnAboutUpdateOnUnmountedFiberInDEV(fiber); 21871 return null; 21872 } // Mark that the root has a pending update. 21873 21874 21875 markRootUpdated(root, lane, eventTime); 21876 21877 if (root === workInProgressRoot) { 21878 // Received an update to a tree that's in the middle of rendering. Mark 21879 // that there was an interleaved update work on this root. Unless the 21880 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render 21881 // phase update. In that case, we don't treat render phase updates as if 21882 // they were interleaved, for backwards compat reasons. 21883 { 21884 workInProgressRootUpdatedLanes = mergeLanes(workInProgressRootUpdatedLanes, lane); 21885 } 21886 21887 if (workInProgressRootExitStatus === RootSuspendedWithDelay) { 21888 // The root already suspended with a delay, which means this render 21889 // definitely won't finish. Since we have a new update, let's mark it as 21890 // suspended now, right before marking the incoming update. This has the 21891 // effect of interrupting the current render and switching to the update. 21892 // TODO: Make sure this doesn't override pings that happen while we've 21893 // already started rendering. 21894 markRootSuspended$1(root, workInProgressRootRenderLanes); 21895 } 21896 } // TODO: requestUpdateLanePriority also reads the priority. Pass the 21897 // priority as an argument to that function and this one. 21898 21899 21900 var priorityLevel = getCurrentPriorityLevel(); 21901 21902 if (lane === SyncLane) { 21903 if ( // Check if we're inside unbatchedUpdates 21904 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering 21905 (executionContext & (RenderContext | CommitContext)) === NoContext) { 21906 // Register pending interactions on the root to avoid losing traced interaction data. 21907 schedulePendingInteractions(root, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed 21908 // root inside of batchedUpdates should be synchronous, but layout updates 21909 // should be deferred until the end of the batch. 21910 21911 performSyncWorkOnRoot(root); 21912 } else { 21913 ensureRootIsScheduled(root, eventTime); 21914 schedulePendingInteractions(root, lane); 21915 21916 if (executionContext === NoContext) { 21917 // Flush the synchronous work now, unless we're already working or inside 21918 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of 21919 // scheduleCallbackForFiber to preserve the ability to schedule a callback 21920 // without immediately flushing it. We only do this for user-initiated 21921 // updates, to preserve historical behavior of legacy mode. 21922 resetRenderTimer(); 21923 flushSyncCallbackQueue(); 21924 } 21925 } 21926 } else { 21927 // Schedule a discrete update but only if it's not Sync. 21928 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered 21929 // discrete, even inside a discrete event. 21930 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority$1)) { 21931 // This is the result of a discrete event. Track the lowest priority 21932 // discrete update per root so we can flush them early, if needed. 21933 if (rootsWithPendingDiscreteUpdates === null) { 21934 rootsWithPendingDiscreteUpdates = new Set([root]); 21935 } else { 21936 rootsWithPendingDiscreteUpdates.add(root); 21937 } 21938 } // Schedule other updates after in case the callback is sync. 21939 21940 21941 ensureRootIsScheduled(root, eventTime); 21942 schedulePendingInteractions(root, lane); 21943 } // We use this when assigning a lane for a transition inside 21944 // `requestUpdateLane`. We assume it's the same as the root being updated, 21945 // since in the common case of a single root app it probably is. If it's not 21946 // the same root, then it's not a huge deal, we just might batch more stuff 21947 // together more than necessary. 21948 21949 21950 mostRecentlyUpdatedRoot = root; 21951 } // This is split into a separate function so we can mark a fiber with pending 21952 // work without treating it as a typical update that originates from an event; 21953 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work 21954 // on a fiber. 21955 21956 function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { 21957 // Update the source fiber's lanes 21958 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane); 21959 var alternate = sourceFiber.alternate; 21960 21961 if (alternate !== null) { 21962 alternate.lanes = mergeLanes(alternate.lanes, lane); 21963 } 21964 21965 { 21966 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) { 21967 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); 21968 } 21969 } // Walk the parent path to the root and update the child expiration time. 21970 21971 21972 var node = sourceFiber; 21973 var parent = sourceFiber.return; 21974 21975 while (parent !== null) { 21976 parent.childLanes = mergeLanes(parent.childLanes, lane); 21977 alternate = parent.alternate; 21978 21979 if (alternate !== null) { 21980 alternate.childLanes = mergeLanes(alternate.childLanes, lane); 21981 } else { 21982 { 21983 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) { 21984 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); 21985 } 21986 } 21987 } 21988 21989 node = parent; 21990 parent = parent.return; 21991 } 21992 21993 if (node.tag === HostRoot) { 21994 var root = node.stateNode; 21995 return root; 21996 } else { 21997 return null; 21998 } 21999 } // Use this function to schedule a task for a root. There's only one task per 22000 // root; if a task was already scheduled, we'll check to make sure the priority 22001 // of the existing task is the same as the priority of the next level that the 22002 // root has work on. This function is called on every update, and right before 22003 // exiting a task. 22004 22005 22006 function ensureRootIsScheduled(root, currentTime) { 22007 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as 22008 // expired so we know to work on those next. 22009 22010 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. 22011 22012 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call. 22013 22014 var newCallbackPriority = returnNextLanesPriority(); 22015 22016 if (nextLanes === NoLanes) { 22017 // Special case: There's nothing to work on. 22018 if (existingCallbackNode !== null) { 22019 cancelCallback(existingCallbackNode); 22020 root.callbackNode = null; 22021 root.callbackPriority = NoLanePriority; 22022 } 22023 22024 return; 22025 } // Check if there's an existing task. We may be able to reuse it. 22026 22027 22028 if (existingCallbackNode !== null) { 22029 var existingCallbackPriority = root.callbackPriority; 22030 22031 if (existingCallbackPriority === newCallbackPriority) { 22032 // The priority hasn't changed. We can reuse the existing task. Exit. 22033 return; 22034 } // The priority changed. Cancel the existing callback. We'll schedule a new 22035 // one below. 22036 22037 22038 cancelCallback(existingCallbackNode); 22039 } // Schedule a new callback. 22040 22041 22042 var newCallbackNode; 22043 22044 if (newCallbackPriority === SyncLanePriority) { 22045 // Special case: Sync React callbacks are scheduled on a special 22046 // internal queue 22047 newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); 22048 } else if (newCallbackPriority === SyncBatchedLanePriority) { 22049 newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root)); 22050 } else { 22051 var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority); 22052 newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); 22053 } 22054 22055 root.callbackPriority = newCallbackPriority; 22056 root.callbackNode = newCallbackNode; 22057 } // This is the entry point for every concurrent task, i.e. anything that 22058 // goes through Scheduler. 22059 22060 22061 function performConcurrentWorkOnRoot(root) { 22062 // Since we know we're in a React event, we can clear the current 22063 // event time. The next update will compute a new event time. 22064 currentEventTime = NoTimestamp; 22065 currentEventWipLanes = NoLanes; 22066 currentEventPendingLanes = NoLanes; 22067 22068 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { 22069 { 22070 throw Error( "Should not already be working." ); 22071 } 22072 } // Flush any pending passive effects before deciding which lanes to work on, 22073 // in case they schedule additional work. 22074 22075 22076 var originalCallbackNode = root.callbackNode; 22077 var didFlushPassiveEffects = flushPassiveEffects(); 22078 22079 if (didFlushPassiveEffects) { 22080 // Something in the passive effect phase may have canceled the current task. 22081 // Check if the task node for this root was changed. 22082 if (root.callbackNode !== originalCallbackNode) { 22083 // The current task was canceled. Exit. We don't need to call 22084 // `ensureRootIsScheduled` because the check above implies either that 22085 // there's a new task, or that there's no remaining work on this root. 22086 return null; 22087 } 22088 } // Determine the next expiration time to work on, using the fields stored 22089 // on the root. 22090 22091 22092 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); 22093 22094 if (lanes === NoLanes) { 22095 // Defensive coding. This is never expected to happen. 22096 return null; 22097 } 22098 22099 var exitStatus = renderRootConcurrent(root, lanes); 22100 22101 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) { 22102 // The render included lanes that were updated during the render phase. 22103 // For example, when unhiding a hidden tree, we include all the lanes 22104 // that were previously skipped when the tree was hidden. That set of 22105 // lanes is a superset of the lanes we started rendering with. 22106 // 22107 // So we'll throw out the current work and restart. 22108 prepareFreshStack(root, NoLanes); 22109 } else if (exitStatus !== RootIncomplete) { 22110 if (exitStatus === RootErrored) { 22111 executionContext |= RetryAfterError; // If an error occurred during hydration, 22112 // discard server response and fall back to client side render. 22113 22114 if (root.hydrate) { 22115 root.hydrate = false; 22116 clearContainer(root.containerInfo); 22117 } // If something threw an error, try rendering one more time. We'll render 22118 // synchronously to block concurrent data mutations, and we'll includes 22119 // all pending updates are included. If it still fails after the second 22120 // attempt, we'll give up and commit the resulting tree. 22121 22122 22123 lanes = getLanesToRetrySynchronouslyOnError(root); 22124 22125 if (lanes !== NoLanes) { 22126 exitStatus = renderRootSync(root, lanes); 22127 } 22128 } 22129 22130 if (exitStatus === RootFatalErrored) { 22131 var fatalError = workInProgressRootFatalError; 22132 prepareFreshStack(root, NoLanes); 22133 markRootSuspended$1(root, lanes); 22134 ensureRootIsScheduled(root, now()); 22135 throw fatalError; 22136 } // We now have a consistent tree. The next step is either to commit it, 22137 // or, if something suspended, wait to commit it after a timeout. 22138 22139 22140 var finishedWork = root.current.alternate; 22141 root.finishedWork = finishedWork; 22142 root.finishedLanes = lanes; 22143 finishConcurrentRender(root, exitStatus, lanes); 22144 } 22145 22146 ensureRootIsScheduled(root, now()); 22147 22148 if (root.callbackNode === originalCallbackNode) { 22149 // The task node scheduled for this root is the same one that's 22150 // currently executed. Need to return a continuation. 22151 return performConcurrentWorkOnRoot.bind(null, root); 22152 } 22153 22154 return null; 22155 } 22156 22157 function finishConcurrentRender(root, exitStatus, lanes) { 22158 switch (exitStatus) { 22159 case RootIncomplete: 22160 case RootFatalErrored: 22161 { 22162 { 22163 { 22164 throw Error( "Root did not complete. This is a bug in React." ); 22165 } 22166 } 22167 } 22168 // Flow knows about invariant, so it complains if I add a break 22169 // statement, but eslint doesn't know about invariant, so it complains 22170 // if I do. eslint-disable-next-line no-fallthrough 22171 22172 case RootErrored: 22173 { 22174 // We should have already attempted to retry this tree. If we reached 22175 // this point, it errored again. Commit it. 22176 commitRoot(root); 22177 break; 22178 } 22179 22180 case RootSuspended: 22181 { 22182 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we 22183 // should immediately commit it or wait a bit. 22184 22185 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope 22186 !shouldForceFlushFallbacksInDEV()) { 22187 // This render only included retries, no updates. Throttle committing 22188 // retries so that we don't show too many loading states too quickly. 22189 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time. 22190 22191 if (msUntilTimeout > 10) { 22192 var nextLanes = getNextLanes(root, NoLanes); 22193 22194 if (nextLanes !== NoLanes) { 22195 // There's additional work on this root. 22196 break; 22197 } 22198 22199 var suspendedLanes = root.suspendedLanes; 22200 22201 if (!isSubsetOfLanes(suspendedLanes, lanes)) { 22202 // We should prefer to render the fallback of at the last 22203 // suspended level. Ping the last suspended level to try 22204 // rendering it again. 22205 // FIXME: What if the suspended lanes are Idle? Should not restart. 22206 var eventTime = requestEventTime(); 22207 markRootPinged(root, suspendedLanes); 22208 break; 22209 } // The render is suspended, it hasn't timed out, and there's no 22210 // lower priority work to do. Instead of committing the fallback 22211 // immediately, wait for more data to arrive. 22212 22213 22214 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout); 22215 break; 22216 } 22217 } // The work expired. Commit immediately. 22218 22219 22220 commitRoot(root); 22221 break; 22222 } 22223 22224 case RootSuspendedWithDelay: 22225 { 22226 markRootSuspended$1(root, lanes); 22227 22228 if (includesOnlyTransitions(lanes)) { 22229 // This is a transition, so we should exit without committing a 22230 // placeholder and without scheduling a timeout. Delay indefinitely 22231 // until we receive more data. 22232 break; 22233 } 22234 22235 if (!shouldForceFlushFallbacksInDEV()) { 22236 // This is not a transition, but we did trigger an avoided state. 22237 // Schedule a placeholder to display after a short delay, using the Just 22238 // Noticeable Difference. 22239 // TODO: Is the JND optimization worth the added complexity? If this is 22240 // the only reason we track the event time, then probably not. 22241 // Consider removing. 22242 var mostRecentEventTime = getMostRecentEventTime(root, lanes); 22243 var eventTimeMs = mostRecentEventTime; 22244 var timeElapsedMs = now() - eventTimeMs; 22245 22246 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time. 22247 22248 22249 if (_msUntilTimeout > 10) { 22250 // Instead of committing the fallback immediately, wait for more data 22251 // to arrive. 22252 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout); 22253 break; 22254 } 22255 } // Commit the placeholder. 22256 22257 22258 commitRoot(root); 22259 break; 22260 } 22261 22262 case RootCompleted: 22263 { 22264 // The work completed. Ready to commit. 22265 commitRoot(root); 22266 break; 22267 } 22268 22269 default: 22270 { 22271 { 22272 { 22273 throw Error( "Unknown root exit status." ); 22274 } 22275 } 22276 } 22277 } 22278 } 22279 22280 function markRootSuspended$1(root, suspendedLanes) { 22281 // When suspending, we should always exclude lanes that were pinged or (more 22282 // rarely, since we try to avoid it) updated during the render phase. 22283 // TODO: Lol maybe there's a better way to factor this besides this 22284 // obnoxiously named function :) 22285 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes); 22286 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes); 22287 markRootSuspended(root, suspendedLanes); 22288 } // This is the entry point for synchronous tasks that don't go 22289 // through Scheduler 22290 22291 22292 function performSyncWorkOnRoot(root) { 22293 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { 22294 { 22295 throw Error( "Should not already be working." ); 22296 } 22297 } 22298 22299 flushPassiveEffects(); 22300 var lanes; 22301 var exitStatus; 22302 22303 if (root === workInProgressRoot && includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)) { 22304 // There's a partial tree, and at least one of its lanes has expired. Finish 22305 // rendering it before rendering the rest of the expired work. 22306 lanes = workInProgressRootRenderLanes; 22307 exitStatus = renderRootSync(root, lanes); 22308 22309 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) { 22310 // The render included lanes that were updated during the render phase. 22311 // For example, when unhiding a hidden tree, we include all the lanes 22312 // that were previously skipped when the tree was hidden. That set of 22313 // lanes is a superset of the lanes we started rendering with. 22314 // 22315 // Note that this only happens when part of the tree is rendered 22316 // concurrently. If the whole tree is rendered synchronously, then there 22317 // are no interleaved events. 22318 lanes = getNextLanes(root, lanes); 22319 exitStatus = renderRootSync(root, lanes); 22320 } 22321 } else { 22322 lanes = getNextLanes(root, NoLanes); 22323 exitStatus = renderRootSync(root, lanes); 22324 } 22325 22326 if (root.tag !== LegacyRoot && exitStatus === RootErrored) { 22327 executionContext |= RetryAfterError; // If an error occurred during hydration, 22328 // discard server response and fall back to client side render. 22329 22330 if (root.hydrate) { 22331 root.hydrate = false; 22332 clearContainer(root.containerInfo); 22333 } // If something threw an error, try rendering one more time. We'll render 22334 // synchronously to block concurrent data mutations, and we'll includes 22335 // all pending updates are included. If it still fails after the second 22336 // attempt, we'll give up and commit the resulting tree. 22337 22338 22339 lanes = getLanesToRetrySynchronouslyOnError(root); 22340 22341 if (lanes !== NoLanes) { 22342 exitStatus = renderRootSync(root, lanes); 22343 } 22344 } 22345 22346 if (exitStatus === RootFatalErrored) { 22347 var fatalError = workInProgressRootFatalError; 22348 prepareFreshStack(root, NoLanes); 22349 markRootSuspended$1(root, lanes); 22350 ensureRootIsScheduled(root, now()); 22351 throw fatalError; 22352 } // We now have a consistent tree. Because this is a sync render, we 22353 // will commit it even if something suspended. 22354 22355 22356 var finishedWork = root.current.alternate; 22357 root.finishedWork = finishedWork; 22358 root.finishedLanes = lanes; 22359 commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next 22360 // pending level. 22361 22362 ensureRootIsScheduled(root, now()); 22363 return null; 22364 } 22365 function flushDiscreteUpdates() { 22366 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. 22367 // However, `act` uses `batchedUpdates`, so there's no way to distinguish 22368 // those two cases. Need to fix this before exposing flushDiscreteUpdates 22369 // as a public API. 22370 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) { 22371 { 22372 if ((executionContext & RenderContext) !== NoContext) { 22373 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.'); 22374 } 22375 } // We're already rendering, so we can't synchronously flush pending work. 22376 // This is probably a nested event dispatch triggered by a lifecycle/effect, 22377 // like `el.focus()`. Exit. 22378 22379 22380 return; 22381 } 22382 22383 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that 22384 // they fire before the next serial event. 22385 22386 flushPassiveEffects(); 22387 } 22388 22389 function flushPendingDiscreteUpdates() { 22390 if (rootsWithPendingDiscreteUpdates !== null) { 22391 // For each root with pending discrete updates, schedule a callback to 22392 // immediately flush them. 22393 var roots = rootsWithPendingDiscreteUpdates; 22394 rootsWithPendingDiscreteUpdates = null; 22395 roots.forEach(function (root) { 22396 markDiscreteUpdatesExpired(root); 22397 ensureRootIsScheduled(root, now()); 22398 }); 22399 } // Now flush the immediate queue. 22400 22401 22402 flushSyncCallbackQueue(); 22403 } 22404 22405 function batchedUpdates$1(fn, a) { 22406 var prevExecutionContext = executionContext; 22407 executionContext |= BatchedContext; 22408 22409 try { 22410 return fn(a); 22411 } finally { 22412 executionContext = prevExecutionContext; 22413 22414 if (executionContext === NoContext) { 22415 // Flush the immediate callbacks that were scheduled during this batch 22416 resetRenderTimer(); 22417 flushSyncCallbackQueue(); 22418 } 22419 } 22420 } 22421 function batchedEventUpdates$1(fn, a) { 22422 var prevExecutionContext = executionContext; 22423 executionContext |= EventContext; 22424 22425 try { 22426 return fn(a); 22427 } finally { 22428 executionContext = prevExecutionContext; 22429 22430 if (executionContext === NoContext) { 22431 // Flush the immediate callbacks that were scheduled during this batch 22432 resetRenderTimer(); 22433 flushSyncCallbackQueue(); 22434 } 22435 } 22436 } 22437 function discreteUpdates$1(fn, a, b, c, d) { 22438 var prevExecutionContext = executionContext; 22439 executionContext |= DiscreteEventContext; 22440 22441 { 22442 try { 22443 return runWithPriority$1(UserBlockingPriority$2, fn.bind(null, a, b, c, d)); 22444 } finally { 22445 executionContext = prevExecutionContext; 22446 22447 if (executionContext === NoContext) { 22448 // Flush the immediate callbacks that were scheduled during this batch 22449 resetRenderTimer(); 22450 flushSyncCallbackQueue(); 22451 } 22452 } 22453 } 22454 } 22455 function unbatchedUpdates(fn, a) { 22456 var prevExecutionContext = executionContext; 22457 executionContext &= ~BatchedContext; 22458 executionContext |= LegacyUnbatchedContext; 22459 22460 try { 22461 return fn(a); 22462 } finally { 22463 executionContext = prevExecutionContext; 22464 22465 if (executionContext === NoContext) { 22466 // Flush the immediate callbacks that were scheduled during this batch 22467 resetRenderTimer(); 22468 flushSyncCallbackQueue(); 22469 } 22470 } 22471 } 22472 function flushSync(fn, a) { 22473 var prevExecutionContext = executionContext; 22474 22475 if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) { 22476 { 22477 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.'); 22478 } 22479 22480 return fn(a); 22481 } 22482 22483 executionContext |= BatchedContext; 22484 22485 { 22486 try { 22487 if (fn) { 22488 return runWithPriority$1(ImmediatePriority$1, fn.bind(null, a)); 22489 } else { 22490 return undefined; 22491 } 22492 } finally { 22493 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. 22494 // Note that this will happen even if batchedUpdates is higher up 22495 // the stack. 22496 22497 flushSyncCallbackQueue(); 22498 } 22499 } 22500 } 22501 function pushRenderLanes(fiber, lanes) { 22502 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber); 22503 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes); 22504 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes); 22505 } 22506 function popRenderLanes(fiber) { 22507 subtreeRenderLanes = subtreeRenderLanesCursor.current; 22508 pop(subtreeRenderLanesCursor, fiber); 22509 } 22510 22511 function prepareFreshStack(root, lanes) { 22512 root.finishedWork = null; 22513 root.finishedLanes = NoLanes; 22514 var timeoutHandle = root.timeoutHandle; 22515 22516 if (timeoutHandle !== noTimeout) { 22517 // The root previous suspended and scheduled a timeout to commit a fallback 22518 // state. Now that we have additional work, cancel the timeout. 22519 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 22520 22521 cancelTimeout(timeoutHandle); 22522 } 22523 22524 if (workInProgress !== null) { 22525 var interruptedWork = workInProgress.return; 22526 22527 while (interruptedWork !== null) { 22528 unwindInterruptedWork(interruptedWork); 22529 interruptedWork = interruptedWork.return; 22530 } 22531 } 22532 22533 workInProgressRoot = root; 22534 workInProgress = createWorkInProgress(root.current, null); 22535 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; 22536 workInProgressRootExitStatus = RootIncomplete; 22537 workInProgressRootFatalError = null; 22538 workInProgressRootSkippedLanes = NoLanes; 22539 workInProgressRootUpdatedLanes = NoLanes; 22540 workInProgressRootPingedLanes = NoLanes; 22541 22542 { 22543 spawnedWorkDuringRender = null; 22544 } 22545 22546 { 22547 ReactStrictModeWarnings.discardPendingWarnings(); 22548 } 22549 } 22550 22551 function handleError(root, thrownValue) { 22552 do { 22553 var erroredWork = workInProgress; 22554 22555 try { 22556 // Reset module-level state that was set during the render phase. 22557 resetContextDependencies(); 22558 resetHooksAfterThrow(); 22559 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a 22560 // separate issue. Write a regression test using string refs. 22561 22562 ReactCurrentOwner$2.current = null; 22563 22564 if (erroredWork === null || erroredWork.return === null) { 22565 // Expected to be working on a non-root fiber. This is a fatal error 22566 // because there's no ancestor that can handle it; the root is 22567 // supposed to capture all errors that weren't caught by an error 22568 // boundary. 22569 workInProgressRootExitStatus = RootFatalErrored; 22570 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next 22571 // sibling, or the parent if there are no siblings. But since the root 22572 // has no siblings nor a parent, we set it to null. Usually this is 22573 // handled by `completeUnitOfWork` or `unwindWork`, but since we're 22574 // intentionally not calling those, we need set it here. 22575 // TODO: Consider calling `unwindWork` to pop the contexts. 22576 22577 workInProgress = null; 22578 return; 22579 } 22580 22581 if (enableProfilerTimer && erroredWork.mode & ProfileMode) { 22582 // Record the time spent rendering before an error was thrown. This 22583 // avoids inaccurate Profiler durations in the case of a 22584 // suspended render. 22585 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); 22586 } 22587 22588 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes); 22589 completeUnitOfWork(erroredWork); 22590 } catch (yetAnotherThrownValue) { 22591 // Something in the return path also threw. 22592 thrownValue = yetAnotherThrownValue; 22593 22594 if (workInProgress === erroredWork && erroredWork !== null) { 22595 // If this boundary has already errored, then we had trouble processing 22596 // the error. Bubble it to the next boundary. 22597 erroredWork = erroredWork.return; 22598 workInProgress = erroredWork; 22599 } else { 22600 erroredWork = workInProgress; 22601 } 22602 22603 continue; 22604 } // Return to the normal work loop. 22605 22606 22607 return; 22608 } while (true); 22609 } 22610 22611 function pushDispatcher() { 22612 var prevDispatcher = ReactCurrentDispatcher$2.current; 22613 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; 22614 22615 if (prevDispatcher === null) { 22616 // The React isomorphic package does not include a default dispatcher. 22617 // Instead the first renderer will lazily attach one, in order to give 22618 // nicer error messages. 22619 return ContextOnlyDispatcher; 22620 } else { 22621 return prevDispatcher; 22622 } 22623 } 22624 22625 function popDispatcher(prevDispatcher) { 22626 ReactCurrentDispatcher$2.current = prevDispatcher; 22627 } 22628 22629 function pushInteractions(root) { 22630 { 22631 var prevInteractions = __interactionsRef.current; 22632 __interactionsRef.current = root.memoizedInteractions; 22633 return prevInteractions; 22634 } 22635 } 22636 22637 function popInteractions(prevInteractions) { 22638 { 22639 __interactionsRef.current = prevInteractions; 22640 } 22641 } 22642 22643 function markCommitTimeOfFallback() { 22644 globalMostRecentFallbackTime = now(); 22645 } 22646 function markSkippedUpdateLanes(lane) { 22647 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes); 22648 } 22649 function renderDidSuspend() { 22650 if (workInProgressRootExitStatus === RootIncomplete) { 22651 workInProgressRootExitStatus = RootSuspended; 22652 } 22653 } 22654 function renderDidSuspendDelayIfPossible() { 22655 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) { 22656 workInProgressRootExitStatus = RootSuspendedWithDelay; 22657 } // Check if there are updates that we skipped tree that might have unblocked 22658 // this render. 22659 22660 22661 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootUpdatedLanes))) { 22662 // Mark the current render as suspended so that we switch to working on 22663 // the updates that were skipped. Usually we only suspend at the end of 22664 // the render phase. 22665 // TODO: We should probably always mark the root as suspended immediately 22666 // (inside this function), since by suspending at the end of the render 22667 // phase introduces a potential mistake where we suspend lanes that were 22668 // pinged or updated while we were rendering. 22669 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes); 22670 } 22671 } 22672 function renderDidError() { 22673 if (workInProgressRootExitStatus !== RootCompleted) { 22674 workInProgressRootExitStatus = RootErrored; 22675 } 22676 } // Called during render to determine if anything has suspended. 22677 // Returns false if we're not sure. 22678 22679 function renderHasNotSuspendedYet() { 22680 // If something errored or completed, we can't really be sure, 22681 // so those are false. 22682 return workInProgressRootExitStatus === RootIncomplete; 22683 } 22684 22685 function renderRootSync(root, lanes) { 22686 var prevExecutionContext = executionContext; 22687 executionContext |= RenderContext; 22688 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack 22689 // and prepare a fresh one. Otherwise we'll continue where we left off. 22690 22691 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { 22692 prepareFreshStack(root, lanes); 22693 startWorkOnPendingInteractions(root, lanes); 22694 } 22695 22696 var prevInteractions = pushInteractions(root); 22697 22698 do { 22699 try { 22700 workLoopSync(); 22701 break; 22702 } catch (thrownValue) { 22703 handleError(root, thrownValue); 22704 } 22705 } while (true); 22706 22707 resetContextDependencies(); 22708 22709 { 22710 popInteractions(prevInteractions); 22711 } 22712 22713 executionContext = prevExecutionContext; 22714 popDispatcher(prevDispatcher); 22715 22716 if (workInProgress !== null) { 22717 // This is a sync render, so we should have finished the whole tree. 22718 { 22719 { 22720 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." ); 22721 } 22722 } 22723 } 22724 22725 22726 workInProgressRoot = null; 22727 workInProgressRootRenderLanes = NoLanes; 22728 return workInProgressRootExitStatus; 22729 } // The work loop is an extremely hot path. Tell Closure not to inline it. 22730 22731 /** @noinline */ 22732 22733 22734 function workLoopSync() { 22735 // Already timed out, so perform work without checking if we need to yield. 22736 while (workInProgress !== null) { 22737 performUnitOfWork(workInProgress); 22738 } 22739 } 22740 22741 function renderRootConcurrent(root, lanes) { 22742 var prevExecutionContext = executionContext; 22743 executionContext |= RenderContext; 22744 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack 22745 // and prepare a fresh one. Otherwise we'll continue where we left off. 22746 22747 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { 22748 resetRenderTimer(); 22749 prepareFreshStack(root, lanes); 22750 startWorkOnPendingInteractions(root, lanes); 22751 } 22752 22753 var prevInteractions = pushInteractions(root); 22754 22755 do { 22756 try { 22757 workLoopConcurrent(); 22758 break; 22759 } catch (thrownValue) { 22760 handleError(root, thrownValue); 22761 } 22762 } while (true); 22763 22764 resetContextDependencies(); 22765 22766 { 22767 popInteractions(prevInteractions); 22768 } 22769 22770 popDispatcher(prevDispatcher); 22771 executionContext = prevExecutionContext; 22772 22773 22774 if (workInProgress !== null) { 22775 22776 return RootIncomplete; 22777 } else { 22778 22779 22780 workInProgressRoot = null; 22781 workInProgressRootRenderLanes = NoLanes; // Return the final exit status. 22782 22783 return workInProgressRootExitStatus; 22784 } 22785 } 22786 /** @noinline */ 22787 22788 22789 function workLoopConcurrent() { 22790 // Perform work until Scheduler asks us to yield 22791 while (workInProgress !== null && !shouldYield()) { 22792 performUnitOfWork(workInProgress); 22793 } 22794 } 22795 22796 function performUnitOfWork(unitOfWork) { 22797 // The current, flushed, state of this fiber is the alternate. Ideally 22798 // nothing should rely on this, but relying on it here means that we don't 22799 // need an additional field on the work in progress. 22800 var current = unitOfWork.alternate; 22801 setCurrentFiber(unitOfWork); 22802 var next; 22803 22804 if ( (unitOfWork.mode & ProfileMode) !== NoMode) { 22805 startProfilerTimer(unitOfWork); 22806 next = beginWork$1(current, unitOfWork, subtreeRenderLanes); 22807 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); 22808 } else { 22809 next = beginWork$1(current, unitOfWork, subtreeRenderLanes); 22810 } 22811 22812 resetCurrentFiber(); 22813 unitOfWork.memoizedProps = unitOfWork.pendingProps; 22814 22815 if (next === null) { 22816 // If this doesn't spawn new work, complete the current work. 22817 completeUnitOfWork(unitOfWork); 22818 } else { 22819 workInProgress = next; 22820 } 22821 22822 ReactCurrentOwner$2.current = null; 22823 } 22824 22825 function completeUnitOfWork(unitOfWork) { 22826 // Attempt to complete the current unit of work, then move to the next 22827 // sibling. If there are no more siblings, return to the parent fiber. 22828 var completedWork = unitOfWork; 22829 22830 do { 22831 // The current, flushed, state of this fiber is the alternate. Ideally 22832 // nothing should rely on this, but relying on it here means that we don't 22833 // need an additional field on the work in progress. 22834 var current = completedWork.alternate; 22835 var returnFiber = completedWork.return; // Check if the work completed or if something threw. 22836 22837 if ((completedWork.flags & Incomplete) === NoFlags) { 22838 setCurrentFiber(completedWork); 22839 var next = void 0; 22840 22841 if ( (completedWork.mode & ProfileMode) === NoMode) { 22842 next = completeWork(current, completedWork, subtreeRenderLanes); 22843 } else { 22844 startProfilerTimer(completedWork); 22845 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error. 22846 22847 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); 22848 } 22849 22850 resetCurrentFiber(); 22851 22852 if (next !== null) { 22853 // Completing this fiber spawned new work. Work on that next. 22854 workInProgress = next; 22855 return; 22856 } 22857 22858 resetChildLanes(completedWork); 22859 22860 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete 22861 (returnFiber.flags & Incomplete) === NoFlags) { 22862 // Append all the effects of the subtree and this fiber onto the effect 22863 // list of the parent. The completion order of the children affects the 22864 // side-effect order. 22865 if (returnFiber.firstEffect === null) { 22866 returnFiber.firstEffect = completedWork.firstEffect; 22867 } 22868 22869 if (completedWork.lastEffect !== null) { 22870 if (returnFiber.lastEffect !== null) { 22871 returnFiber.lastEffect.nextEffect = completedWork.firstEffect; 22872 } 22873 22874 returnFiber.lastEffect = completedWork.lastEffect; 22875 } // If this fiber had side-effects, we append it AFTER the children's 22876 // side-effects. We can perform certain side-effects earlier if needed, 22877 // by doing multiple passes over the effect list. We don't want to 22878 // schedule our own side-effect on our own list because if end up 22879 // reusing children we'll schedule this effect onto itself since we're 22880 // at the end. 22881 22882 22883 var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect 22884 // list. PerformedWork effect is read by React DevTools but shouldn't be 22885 // committed. 22886 22887 if (flags > PerformedWork) { 22888 if (returnFiber.lastEffect !== null) { 22889 returnFiber.lastEffect.nextEffect = completedWork; 22890 } else { 22891 returnFiber.firstEffect = completedWork; 22892 } 22893 22894 returnFiber.lastEffect = completedWork; 22895 } 22896 } 22897 } else { 22898 // This fiber did not complete because something threw. Pop values off 22899 // the stack without entering the complete phase. If this is a boundary, 22900 // capture values if possible. 22901 var _next = unwindWork(completedWork); // Because this fiber did not complete, don't reset its expiration time. 22902 22903 22904 if (_next !== null) { 22905 // If completing this work spawned new work, do that next. We'll come 22906 // back here again. 22907 // Since we're restarting, remove anything that is not a host effect 22908 // from the effect tag. 22909 _next.flags &= HostEffectMask; 22910 workInProgress = _next; 22911 return; 22912 } 22913 22914 if ( (completedWork.mode & ProfileMode) !== NoMode) { 22915 // Record the render duration for the fiber that errored. 22916 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing. 22917 22918 var actualDuration = completedWork.actualDuration; 22919 var child = completedWork.child; 22920 22921 while (child !== null) { 22922 actualDuration += child.actualDuration; 22923 child = child.sibling; 22924 } 22925 22926 completedWork.actualDuration = actualDuration; 22927 } 22928 22929 if (returnFiber !== null) { 22930 // Mark the parent fiber as incomplete and clear its effect list. 22931 returnFiber.firstEffect = returnFiber.lastEffect = null; 22932 returnFiber.flags |= Incomplete; 22933 } 22934 } 22935 22936 var siblingFiber = completedWork.sibling; 22937 22938 if (siblingFiber !== null) { 22939 // If there is more work to do in this returnFiber, do that next. 22940 workInProgress = siblingFiber; 22941 return; 22942 } // Otherwise, return to the parent 22943 22944 22945 completedWork = returnFiber; // Update the next thing we're working on in case something throws. 22946 22947 workInProgress = completedWork; 22948 } while (completedWork !== null); // We've reached the root. 22949 22950 22951 if (workInProgressRootExitStatus === RootIncomplete) { 22952 workInProgressRootExitStatus = RootCompleted; 22953 } 22954 } 22955 22956 function resetChildLanes(completedWork) { 22957 if ( // TODO: Move this check out of the hot path by moving `resetChildLanes` 22958 // to switch statement in `completeWork`. 22959 (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) { 22960 // The children of this component are hidden. Don't bubble their 22961 // expiration times. 22962 return; 22963 } 22964 22965 var newChildLanes = NoLanes; // Bubble up the earliest expiration time. 22966 22967 if ( (completedWork.mode & ProfileMode) !== NoMode) { 22968 // In profiling mode, resetChildExpirationTime is also used to reset 22969 // profiler durations. 22970 var actualDuration = completedWork.actualDuration; 22971 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will 22972 // only be updated if work is done on the fiber (i.e. it doesn't bailout). 22973 // When work is done, it should bubble to the parent's actualDuration. If 22974 // the fiber has not been cloned though, (meaning no work was done), then 22975 // this value will reflect the amount of time spent working on a previous 22976 // render. In that case it should not bubble. We determine whether it was 22977 // cloned by comparing the child pointer. 22978 22979 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child; 22980 var child = completedWork.child; 22981 22982 while (child !== null) { 22983 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes)); 22984 22985 if (shouldBubbleActualDurations) { 22986 actualDuration += child.actualDuration; 22987 } 22988 22989 treeBaseDuration += child.treeBaseDuration; 22990 child = child.sibling; 22991 } 22992 22993 var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null; 22994 22995 if (isTimedOutSuspense) { 22996 // Don't count time spent in a timed out Suspense subtree as part of the base duration. 22997 var primaryChildFragment = completedWork.child; 22998 22999 if (primaryChildFragment !== null) { 23000 treeBaseDuration -= primaryChildFragment.treeBaseDuration; 23001 } 23002 } 23003 23004 completedWork.actualDuration = actualDuration; 23005 completedWork.treeBaseDuration = treeBaseDuration; 23006 } else { 23007 var _child = completedWork.child; 23008 23009 while (_child !== null) { 23010 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes)); 23011 _child = _child.sibling; 23012 } 23013 } 23014 23015 completedWork.childLanes = newChildLanes; 23016 } 23017 23018 function commitRoot(root) { 23019 var renderPriorityLevel = getCurrentPriorityLevel(); 23020 runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel)); 23021 return null; 23022 } 23023 23024 function commitRootImpl(root, renderPriorityLevel) { 23025 do { 23026 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which 23027 // means `flushPassiveEffects` will sometimes result in additional 23028 // passive effects. So we need to keep flushing in a loop until there are 23029 // no more pending effects. 23030 // TODO: Might be better if `flushPassiveEffects` did not automatically 23031 // flush synchronous work at the end, to avoid factoring hazards like this. 23032 flushPassiveEffects(); 23033 } while (rootWithPendingPassiveEffects !== null); 23034 23035 flushRenderPhaseStrictModeWarningsInDEV(); 23036 23037 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { 23038 { 23039 throw Error( "Should not already be working." ); 23040 } 23041 } 23042 23043 var finishedWork = root.finishedWork; 23044 var lanes = root.finishedLanes; 23045 23046 if (finishedWork === null) { 23047 23048 return null; 23049 } 23050 23051 root.finishedWork = null; 23052 root.finishedLanes = NoLanes; 23053 23054 if (!(finishedWork !== root.current)) { 23055 { 23056 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); 23057 } 23058 } // commitRoot never returns a continuation; it always finishes synchronously. 23059 // So we can clear these now to allow a new callback to be scheduled. 23060 23061 23062 root.callbackNode = null; // Update the first and last pending times on this root. The new first 23063 // pending time is whatever is left on the root fiber. 23064 23065 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); 23066 markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of 23067 // `flushDiscreteUpdates` starts a useless render pass which may cancels 23068 // a scheduled timeout. 23069 23070 if (rootsWithPendingDiscreteUpdates !== null) { 23071 if (!hasDiscreteLanes(remainingLanes) && rootsWithPendingDiscreteUpdates.has(root)) { 23072 rootsWithPendingDiscreteUpdates.delete(root); 23073 } 23074 } 23075 23076 if (root === workInProgressRoot) { 23077 // We can reset these now that they are finished. 23078 workInProgressRoot = null; 23079 workInProgress = null; 23080 workInProgressRootRenderLanes = NoLanes; 23081 } // Get the list of effects. 23082 23083 23084 var firstEffect; 23085 23086 if (finishedWork.flags > PerformedWork) { 23087 // A fiber's effect list consists only of its children, not itself. So if 23088 // the root has an effect, we need to add it to the end of the list. The 23089 // resulting list is the set that would belong to the root's parent, if it 23090 // had one; that is, all the effects in the tree including the root. 23091 if (finishedWork.lastEffect !== null) { 23092 finishedWork.lastEffect.nextEffect = finishedWork; 23093 firstEffect = finishedWork.firstEffect; 23094 } else { 23095 firstEffect = finishedWork; 23096 } 23097 } else { 23098 // There is no effect on the root. 23099 firstEffect = finishedWork.firstEffect; 23100 } 23101 23102 if (firstEffect !== null) { 23103 23104 var prevExecutionContext = executionContext; 23105 executionContext |= CommitContext; 23106 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles 23107 23108 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass 23109 // of the effect list for each phase: all mutation effects come before all 23110 // layout effects, and so on. 23111 // The first phase a "before mutation" phase. We use this phase to read the 23112 // state of the host tree right before we mutate it. This is where 23113 // getSnapshotBeforeUpdate is called. 23114 23115 focusedInstanceHandle = prepareForCommit(root.containerInfo); 23116 shouldFireAfterActiveInstanceBlur = false; 23117 nextEffect = firstEffect; 23118 23119 do { 23120 { 23121 invokeGuardedCallback(null, commitBeforeMutationEffects, null); 23122 23123 if (hasCaughtError()) { 23124 if (!(nextEffect !== null)) { 23125 { 23126 throw Error( "Should be working on an effect." ); 23127 } 23128 } 23129 23130 var error = clearCaughtError(); 23131 captureCommitPhaseError(nextEffect, error); 23132 nextEffect = nextEffect.nextEffect; 23133 } 23134 } 23135 } while (nextEffect !== null); // We no longer need to track the active instance fiber 23136 23137 23138 focusedInstanceHandle = null; 23139 23140 { 23141 // Mark the current commit time to be shared by all Profilers in this 23142 // batch. This enables them to be grouped later. 23143 recordCommitTime(); 23144 } // The next phase is the mutation phase, where we mutate the host tree. 23145 23146 23147 nextEffect = firstEffect; 23148 23149 do { 23150 { 23151 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel); 23152 23153 if (hasCaughtError()) { 23154 if (!(nextEffect !== null)) { 23155 { 23156 throw Error( "Should be working on an effect." ); 23157 } 23158 } 23159 23160 var _error = clearCaughtError(); 23161 23162 captureCommitPhaseError(nextEffect, _error); 23163 nextEffect = nextEffect.nextEffect; 23164 } 23165 } 23166 } while (nextEffect !== null); 23167 23168 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after 23169 // the mutation phase, so that the previous tree is still current during 23170 // componentWillUnmount, but before the layout phase, so that the finished 23171 // work is current during componentDidMount/Update. 23172 23173 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read 23174 // the host tree after it's been mutated. The idiomatic use case for this is 23175 // layout, but class component lifecycles also fire here for legacy reasons. 23176 23177 nextEffect = firstEffect; 23178 23179 do { 23180 { 23181 invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); 23182 23183 if (hasCaughtError()) { 23184 if (!(nextEffect !== null)) { 23185 { 23186 throw Error( "Should be working on an effect." ); 23187 } 23188 } 23189 23190 var _error2 = clearCaughtError(); 23191 23192 captureCommitPhaseError(nextEffect, _error2); 23193 nextEffect = nextEffect.nextEffect; 23194 } 23195 } 23196 } while (nextEffect !== null); 23197 23198 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an 23199 // opportunity to paint. 23200 23201 requestPaint(); 23202 23203 { 23204 popInteractions(prevInteractions); 23205 } 23206 23207 executionContext = prevExecutionContext; 23208 } else { 23209 // No effects. 23210 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were 23211 // no effects. 23212 // TODO: Maybe there's a better way to report this. 23213 23214 { 23215 recordCommitTime(); 23216 } 23217 } 23218 23219 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; 23220 23221 if (rootDoesHavePassiveEffects) { 23222 // This commit has passive effects. Stash a reference to them. But don't 23223 // schedule a callback until after flushing layout work. 23224 rootDoesHavePassiveEffects = false; 23225 rootWithPendingPassiveEffects = root; 23226 pendingPassiveEffectsLanes = lanes; 23227 pendingPassiveEffectsRenderPriority = renderPriorityLevel; 23228 } else { 23229 // We are done with the effect chain at this point so let's clear the 23230 // nextEffect pointers to assist with GC. If we have passive effects, we'll 23231 // clear this in flushPassiveEffects. 23232 nextEffect = firstEffect; 23233 23234 while (nextEffect !== null) { 23235 var nextNextEffect = nextEffect.nextEffect; 23236 nextEffect.nextEffect = null; 23237 23238 if (nextEffect.flags & Deletion) { 23239 detachFiberAfterEffects(nextEffect); 23240 } 23241 23242 nextEffect = nextNextEffect; 23243 } 23244 } // Read this again, since an effect might have updated it 23245 23246 23247 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root 23248 23249 if (remainingLanes !== NoLanes) { 23250 { 23251 if (spawnedWorkDuringRender !== null) { 23252 var expirationTimes = spawnedWorkDuringRender; 23253 spawnedWorkDuringRender = null; 23254 23255 for (var i = 0; i < expirationTimes.length; i++) { 23256 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions); 23257 } 23258 } 23259 23260 schedulePendingInteractions(root, remainingLanes); 23261 } 23262 } else { 23263 // If there's no remaining work, we can clear the set of already failed 23264 // error boundaries. 23265 legacyErrorBoundariesThatAlreadyFailed = null; 23266 } 23267 23268 { 23269 if (!rootDidHavePassiveEffects) { 23270 // If there are no passive effects, then we can complete the pending interactions. 23271 // Otherwise, we'll wait until after the passive effects are flushed. 23272 // Wait to do this until after remaining work has been scheduled, 23273 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work. 23274 finishPendingInteractions(root, lanes); 23275 } 23276 } 23277 23278 if (remainingLanes === SyncLane) { 23279 // Count the number of times the root synchronously re-renders without 23280 // finishing. If there are too many, it indicates an infinite update loop. 23281 if (root === rootWithNestedUpdates) { 23282 nestedUpdateCount++; 23283 } else { 23284 nestedUpdateCount = 0; 23285 rootWithNestedUpdates = root; 23286 } 23287 } else { 23288 nestedUpdateCount = 0; 23289 } 23290 23291 onCommitRoot(finishedWork.stateNode, renderPriorityLevel); 23292 23293 { 23294 onCommitRoot$1(); 23295 } // Always call this before exiting `commitRoot`, to ensure that any 23296 // additional work on this root is scheduled. 23297 23298 23299 ensureRootIsScheduled(root, now()); 23300 23301 if (hasUncaughtError) { 23302 hasUncaughtError = false; 23303 var _error3 = firstUncaughtError; 23304 firstUncaughtError = null; 23305 throw _error3; 23306 } 23307 23308 if ((executionContext & LegacyUnbatchedContext) !== NoContext) { 23309 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired 23310 // synchronously, but layout updates should be deferred until the end 23311 // of the batch. 23312 23313 23314 return null; 23315 } // If layout work was scheduled, flush it now. 23316 23317 23318 flushSyncCallbackQueue(); 23319 23320 return null; 23321 } 23322 23323 function commitBeforeMutationEffects() { 23324 while (nextEffect !== null) { 23325 var current = nextEffect.alternate; 23326 23327 if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { 23328 if ((nextEffect.flags & Deletion) !== NoFlags) { 23329 if (doesFiberContain(nextEffect, focusedInstanceHandle)) { 23330 shouldFireAfterActiveInstanceBlur = true; 23331 } 23332 } else { 23333 // TODO: Move this out of the hot path using a dedicated effect tag. 23334 if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) { 23335 shouldFireAfterActiveInstanceBlur = true; 23336 } 23337 } 23338 } 23339 23340 var flags = nextEffect.flags; 23341 23342 if ((flags & Snapshot) !== NoFlags) { 23343 setCurrentFiber(nextEffect); 23344 commitBeforeMutationLifeCycles(current, nextEffect); 23345 resetCurrentFiber(); 23346 } 23347 23348 if ((flags & Passive) !== NoFlags) { 23349 // If there are passive effects, schedule a callback to flush at 23350 // the earliest opportunity. 23351 if (!rootDoesHavePassiveEffects) { 23352 rootDoesHavePassiveEffects = true; 23353 scheduleCallback(NormalPriority$1, function () { 23354 flushPassiveEffects(); 23355 return null; 23356 }); 23357 } 23358 } 23359 23360 nextEffect = nextEffect.nextEffect; 23361 } 23362 } 23363 23364 function commitMutationEffects(root, renderPriorityLevel) { 23365 // TODO: Should probably move the bulk of this function to commitWork. 23366 while (nextEffect !== null) { 23367 setCurrentFiber(nextEffect); 23368 var flags = nextEffect.flags; 23369 23370 if (flags & ContentReset) { 23371 commitResetTextContent(nextEffect); 23372 } 23373 23374 if (flags & Ref) { 23375 var current = nextEffect.alternate; 23376 23377 if (current !== null) { 23378 commitDetachRef(current); 23379 } 23380 } // The following switch statement is only concerned about placement, 23381 // updates, and deletions. To avoid needing to add a case for every possible 23382 // bitmap value, we remove the secondary effects from the effect tag and 23383 // switch on that value. 23384 23385 23386 var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); 23387 23388 switch (primaryFlags) { 23389 case Placement: 23390 { 23391 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is 23392 // inserted, before any life-cycles like componentDidMount gets called. 23393 // TODO: findDOMNode doesn't rely on this any more but isMounted does 23394 // and isMounted is deprecated anyway so we should be able to kill this. 23395 23396 nextEffect.flags &= ~Placement; 23397 break; 23398 } 23399 23400 case PlacementAndUpdate: 23401 { 23402 // Placement 23403 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is 23404 // inserted, before any life-cycles like componentDidMount gets called. 23405 23406 nextEffect.flags &= ~Placement; // Update 23407 23408 var _current = nextEffect.alternate; 23409 commitWork(_current, nextEffect); 23410 break; 23411 } 23412 23413 case Hydrating: 23414 { 23415 nextEffect.flags &= ~Hydrating; 23416 break; 23417 } 23418 23419 case HydratingAndUpdate: 23420 { 23421 nextEffect.flags &= ~Hydrating; // Update 23422 23423 var _current2 = nextEffect.alternate; 23424 commitWork(_current2, nextEffect); 23425 break; 23426 } 23427 23428 case Update: 23429 { 23430 var _current3 = nextEffect.alternate; 23431 commitWork(_current3, nextEffect); 23432 break; 23433 } 23434 23435 case Deletion: 23436 { 23437 commitDeletion(root, nextEffect); 23438 break; 23439 } 23440 } 23441 23442 resetCurrentFiber(); 23443 nextEffect = nextEffect.nextEffect; 23444 } 23445 } 23446 23447 function commitLayoutEffects(root, committedLanes) { 23448 23449 23450 while (nextEffect !== null) { 23451 setCurrentFiber(nextEffect); 23452 var flags = nextEffect.flags; 23453 23454 if (flags & (Update | Callback)) { 23455 var current = nextEffect.alternate; 23456 commitLifeCycles(root, current, nextEffect); 23457 } 23458 23459 { 23460 if (flags & Ref) { 23461 commitAttachRef(nextEffect); 23462 } 23463 } 23464 23465 resetCurrentFiber(); 23466 nextEffect = nextEffect.nextEffect; 23467 } 23468 } 23469 23470 function flushPassiveEffects() { 23471 // Returns whether passive effects were flushed. 23472 if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { 23473 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority$1 ? NormalPriority$1 : pendingPassiveEffectsRenderPriority; 23474 pendingPassiveEffectsRenderPriority = NoPriority$1; 23475 23476 { 23477 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); 23478 } 23479 } 23480 23481 return false; 23482 } 23483 function enqueuePendingPassiveHookEffectMount(fiber, effect) { 23484 pendingPassiveHookEffectsMount.push(effect, fiber); 23485 23486 if (!rootDoesHavePassiveEffects) { 23487 rootDoesHavePassiveEffects = true; 23488 scheduleCallback(NormalPriority$1, function () { 23489 flushPassiveEffects(); 23490 return null; 23491 }); 23492 } 23493 } 23494 function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { 23495 pendingPassiveHookEffectsUnmount.push(effect, fiber); 23496 23497 { 23498 fiber.flags |= PassiveUnmountPendingDev; 23499 var alternate = fiber.alternate; 23500 23501 if (alternate !== null) { 23502 alternate.flags |= PassiveUnmountPendingDev; 23503 } 23504 } 23505 23506 if (!rootDoesHavePassiveEffects) { 23507 rootDoesHavePassiveEffects = true; 23508 scheduleCallback(NormalPriority$1, function () { 23509 flushPassiveEffects(); 23510 return null; 23511 }); 23512 } 23513 } 23514 23515 function invokePassiveEffectCreate(effect) { 23516 var create = effect.create; 23517 effect.destroy = create(); 23518 } 23519 23520 function flushPassiveEffectsImpl() { 23521 if (rootWithPendingPassiveEffects === null) { 23522 return false; 23523 } 23524 23525 var root = rootWithPendingPassiveEffects; 23526 var lanes = pendingPassiveEffectsLanes; 23527 rootWithPendingPassiveEffects = null; 23528 pendingPassiveEffectsLanes = NoLanes; 23529 23530 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { 23531 { 23532 throw Error( "Cannot flush passive effects while already rendering." ); 23533 } 23534 } 23535 23536 { 23537 isFlushingPassiveEffects = true; 23538 } 23539 23540 var prevExecutionContext = executionContext; 23541 executionContext |= CommitContext; 23542 var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called 23543 // before ANY passive effect create functions are called. 23544 // Otherwise effects in sibling components might interfere with each other. 23545 // e.g. a destroy function in one component may unintentionally override a ref 23546 // value set by a create function in another component. 23547 // Layout effects have the same constraint. 23548 // First pass: Destroy stale passive effects. 23549 23550 var unmountEffects = pendingPassiveHookEffectsUnmount; 23551 pendingPassiveHookEffectsUnmount = []; 23552 23553 for (var i = 0; i < unmountEffects.length; i += 2) { 23554 var _effect = unmountEffects[i]; 23555 var fiber = unmountEffects[i + 1]; 23556 var destroy = _effect.destroy; 23557 _effect.destroy = undefined; 23558 23559 { 23560 fiber.flags &= ~PassiveUnmountPendingDev; 23561 var alternate = fiber.alternate; 23562 23563 if (alternate !== null) { 23564 alternate.flags &= ~PassiveUnmountPendingDev; 23565 } 23566 } 23567 23568 if (typeof destroy === 'function') { 23569 { 23570 setCurrentFiber(fiber); 23571 23572 { 23573 invokeGuardedCallback(null, destroy, null); 23574 } 23575 23576 if (hasCaughtError()) { 23577 if (!(fiber !== null)) { 23578 { 23579 throw Error( "Should be working on an effect." ); 23580 } 23581 } 23582 23583 var error = clearCaughtError(); 23584 captureCommitPhaseError(fiber, error); 23585 } 23586 23587 resetCurrentFiber(); 23588 } 23589 } 23590 } // Second pass: Create new passive effects. 23591 23592 23593 var mountEffects = pendingPassiveHookEffectsMount; 23594 pendingPassiveHookEffectsMount = []; 23595 23596 for (var _i = 0; _i < mountEffects.length; _i += 2) { 23597 var _effect2 = mountEffects[_i]; 23598 var _fiber = mountEffects[_i + 1]; 23599 23600 { 23601 setCurrentFiber(_fiber); 23602 23603 { 23604 invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); 23605 } 23606 23607 if (hasCaughtError()) { 23608 if (!(_fiber !== null)) { 23609 { 23610 throw Error( "Should be working on an effect." ); 23611 } 23612 } 23613 23614 var _error4 = clearCaughtError(); 23615 23616 captureCommitPhaseError(_fiber, _error4); 23617 } 23618 23619 resetCurrentFiber(); 23620 } 23621 } // Note: This currently assumes there are no passive effects on the root fiber 23622 // because the root is not part of its own effect list. 23623 // This could change in the future. 23624 23625 23626 var effect = root.current.firstEffect; 23627 23628 while (effect !== null) { 23629 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC 23630 23631 effect.nextEffect = null; 23632 23633 if (effect.flags & Deletion) { 23634 detachFiberAfterEffects(effect); 23635 } 23636 23637 effect = nextNextEffect; 23638 } 23639 23640 { 23641 popInteractions(prevInteractions); 23642 finishPendingInteractions(root, lanes); 23643 } 23644 23645 { 23646 isFlushingPassiveEffects = false; 23647 } 23648 23649 executionContext = prevExecutionContext; 23650 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this 23651 // exceeds the limit, we'll fire a warning. 23652 23653 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; 23654 return true; 23655 } 23656 23657 function isAlreadyFailedLegacyErrorBoundary(instance) { 23658 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance); 23659 } 23660 function markLegacyErrorBoundaryAsFailed(instance) { 23661 if (legacyErrorBoundariesThatAlreadyFailed === null) { 23662 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); 23663 } else { 23664 legacyErrorBoundariesThatAlreadyFailed.add(instance); 23665 } 23666 } 23667 23668 function prepareToThrowUncaughtError(error) { 23669 if (!hasUncaughtError) { 23670 hasUncaughtError = true; 23671 firstUncaughtError = error; 23672 } 23673 } 23674 23675 var onUncaughtError = prepareToThrowUncaughtError; 23676 23677 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { 23678 var errorInfo = createCapturedValue(error, sourceFiber); 23679 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane); 23680 enqueueUpdate(rootFiber, update); 23681 var eventTime = requestEventTime(); 23682 var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane); 23683 23684 if (root !== null) { 23685 markRootUpdated(root, SyncLane, eventTime); 23686 ensureRootIsScheduled(root, eventTime); 23687 schedulePendingInteractions(root, SyncLane); 23688 } 23689 } 23690 23691 function captureCommitPhaseError(sourceFiber, error) { 23692 if (sourceFiber.tag === HostRoot) { 23693 // Error was thrown at the root. There is no parent, so the root 23694 // itself should capture it. 23695 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); 23696 return; 23697 } 23698 23699 var fiber = sourceFiber.return; 23700 23701 while (fiber !== null) { 23702 if (fiber.tag === HostRoot) { 23703 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); 23704 return; 23705 } else if (fiber.tag === ClassComponent) { 23706 var ctor = fiber.type; 23707 var instance = fiber.stateNode; 23708 23709 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) { 23710 var errorInfo = createCapturedValue(error, sourceFiber); 23711 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); 23712 enqueueUpdate(fiber, update); 23713 var eventTime = requestEventTime(); 23714 var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane); 23715 23716 if (root !== null) { 23717 markRootUpdated(root, SyncLane, eventTime); 23718 ensureRootIsScheduled(root, eventTime); 23719 schedulePendingInteractions(root, SyncLane); 23720 } else { 23721 // This component has already been unmounted. 23722 // We can't schedule any follow up work for the root because the fiber is already unmounted, 23723 // but we can still call the log-only boundary so the error isn't swallowed. 23724 // 23725 // TODO This is only a temporary bandaid for the old reconciler fork. 23726 // We can delete this special case once the new fork is merged. 23727 if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) { 23728 try { 23729 instance.componentDidCatch(error, errorInfo); 23730 } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it? 23731 // This is kind of an edge case. 23732 } 23733 } 23734 } 23735 23736 return; 23737 } 23738 } 23739 23740 fiber = fiber.return; 23741 } 23742 } 23743 function pingSuspendedRoot(root, wakeable, pingedLanes) { 23744 var pingCache = root.pingCache; 23745 23746 if (pingCache !== null) { 23747 // The wakeable resolved, so we no longer need to memoize, because it will 23748 // never be thrown again. 23749 pingCache.delete(wakeable); 23750 } 23751 23752 var eventTime = requestEventTime(); 23753 markRootPinged(root, pingedLanes); 23754 23755 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) { 23756 // Received a ping at the same priority level at which we're currently 23757 // rendering. We might want to restart this render. This should mirror 23758 // the logic of whether or not a root suspends once it completes. 23759 // TODO: If we're rendering sync either due to Sync, Batched or expired, 23760 // we should probably never restart. 23761 // If we're suspended with delay, or if it's a retry, we'll always suspend 23762 // so we can always restart. 23763 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) { 23764 // Restart from the root. 23765 prepareFreshStack(root, NoLanes); 23766 } else { 23767 // Even though we can't restart right now, we might get an 23768 // opportunity later. So we mark this render as having a ping. 23769 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes); 23770 } 23771 } 23772 23773 ensureRootIsScheduled(root, eventTime); 23774 schedulePendingInteractions(root, pingedLanes); 23775 } 23776 23777 function retryTimedOutBoundary(boundaryFiber, retryLane) { 23778 // The boundary fiber (a Suspense component or SuspenseList component) 23779 // previously was rendered in its fallback state. One of the promises that 23780 // suspended it has resolved, which means at least part of the tree was 23781 // likely unblocked. Try rendering again, at a new expiration time. 23782 if (retryLane === NoLane) { 23783 retryLane = requestRetryLane(boundaryFiber); 23784 } // TODO: Special case idle priority? 23785 23786 23787 var eventTime = requestEventTime(); 23788 var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane); 23789 23790 if (root !== null) { 23791 markRootUpdated(root, retryLane, eventTime); 23792 ensureRootIsScheduled(root, eventTime); 23793 schedulePendingInteractions(root, retryLane); 23794 } 23795 } 23796 function resolveRetryWakeable(boundaryFiber, wakeable) { 23797 var retryLane = NoLane; // Default 23798 23799 var retryCache; 23800 23801 { 23802 retryCache = boundaryFiber.stateNode; 23803 } 23804 23805 if (retryCache !== null) { 23806 // The wakeable resolved, so we no longer need to memoize, because it will 23807 // never be thrown again. 23808 retryCache.delete(wakeable); 23809 } 23810 23811 retryTimedOutBoundary(boundaryFiber, retryLane); 23812 } // Computes the next Just Noticeable Difference (JND) boundary. 23813 // The theory is that a person can't tell the difference between small differences in time. 23814 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable 23815 // difference in the experience. However, waiting for longer might mean that we can avoid 23816 // showing an intermediate loading state. The longer we have already waited, the harder it 23817 // is to tell small differences in time. Therefore, the longer we've already waited, 23818 // the longer we can wait additionally. At some point we have to give up though. 23819 // We pick a train model where the next boundary commits at a consistent schedule. 23820 // These particular numbers are vague estimates. We expect to adjust them based on research. 23821 23822 function jnd(timeElapsed) { 23823 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960; 23824 } 23825 23826 function checkForNestedUpdates() { 23827 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { 23828 nestedUpdateCount = 0; 23829 rootWithNestedUpdates = null; 23830 23831 { 23832 { 23833 throw 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." ); 23834 } 23835 } 23836 } 23837 23838 { 23839 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { 23840 nestedPassiveUpdateCount = 0; 23841 23842 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.'); 23843 } 23844 } 23845 } 23846 23847 function flushRenderPhaseStrictModeWarningsInDEV() { 23848 { 23849 ReactStrictModeWarnings.flushLegacyContextWarning(); 23850 23851 { 23852 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); 23853 } 23854 } 23855 } 23856 23857 var didWarnStateUpdateForNotYetMountedComponent = null; 23858 23859 function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { 23860 { 23861 if ((executionContext & RenderContext) !== NoContext) { 23862 // We let the other warning about render phase updates deal with this one. 23863 return; 23864 } 23865 23866 if (!(fiber.mode & (BlockingMode | ConcurrentMode))) { 23867 return; 23868 } 23869 23870 var tag = fiber.tag; 23871 23872 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) { 23873 // Only warn for user-defined components, not internal ones like Suspense. 23874 return; 23875 } // We show the whole stack but dedupe on the top component's name because 23876 // the problematic code almost always lies inside that component. 23877 23878 23879 var componentName = getComponentName(fiber.type) || 'ReactComponent'; 23880 23881 if (didWarnStateUpdateForNotYetMountedComponent !== null) { 23882 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { 23883 return; 23884 } 23885 23886 didWarnStateUpdateForNotYetMountedComponent.add(componentName); 23887 } else { 23888 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]); 23889 } 23890 23891 var previousFiber = current; 23892 23893 try { 23894 setCurrentFiber(fiber); 23895 23896 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.'); 23897 } finally { 23898 if (previousFiber) { 23899 setCurrentFiber(fiber); 23900 } else { 23901 resetCurrentFiber(); 23902 } 23903 } 23904 } 23905 } 23906 23907 var didWarnStateUpdateForUnmountedComponent = null; 23908 23909 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { 23910 { 23911 var tag = fiber.tag; 23912 23913 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) { 23914 // Only warn for user-defined components, not internal ones like Suspense. 23915 return; 23916 } // If there are pending passive effects unmounts for this Fiber, 23917 // we can assume that they would have prevented this update. 23918 23919 23920 if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { 23921 return; 23922 } // We show the whole stack but dedupe on the top component's name because 23923 // the problematic code almost always lies inside that component. 23924 23925 23926 var componentName = getComponentName(fiber.type) || 'ReactComponent'; 23927 23928 if (didWarnStateUpdateForUnmountedComponent !== null) { 23929 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { 23930 return; 23931 } 23932 23933 didWarnStateUpdateForUnmountedComponent.add(componentName); 23934 } else { 23935 didWarnStateUpdateForUnmountedComponent = new Set([componentName]); 23936 } 23937 23938 if (isFlushingPassiveEffects) ; else { 23939 var previousFiber = current; 23940 23941 try { 23942 setCurrentFiber(fiber); 23943 23944 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function'); 23945 } finally { 23946 if (previousFiber) { 23947 setCurrentFiber(fiber); 23948 } else { 23949 resetCurrentFiber(); 23950 } 23951 } 23952 } 23953 } 23954 } 23955 23956 var beginWork$1; 23957 23958 { 23959 var dummyFiber = null; 23960 23961 beginWork$1 = function (current, unitOfWork, lanes) { 23962 // If a component throws an error, we replay it again in a synchronously 23963 // dispatched event, so that the debugger will treat it as an uncaught 23964 // error See ReactErrorUtils for more information. 23965 // Before entering the begin phase, copy the work-in-progress onto a dummy 23966 // fiber. If beginWork throws, we'll use this to reset the state. 23967 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork); 23968 23969 try { 23970 return beginWork(current, unitOfWork, lanes); 23971 } catch (originalError) { 23972 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') { 23973 // Don't replay promises. Treat everything else like an error. 23974 throw originalError; 23975 } // Keep this code in sync with handleError; any changes here must have 23976 // corresponding changes there. 23977 23978 23979 resetContextDependencies(); 23980 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the 23981 // same fiber again. 23982 // Unwind the failed stack frame 23983 23984 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber. 23985 23986 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); 23987 23988 if ( unitOfWork.mode & ProfileMode) { 23989 // Reset the profiler timer. 23990 startProfilerTimer(unitOfWork); 23991 } // Run beginWork again. 23992 23993 23994 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); 23995 23996 if (hasCaughtError()) { 23997 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. 23998 // Rethrow this error instead of the original one. 23999 24000 throw replayError; 24001 } else { 24002 // This branch is reachable if the render phase is impure. 24003 throw originalError; 24004 } 24005 } 24006 }; 24007 } 24008 24009 var didWarnAboutUpdateInRender = false; 24010 var didWarnAboutUpdateInRenderForAnotherComponent; 24011 24012 { 24013 didWarnAboutUpdateInRenderForAnotherComponent = new Set(); 24014 } 24015 24016 function warnAboutRenderPhaseUpdatesInDEV(fiber) { 24017 { 24018 if (isRendering && (executionContext & RenderContext) !== NoContext && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) { 24019 switch (fiber.tag) { 24020 case FunctionComponent: 24021 case ForwardRef: 24022 case SimpleMemoComponent: 24023 { 24024 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed. 24025 24026 var dedupeKey = renderingComponentName; 24027 24028 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) { 24029 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); 24030 var setStateComponentName = getComponentName(fiber.type) || 'Unknown'; 24031 24032 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); 24033 } 24034 24035 break; 24036 } 24037 24038 case ClassComponent: 24039 { 24040 if (!didWarnAboutUpdateInRender) { 24041 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.'); 24042 24043 didWarnAboutUpdateInRender = true; 24044 } 24045 24046 break; 24047 } 24048 } 24049 } 24050 } 24051 } // a 'shared' variable that changes when act() opens/closes in tests. 24052 24053 24054 var IsThisRendererActing = { 24055 current: false 24056 }; 24057 function warnIfNotScopedWithMatchingAct(fiber) { 24058 { 24059 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) { 24060 var previousFiber = current; 24061 24062 try { 24063 setCurrentFiber(fiber); 24064 24065 error("It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + // Break up imports to avoid accidentally parsing them as dependencies. 24066 'import {act} fr' + "om 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + // Break up imports to avoid accidentally parsing them as dependencies. 24067 'import TestRenderer fr' + "om react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);'); 24068 } finally { 24069 if (previousFiber) { 24070 setCurrentFiber(fiber); 24071 } else { 24072 resetCurrentFiber(); 24073 } 24074 } 24075 } 24076 } 24077 } 24078 function warnIfNotCurrentlyActingEffectsInDEV(fiber) { 24079 { 24080 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) { 24081 error('An update to %s ran an effect, but 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', getComponentName(fiber.type)); 24082 } 24083 } 24084 } 24085 24086 function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { 24087 { 24088 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) { 24089 var previousFiber = current; 24090 24091 try { 24092 setCurrentFiber(fiber); 24093 24094 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', getComponentName(fiber.type)); 24095 } finally { 24096 if (previousFiber) { 24097 setCurrentFiber(fiber); 24098 } else { 24099 resetCurrentFiber(); 24100 } 24101 } 24102 } 24103 } 24104 } 24105 24106 var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler. 24107 24108 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked 24109 // scheduler is the actual recommendation. The alternative could be a testing build, 24110 // a new lib, or whatever; we dunno just yet. This message is for early adopters 24111 // to get their tests right. 24112 24113 function warnIfUnmockedScheduler(fiber) { 24114 { 24115 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) { 24116 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { 24117 didWarnAboutUnmockedScheduler = true; 24118 24119 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + // Break up requires to avoid accidentally parsing them as dependencies. 24120 "jest.mock('scheduler', () => require" + "('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://reactjs.org/link/mock-scheduler'); 24121 } 24122 } 24123 } 24124 } 24125 24126 function computeThreadID(root, lane) { 24127 // Interaction threads are unique per root and expiration time. 24128 // NOTE: Intentionally unsound cast. All that matters is that it's a number 24129 // and it represents a batch of work. Could make a helper function instead, 24130 // but meh this is fine for now. 24131 return lane * 1000 + root.interactionThreadID; 24132 } 24133 24134 function markSpawnedWork(lane) { 24135 24136 if (spawnedWorkDuringRender === null) { 24137 spawnedWorkDuringRender = [lane]; 24138 } else { 24139 spawnedWorkDuringRender.push(lane); 24140 } 24141 } 24142 24143 function scheduleInteractions(root, lane, interactions) { 24144 24145 if (interactions.size > 0) { 24146 var pendingInteractionMap = root.pendingInteractionMap; 24147 var pendingInteractions = pendingInteractionMap.get(lane); 24148 24149 if (pendingInteractions != null) { 24150 interactions.forEach(function (interaction) { 24151 if (!pendingInteractions.has(interaction)) { 24152 // Update the pending async work count for previously unscheduled interaction. 24153 interaction.__count++; 24154 } 24155 24156 pendingInteractions.add(interaction); 24157 }); 24158 } else { 24159 pendingInteractionMap.set(lane, new Set(interactions)); // Update the pending async work count for the current interactions. 24160 24161 interactions.forEach(function (interaction) { 24162 interaction.__count++; 24163 }); 24164 } 24165 24166 var subscriber = __subscriberRef.current; 24167 24168 if (subscriber !== null) { 24169 var threadID = computeThreadID(root, lane); 24170 subscriber.onWorkScheduled(interactions, threadID); 24171 } 24172 } 24173 } 24174 24175 function schedulePendingInteractions(root, lane) { 24176 24177 scheduleInteractions(root, lane, __interactionsRef.current); 24178 } 24179 24180 function startWorkOnPendingInteractions(root, lanes) { 24181 // we can accurately attribute time spent working on it, And so that cascading 24182 // work triggered during the render phase will be associated with it. 24183 24184 24185 var interactions = new Set(); 24186 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledLane) { 24187 if (includesSomeLane(lanes, scheduledLane)) { 24188 scheduledInteractions.forEach(function (interaction) { 24189 return interactions.add(interaction); 24190 }); 24191 } 24192 }); // Store the current set of interactions on the FiberRoot for a few reasons: 24193 // We can re-use it in hot functions like performConcurrentWorkOnRoot() 24194 // without having to recalculate it. We will also use it in commitWork() to 24195 // pass to any Profiler onRender() hooks. This also provides DevTools with a 24196 // way to access it when the onCommitRoot() hook is called. 24197 24198 root.memoizedInteractions = interactions; 24199 24200 if (interactions.size > 0) { 24201 var subscriber = __subscriberRef.current; 24202 24203 if (subscriber !== null) { 24204 var threadID = computeThreadID(root, lanes); 24205 24206 try { 24207 subscriber.onWorkStarted(interactions, threadID); 24208 } catch (error) { 24209 // If the subscriber throws, rethrow it in a separate task 24210 scheduleCallback(ImmediatePriority$1, function () { 24211 throw error; 24212 }); 24213 } 24214 } 24215 } 24216 } 24217 24218 function finishPendingInteractions(root, committedLanes) { 24219 24220 var remainingLanesAfterCommit = root.pendingLanes; 24221 var subscriber; 24222 24223 try { 24224 subscriber = __subscriberRef.current; 24225 24226 if (subscriber !== null && root.memoizedInteractions.size > 0) { 24227 // FIXME: More than one lane can finish in a single commit. 24228 var threadID = computeThreadID(root, committedLanes); 24229 subscriber.onWorkStopped(root.memoizedInteractions, threadID); 24230 } 24231 } catch (error) { 24232 // If the subscriber throws, rethrow it in a separate task 24233 scheduleCallback(ImmediatePriority$1, function () { 24234 throw error; 24235 }); 24236 } finally { 24237 // Clear completed interactions from the pending Map. 24238 // Unless the render was suspended or cascading work was scheduled, 24239 // In which case– leave pending interactions until the subsequent render. 24240 var pendingInteractionMap = root.pendingInteractionMap; 24241 pendingInteractionMap.forEach(function (scheduledInteractions, lane) { 24242 // Only decrement the pending interaction count if we're done. 24243 // If there's still work at the current priority, 24244 // That indicates that we are waiting for suspense data. 24245 if (!includesSomeLane(remainingLanesAfterCommit, lane)) { 24246 pendingInteractionMap.delete(lane); 24247 scheduledInteractions.forEach(function (interaction) { 24248 interaction.__count--; 24249 24250 if (subscriber !== null && interaction.__count === 0) { 24251 try { 24252 subscriber.onInteractionScheduledWorkCompleted(interaction); 24253 } catch (error) { 24254 // If the subscriber throws, rethrow it in a separate task 24255 scheduleCallback(ImmediatePriority$1, function () { 24256 throw error; 24257 }); 24258 } 24259 } 24260 }); 24261 } 24262 }); 24263 } 24264 } // `act` testing API 24265 24266 function shouldForceFlushFallbacksInDEV() { 24267 // Never force flush in production. This function should get stripped out. 24268 return actingUpdatesScopeDepth > 0; 24269 } 24270 // so we can tell if any async act() calls try to run in parallel. 24271 24272 24273 var actingUpdatesScopeDepth = 0; 24274 24275 function detachFiberAfterEffects(fiber) { 24276 fiber.sibling = null; 24277 fiber.stateNode = null; 24278 } 24279 24280 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. 24281 24282 var failedBoundaries = null; 24283 var setRefreshHandler = function (handler) { 24284 { 24285 resolveFamily = handler; 24286 } 24287 }; 24288 function resolveFunctionForHotReloading(type) { 24289 { 24290 if (resolveFamily === null) { 24291 // Hot reloading is disabled. 24292 return type; 24293 } 24294 24295 var family = resolveFamily(type); 24296 24297 if (family === undefined) { 24298 return type; 24299 } // Use the latest known implementation. 24300 24301 24302 return family.current; 24303 } 24304 } 24305 function resolveClassForHotReloading(type) { 24306 // No implementation differences. 24307 return resolveFunctionForHotReloading(type); 24308 } 24309 function resolveForwardRefForHotReloading(type) { 24310 { 24311 if (resolveFamily === null) { 24312 // Hot reloading is disabled. 24313 return type; 24314 } 24315 24316 var family = resolveFamily(type); 24317 24318 if (family === undefined) { 24319 // Check if we're dealing with a real forwardRef. Don't want to crash early. 24320 if (type !== null && type !== undefined && typeof type.render === 'function') { 24321 // ForwardRef is special because its resolved .type is an object, 24322 // but it's possible that we only have its inner render function in the map. 24323 // If that inner render function is different, we'll build a new forwardRef type. 24324 var currentRender = resolveFunctionForHotReloading(type.render); 24325 24326 if (type.render !== currentRender) { 24327 var syntheticType = { 24328 $$typeof: REACT_FORWARD_REF_TYPE, 24329 render: currentRender 24330 }; 24331 24332 if (type.displayName !== undefined) { 24333 syntheticType.displayName = type.displayName; 24334 } 24335 24336 return syntheticType; 24337 } 24338 } 24339 24340 return type; 24341 } // Use the latest known implementation. 24342 24343 24344 return family.current; 24345 } 24346 } 24347 function isCompatibleFamilyForHotReloading(fiber, element) { 24348 { 24349 if (resolveFamily === null) { 24350 // Hot reloading is disabled. 24351 return false; 24352 } 24353 24354 var prevType = fiber.elementType; 24355 var nextType = element.type; // If we got here, we know types aren't === equal. 24356 24357 var needsCompareFamilies = false; 24358 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null; 24359 24360 switch (fiber.tag) { 24361 case ClassComponent: 24362 { 24363 if (typeof nextType === 'function') { 24364 needsCompareFamilies = true; 24365 } 24366 24367 break; 24368 } 24369 24370 case FunctionComponent: 24371 { 24372 if (typeof nextType === 'function') { 24373 needsCompareFamilies = true; 24374 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 24375 // We don't know the inner type yet. 24376 // We're going to assume that the lazy inner type is stable, 24377 // and so it is sufficient to avoid reconciling it away. 24378 // We're not going to unwrap or actually use the new lazy type. 24379 needsCompareFamilies = true; 24380 } 24381 24382 break; 24383 } 24384 24385 case ForwardRef: 24386 { 24387 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { 24388 needsCompareFamilies = true; 24389 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 24390 needsCompareFamilies = true; 24391 } 24392 24393 break; 24394 } 24395 24396 case MemoComponent: 24397 case SimpleMemoComponent: 24398 { 24399 if ($$typeofNextType === REACT_MEMO_TYPE) { 24400 // TODO: if it was but can no longer be simple, 24401 // we shouldn't set this. 24402 needsCompareFamilies = true; 24403 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 24404 needsCompareFamilies = true; 24405 } 24406 24407 break; 24408 } 24409 24410 default: 24411 return false; 24412 } // Check if both types have a family and it's the same one. 24413 24414 24415 if (needsCompareFamilies) { 24416 // Note: memo() and forwardRef() we'll compare outer rather than inner type. 24417 // This means both of them need to be registered to preserve state. 24418 // If we unwrapped and compared the inner types for wrappers instead, 24419 // then we would risk falsely saying two separate memo(Foo) 24420 // calls are equivalent because they wrap the same Foo function. 24421 var prevFamily = resolveFamily(prevType); 24422 24423 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { 24424 return true; 24425 } 24426 } 24427 24428 return false; 24429 } 24430 } 24431 function markFailedErrorBoundaryForHotReloading(fiber) { 24432 { 24433 if (resolveFamily === null) { 24434 // Hot reloading is disabled. 24435 return; 24436 } 24437 24438 if (typeof WeakSet !== 'function') { 24439 return; 24440 } 24441 24442 if (failedBoundaries === null) { 24443 failedBoundaries = new WeakSet(); 24444 } 24445 24446 failedBoundaries.add(fiber); 24447 } 24448 } 24449 var scheduleRefresh = function (root, update) { 24450 { 24451 if (resolveFamily === null) { 24452 // Hot reloading is disabled. 24453 return; 24454 } 24455 24456 var staleFamilies = update.staleFamilies, 24457 updatedFamilies = update.updatedFamilies; 24458 flushPassiveEffects(); 24459 flushSync(function () { 24460 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies); 24461 }); 24462 } 24463 }; 24464 var scheduleRoot = function (root, element) { 24465 { 24466 if (root.context !== emptyContextObject) { 24467 // Super edge case: root has a legacy _renderSubtree context 24468 // but we don't know the parentComponent so we can't pass it. 24469 // Just ignore. We'll delete this with _renderSubtree code path later. 24470 return; 24471 } 24472 24473 flushPassiveEffects(); 24474 flushSync(function () { 24475 updateContainer(element, root, null, null); 24476 }); 24477 } 24478 }; 24479 24480 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) { 24481 { 24482 var alternate = fiber.alternate, 24483 child = fiber.child, 24484 sibling = fiber.sibling, 24485 tag = fiber.tag, 24486 type = fiber.type; 24487 var candidateType = null; 24488 24489 switch (tag) { 24490 case FunctionComponent: 24491 case SimpleMemoComponent: 24492 case ClassComponent: 24493 candidateType = type; 24494 break; 24495 24496 case ForwardRef: 24497 candidateType = type.render; 24498 break; 24499 } 24500 24501 if (resolveFamily === null) { 24502 throw new Error('Expected resolveFamily to be set during hot reload.'); 24503 } 24504 24505 var needsRender = false; 24506 var needsRemount = false; 24507 24508 if (candidateType !== null) { 24509 var family = resolveFamily(candidateType); 24510 24511 if (family !== undefined) { 24512 if (staleFamilies.has(family)) { 24513 needsRemount = true; 24514 } else if (updatedFamilies.has(family)) { 24515 if (tag === ClassComponent) { 24516 needsRemount = true; 24517 } else { 24518 needsRender = true; 24519 } 24520 } 24521 } 24522 } 24523 24524 if (failedBoundaries !== null) { 24525 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) { 24526 needsRemount = true; 24527 } 24528 } 24529 24530 if (needsRemount) { 24531 fiber._debugNeedsRemount = true; 24532 } 24533 24534 if (needsRemount || needsRender) { 24535 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 24536 } 24537 24538 if (child !== null && !needsRemount) { 24539 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies); 24540 } 24541 24542 if (sibling !== null) { 24543 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies); 24544 } 24545 } 24546 } 24547 24548 var findHostInstancesForRefresh = function (root, families) { 24549 { 24550 var hostInstances = new Set(); 24551 var types = new Set(families.map(function (family) { 24552 return family.current; 24553 })); 24554 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances); 24555 return hostInstances; 24556 } 24557 }; 24558 24559 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) { 24560 { 24561 var child = fiber.child, 24562 sibling = fiber.sibling, 24563 tag = fiber.tag, 24564 type = fiber.type; 24565 var candidateType = null; 24566 24567 switch (tag) { 24568 case FunctionComponent: 24569 case SimpleMemoComponent: 24570 case ClassComponent: 24571 candidateType = type; 24572 break; 24573 24574 case ForwardRef: 24575 candidateType = type.render; 24576 break; 24577 } 24578 24579 var didMatch = false; 24580 24581 if (candidateType !== null) { 24582 if (types.has(candidateType)) { 24583 didMatch = true; 24584 } 24585 } 24586 24587 if (didMatch) { 24588 // We have a match. This only drills down to the closest host components. 24589 // There's no need to search deeper because for the purpose of giving 24590 // visual feedback, "flashing" outermost parent rectangles is sufficient. 24591 findHostInstancesForFiberShallowly(fiber, hostInstances); 24592 } else { 24593 // If there's no match, maybe there will be one further down in the child tree. 24594 if (child !== null) { 24595 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances); 24596 } 24597 } 24598 24599 if (sibling !== null) { 24600 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances); 24601 } 24602 } 24603 } 24604 24605 function findHostInstancesForFiberShallowly(fiber, hostInstances) { 24606 { 24607 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances); 24608 24609 if (foundHostInstances) { 24610 return; 24611 } // If we didn't find any host children, fallback to closest host parent. 24612 24613 24614 var node = fiber; 24615 24616 while (true) { 24617 switch (node.tag) { 24618 case HostComponent: 24619 hostInstances.add(node.stateNode); 24620 return; 24621 24622 case HostPortal: 24623 hostInstances.add(node.stateNode.containerInfo); 24624 return; 24625 24626 case HostRoot: 24627 hostInstances.add(node.stateNode.containerInfo); 24628 return; 24629 } 24630 24631 if (node.return === null) { 24632 throw new Error('Expected to reach root first.'); 24633 } 24634 24635 node = node.return; 24636 } 24637 } 24638 } 24639 24640 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { 24641 { 24642 var node = fiber; 24643 var foundHostInstances = false; 24644 24645 while (true) { 24646 if (node.tag === HostComponent) { 24647 // We got a match. 24648 foundHostInstances = true; 24649 hostInstances.add(node.stateNode); // There may still be more, so keep searching. 24650 } else if (node.child !== null) { 24651 node.child.return = node; 24652 node = node.child; 24653 continue; 24654 } 24655 24656 if (node === fiber) { 24657 return foundHostInstances; 24658 } 24659 24660 while (node.sibling === null) { 24661 if (node.return === null || node.return === fiber) { 24662 return foundHostInstances; 24663 } 24664 24665 node = node.return; 24666 } 24667 24668 node.sibling.return = node.return; 24669 node = node.sibling; 24670 } 24671 } 24672 24673 return false; 24674 } 24675 24676 var hasBadMapPolyfill; 24677 24678 { 24679 hasBadMapPolyfill = false; 24680 24681 try { 24682 var nonExtensibleObject = Object.preventExtensions({}); 24683 /* eslint-disable no-new */ 24684 24685 new Map([[nonExtensibleObject, null]]); 24686 new Set([nonExtensibleObject]); 24687 /* eslint-enable no-new */ 24688 } catch (e) { 24689 // TODO: Consider warning about bad polyfills 24690 hasBadMapPolyfill = true; 24691 } 24692 } 24693 24694 var debugCounter = 1; 24695 24696 function FiberNode(tag, pendingProps, key, mode) { 24697 // Instance 24698 this.tag = tag; 24699 this.key = key; 24700 this.elementType = null; 24701 this.type = null; 24702 this.stateNode = null; // Fiber 24703 24704 this.return = null; 24705 this.child = null; 24706 this.sibling = null; 24707 this.index = 0; 24708 this.ref = null; 24709 this.pendingProps = pendingProps; 24710 this.memoizedProps = null; 24711 this.updateQueue = null; 24712 this.memoizedState = null; 24713 this.dependencies = null; 24714 this.mode = mode; // Effects 24715 24716 this.flags = NoFlags; 24717 this.nextEffect = null; 24718 this.firstEffect = null; 24719 this.lastEffect = null; 24720 this.lanes = NoLanes; 24721 this.childLanes = NoLanes; 24722 this.alternate = null; 24723 24724 { 24725 // Note: The following is done to avoid a v8 performance cliff. 24726 // 24727 // Initializing the fields below to smis and later updating them with 24728 // double values will cause Fibers to end up having separate shapes. 24729 // This behavior/bug has something to do with Object.preventExtension(). 24730 // Fortunately this only impacts DEV builds. 24731 // Unfortunately it makes React unusably slow for some applications. 24732 // To work around this, initialize the fields below with doubles. 24733 // 24734 // Learn more about this here: 24735 // https://github.com/facebook/react/issues/14365 24736 // https://bugs.chromium.org/p/v8/issues/detail?id=8538 24737 this.actualDuration = Number.NaN; 24738 this.actualStartTime = Number.NaN; 24739 this.selfBaseDuration = Number.NaN; 24740 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization. 24741 // This won't trigger the performance cliff mentioned above, 24742 // and it simplifies other profiler code (including DevTools). 24743 24744 this.actualDuration = 0; 24745 this.actualStartTime = -1; 24746 this.selfBaseDuration = 0; 24747 this.treeBaseDuration = 0; 24748 } 24749 24750 { 24751 // This isn't directly used but is handy for debugging internals: 24752 this._debugID = debugCounter++; 24753 this._debugSource = null; 24754 this._debugOwner = null; 24755 this._debugNeedsRemount = false; 24756 this._debugHookTypes = null; 24757 24758 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { 24759 Object.preventExtensions(this); 24760 } 24761 } 24762 } // This is a constructor function, rather than a POJO constructor, still 24763 // please ensure we do the following: 24764 // 1) Nobody should add any instance methods on this. Instance methods can be 24765 // more difficult to predict when they get optimized and they are almost 24766 // never inlined properly in static compilers. 24767 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should 24768 // always know when it is a fiber. 24769 // 3) We might want to experiment with using numeric keys since they are easier 24770 // to optimize in a non-JIT environment. 24771 // 4) We can easily go from a constructor to a createFiber object literal if that 24772 // is faster. 24773 // 5) It should be easy to port this to a C struct and keep a C implementation 24774 // compatible. 24775 24776 24777 var createFiber = function (tag, pendingProps, key, mode) { 24778 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors 24779 return new FiberNode(tag, pendingProps, key, mode); 24780 }; 24781 24782 function shouldConstruct$1(Component) { 24783 var prototype = Component.prototype; 24784 return !!(prototype && prototype.isReactComponent); 24785 } 24786 24787 function isSimpleFunctionComponent(type) { 24788 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined; 24789 } 24790 function resolveLazyComponentTag(Component) { 24791 if (typeof Component === 'function') { 24792 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent; 24793 } else if (Component !== undefined && Component !== null) { 24794 var $$typeof = Component.$$typeof; 24795 24796 if ($$typeof === REACT_FORWARD_REF_TYPE) { 24797 return ForwardRef; 24798 } 24799 24800 if ($$typeof === REACT_MEMO_TYPE) { 24801 return MemoComponent; 24802 } 24803 } 24804 24805 return IndeterminateComponent; 24806 } // This is used to create an alternate fiber to do work on. 24807 24808 function createWorkInProgress(current, pendingProps) { 24809 var workInProgress = current.alternate; 24810 24811 if (workInProgress === null) { 24812 // We use a double buffering pooling technique because we know that we'll 24813 // only ever need at most two versions of a tree. We pool the "other" unused 24814 // node that we're free to reuse. This is lazily created to avoid allocating 24815 // extra objects for things that are never updated. It also allow us to 24816 // reclaim the extra memory if needed. 24817 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode); 24818 workInProgress.elementType = current.elementType; 24819 workInProgress.type = current.type; 24820 workInProgress.stateNode = current.stateNode; 24821 24822 { 24823 // DEV-only fields 24824 workInProgress._debugID = current._debugID; 24825 workInProgress._debugSource = current._debugSource; 24826 workInProgress._debugOwner = current._debugOwner; 24827 workInProgress._debugHookTypes = current._debugHookTypes; 24828 } 24829 24830 workInProgress.alternate = current; 24831 current.alternate = workInProgress; 24832 } else { 24833 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type. 24834 24835 workInProgress.type = current.type; // We already have an alternate. 24836 // Reset the effect tag. 24837 24838 workInProgress.flags = NoFlags; // The effect list is no longer valid. 24839 24840 workInProgress.nextEffect = null; 24841 workInProgress.firstEffect = null; 24842 workInProgress.lastEffect = null; 24843 24844 { 24845 // We intentionally reset, rather than copy, actualDuration & actualStartTime. 24846 // This prevents time from endlessly accumulating in new commits. 24847 // This has the downside of resetting values for different priority renders, 24848 // But works for yielding (the common case) and should support resuming. 24849 workInProgress.actualDuration = 0; 24850 workInProgress.actualStartTime = -1; 24851 } 24852 } 24853 24854 workInProgress.childLanes = current.childLanes; 24855 workInProgress.lanes = current.lanes; 24856 workInProgress.child = current.child; 24857 workInProgress.memoizedProps = current.memoizedProps; 24858 workInProgress.memoizedState = current.memoizedState; 24859 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so 24860 // it cannot be shared with the current fiber. 24861 24862 var currentDependencies = current.dependencies; 24863 workInProgress.dependencies = currentDependencies === null ? null : { 24864 lanes: currentDependencies.lanes, 24865 firstContext: currentDependencies.firstContext 24866 }; // These will be overridden during the parent's reconciliation 24867 24868 workInProgress.sibling = current.sibling; 24869 workInProgress.index = current.index; 24870 workInProgress.ref = current.ref; 24871 24872 { 24873 workInProgress.selfBaseDuration = current.selfBaseDuration; 24874 workInProgress.treeBaseDuration = current.treeBaseDuration; 24875 } 24876 24877 { 24878 workInProgress._debugNeedsRemount = current._debugNeedsRemount; 24879 24880 switch (workInProgress.tag) { 24881 case IndeterminateComponent: 24882 case FunctionComponent: 24883 case SimpleMemoComponent: 24884 workInProgress.type = resolveFunctionForHotReloading(current.type); 24885 break; 24886 24887 case ClassComponent: 24888 workInProgress.type = resolveClassForHotReloading(current.type); 24889 break; 24890 24891 case ForwardRef: 24892 workInProgress.type = resolveForwardRefForHotReloading(current.type); 24893 break; 24894 } 24895 } 24896 24897 return workInProgress; 24898 } // Used to reuse a Fiber for a second pass. 24899 24900 function resetWorkInProgress(workInProgress, renderLanes) { 24901 // This resets the Fiber to what createFiber or createWorkInProgress would 24902 // have set the values to before during the first pass. Ideally this wouldn't 24903 // be necessary but unfortunately many code paths reads from the workInProgress 24904 // when they should be reading from current and writing to workInProgress. 24905 // We assume pendingProps, index, key, ref, return are still untouched to 24906 // avoid doing another reconciliation. 24907 // Reset the effect tag but keep any Placement tags, since that's something 24908 // that child fiber is setting, not the reconciliation. 24909 workInProgress.flags &= Placement; // The effect list is no longer valid. 24910 24911 workInProgress.nextEffect = null; 24912 workInProgress.firstEffect = null; 24913 workInProgress.lastEffect = null; 24914 var current = workInProgress.alternate; 24915 24916 if (current === null) { 24917 // Reset to createFiber's initial values. 24918 workInProgress.childLanes = NoLanes; 24919 workInProgress.lanes = renderLanes; 24920 workInProgress.child = null; 24921 workInProgress.memoizedProps = null; 24922 workInProgress.memoizedState = null; 24923 workInProgress.updateQueue = null; 24924 workInProgress.dependencies = null; 24925 workInProgress.stateNode = null; 24926 24927 { 24928 // Note: We don't reset the actualTime counts. It's useful to accumulate 24929 // actual time across multiple render passes. 24930 workInProgress.selfBaseDuration = 0; 24931 workInProgress.treeBaseDuration = 0; 24932 } 24933 } else { 24934 // Reset to the cloned values that createWorkInProgress would've. 24935 workInProgress.childLanes = current.childLanes; 24936 workInProgress.lanes = current.lanes; 24937 workInProgress.child = current.child; 24938 workInProgress.memoizedProps = current.memoizedProps; 24939 workInProgress.memoizedState = current.memoizedState; 24940 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. 24941 24942 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so 24943 // it cannot be shared with the current fiber. 24944 24945 var currentDependencies = current.dependencies; 24946 workInProgress.dependencies = currentDependencies === null ? null : { 24947 lanes: currentDependencies.lanes, 24948 firstContext: currentDependencies.firstContext 24949 }; 24950 24951 { 24952 // Note: We don't reset the actualTime counts. It's useful to accumulate 24953 // actual time across multiple render passes. 24954 workInProgress.selfBaseDuration = current.selfBaseDuration; 24955 workInProgress.treeBaseDuration = current.treeBaseDuration; 24956 } 24957 } 24958 24959 return workInProgress; 24960 } 24961 function createHostRootFiber(tag) { 24962 var mode; 24963 24964 if (tag === ConcurrentRoot) { 24965 mode = ConcurrentMode | BlockingMode | StrictMode; 24966 } else if (tag === BlockingRoot) { 24967 mode = BlockingMode | StrictMode; 24968 } else { 24969 mode = NoMode; 24970 } 24971 24972 if ( isDevToolsPresent) { 24973 // Always collect profile timings when DevTools are present. 24974 // This enables DevTools to start capturing timing at any point– 24975 // Without some nodes in the tree having empty base times. 24976 mode |= ProfileMode; 24977 } 24978 24979 return createFiber(HostRoot, null, null, mode); 24980 } 24981 function createFiberFromTypeAndProps(type, // React$ElementType 24982 key, pendingProps, owner, mode, lanes) { 24983 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy. 24984 24985 var resolvedType = type; 24986 24987 if (typeof type === 'function') { 24988 if (shouldConstruct$1(type)) { 24989 fiberTag = ClassComponent; 24990 24991 { 24992 resolvedType = resolveClassForHotReloading(resolvedType); 24993 } 24994 } else { 24995 { 24996 resolvedType = resolveFunctionForHotReloading(resolvedType); 24997 } 24998 } 24999 } else if (typeof type === 'string') { 25000 fiberTag = HostComponent; 25001 } else { 25002 getTag: switch (type) { 25003 case REACT_FRAGMENT_TYPE: 25004 return createFiberFromFragment(pendingProps.children, mode, lanes, key); 25005 25006 case REACT_DEBUG_TRACING_MODE_TYPE: 25007 fiberTag = Mode; 25008 mode |= DebugTracingMode; 25009 break; 25010 25011 case REACT_STRICT_MODE_TYPE: 25012 fiberTag = Mode; 25013 mode |= StrictMode; 25014 break; 25015 25016 case REACT_PROFILER_TYPE: 25017 return createFiberFromProfiler(pendingProps, mode, lanes, key); 25018 25019 case REACT_SUSPENSE_TYPE: 25020 return createFiberFromSuspense(pendingProps, mode, lanes, key); 25021 25022 case REACT_SUSPENSE_LIST_TYPE: 25023 return createFiberFromSuspenseList(pendingProps, mode, lanes, key); 25024 25025 case REACT_OFFSCREEN_TYPE: 25026 return createFiberFromOffscreen(pendingProps, mode, lanes, key); 25027 25028 case REACT_LEGACY_HIDDEN_TYPE: 25029 return createFiberFromLegacyHidden(pendingProps, mode, lanes, key); 25030 25031 case REACT_SCOPE_TYPE: 25032 25033 // eslint-disable-next-line no-fallthrough 25034 25035 default: 25036 { 25037 if (typeof type === 'object' && type !== null) { 25038 switch (type.$$typeof) { 25039 case REACT_PROVIDER_TYPE: 25040 fiberTag = ContextProvider; 25041 break getTag; 25042 25043 case REACT_CONTEXT_TYPE: 25044 // This is a consumer 25045 fiberTag = ContextConsumer; 25046 break getTag; 25047 25048 case REACT_FORWARD_REF_TYPE: 25049 fiberTag = ForwardRef; 25050 25051 { 25052 resolvedType = resolveForwardRefForHotReloading(resolvedType); 25053 } 25054 25055 break getTag; 25056 25057 case REACT_MEMO_TYPE: 25058 fiberTag = MemoComponent; 25059 break getTag; 25060 25061 case REACT_LAZY_TYPE: 25062 fiberTag = LazyComponent; 25063 resolvedType = null; 25064 break getTag; 25065 25066 case REACT_BLOCK_TYPE: 25067 fiberTag = Block; 25068 break getTag; 25069 } 25070 } 25071 25072 var info = ''; 25073 25074 { 25075 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { 25076 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.'; 25077 } 25078 25079 var ownerName = owner ? getComponentName(owner.type) : null; 25080 25081 if (ownerName) { 25082 info += '\n\nCheck the render method of `' + ownerName + '`.'; 25083 } 25084 } 25085 25086 { 25087 { 25088 throw 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 ); 25089 } 25090 } 25091 } 25092 } 25093 } 25094 25095 var fiber = createFiber(fiberTag, pendingProps, key, mode); 25096 fiber.elementType = type; 25097 fiber.type = resolvedType; 25098 fiber.lanes = lanes; 25099 25100 { 25101 fiber._debugOwner = owner; 25102 } 25103 25104 return fiber; 25105 } 25106 function createFiberFromElement(element, mode, lanes) { 25107 var owner = null; 25108 25109 { 25110 owner = element._owner; 25111 } 25112 25113 var type = element.type; 25114 var key = element.key; 25115 var pendingProps = element.props; 25116 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes); 25117 25118 { 25119 fiber._debugSource = element._source; 25120 fiber._debugOwner = element._owner; 25121 } 25122 25123 return fiber; 25124 } 25125 function createFiberFromFragment(elements, mode, lanes, key) { 25126 var fiber = createFiber(Fragment, elements, key, mode); 25127 fiber.lanes = lanes; 25128 return fiber; 25129 } 25130 25131 function createFiberFromProfiler(pendingProps, mode, lanes, key) { 25132 { 25133 if (typeof pendingProps.id !== 'string') { 25134 error('Profiler must specify an "id" as a prop'); 25135 } 25136 } 25137 25138 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag. 25139 25140 fiber.elementType = REACT_PROFILER_TYPE; 25141 fiber.type = REACT_PROFILER_TYPE; 25142 fiber.lanes = lanes; 25143 25144 { 25145 fiber.stateNode = { 25146 effectDuration: 0, 25147 passiveEffectDuration: 0 25148 }; 25149 } 25150 25151 return fiber; 25152 } 25153 25154 function createFiberFromSuspense(pendingProps, mode, lanes, key) { 25155 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. 25156 // This needs to be fixed in getComponentName so that it relies on the tag 25157 // instead. 25158 25159 fiber.type = REACT_SUSPENSE_TYPE; 25160 fiber.elementType = REACT_SUSPENSE_TYPE; 25161 fiber.lanes = lanes; 25162 return fiber; 25163 } 25164 function createFiberFromSuspenseList(pendingProps, mode, lanes, key) { 25165 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); 25166 25167 { 25168 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag. 25169 // This needs to be fixed in getComponentName so that it relies on the tag 25170 // instead. 25171 fiber.type = REACT_SUSPENSE_LIST_TYPE; 25172 } 25173 25174 fiber.elementType = REACT_SUSPENSE_LIST_TYPE; 25175 fiber.lanes = lanes; 25176 return fiber; 25177 } 25178 function createFiberFromOffscreen(pendingProps, mode, lanes, key) { 25179 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); // TODO: The OffscreenComponent fiber shouldn't have a type. It has a tag. 25180 // This needs to be fixed in getComponentName so that it relies on the tag 25181 // instead. 25182 25183 { 25184 fiber.type = REACT_OFFSCREEN_TYPE; 25185 } 25186 25187 fiber.elementType = REACT_OFFSCREEN_TYPE; 25188 fiber.lanes = lanes; 25189 return fiber; 25190 } 25191 function createFiberFromLegacyHidden(pendingProps, mode, lanes, key) { 25192 var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); // TODO: The LegacyHidden fiber shouldn't have a type. It has a tag. 25193 // This needs to be fixed in getComponentName so that it relies on the tag 25194 // instead. 25195 25196 { 25197 fiber.type = REACT_LEGACY_HIDDEN_TYPE; 25198 } 25199 25200 fiber.elementType = REACT_LEGACY_HIDDEN_TYPE; 25201 fiber.lanes = lanes; 25202 return fiber; 25203 } 25204 function createFiberFromText(content, mode, lanes) { 25205 var fiber = createFiber(HostText, content, null, mode); 25206 fiber.lanes = lanes; 25207 return fiber; 25208 } 25209 function createFiberFromHostInstanceForDeletion() { 25210 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. 25211 25212 fiber.elementType = 'DELETED'; 25213 fiber.type = 'DELETED'; 25214 return fiber; 25215 } 25216 function createFiberFromPortal(portal, mode, lanes) { 25217 var pendingProps = portal.children !== null ? portal.children : []; 25218 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); 25219 fiber.lanes = lanes; 25220 fiber.stateNode = { 25221 containerInfo: portal.containerInfo, 25222 pendingChildren: null, 25223 // Used by persistent updates 25224 implementation: portal.implementation 25225 }; 25226 return fiber; 25227 } // Used for stashing WIP properties to replay failed work in DEV. 25228 25229 function assignFiberPropertiesInDEV(target, source) { 25230 if (target === null) { 25231 // This Fiber's initial properties will always be overwritten. 25232 // We only use a Fiber to ensure the same hidden class so DEV isn't slow. 25233 target = createFiber(IndeterminateComponent, null, null, NoMode); 25234 } // This is intentionally written as a list of all properties. 25235 // We tried to use Object.assign() instead but this is called in 25236 // the hottest path, and Object.assign() was too slow: 25237 // https://github.com/facebook/react/issues/12502 25238 // This code is DEV-only so size is not a concern. 25239 25240 25241 target.tag = source.tag; 25242 target.key = source.key; 25243 target.elementType = source.elementType; 25244 target.type = source.type; 25245 target.stateNode = source.stateNode; 25246 target.return = source.return; 25247 target.child = source.child; 25248 target.sibling = source.sibling; 25249 target.index = source.index; 25250 target.ref = source.ref; 25251 target.pendingProps = source.pendingProps; 25252 target.memoizedProps = source.memoizedProps; 25253 target.updateQueue = source.updateQueue; 25254 target.memoizedState = source.memoizedState; 25255 target.dependencies = source.dependencies; 25256 target.mode = source.mode; 25257 target.flags = source.flags; 25258 target.nextEffect = source.nextEffect; 25259 target.firstEffect = source.firstEffect; 25260 target.lastEffect = source.lastEffect; 25261 target.lanes = source.lanes; 25262 target.childLanes = source.childLanes; 25263 target.alternate = source.alternate; 25264 25265 { 25266 target.actualDuration = source.actualDuration; 25267 target.actualStartTime = source.actualStartTime; 25268 target.selfBaseDuration = source.selfBaseDuration; 25269 target.treeBaseDuration = source.treeBaseDuration; 25270 } 25271 25272 target._debugID = source._debugID; 25273 target._debugSource = source._debugSource; 25274 target._debugOwner = source._debugOwner; 25275 target._debugNeedsRemount = source._debugNeedsRemount; 25276 target._debugHookTypes = source._debugHookTypes; 25277 return target; 25278 } 25279 25280 function FiberRootNode(containerInfo, tag, hydrate) { 25281 this.tag = tag; 25282 this.containerInfo = containerInfo; 25283 this.pendingChildren = null; 25284 this.current = null; 25285 this.pingCache = null; 25286 this.finishedWork = null; 25287 this.timeoutHandle = noTimeout; 25288 this.context = null; 25289 this.pendingContext = null; 25290 this.hydrate = hydrate; 25291 this.callbackNode = null; 25292 this.callbackPriority = NoLanePriority; 25293 this.eventTimes = createLaneMap(NoLanes); 25294 this.expirationTimes = createLaneMap(NoTimestamp); 25295 this.pendingLanes = NoLanes; 25296 this.suspendedLanes = NoLanes; 25297 this.pingedLanes = NoLanes; 25298 this.expiredLanes = NoLanes; 25299 this.mutableReadLanes = NoLanes; 25300 this.finishedLanes = NoLanes; 25301 this.entangledLanes = NoLanes; 25302 this.entanglements = createLaneMap(NoLanes); 25303 25304 { 25305 this.mutableSourceEagerHydrationData = null; 25306 } 25307 25308 { 25309 this.interactionThreadID = unstable_getThreadID(); 25310 this.memoizedInteractions = new Set(); 25311 this.pendingInteractionMap = new Map(); 25312 } 25313 25314 { 25315 switch (tag) { 25316 case BlockingRoot: 25317 this._debugRootType = 'createBlockingRoot()'; 25318 break; 25319 25320 case ConcurrentRoot: 25321 this._debugRootType = 'createRoot()'; 25322 break; 25323 25324 case LegacyRoot: 25325 this._debugRootType = 'createLegacyRoot()'; 25326 break; 25327 } 25328 } 25329 } 25330 25331 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { 25332 var root = new FiberRootNode(containerInfo, tag, hydrate); 25333 // stateNode is any. 25334 25335 25336 var uninitializedFiber = createHostRootFiber(tag); 25337 root.current = uninitializedFiber; 25338 uninitializedFiber.stateNode = root; 25339 initializeUpdateQueue(uninitializedFiber); 25340 return root; 25341 } 25342 25343 // This ensures that the version used for server rendering matches the one 25344 // that is eventually read during hydration. 25345 // If they don't match there's a potential tear and a full deopt render is required. 25346 25347 function registerMutableSourceForHydration(root, mutableSource) { 25348 var getVersion = mutableSource._getVersion; 25349 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished. 25350 // Retaining it forever may interfere with GC. 25351 25352 if (root.mutableSourceEagerHydrationData == null) { 25353 root.mutableSourceEagerHydrationData = [mutableSource, version]; 25354 } else { 25355 root.mutableSourceEagerHydrationData.push(mutableSource, version); 25356 } 25357 } 25358 25359 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. 25360 implementation) { 25361 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 25362 return { 25363 // This tag allow us to uniquely identify this as a React Portal 25364 $$typeof: REACT_PORTAL_TYPE, 25365 key: key == null ? null : '' + key, 25366 children: children, 25367 containerInfo: containerInfo, 25368 implementation: implementation 25369 }; 25370 } 25371 25372 var didWarnAboutNestedUpdates; 25373 var didWarnAboutFindNodeInStrictMode; 25374 25375 { 25376 didWarnAboutNestedUpdates = false; 25377 didWarnAboutFindNodeInStrictMode = {}; 25378 } 25379 25380 function getContextForSubtree(parentComponent) { 25381 if (!parentComponent) { 25382 return emptyContextObject; 25383 } 25384 25385 var fiber = get(parentComponent); 25386 var parentContext = findCurrentUnmaskedContext(fiber); 25387 25388 if (fiber.tag === ClassComponent) { 25389 var Component = fiber.type; 25390 25391 if (isContextProvider(Component)) { 25392 return processChildContext(fiber, Component, parentContext); 25393 } 25394 } 25395 25396 return parentContext; 25397 } 25398 25399 function findHostInstanceWithWarning(component, methodName) { 25400 { 25401 var fiber = get(component); 25402 25403 if (fiber === undefined) { 25404 if (typeof component.render === 'function') { 25405 { 25406 { 25407 throw Error( "Unable to find node on an unmounted component." ); 25408 } 25409 } 25410 } else { 25411 { 25412 { 25413 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) ); 25414 } 25415 } 25416 } 25417 } 25418 25419 var hostFiber = findCurrentHostFiber(fiber); 25420 25421 if (hostFiber === null) { 25422 return null; 25423 } 25424 25425 if (hostFiber.mode & StrictMode) { 25426 var componentName = getComponentName(fiber.type) || 'Component'; 25427 25428 if (!didWarnAboutFindNodeInStrictMode[componentName]) { 25429 didWarnAboutFindNodeInStrictMode[componentName] = true; 25430 var previousFiber = current; 25431 25432 try { 25433 setCurrentFiber(hostFiber); 25434 25435 if (fiber.mode & StrictMode) { 25436 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); 25437 } else { 25438 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); 25439 } 25440 } finally { 25441 // Ideally this should reset to previous but this shouldn't be called in 25442 // render and there's another warning for that anyway. 25443 if (previousFiber) { 25444 setCurrentFiber(previousFiber); 25445 } else { 25446 resetCurrentFiber(); 25447 } 25448 } 25449 } 25450 } 25451 25452 return hostFiber.stateNode; 25453 } 25454 } 25455 25456 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { 25457 return createFiberRoot(containerInfo, tag, hydrate); 25458 } 25459 function updateContainer(element, container, parentComponent, callback) { 25460 { 25461 onScheduleRoot(container, element); 25462 } 25463 25464 var current$1 = container.current; 25465 var eventTime = requestEventTime(); 25466 25467 { 25468 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests 25469 if ('undefined' !== typeof jest) { 25470 warnIfUnmockedScheduler(current$1); 25471 warnIfNotScopedWithMatchingAct(current$1); 25472 } 25473 } 25474 25475 var lane = requestUpdateLane(current$1); 25476 25477 var context = getContextForSubtree(parentComponent); 25478 25479 if (container.context === null) { 25480 container.context = context; 25481 } else { 25482 container.pendingContext = context; 25483 } 25484 25485 { 25486 if (isRendering && current !== null && !didWarnAboutNestedUpdates) { 25487 didWarnAboutNestedUpdates = true; 25488 25489 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.', getComponentName(current.type) || 'Unknown'); 25490 } 25491 } 25492 25493 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property 25494 // being called "element". 25495 25496 update.payload = { 25497 element: element 25498 }; 25499 callback = callback === undefined ? null : callback; 25500 25501 if (callback !== null) { 25502 { 25503 if (typeof callback !== 'function') { 25504 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback); 25505 } 25506 } 25507 25508 update.callback = callback; 25509 } 25510 25511 enqueueUpdate(current$1, update); 25512 scheduleUpdateOnFiber(current$1, lane, eventTime); 25513 return lane; 25514 } 25515 function getPublicRootInstance(container) { 25516 var containerFiber = container.current; 25517 25518 if (!containerFiber.child) { 25519 return null; 25520 } 25521 25522 switch (containerFiber.child.tag) { 25523 case HostComponent: 25524 return getPublicInstance(containerFiber.child.stateNode); 25525 25526 default: 25527 return containerFiber.child.stateNode; 25528 } 25529 } 25530 25531 function markRetryLaneImpl(fiber, retryLane) { 25532 var suspenseState = fiber.memoizedState; 25533 25534 if (suspenseState !== null && suspenseState.dehydrated !== null) { 25535 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane); 25536 } 25537 } // Increases the priority of thennables when they resolve within this boundary. 25538 25539 25540 function markRetryLaneIfNotHydrated(fiber, retryLane) { 25541 markRetryLaneImpl(fiber, retryLane); 25542 var alternate = fiber.alternate; 25543 25544 if (alternate) { 25545 markRetryLaneImpl(alternate, retryLane); 25546 } 25547 } 25548 25549 function attemptUserBlockingHydration$1(fiber) { 25550 if (fiber.tag !== SuspenseComponent) { 25551 // We ignore HostRoots here because we can't increase 25552 // their priority and they should not suspend on I/O, 25553 // since you have to wrap anything that might suspend in 25554 // Suspense. 25555 return; 25556 } 25557 25558 var eventTime = requestEventTime(); 25559 var lane = InputDiscreteHydrationLane; 25560 scheduleUpdateOnFiber(fiber, lane, eventTime); 25561 markRetryLaneIfNotHydrated(fiber, lane); 25562 } 25563 function attemptContinuousHydration$1(fiber) { 25564 if (fiber.tag !== SuspenseComponent) { 25565 // We ignore HostRoots here because we can't increase 25566 // their priority and they should not suspend on I/O, 25567 // since you have to wrap anything that might suspend in 25568 // Suspense. 25569 return; 25570 } 25571 25572 var eventTime = requestEventTime(); 25573 var lane = SelectiveHydrationLane; 25574 scheduleUpdateOnFiber(fiber, lane, eventTime); 25575 markRetryLaneIfNotHydrated(fiber, lane); 25576 } 25577 function attemptHydrationAtCurrentPriority$1(fiber) { 25578 if (fiber.tag !== SuspenseComponent) { 25579 // We ignore HostRoots here because we can't increase 25580 // their priority other than synchronously flush it. 25581 return; 25582 } 25583 25584 var eventTime = requestEventTime(); 25585 var lane = requestUpdateLane(fiber); 25586 scheduleUpdateOnFiber(fiber, lane, eventTime); 25587 markRetryLaneIfNotHydrated(fiber, lane); 25588 } 25589 function runWithPriority$2(priority, fn) { 25590 25591 try { 25592 setCurrentUpdateLanePriority(priority); 25593 return fn(); 25594 } finally { 25595 } 25596 } 25597 function findHostInstanceWithNoPortals(fiber) { 25598 var hostFiber = findCurrentHostFiberWithNoPortals(fiber); 25599 25600 if (hostFiber === null) { 25601 return null; 25602 } 25603 25604 if (hostFiber.tag === FundamentalComponent) { 25605 return hostFiber.stateNode.instance; 25606 } 25607 25608 return hostFiber.stateNode; 25609 } 25610 25611 var shouldSuspendImpl = function (fiber) { 25612 return false; 25613 }; 25614 25615 function shouldSuspend(fiber) { 25616 return shouldSuspendImpl(fiber); 25617 } 25618 var overrideHookState = null; 25619 var overrideHookStateDeletePath = null; 25620 var overrideHookStateRenamePath = null; 25621 var overrideProps = null; 25622 var overridePropsDeletePath = null; 25623 var overridePropsRenamePath = null; 25624 var scheduleUpdate = null; 25625 var setSuspenseHandler = null; 25626 25627 { 25628 var copyWithDeleteImpl = function (obj, path, index) { 25629 var key = path[index]; 25630 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); 25631 25632 if (index + 1 === path.length) { 25633 if (Array.isArray(updated)) { 25634 updated.splice(key, 1); 25635 } else { 25636 delete updated[key]; 25637 } 25638 25639 return updated; 25640 } // $FlowFixMe number or string is fine here 25641 25642 25643 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); 25644 return updated; 25645 }; 25646 25647 var copyWithDelete = function (obj, path) { 25648 return copyWithDeleteImpl(obj, path, 0); 25649 }; 25650 25651 var copyWithRenameImpl = function (obj, oldPath, newPath, index) { 25652 var oldKey = oldPath[index]; 25653 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); 25654 25655 if (index + 1 === oldPath.length) { 25656 var newKey = newPath[index]; // $FlowFixMe number or string is fine here 25657 25658 updated[newKey] = updated[oldKey]; 25659 25660 if (Array.isArray(updated)) { 25661 updated.splice(oldKey, 1); 25662 } else { 25663 delete updated[oldKey]; 25664 } 25665 } else { 25666 // $FlowFixMe number or string is fine here 25667 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here 25668 obj[oldKey], oldPath, newPath, index + 1); 25669 } 25670 25671 return updated; 25672 }; 25673 25674 var copyWithRename = function (obj, oldPath, newPath) { 25675 if (oldPath.length !== newPath.length) { 25676 warn('copyWithRename() expects paths of the same length'); 25677 25678 return; 25679 } else { 25680 for (var i = 0; i < newPath.length - 1; i++) { 25681 if (oldPath[i] !== newPath[i]) { 25682 warn('copyWithRename() expects paths to be the same except for the deepest key'); 25683 25684 return; 25685 } 25686 } 25687 } 25688 25689 return copyWithRenameImpl(obj, oldPath, newPath, 0); 25690 }; 25691 25692 var copyWithSetImpl = function (obj, path, index, value) { 25693 if (index >= path.length) { 25694 return value; 25695 } 25696 25697 var key = path[index]; 25698 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here 25699 25700 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); 25701 return updated; 25702 }; 25703 25704 var copyWithSet = function (obj, path, value) { 25705 return copyWithSetImpl(obj, path, 0, value); 25706 }; 25707 25708 var findHook = function (fiber, id) { 25709 // For now, the "id" of stateful hooks is just the stateful hook index. 25710 // This may change in the future with e.g. nested hooks. 25711 var currentHook = fiber.memoizedState; 25712 25713 while (currentHook !== null && id > 0) { 25714 currentHook = currentHook.next; 25715 id--; 25716 } 25717 25718 return currentHook; 25719 }; // Support DevTools editable values for useState and useReducer. 25720 25721 25722 overrideHookState = function (fiber, id, path, value) { 25723 var hook = findHook(fiber, id); 25724 25725 if (hook !== null) { 25726 var newState = copyWithSet(hook.memoizedState, path, value); 25727 hook.memoizedState = newState; 25728 hook.baseState = newState; // We aren't actually adding an update to the queue, 25729 // because there is no update we can add for useReducer hooks that won't trigger an error. 25730 // (There's no appropriate action type for DevTools overrides.) 25731 // As a result though, React will see the scheduled update as a noop and bailout. 25732 // Shallow cloning props works as a workaround for now to bypass the bailout check. 25733 25734 fiber.memoizedProps = _assign({}, fiber.memoizedProps); 25735 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25736 } 25737 }; 25738 25739 overrideHookStateDeletePath = function (fiber, id, path) { 25740 var hook = findHook(fiber, id); 25741 25742 if (hook !== null) { 25743 var newState = copyWithDelete(hook.memoizedState, path); 25744 hook.memoizedState = newState; 25745 hook.baseState = newState; // We aren't actually adding an update to the queue, 25746 // because there is no update we can add for useReducer hooks that won't trigger an error. 25747 // (There's no appropriate action type for DevTools overrides.) 25748 // As a result though, React will see the scheduled update as a noop and bailout. 25749 // Shallow cloning props works as a workaround for now to bypass the bailout check. 25750 25751 fiber.memoizedProps = _assign({}, fiber.memoizedProps); 25752 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25753 } 25754 }; 25755 25756 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { 25757 var hook = findHook(fiber, id); 25758 25759 if (hook !== null) { 25760 var newState = copyWithRename(hook.memoizedState, oldPath, newPath); 25761 hook.memoizedState = newState; 25762 hook.baseState = newState; // We aren't actually adding an update to the queue, 25763 // because there is no update we can add for useReducer hooks that won't trigger an error. 25764 // (There's no appropriate action type for DevTools overrides.) 25765 // As a result though, React will see the scheduled update as a noop and bailout. 25766 // Shallow cloning props works as a workaround for now to bypass the bailout check. 25767 25768 fiber.memoizedProps = _assign({}, fiber.memoizedProps); 25769 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25770 } 25771 }; // Support DevTools props for function components, forwardRef, memo, host components, etc. 25772 25773 25774 overrideProps = function (fiber, path, value) { 25775 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); 25776 25777 if (fiber.alternate) { 25778 fiber.alternate.pendingProps = fiber.pendingProps; 25779 } 25780 25781 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25782 }; 25783 25784 overridePropsDeletePath = function (fiber, path) { 25785 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path); 25786 25787 if (fiber.alternate) { 25788 fiber.alternate.pendingProps = fiber.pendingProps; 25789 } 25790 25791 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25792 }; 25793 25794 overridePropsRenamePath = function (fiber, oldPath, newPath) { 25795 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath); 25796 25797 if (fiber.alternate) { 25798 fiber.alternate.pendingProps = fiber.pendingProps; 25799 } 25800 25801 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25802 }; 25803 25804 scheduleUpdate = function (fiber) { 25805 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp); 25806 }; 25807 25808 setSuspenseHandler = function (newShouldSuspendImpl) { 25809 shouldSuspendImpl = newShouldSuspendImpl; 25810 }; 25811 } 25812 25813 function findHostInstanceByFiber(fiber) { 25814 var hostFiber = findCurrentHostFiber(fiber); 25815 25816 if (hostFiber === null) { 25817 return null; 25818 } 25819 25820 return hostFiber.stateNode; 25821 } 25822 25823 function emptyFindFiberByHostInstance(instance) { 25824 return null; 25825 } 25826 25827 function getCurrentFiberForDevTools() { 25828 return current; 25829 } 25830 25831 function injectIntoDevTools(devToolsConfig) { 25832 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; 25833 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 25834 return injectInternals({ 25835 bundleType: devToolsConfig.bundleType, 25836 version: devToolsConfig.version, 25837 rendererPackageName: devToolsConfig.rendererPackageName, 25838 rendererConfig: devToolsConfig.rendererConfig, 25839 overrideHookState: overrideHookState, 25840 overrideHookStateDeletePath: overrideHookStateDeletePath, 25841 overrideHookStateRenamePath: overrideHookStateRenamePath, 25842 overrideProps: overrideProps, 25843 overridePropsDeletePath: overridePropsDeletePath, 25844 overridePropsRenamePath: overridePropsRenamePath, 25845 setSuspenseHandler: setSuspenseHandler, 25846 scheduleUpdate: scheduleUpdate, 25847 currentDispatcherRef: ReactCurrentDispatcher, 25848 findHostInstanceByFiber: findHostInstanceByFiber, 25849 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance, 25850 // React Refresh 25851 findHostInstancesForRefresh: findHostInstancesForRefresh , 25852 scheduleRefresh: scheduleRefresh , 25853 scheduleRoot: scheduleRoot , 25854 setRefreshHandler: setRefreshHandler , 25855 // Enables DevTools to append owner stacks to error messages in DEV mode. 25856 getCurrentFiber: getCurrentFiberForDevTools 25857 }); 25858 } 25859 25860 function ReactDOMRoot(container, options) { 25861 this._internalRoot = createRootImpl(container, ConcurrentRoot, options); 25862 } 25863 25864 function ReactDOMBlockingRoot(container, tag, options) { 25865 this._internalRoot = createRootImpl(container, tag, options); 25866 } 25867 25868 ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) { 25869 var root = this._internalRoot; 25870 25871 { 25872 if (typeof arguments[1] === 'function') { 25873 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); 25874 } 25875 25876 var container = root.containerInfo; 25877 25878 if (container.nodeType !== COMMENT_NODE) { 25879 var hostInstance = findHostInstanceWithNoPortals(root.current); 25880 25881 if (hostInstance) { 25882 if (hostInstance.parentNode !== container) { 25883 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."); 25884 } 25885 } 25886 } 25887 } 25888 25889 updateContainer(children, root, null, null); 25890 }; 25891 25892 ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () { 25893 { 25894 if (typeof arguments[0] === 'function') { 25895 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); 25896 } 25897 } 25898 25899 var root = this._internalRoot; 25900 var container = root.containerInfo; 25901 updateContainer(null, root, null, function () { 25902 unmarkContainerAsRoot(container); 25903 }); 25904 }; 25905 25906 function createRootImpl(container, tag, options) { 25907 // Tag is either LegacyRoot or Concurrent Root 25908 var hydrate = options != null && options.hydrate === true; 25909 var hydrationCallbacks = options != null && options.hydrationOptions || null; 25910 var mutableSources = options != null && options.hydrationOptions != null && options.hydrationOptions.mutableSources || null; 25911 var root = createContainer(container, tag, hydrate); 25912 markContainerAsRoot(root.current, container); 25913 var containerNodeType = container.nodeType; 25914 25915 { 25916 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; 25917 listenToAllSupportedEvents(rootContainerElement); 25918 } 25919 25920 if (mutableSources) { 25921 for (var i = 0; i < mutableSources.length; i++) { 25922 var mutableSource = mutableSources[i]; 25923 registerMutableSourceForHydration(root, mutableSource); 25924 } 25925 } 25926 25927 return root; 25928 } 25929 function createLegacyRoot(container, options) { 25930 return new ReactDOMBlockingRoot(container, LegacyRoot, options); 25931 } 25932 function isValidContainer(node) { 25933 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 ')); 25934 } 25935 25936 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; 25937 var topLevelUpdateWarnings; 25938 var warnedAboutHydrateAPI = false; 25939 25940 { 25941 topLevelUpdateWarnings = function (container) { 25942 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { 25943 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current); 25944 25945 if (hostInstance) { 25946 if (hostInstance.parentNode !== container) { 25947 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.'); 25948 } 25949 } 25950 } 25951 25952 var isRootRenderedBySomeReact = !!container._reactRootContainer; 25953 var rootEl = getReactRootElementInContainer(container); 25954 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl)); 25955 25956 if (hasNonRootReactChild && !isRootRenderedBySomeReact) { 25957 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.'); 25958 } 25959 25960 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') { 25961 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.'); 25962 } 25963 }; 25964 } 25965 25966 function getReactRootElementInContainer(container) { 25967 if (!container) { 25968 return null; 25969 } 25970 25971 if (container.nodeType === DOCUMENT_NODE) { 25972 return container.documentElement; 25973 } else { 25974 return container.firstChild; 25975 } 25976 } 25977 25978 function shouldHydrateDueToLegacyHeuristic(container) { 25979 var rootElement = getReactRootElementInContainer(container); 25980 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME)); 25981 } 25982 25983 function legacyCreateRootFromDOMContainer(container, forceHydrate) { 25984 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content. 25985 25986 if (!shouldHydrate) { 25987 var warned = false; 25988 var rootSibling; 25989 25990 while (rootSibling = container.lastChild) { 25991 { 25992 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) { 25993 warned = true; 25994 25995 error('render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.'); 25996 } 25997 } 25998 25999 container.removeChild(rootSibling); 26000 } 26001 } 26002 26003 { 26004 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) { 26005 warnedAboutHydrateAPI = true; 26006 26007 warn('render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v18. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.'); 26008 } 26009 } 26010 26011 return createLegacyRoot(container, shouldHydrate ? { 26012 hydrate: true 26013 } : undefined); 26014 } 26015 26016 function warnOnInvalidCallback$1(callback, callerName) { 26017 { 26018 if (callback !== null && typeof callback !== 'function') { 26019 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 26020 } 26021 } 26022 } 26023 26024 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { 26025 { 26026 topLevelUpdateWarnings(container); 26027 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render'); 26028 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any 26029 // member of intersection type." Whyyyyyy. 26030 26031 26032 var root = container._reactRootContainer; 26033 var fiberRoot; 26034 26035 if (!root) { 26036 // Initial mount 26037 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate); 26038 fiberRoot = root._internalRoot; 26039 26040 if (typeof callback === 'function') { 26041 var originalCallback = callback; 26042 26043 callback = function () { 26044 var instance = getPublicRootInstance(fiberRoot); 26045 originalCallback.call(instance); 26046 }; 26047 } // Initial mount should not be batched. 26048 26049 26050 unbatchedUpdates(function () { 26051 updateContainer(children, fiberRoot, parentComponent, callback); 26052 }); 26053 } else { 26054 fiberRoot = root._internalRoot; 26055 26056 if (typeof callback === 'function') { 26057 var _originalCallback = callback; 26058 26059 callback = function () { 26060 var instance = getPublicRootInstance(fiberRoot); 26061 26062 _originalCallback.call(instance); 26063 }; 26064 } // Update 26065 26066 26067 updateContainer(children, fiberRoot, parentComponent, callback); 26068 } 26069 26070 return getPublicRootInstance(fiberRoot); 26071 } 26072 26073 function findDOMNode(componentOrElement) { 26074 { 26075 var owner = ReactCurrentOwner$3.current; 26076 26077 if (owner !== null && owner.stateNode !== null) { 26078 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; 26079 26080 if (!warnedAboutRefsInRender) { 26081 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.', getComponentName(owner.type) || 'A component'); 26082 } 26083 26084 owner.stateNode._warnedAboutRefsInRender = true; 26085 } 26086 } 26087 26088 if (componentOrElement == null) { 26089 return null; 26090 } 26091 26092 if (componentOrElement.nodeType === ELEMENT_NODE) { 26093 return componentOrElement; 26094 } 26095 26096 { 26097 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode'); 26098 } 26099 } 26100 function hydrate(element, container, callback) { 26101 if (!isValidContainer(container)) { 26102 { 26103 throw Error( "Target container is not a DOM element." ); 26104 } 26105 } 26106 26107 { 26108 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 26109 26110 if (isModernRoot) { 26111 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?'); 26112 } 26113 } // TODO: throw or warn if we couldn't hydrate? 26114 26115 26116 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback); 26117 } 26118 function render(element, container, callback) { 26119 if (!isValidContainer(container)) { 26120 { 26121 throw Error( "Target container is not a DOM element." ); 26122 } 26123 } 26124 26125 { 26126 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 26127 26128 if (isModernRoot) { 26129 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?'); 26130 } 26131 } 26132 26133 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); 26134 } 26135 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { 26136 if (!isValidContainer(containerNode)) { 26137 { 26138 throw Error( "Target container is not a DOM element." ); 26139 } 26140 } 26141 26142 if (!(parentComponent != null && has(parentComponent))) { 26143 { 26144 throw Error( "parentComponent must be a valid React Component" ); 26145 } 26146 } 26147 26148 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); 26149 } 26150 function unmountComponentAtNode(container) { 26151 if (!isValidContainer(container)) { 26152 { 26153 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." ); 26154 } 26155 } 26156 26157 { 26158 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 26159 26160 if (isModernRoot) { 26161 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?'); 26162 } 26163 } 26164 26165 if (container._reactRootContainer) { 26166 { 26167 var rootEl = getReactRootElementInContainer(container); 26168 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl); 26169 26170 if (renderedByDifferentReact) { 26171 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.'); 26172 } 26173 } // Unmount should not be batched. 26174 26175 26176 unbatchedUpdates(function () { 26177 legacyRenderSubtreeIntoContainer(null, null, container, false, function () { 26178 // $FlowFixMe This should probably use `delete container._reactRootContainer` 26179 container._reactRootContainer = null; 26180 unmarkContainerAsRoot(container); 26181 }); 26182 }); // If you call unmountComponentAtNode twice in quick succession, you'll 26183 // get `true` twice. That's probably fine? 26184 26185 return true; 26186 } else { 26187 { 26188 var _rootEl = getReactRootElementInContainer(container); 26189 26190 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node. 26191 26192 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer; 26193 26194 if (hasNonRootReactChild) { 26195 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.'); 26196 } 26197 } 26198 26199 return false; 26200 } 26201 } 26202 26203 setAttemptUserBlockingHydration(attemptUserBlockingHydration$1); 26204 setAttemptContinuousHydration(attemptContinuousHydration$1); 26205 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1); 26206 setAttemptHydrationAtPriority(runWithPriority$2); 26207 var didWarnAboutUnstableCreatePortal = false; 26208 26209 { 26210 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype 26211 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype 26212 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') { 26213 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'); 26214 } 26215 } 26216 26217 setRestoreImplementation(restoreControlledState$3); 26218 setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1); 26219 26220 function createPortal$1(children, container) { 26221 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 26222 26223 if (!isValidContainer(container)) { 26224 { 26225 throw Error( "Target container is not a DOM element." ); 26226 } 26227 } // TODO: pass ReactDOM portal implementation as third argument 26228 // $FlowFixMe The Flow type is opaque but there's no way to actually create it. 26229 26230 26231 return createPortal(children, container, null, key); 26232 } 26233 26234 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { 26235 26236 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback); 26237 } 26238 26239 function unstable_createPortal(children, container) { 26240 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 26241 26242 { 26243 if (!didWarnAboutUnstableCreatePortal) { 26244 didWarnAboutUnstableCreatePortal = true; 26245 26246 warn('The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 18+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.'); 26247 } 26248 } 26249 26250 return createPortal$1(children, container, key); 26251 } 26252 26253 var Internals = { 26254 // Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js. 26255 // This is an array for better minification. 26256 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, flushPassiveEffects, // TODO: This is related to `act`, not events. Move to separate key? 26257 IsThisRendererActing] 26258 }; 26259 var foundDevTools = injectIntoDevTools({ 26260 findFiberByHostInstance: getClosestInstanceFromNode, 26261 bundleType: 1 , 26262 version: ReactVersion, 26263 rendererPackageName: 'react-dom' 26264 }); 26265 26266 { 26267 if (!foundDevTools && canUseDOM && window.top === window.self) { 26268 // If we're in Chrome or Firefox, provide a download link if not installed. 26269 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { 26270 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://. 26271 26272 if (/^(https?|file):$/.test(protocol)) { 26273 // eslint-disable-next-line react-internal/no-production-logging 26274 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'); 26275 } 26276 } 26277 } 26278 } 26279 26280 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; 26281 exports.createPortal = createPortal$1; 26282 exports.findDOMNode = findDOMNode; 26283 exports.flushSync = flushSync; 26284 exports.hydrate = hydrate; 26285 exports.render = render; 26286 exports.unmountComponentAtNode = unmountComponentAtNode; 26287 exports.unstable_batchedUpdates = batchedUpdates$1; 26288 exports.unstable_createPortal = unstable_createPortal; 26289 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer; 26290 exports.version = ReactVersion; 26291 26292 })));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 25 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |