react-dom-server.browser.development.js (254652B)
1/** 2 * @license React 3 * react-dom-server.browser.development.js 4 * 5 * Copyright (c) Facebook, Inc. and its affiliates. 6 * 7 * This source code is licensed under the MIT license found in the 8 * LICENSE file in the root directory of this source tree. 9 */ 10(function (global, factory) { 11 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) : 12 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) : 13 (global = global || self, factory(global.ReactDOMServer = {}, global.React)); 14}(this, (function (exports, React) { 'use strict'; 15 16 var ReactVersion = '18.2.0'; 17 18 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 19 20 // by calls to these methods by a Babel plugin. 21 // 22 // In PROD (or in packages without access to React internals), 23 // they are left as they are instead. 24 25 function warn(format) { 26 { 27 { 28 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 29 args[_key - 1] = arguments[_key]; 30 } 31 32 printWarning('warn', format, args); 33 } 34 } 35 } 36 function error(format) { 37 { 38 { 39 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 40 args[_key2 - 1] = arguments[_key2]; 41 } 42 43 printWarning('error', format, args); 44 } 45 } 46 } 47 48 function printWarning(level, format, args) { 49 // When changing this logic, you might want to also 50 // update consoleWithStackDev.www.js as well. 51 { 52 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 53 var stack = ReactDebugCurrentFrame.getStackAddendum(); 54 55 if (stack !== '') { 56 format += '%s'; 57 args = args.concat([stack]); 58 } // eslint-disable-next-line react-internal/safe-string-coercion 59 60 61 var argsWithFormat = args.map(function (item) { 62 return String(item); 63 }); // Careful: RN currently depends on this prefix 64 65 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it 66 // breaks IE9: https://github.com/facebook/react/issues/13610 67 // eslint-disable-next-line react-internal/no-production-logging 68 69 Function.prototype.apply.call(console[level], console, argsWithFormat); 70 } 71 } 72 73 function scheduleWork(callback) { 74 callback(); 75 } 76 var VIEW_SIZE = 512; 77 var currentView = null; 78 var writtenBytes = 0; 79 function beginWriting(destination) { 80 currentView = new Uint8Array(VIEW_SIZE); 81 writtenBytes = 0; 82 } 83 function writeChunk(destination, chunk) { 84 if (chunk.length === 0) { 85 return; 86 } 87 88 if (chunk.length > VIEW_SIZE) { 89 // this chunk may overflow a single view which implies it was not 90 // one that is cached by the streaming renderer. We will enqueu 91 // it directly and expect it is not re-used 92 if (writtenBytes > 0) { 93 destination.enqueue(new Uint8Array(currentView.buffer, 0, writtenBytes)); 94 currentView = new Uint8Array(VIEW_SIZE); 95 writtenBytes = 0; 96 } 97 98 destination.enqueue(chunk); 99 return; 100 } 101 102 var bytesToWrite = chunk; 103 var allowableBytes = currentView.length - writtenBytes; 104 105 if (allowableBytes < bytesToWrite.length) { 106 // this chunk would overflow the current view. We enqueue a full view 107 // and start a new view with the remaining chunk 108 if (allowableBytes === 0) { 109 // the current view is already full, send it 110 destination.enqueue(currentView); 111 } else { 112 // fill up the current view and apply the remaining chunk bytes 113 // to a new view. 114 currentView.set(bytesToWrite.subarray(0, allowableBytes), writtenBytes); // writtenBytes += allowableBytes; // this can be skipped because we are going to immediately reset the view 115 116 destination.enqueue(currentView); 117 bytesToWrite = bytesToWrite.subarray(allowableBytes); 118 } 119 120 currentView = new Uint8Array(VIEW_SIZE); 121 writtenBytes = 0; 122 } 123 124 currentView.set(bytesToWrite, writtenBytes); 125 writtenBytes += bytesToWrite.length; 126 } 127 function writeChunkAndReturn(destination, chunk) { 128 writeChunk(destination, chunk); // in web streams there is no backpressure so we can alwas write more 129 130 return true; 131 } 132 function completeWriting(destination) { 133 if (currentView && writtenBytes > 0) { 134 destination.enqueue(new Uint8Array(currentView.buffer, 0, writtenBytes)); 135 currentView = null; 136 writtenBytes = 0; 137 } 138 } 139 function close(destination) { 140 destination.close(); 141 } 142 var textEncoder = new TextEncoder(); 143 function stringToChunk(content) { 144 return textEncoder.encode(content); 145 } 146 function stringToPrecomputedChunk(content) { 147 return textEncoder.encode(content); 148 } 149 function closeWithError(destination, error) { 150 if (typeof destination.error === 'function') { 151 // $FlowFixMe: This is an Error object or the destination accepts other types. 152 destination.error(error); 153 } else { 154 // Earlier implementations doesn't support this method. In that environment you're 155 // supposed to throw from a promise returned but we don't return a promise in our 156 // approach. We could fork this implementation but this is environment is an edge 157 // case to begin with. It's even less common to run this in an older environment. 158 // Even then, this is not where errors are supposed to happen and they get reported 159 // to a global callback in addition to this anyway. So it's fine just to close this. 160 destination.close(); 161 } 162 } 163 164 /* 165 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol 166 * and Temporal.* types. See https://github.com/facebook/react/pull/22064. 167 * 168 * The functions in this module will throw an easier-to-understand, 169 * easier-to-debug exception with a clear errors message message explaining the 170 * problem. (Instead of a confusing exception thrown inside the implementation 171 * of the `value` object). 172 */ 173 // $FlowFixMe only called in DEV, so void return is not possible. 174 function typeName(value) { 175 { 176 // toStringTag is needed for namespaced types like Temporal.Instant 177 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag; 178 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object'; 179 return type; 180 } 181 } // $FlowFixMe only called in DEV, so void return is not possible. 182 183 184 function willCoercionThrow(value) { 185 { 186 try { 187 testStringCoercion(value); 188 return false; 189 } catch (e) { 190 return true; 191 } 192 } 193 } 194 195 function testStringCoercion(value) { 196 // If you ended up here by following an exception call stack, here's what's 197 // happened: you supplied an object or symbol value to React (as a prop, key, 198 // DOM attribute, CSS property, string ref, etc.) and when React tried to 199 // coerce it to a string using `'' + value`, an exception was thrown. 200 // 201 // The most common types that will cause this exception are `Symbol` instances 202 // and Temporal objects like `Temporal.Instant`. But any object that has a 203 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this 204 // exception. (Library authors do this to prevent users from using built-in 205 // numeric operators like `+` or comparison operators like `>=` because custom 206 // methods are needed to perform accurate arithmetic or comparison.) 207 // 208 // To fix the problem, coerce this object or symbol value to a string before 209 // passing it to React. The most reliable way is usually `String(value)`. 210 // 211 // To find which value is throwing, check the browser or debugger console. 212 // Before this exception was thrown, there should be `console.error` output 213 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the 214 // problem and how that type was used: key, atrribute, input value prop, etc. 215 // In most cases, this console output also shows the component and its 216 // ancestor components where the exception happened. 217 // 218 // eslint-disable-next-line react-internal/safe-string-coercion 219 return '' + value; 220 } 221 222 function checkAttributeStringCoercion(value, attributeName) { 223 { 224 if (willCoercionThrow(value)) { 225 error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value)); 226 227 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 228 } 229 } 230 } 231 function checkCSSPropertyStringCoercion(value, propName) { 232 { 233 if (willCoercionThrow(value)) { 234 error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value)); 235 236 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 237 } 238 } 239 } 240 function checkHtmlStringCoercion(value) { 241 { 242 if (willCoercionThrow(value)) { 243 error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); 244 245 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 246 } 247 } 248 } 249 250 var hasOwnProperty = Object.prototype.hasOwnProperty; 251 252 // A reserved attribute. 253 // It is handled by React separately and shouldn't be written to the DOM. 254 var RESERVED = 0; // A simple string attribute. 255 // Attributes that aren't in the filter are presumed to have this type. 256 257 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called 258 // "enumerated" attributes with "true" and "false" as possible values. 259 // When true, it should be set to a "true" string. 260 // When false, it should be set to a "false" string. 261 262 var BOOLEANISH_STRING = 2; // A real boolean attribute. 263 // When true, it should be present (set either to an empty string or its name). 264 // When false, it should be omitted. 265 266 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value. 267 // When true, it should be present (set either to an empty string or its name). 268 // When false, it should be omitted. 269 // For any other value, should be present with that value. 270 271 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric. 272 // When falsy, it should be removed. 273 274 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric. 275 // When falsy, it should be removed. 276 277 var POSITIVE_NUMERIC = 6; 278 279 /* eslint-disable max-len */ 280 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"; 281 /* eslint-enable max-len */ 282 283 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; 284 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 285 var illegalAttributeNameCache = {}; 286 var validatedAttributeNameCache = {}; 287 function isAttributeNameSafe(attributeName) { 288 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 289 return true; 290 } 291 292 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 293 return false; 294 } 295 296 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 297 validatedAttributeNameCache[attributeName] = true; 298 return true; 299 } 300 301 illegalAttributeNameCache[attributeName] = true; 302 303 { 304 error('Invalid attribute name: `%s`', attributeName); 305 } 306 307 return false; 308 } 309 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 310 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 311 return false; 312 } 313 314 switch (typeof value) { 315 case 'function': // $FlowIssue symbol is perfectly valid here 316 317 case 'symbol': 318 // eslint-disable-line 319 return true; 320 321 case 'boolean': 322 { 323 if (isCustomComponentTag) { 324 return false; 325 } 326 327 if (propertyInfo !== null) { 328 return !propertyInfo.acceptsBooleans; 329 } else { 330 var prefix = name.toLowerCase().slice(0, 5); 331 return prefix !== 'data-' && prefix !== 'aria-'; 332 } 333 } 334 335 default: 336 return false; 337 } 338 } 339 function getPropertyInfo(name) { 340 return properties.hasOwnProperty(name) ? properties[name] : null; 341 } 342 343 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) { 344 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 345 this.attributeName = attributeName; 346 this.attributeNamespace = attributeNamespace; 347 this.mustUseProperty = mustUseProperty; 348 this.propertyName = name; 349 this.type = type; 350 this.sanitizeURL = sanitizeURL; 351 this.removeEmptyString = removeEmptyString; 352 } // When adding attributes to this list, be sure to also add them to 353 // the `possibleStandardNames` module to ensure casing and incorrect 354 // name warnings. 355 356 357 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM. 358 359 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular 360 // elements (not just inputs). Now that ReactDOMInput assigns to the 361 // defaultValue property -- do we need this? 362 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style']; 363 364 reservedProps.forEach(function (name) { 365 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 366 name, // attributeName 367 null, // attributeNamespace 368 false, // sanitizeURL 369 false); 370 }); // A few React string attributes have a different name. 371 // This is a mapping from React prop names to the attribute names. 372 373 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 374 var name = _ref[0], 375 attributeName = _ref[1]; 376 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 377 attributeName, // attributeName 378 null, // attributeNamespace 379 false, // sanitizeURL 380 false); 381 }); // These are "enumerated" HTML attributes that accept "true" and "false". 382 // In React, we let users pass `true` and `false` even though technically 383 // these aren't boolean attributes (they are coerced to strings). 384 385 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 386 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 387 name.toLowerCase(), // attributeName 388 null, // attributeNamespace 389 false, // sanitizeURL 390 false); 391 }); // These are "enumerated" SVG attributes that accept "true" and "false". 392 // In React, we let users pass `true` and `false` even though technically 393 // these aren't boolean attributes (they are coerced to strings). 394 // Since these are SVG attributes, their attribute names are case-sensitive. 395 396 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 397 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 398 name, // attributeName 399 null, // attributeNamespace 400 false, // sanitizeURL 401 false); 402 }); // These are HTML boolean attributes. 403 404 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM 405 // on the client side because the browsers are inconsistent. Instead we call focus(). 406 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata 407 'itemScope'].forEach(function (name) { 408 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 409 name.toLowerCase(), // attributeName 410 null, // attributeNamespace 411 false, // sanitizeURL 412 false); 413 }); // These are the few React props that we set as DOM properties 414 // rather than attributes. These are all booleans. 415 416 ['checked', // Note: `option.selected` is not updated if `select.multiple` is 417 // disabled with `removeAttribute`. We have special logic for handling this. 418 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list, 419 // you'll need to set attributeName to name.toLowerCase() 420 // instead in the assignment below. 421 ].forEach(function (name) { 422 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 423 name, // attributeName 424 null, // attributeNamespace 425 false, // sanitizeURL 426 false); 427 }); // These are HTML attributes that are "overloaded booleans": they behave like 428 // booleans, but can also accept a string value. 429 430 ['capture', 'download' // 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 (name) { 434 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 435 name, // attributeName 436 null, // attributeNamespace 437 false, // sanitizeURL 438 false); 439 }); // These are HTML attributes that must be positive numbers. 440 441 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list, 442 // you'll need to set attributeName to name.toLowerCase() 443 // instead in the assignment below. 444 ].forEach(function (name) { 445 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 446 name, // attributeName 447 null, // attributeNamespace 448 false, // sanitizeURL 449 false); 450 }); // These are HTML attributes that must be numbers. 451 452 ['rowSpan', 'start'].forEach(function (name) { 453 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 454 name.toLowerCase(), // attributeName 455 null, // attributeNamespace 456 false, // sanitizeURL 457 false); 458 }); 459 var CAMELIZE = /[\-\:]([a-z])/g; 460 461 var capitalize = function (token) { 462 return token[1].toUpperCase(); 463 }; // This is a list of all SVG attributes that need special casing, namespacing, 464 // or boolean value assignment. Regular attributes that just accept strings 465 // and have the same names are omitted, just like in the HTML attribute filter. 466 // Some of these attributes can be hard to find. This list was created by 467 // scraping the MDN documentation. 468 469 470 ['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, 471 // you'll need to set attributeName to name.toLowerCase() 472 // instead in the assignment below. 473 ].forEach(function (attributeName) { 474 var name = attributeName.replace(CAMELIZE, capitalize); 475 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 476 attributeName, null, // attributeNamespace 477 false, // sanitizeURL 478 false); 479 }); // String SVG attributes with the xlink namespace. 480 481 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list, 482 // you'll need to set attributeName to name.toLowerCase() 483 // instead in the assignment below. 484 ].forEach(function (attributeName) { 485 var name = attributeName.replace(CAMELIZE, capitalize); 486 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 487 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL 488 false); 489 }); // String SVG attributes with the xml namespace. 490 491 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list, 492 // you'll need to set attributeName to name.toLowerCase() 493 // instead in the assignment below. 494 ].forEach(function (attributeName) { 495 var name = attributeName.replace(CAMELIZE, capitalize); 496 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 497 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL 498 false); 499 }); // These attribute exists both in HTML and SVG. 500 // The attribute name is case-sensitive in SVG so we can't just use 501 // the React name like we do for attributes that exist only in HTML. 502 503 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) { 504 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 505 attributeName.toLowerCase(), // attributeName 506 null, // attributeNamespace 507 false, // sanitizeURL 508 false); 509 }); // These attributes accept URLs. These must not allow javascript: URLS. 510 // These will also need to accept Trusted Types object in the future. 511 512 var xlinkHref = 'xlinkHref'; 513 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty 514 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL 515 false); 516 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) { 517 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 518 attributeName.toLowerCase(), // attributeName 519 null, // attributeNamespace 520 true, // sanitizeURL 521 true); 522 }); 523 524 /** 525 * CSS properties which accept numbers but are not in units of "px". 526 */ 527 var isUnitlessNumber = { 528 animationIterationCount: true, 529 aspectRatio: true, 530 borderImageOutset: true, 531 borderImageSlice: true, 532 borderImageWidth: true, 533 boxFlex: true, 534 boxFlexGroup: true, 535 boxOrdinalGroup: true, 536 columnCount: true, 537 columns: true, 538 flex: true, 539 flexGrow: true, 540 flexPositive: true, 541 flexShrink: true, 542 flexNegative: true, 543 flexOrder: true, 544 gridArea: true, 545 gridRow: true, 546 gridRowEnd: true, 547 gridRowSpan: true, 548 gridRowStart: true, 549 gridColumn: true, 550 gridColumnEnd: true, 551 gridColumnSpan: true, 552 gridColumnStart: true, 553 fontWeight: true, 554 lineClamp: true, 555 lineHeight: true, 556 opacity: true, 557 order: true, 558 orphans: true, 559 tabSize: true, 560 widows: true, 561 zIndex: true, 562 zoom: true, 563 // SVG-related properties 564 fillOpacity: true, 565 floodOpacity: true, 566 stopOpacity: true, 567 strokeDasharray: true, 568 strokeDashoffset: true, 569 strokeMiterlimit: true, 570 strokeOpacity: true, 571 strokeWidth: true 572 }; 573 /** 574 * @param {string} prefix vendor-specific prefix, eg: Webkit 575 * @param {string} key style name, eg: transitionDuration 576 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 577 * WebkitTransitionDuration 578 */ 579 580 function prefixKey(prefix, key) { 581 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 582 } 583 /** 584 * Support style names that may come passed in prefixed by adding permutations 585 * of vendor prefixes. 586 */ 587 588 589 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 590 // infinite loop, because it iterates over the newly added props too. 591 592 Object.keys(isUnitlessNumber).forEach(function (prop) { 593 prefixes.forEach(function (prefix) { 594 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 595 }); 596 }); 597 598 var hasReadOnlyValue = { 599 button: true, 600 checkbox: true, 601 image: true, 602 hidden: true, 603 radio: true, 604 reset: true, 605 submit: true 606 }; 607 function checkControlledValueProps(tagName, props) { 608 { 609 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { 610 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`.'); 611 } 612 613 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { 614 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`.'); 615 } 616 } 617 } 618 619 function isCustomComponent(tagName, props) { 620 if (tagName.indexOf('-') === -1) { 621 return typeof props.is === 'string'; 622 } 623 624 switch (tagName) { 625 // These are reserved SVG and MathML elements. 626 // We don't mind this list too much because we expect it to never grow. 627 // The alternative is to track the namespace in a few places which is convoluted. 628 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 629 case 'annotation-xml': 630 case 'color-profile': 631 case 'font-face': 632 case 'font-face-src': 633 case 'font-face-uri': 634 case 'font-face-format': 635 case 'font-face-name': 636 case 'missing-glyph': 637 return false; 638 639 default: 640 return true; 641 } 642 } 643 644 var ariaProperties = { 645 'aria-current': 0, 646 // state 647 'aria-description': 0, 648 'aria-details': 0, 649 'aria-disabled': 0, 650 // state 651 'aria-hidden': 0, 652 // state 653 'aria-invalid': 0, 654 // state 655 'aria-keyshortcuts': 0, 656 'aria-label': 0, 657 'aria-roledescription': 0, 658 // Widget Attributes 659 'aria-autocomplete': 0, 660 'aria-checked': 0, 661 'aria-expanded': 0, 662 'aria-haspopup': 0, 663 'aria-level': 0, 664 'aria-modal': 0, 665 'aria-multiline': 0, 666 'aria-multiselectable': 0, 667 'aria-orientation': 0, 668 'aria-placeholder': 0, 669 'aria-pressed': 0, 670 'aria-readonly': 0, 671 'aria-required': 0, 672 'aria-selected': 0, 673 'aria-sort': 0, 674 'aria-valuemax': 0, 675 'aria-valuemin': 0, 676 'aria-valuenow': 0, 677 'aria-valuetext': 0, 678 // Live Region Attributes 679 'aria-atomic': 0, 680 'aria-busy': 0, 681 'aria-live': 0, 682 'aria-relevant': 0, 683 // Drag-and-Drop Attributes 684 'aria-dropeffect': 0, 685 'aria-grabbed': 0, 686 // Relationship Attributes 687 'aria-activedescendant': 0, 688 'aria-colcount': 0, 689 'aria-colindex': 0, 690 'aria-colspan': 0, 691 'aria-controls': 0, 692 'aria-describedby': 0, 693 'aria-errormessage': 0, 694 'aria-flowto': 0, 695 'aria-labelledby': 0, 696 'aria-owns': 0, 697 'aria-posinset': 0, 698 'aria-rowcount': 0, 699 'aria-rowindex': 0, 700 'aria-rowspan': 0, 701 'aria-setsize': 0 702 }; 703 704 var warnedProperties = {}; 705 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 706 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 707 708 function validateProperty(tagName, name) { 709 { 710 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { 711 return true; 712 } 713 714 if (rARIACamel.test(name)) { 715 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 716 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM 717 // DOM properties, then it is an invalid aria-* attribute. 718 719 if (correctName == null) { 720 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 721 722 warnedProperties[name] = true; 723 return true; 724 } // aria-* attributes should be lowercase; suggest the lowercase version. 725 726 727 if (name !== correctName) { 728 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 729 730 warnedProperties[name] = true; 731 return true; 732 } 733 } 734 735 if (rARIA.test(name)) { 736 var lowerCasedName = name.toLowerCase(); 737 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM 738 // DOM properties, then it is an invalid aria-* attribute. 739 740 if (standardName == null) { 741 warnedProperties[name] = true; 742 return false; 743 } // aria-* attributes should be lowercase; suggest the lowercase version. 744 745 746 if (name !== standardName) { 747 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 748 749 warnedProperties[name] = true; 750 return true; 751 } 752 } 753 } 754 755 return true; 756 } 757 758 function warnInvalidARIAProps(type, props) { 759 { 760 var invalidProps = []; 761 762 for (var key in props) { 763 var isValid = validateProperty(type, key); 764 765 if (!isValid) { 766 invalidProps.push(key); 767 } 768 } 769 770 var unknownPropString = invalidProps.map(function (prop) { 771 return '`' + prop + '`'; 772 }).join(', '); 773 774 if (invalidProps.length === 1) { 775 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 776 } else if (invalidProps.length > 1) { 777 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 778 } 779 } 780 } 781 782 function validateProperties(type, props) { 783 if (isCustomComponent(type, props)) { 784 return; 785 } 786 787 warnInvalidARIAProps(type, props); 788 } 789 790 var didWarnValueNull = false; 791 function validateProperties$1(type, props) { 792 { 793 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 794 return; 795 } 796 797 if (props != null && props.value === null && !didWarnValueNull) { 798 didWarnValueNull = true; 799 800 if (type === 'select' && props.multiple) { 801 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); 802 } else { 803 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); 804 } 805 } 806 } 807 } 808 809 // When adding attributes to the HTML or SVG allowed attribute list, be sure to 810 // also add them to this module to ensure casing and incorrect name 811 // warnings. 812 var possibleStandardNames = { 813 // HTML 814 accept: 'accept', 815 acceptcharset: 'acceptCharset', 816 'accept-charset': 'acceptCharset', 817 accesskey: 'accessKey', 818 action: 'action', 819 allowfullscreen: 'allowFullScreen', 820 alt: 'alt', 821 as: 'as', 822 async: 'async', 823 autocapitalize: 'autoCapitalize', 824 autocomplete: 'autoComplete', 825 autocorrect: 'autoCorrect', 826 autofocus: 'autoFocus', 827 autoplay: 'autoPlay', 828 autosave: 'autoSave', 829 capture: 'capture', 830 cellpadding: 'cellPadding', 831 cellspacing: 'cellSpacing', 832 challenge: 'challenge', 833 charset: 'charSet', 834 checked: 'checked', 835 children: 'children', 836 cite: 'cite', 837 class: 'className', 838 classid: 'classID', 839 classname: 'className', 840 cols: 'cols', 841 colspan: 'colSpan', 842 content: 'content', 843 contenteditable: 'contentEditable', 844 contextmenu: 'contextMenu', 845 controls: 'controls', 846 controlslist: 'controlsList', 847 coords: 'coords', 848 crossorigin: 'crossOrigin', 849 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 850 data: 'data', 851 datetime: 'dateTime', 852 default: 'default', 853 defaultchecked: 'defaultChecked', 854 defaultvalue: 'defaultValue', 855 defer: 'defer', 856 dir: 'dir', 857 disabled: 'disabled', 858 disablepictureinpicture: 'disablePictureInPicture', 859 disableremoteplayback: 'disableRemotePlayback', 860 download: 'download', 861 draggable: 'draggable', 862 enctype: 'encType', 863 enterkeyhint: 'enterKeyHint', 864 for: 'htmlFor', 865 form: 'form', 866 formmethod: 'formMethod', 867 formaction: 'formAction', 868 formenctype: 'formEncType', 869 formnovalidate: 'formNoValidate', 870 formtarget: 'formTarget', 871 frameborder: 'frameBorder', 872 headers: 'headers', 873 height: 'height', 874 hidden: 'hidden', 875 high: 'high', 876 href: 'href', 877 hreflang: 'hrefLang', 878 htmlfor: 'htmlFor', 879 httpequiv: 'httpEquiv', 880 'http-equiv': 'httpEquiv', 881 icon: 'icon', 882 id: 'id', 883 imagesizes: 'imageSizes', 884 imagesrcset: 'imageSrcSet', 885 innerhtml: 'innerHTML', 886 inputmode: 'inputMode', 887 integrity: 'integrity', 888 is: 'is', 889 itemid: 'itemID', 890 itemprop: 'itemProp', 891 itemref: 'itemRef', 892 itemscope: 'itemScope', 893 itemtype: 'itemType', 894 keyparams: 'keyParams', 895 keytype: 'keyType', 896 kind: 'kind', 897 label: 'label', 898 lang: 'lang', 899 list: 'list', 900 loop: 'loop', 901 low: 'low', 902 manifest: 'manifest', 903 marginwidth: 'marginWidth', 904 marginheight: 'marginHeight', 905 max: 'max', 906 maxlength: 'maxLength', 907 media: 'media', 908 mediagroup: 'mediaGroup', 909 method: 'method', 910 min: 'min', 911 minlength: 'minLength', 912 multiple: 'multiple', 913 muted: 'muted', 914 name: 'name', 915 nomodule: 'noModule', 916 nonce: 'nonce', 917 novalidate: 'noValidate', 918 open: 'open', 919 optimum: 'optimum', 920 pattern: 'pattern', 921 placeholder: 'placeholder', 922 playsinline: 'playsInline', 923 poster: 'poster', 924 preload: 'preload', 925 profile: 'profile', 926 radiogroup: 'radioGroup', 927 readonly: 'readOnly', 928 referrerpolicy: 'referrerPolicy', 929 rel: 'rel', 930 required: 'required', 931 reversed: 'reversed', 932 role: 'role', 933 rows: 'rows', 934 rowspan: 'rowSpan', 935 sandbox: 'sandbox', 936 scope: 'scope', 937 scoped: 'scoped', 938 scrolling: 'scrolling', 939 seamless: 'seamless', 940 selected: 'selected', 941 shape: 'shape', 942 size: 'size', 943 sizes: 'sizes', 944 span: 'span', 945 spellcheck: 'spellCheck', 946 src: 'src', 947 srcdoc: 'srcDoc', 948 srclang: 'srcLang', 949 srcset: 'srcSet', 950 start: 'start', 951 step: 'step', 952 style: 'style', 953 summary: 'summary', 954 tabindex: 'tabIndex', 955 target: 'target', 956 title: 'title', 957 type: 'type', 958 usemap: 'useMap', 959 value: 'value', 960 width: 'width', 961 wmode: 'wmode', 962 wrap: 'wrap', 963 // SVG 964 about: 'about', 965 accentheight: 'accentHeight', 966 'accent-height': 'accentHeight', 967 accumulate: 'accumulate', 968 additive: 'additive', 969 alignmentbaseline: 'alignmentBaseline', 970 'alignment-baseline': 'alignmentBaseline', 971 allowreorder: 'allowReorder', 972 alphabetic: 'alphabetic', 973 amplitude: 'amplitude', 974 arabicform: 'arabicForm', 975 'arabic-form': 'arabicForm', 976 ascent: 'ascent', 977 attributename: 'attributeName', 978 attributetype: 'attributeType', 979 autoreverse: 'autoReverse', 980 azimuth: 'azimuth', 981 basefrequency: 'baseFrequency', 982 baselineshift: 'baselineShift', 983 'baseline-shift': 'baselineShift', 984 baseprofile: 'baseProfile', 985 bbox: 'bbox', 986 begin: 'begin', 987 bias: 'bias', 988 by: 'by', 989 calcmode: 'calcMode', 990 capheight: 'capHeight', 991 'cap-height': 'capHeight', 992 clip: 'clip', 993 clippath: 'clipPath', 994 'clip-path': 'clipPath', 995 clippathunits: 'clipPathUnits', 996 cliprule: 'clipRule', 997 'clip-rule': 'clipRule', 998 color: 'color', 999 colorinterpolation: 'colorInterpolation', 1000 'color-interpolation': 'colorInterpolation', 1001 colorinterpolationfilters: 'colorInterpolationFilters', 1002 'color-interpolation-filters': 'colorInterpolationFilters', 1003 colorprofile: 'colorProfile', 1004 'color-profile': 'colorProfile', 1005 colorrendering: 'colorRendering', 1006 'color-rendering': 'colorRendering', 1007 contentscripttype: 'contentScriptType', 1008 contentstyletype: 'contentStyleType', 1009 cursor: 'cursor', 1010 cx: 'cx', 1011 cy: 'cy', 1012 d: 'd', 1013 datatype: 'datatype', 1014 decelerate: 'decelerate', 1015 descent: 'descent', 1016 diffuseconstant: 'diffuseConstant', 1017 direction: 'direction', 1018 display: 'display', 1019 divisor: 'divisor', 1020 dominantbaseline: 'dominantBaseline', 1021 'dominant-baseline': 'dominantBaseline', 1022 dur: 'dur', 1023 dx: 'dx', 1024 dy: 'dy', 1025 edgemode: 'edgeMode', 1026 elevation: 'elevation', 1027 enablebackground: 'enableBackground', 1028 'enable-background': 'enableBackground', 1029 end: 'end', 1030 exponent: 'exponent', 1031 externalresourcesrequired: 'externalResourcesRequired', 1032 fill: 'fill', 1033 fillopacity: 'fillOpacity', 1034 'fill-opacity': 'fillOpacity', 1035 fillrule: 'fillRule', 1036 'fill-rule': 'fillRule', 1037 filter: 'filter', 1038 filterres: 'filterRes', 1039 filterunits: 'filterUnits', 1040 floodopacity: 'floodOpacity', 1041 'flood-opacity': 'floodOpacity', 1042 floodcolor: 'floodColor', 1043 'flood-color': 'floodColor', 1044 focusable: 'focusable', 1045 fontfamily: 'fontFamily', 1046 'font-family': 'fontFamily', 1047 fontsize: 'fontSize', 1048 'font-size': 'fontSize', 1049 fontsizeadjust: 'fontSizeAdjust', 1050 'font-size-adjust': 'fontSizeAdjust', 1051 fontstretch: 'fontStretch', 1052 'font-stretch': 'fontStretch', 1053 fontstyle: 'fontStyle', 1054 'font-style': 'fontStyle', 1055 fontvariant: 'fontVariant', 1056 'font-variant': 'fontVariant', 1057 fontweight: 'fontWeight', 1058 'font-weight': 'fontWeight', 1059 format: 'format', 1060 from: 'from', 1061 fx: 'fx', 1062 fy: 'fy', 1063 g1: 'g1', 1064 g2: 'g2', 1065 glyphname: 'glyphName', 1066 'glyph-name': 'glyphName', 1067 glyphorientationhorizontal: 'glyphOrientationHorizontal', 1068 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 1069 glyphorientationvertical: 'glyphOrientationVertical', 1070 'glyph-orientation-vertical': 'glyphOrientationVertical', 1071 glyphref: 'glyphRef', 1072 gradienttransform: 'gradientTransform', 1073 gradientunits: 'gradientUnits', 1074 hanging: 'hanging', 1075 horizadvx: 'horizAdvX', 1076 'horiz-adv-x': 'horizAdvX', 1077 horizoriginx: 'horizOriginX', 1078 'horiz-origin-x': 'horizOriginX', 1079 ideographic: 'ideographic', 1080 imagerendering: 'imageRendering', 1081 'image-rendering': 'imageRendering', 1082 in2: 'in2', 1083 in: 'in', 1084 inlist: 'inlist', 1085 intercept: 'intercept', 1086 k1: 'k1', 1087 k2: 'k2', 1088 k3: 'k3', 1089 k4: 'k4', 1090 k: 'k', 1091 kernelmatrix: 'kernelMatrix', 1092 kernelunitlength: 'kernelUnitLength', 1093 kerning: 'kerning', 1094 keypoints: 'keyPoints', 1095 keysplines: 'keySplines', 1096 keytimes: 'keyTimes', 1097 lengthadjust: 'lengthAdjust', 1098 letterspacing: 'letterSpacing', 1099 'letter-spacing': 'letterSpacing', 1100 lightingcolor: 'lightingColor', 1101 'lighting-color': 'lightingColor', 1102 limitingconeangle: 'limitingConeAngle', 1103 local: 'local', 1104 markerend: 'markerEnd', 1105 'marker-end': 'markerEnd', 1106 markerheight: 'markerHeight', 1107 markermid: 'markerMid', 1108 'marker-mid': 'markerMid', 1109 markerstart: 'markerStart', 1110 'marker-start': 'markerStart', 1111 markerunits: 'markerUnits', 1112 markerwidth: 'markerWidth', 1113 mask: 'mask', 1114 maskcontentunits: 'maskContentUnits', 1115 maskunits: 'maskUnits', 1116 mathematical: 'mathematical', 1117 mode: 'mode', 1118 numoctaves: 'numOctaves', 1119 offset: 'offset', 1120 opacity: 'opacity', 1121 operator: 'operator', 1122 order: 'order', 1123 orient: 'orient', 1124 orientation: 'orientation', 1125 origin: 'origin', 1126 overflow: 'overflow', 1127 overlineposition: 'overlinePosition', 1128 'overline-position': 'overlinePosition', 1129 overlinethickness: 'overlineThickness', 1130 'overline-thickness': 'overlineThickness', 1131 paintorder: 'paintOrder', 1132 'paint-order': 'paintOrder', 1133 panose1: 'panose1', 1134 'panose-1': 'panose1', 1135 pathlength: 'pathLength', 1136 patterncontentunits: 'patternContentUnits', 1137 patterntransform: 'patternTransform', 1138 patternunits: 'patternUnits', 1139 pointerevents: 'pointerEvents', 1140 'pointer-events': 'pointerEvents', 1141 points: 'points', 1142 pointsatx: 'pointsAtX', 1143 pointsaty: 'pointsAtY', 1144 pointsatz: 'pointsAtZ', 1145 prefix: 'prefix', 1146 preservealpha: 'preserveAlpha', 1147 preserveaspectratio: 'preserveAspectRatio', 1148 primitiveunits: 'primitiveUnits', 1149 property: 'property', 1150 r: 'r', 1151 radius: 'radius', 1152 refx: 'refX', 1153 refy: 'refY', 1154 renderingintent: 'renderingIntent', 1155 'rendering-intent': 'renderingIntent', 1156 repeatcount: 'repeatCount', 1157 repeatdur: 'repeatDur', 1158 requiredextensions: 'requiredExtensions', 1159 requiredfeatures: 'requiredFeatures', 1160 resource: 'resource', 1161 restart: 'restart', 1162 result: 'result', 1163 results: 'results', 1164 rotate: 'rotate', 1165 rx: 'rx', 1166 ry: 'ry', 1167 scale: 'scale', 1168 security: 'security', 1169 seed: 'seed', 1170 shaperendering: 'shapeRendering', 1171 'shape-rendering': 'shapeRendering', 1172 slope: 'slope', 1173 spacing: 'spacing', 1174 specularconstant: 'specularConstant', 1175 specularexponent: 'specularExponent', 1176 speed: 'speed', 1177 spreadmethod: 'spreadMethod', 1178 startoffset: 'startOffset', 1179 stddeviation: 'stdDeviation', 1180 stemh: 'stemh', 1181 stemv: 'stemv', 1182 stitchtiles: 'stitchTiles', 1183 stopcolor: 'stopColor', 1184 'stop-color': 'stopColor', 1185 stopopacity: 'stopOpacity', 1186 'stop-opacity': 'stopOpacity', 1187 strikethroughposition: 'strikethroughPosition', 1188 'strikethrough-position': 'strikethroughPosition', 1189 strikethroughthickness: 'strikethroughThickness', 1190 'strikethrough-thickness': 'strikethroughThickness', 1191 string: 'string', 1192 stroke: 'stroke', 1193 strokedasharray: 'strokeDasharray', 1194 'stroke-dasharray': 'strokeDasharray', 1195 strokedashoffset: 'strokeDashoffset', 1196 'stroke-dashoffset': 'strokeDashoffset', 1197 strokelinecap: 'strokeLinecap', 1198 'stroke-linecap': 'strokeLinecap', 1199 strokelinejoin: 'strokeLinejoin', 1200 'stroke-linejoin': 'strokeLinejoin', 1201 strokemiterlimit: 'strokeMiterlimit', 1202 'stroke-miterlimit': 'strokeMiterlimit', 1203 strokewidth: 'strokeWidth', 1204 'stroke-width': 'strokeWidth', 1205 strokeopacity: 'strokeOpacity', 1206 'stroke-opacity': 'strokeOpacity', 1207 suppresscontenteditablewarning: 'suppressContentEditableWarning', 1208 suppresshydrationwarning: 'suppressHydrationWarning', 1209 surfacescale: 'surfaceScale', 1210 systemlanguage: 'systemLanguage', 1211 tablevalues: 'tableValues', 1212 targetx: 'targetX', 1213 targety: 'targetY', 1214 textanchor: 'textAnchor', 1215 'text-anchor': 'textAnchor', 1216 textdecoration: 'textDecoration', 1217 'text-decoration': 'textDecoration', 1218 textlength: 'textLength', 1219 textrendering: 'textRendering', 1220 'text-rendering': 'textRendering', 1221 to: 'to', 1222 transform: 'transform', 1223 typeof: 'typeof', 1224 u1: 'u1', 1225 u2: 'u2', 1226 underlineposition: 'underlinePosition', 1227 'underline-position': 'underlinePosition', 1228 underlinethickness: 'underlineThickness', 1229 'underline-thickness': 'underlineThickness', 1230 unicode: 'unicode', 1231 unicodebidi: 'unicodeBidi', 1232 'unicode-bidi': 'unicodeBidi', 1233 unicoderange: 'unicodeRange', 1234 'unicode-range': 'unicodeRange', 1235 unitsperem: 'unitsPerEm', 1236 'units-per-em': 'unitsPerEm', 1237 unselectable: 'unselectable', 1238 valphabetic: 'vAlphabetic', 1239 'v-alphabetic': 'vAlphabetic', 1240 values: 'values', 1241 vectoreffect: 'vectorEffect', 1242 'vector-effect': 'vectorEffect', 1243 version: 'version', 1244 vertadvy: 'vertAdvY', 1245 'vert-adv-y': 'vertAdvY', 1246 vertoriginx: 'vertOriginX', 1247 'vert-origin-x': 'vertOriginX', 1248 vertoriginy: 'vertOriginY', 1249 'vert-origin-y': 'vertOriginY', 1250 vhanging: 'vHanging', 1251 'v-hanging': 'vHanging', 1252 videographic: 'vIdeographic', 1253 'v-ideographic': 'vIdeographic', 1254 viewbox: 'viewBox', 1255 viewtarget: 'viewTarget', 1256 visibility: 'visibility', 1257 vmathematical: 'vMathematical', 1258 'v-mathematical': 'vMathematical', 1259 vocab: 'vocab', 1260 widths: 'widths', 1261 wordspacing: 'wordSpacing', 1262 'word-spacing': 'wordSpacing', 1263 writingmode: 'writingMode', 1264 'writing-mode': 'writingMode', 1265 x1: 'x1', 1266 x2: 'x2', 1267 x: 'x', 1268 xchannelselector: 'xChannelSelector', 1269 xheight: 'xHeight', 1270 'x-height': 'xHeight', 1271 xlinkactuate: 'xlinkActuate', 1272 'xlink:actuate': 'xlinkActuate', 1273 xlinkarcrole: 'xlinkArcrole', 1274 'xlink:arcrole': 'xlinkArcrole', 1275 xlinkhref: 'xlinkHref', 1276 'xlink:href': 'xlinkHref', 1277 xlinkrole: 'xlinkRole', 1278 'xlink:role': 'xlinkRole', 1279 xlinkshow: 'xlinkShow', 1280 'xlink:show': 'xlinkShow', 1281 xlinktitle: 'xlinkTitle', 1282 'xlink:title': 'xlinkTitle', 1283 xlinktype: 'xlinkType', 1284 'xlink:type': 'xlinkType', 1285 xmlbase: 'xmlBase', 1286 'xml:base': 'xmlBase', 1287 xmllang: 'xmlLang', 1288 'xml:lang': 'xmlLang', 1289 xmlns: 'xmlns', 1290 'xml:space': 'xmlSpace', 1291 xmlnsxlink: 'xmlnsXlink', 1292 'xmlns:xlink': 'xmlnsXlink', 1293 xmlspace: 'xmlSpace', 1294 y1: 'y1', 1295 y2: 'y2', 1296 y: 'y', 1297 ychannelselector: 'yChannelSelector', 1298 z: 'z', 1299 zoomandpan: 'zoomAndPan' 1300 }; 1301 1302 var validateProperty$1 = function () {}; 1303 1304 { 1305 var warnedProperties$1 = {}; 1306 var EVENT_NAME_REGEX = /^on./; 1307 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 1308 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 1309 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 1310 1311 validateProperty$1 = function (tagName, name, value, eventRegistry) { 1312 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 1313 return true; 1314 } 1315 1316 var lowerCasedName = name.toLowerCase(); 1317 1318 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 1319 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.'); 1320 1321 warnedProperties$1[name] = true; 1322 return true; 1323 } // We can't rely on the event system being injected on the server. 1324 1325 1326 if (eventRegistry != null) { 1327 var registrationNameDependencies = eventRegistry.registrationNameDependencies, 1328 possibleRegistrationNames = eventRegistry.possibleRegistrationNames; 1329 1330 if (registrationNameDependencies.hasOwnProperty(name)) { 1331 return true; 1332 } 1333 1334 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 1335 1336 if (registrationName != null) { 1337 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 1338 1339 warnedProperties$1[name] = true; 1340 return true; 1341 } 1342 1343 if (EVENT_NAME_REGEX.test(name)) { 1344 error('Unknown event handler property `%s`. It will be ignored.', name); 1345 1346 warnedProperties$1[name] = true; 1347 return true; 1348 } 1349 } else if (EVENT_NAME_REGEX.test(name)) { 1350 // If no event plugins have been injected, we are in a server environment. 1351 // So we can't tell if the event name is correct for sure, but we can filter 1352 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 1353 if (INVALID_EVENT_NAME_REGEX.test(name)) { 1354 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 1355 } 1356 1357 warnedProperties$1[name] = true; 1358 return true; 1359 } // Let the ARIA attribute hook validate ARIA attributes 1360 1361 1362 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 1363 return true; 1364 } 1365 1366 if (lowerCasedName === 'innerhtml') { 1367 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 1368 1369 warnedProperties$1[name] = true; 1370 return true; 1371 } 1372 1373 if (lowerCasedName === 'aria') { 1374 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 1375 1376 warnedProperties$1[name] = true; 1377 return true; 1378 } 1379 1380 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 1381 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 1382 1383 warnedProperties$1[name] = true; 1384 return true; 1385 } 1386 1387 if (typeof value === 'number' && isNaN(value)) { 1388 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 1389 1390 warnedProperties$1[name] = true; 1391 return true; 1392 } 1393 1394 var propertyInfo = getPropertyInfo(name); 1395 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config. 1396 1397 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 1398 var standardName = possibleStandardNames[lowerCasedName]; 1399 1400 if (standardName !== name) { 1401 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 1402 1403 warnedProperties$1[name] = true; 1404 return true; 1405 } 1406 } else if (!isReserved && name !== lowerCasedName) { 1407 // Unknown attributes should have lowercase casing since that's how they 1408 // will be cased anyway with server rendering. 1409 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); 1410 1411 warnedProperties$1[name] = true; 1412 return true; 1413 } 1414 1415 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 1416 if (value) { 1417 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); 1418 } else { 1419 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); 1420 } 1421 1422 warnedProperties$1[name] = true; 1423 return true; 1424 } // Now that we've validated casing, do not validate 1425 // data types for reserved props 1426 1427 1428 if (isReserved) { 1429 return true; 1430 } // Warn when a known attribute is a bad type 1431 1432 1433 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 1434 warnedProperties$1[name] = true; 1435 return false; 1436 } // Warn when passing the strings 'false' or 'true' into a boolean prop 1437 1438 1439 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 1440 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); 1441 1442 warnedProperties$1[name] = true; 1443 return true; 1444 } 1445 1446 return true; 1447 }; 1448 } 1449 1450 var warnUnknownProperties = function (type, props, eventRegistry) { 1451 { 1452 var unknownProps = []; 1453 1454 for (var key in props) { 1455 var isValid = validateProperty$1(type, key, props[key], eventRegistry); 1456 1457 if (!isValid) { 1458 unknownProps.push(key); 1459 } 1460 } 1461 1462 var unknownPropString = unknownProps.map(function (prop) { 1463 return '`' + prop + '`'; 1464 }).join(', '); 1465 1466 if (unknownProps.length === 1) { 1467 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); 1468 } else if (unknownProps.length > 1) { 1469 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); 1470 } 1471 } 1472 }; 1473 1474 function validateProperties$2(type, props, eventRegistry) { 1475 if (isCustomComponent(type, props)) { 1476 return; 1477 } 1478 1479 warnUnknownProperties(type, props, eventRegistry); 1480 } 1481 1482 var warnValidStyle = function () {}; 1483 1484 { 1485 // 'msTransform' is correct, but the other prefixes should be capitalized 1486 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 1487 var msPattern = /^-ms-/; 1488 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon 1489 1490 var badStyleValueWithSemicolonPattern = /;\s*$/; 1491 var warnedStyleNames = {}; 1492 var warnedStyleValues = {}; 1493 var warnedForNaNValue = false; 1494 var warnedForInfinityValue = false; 1495 1496 var camelize = function (string) { 1497 return string.replace(hyphenPattern, function (_, character) { 1498 return character.toUpperCase(); 1499 }); 1500 }; 1501 1502 var warnHyphenatedStyleName = function (name) { 1503 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 1504 return; 1505 } 1506 1507 warnedStyleNames[name] = true; 1508 1509 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests 1510 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 1511 // is converted to lowercase `ms`. 1512 camelize(name.replace(msPattern, 'ms-'))); 1513 }; 1514 1515 var warnBadVendoredStyleName = function (name) { 1516 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 1517 return; 1518 } 1519 1520 warnedStyleNames[name] = true; 1521 1522 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 1523 }; 1524 1525 var warnStyleValueWithSemicolon = function (name, value) { 1526 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 1527 return; 1528 } 1529 1530 warnedStyleValues[value] = true; 1531 1532 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 1533 }; 1534 1535 var warnStyleValueIsNaN = function (name, value) { 1536 if (warnedForNaNValue) { 1537 return; 1538 } 1539 1540 warnedForNaNValue = true; 1541 1542 error('`NaN` is an invalid value for the `%s` css style property.', name); 1543 }; 1544 1545 var warnStyleValueIsInfinity = function (name, value) { 1546 if (warnedForInfinityValue) { 1547 return; 1548 } 1549 1550 warnedForInfinityValue = true; 1551 1552 error('`Infinity` is an invalid value for the `%s` css style property.', name); 1553 }; 1554 1555 warnValidStyle = function (name, value) { 1556 if (name.indexOf('-') > -1) { 1557 warnHyphenatedStyleName(name); 1558 } else if (badVendoredStyleNamePattern.test(name)) { 1559 warnBadVendoredStyleName(name); 1560 } else if (badStyleValueWithSemicolonPattern.test(value)) { 1561 warnStyleValueWithSemicolon(name, value); 1562 } 1563 1564 if (typeof value === 'number') { 1565 if (isNaN(value)) { 1566 warnStyleValueIsNaN(name, value); 1567 } else if (!isFinite(value)) { 1568 warnStyleValueIsInfinity(name, value); 1569 } 1570 } 1571 }; 1572 } 1573 1574 var warnValidStyle$1 = warnValidStyle; 1575 1576 // code copied and modified from escape-html 1577 var matchHtmlRegExp = /["'&<>]/; 1578 /** 1579 * Escapes special characters and HTML entities in a given html string. 1580 * 1581 * @param {string} string HTML string to escape for later insertion 1582 * @return {string} 1583 * @public 1584 */ 1585 1586 function escapeHtml(string) { 1587 { 1588 checkHtmlStringCoercion(string); 1589 } 1590 1591 var str = '' + string; 1592 var match = matchHtmlRegExp.exec(str); 1593 1594 if (!match) { 1595 return str; 1596 } 1597 1598 var escape; 1599 var html = ''; 1600 var index; 1601 var lastIndex = 0; 1602 1603 for (index = match.index; index < str.length; index++) { 1604 switch (str.charCodeAt(index)) { 1605 case 34: 1606 // " 1607 escape = '"'; 1608 break; 1609 1610 case 38: 1611 // & 1612 escape = '&'; 1613 break; 1614 1615 case 39: 1616 // ' 1617 escape = '''; // modified from escape-html; used to be ''' 1618 1619 break; 1620 1621 case 60: 1622 // < 1623 escape = '<'; 1624 break; 1625 1626 case 62: 1627 // > 1628 escape = '>'; 1629 break; 1630 1631 default: 1632 continue; 1633 } 1634 1635 if (lastIndex !== index) { 1636 html += str.substring(lastIndex, index); 1637 } 1638 1639 lastIndex = index + 1; 1640 html += escape; 1641 } 1642 1643 return lastIndex !== index ? html + str.substring(lastIndex, index) : html; 1644 } // end code copied and modified from escape-html 1645 1646 /** 1647 * Escapes text to prevent scripting attacks. 1648 * 1649 * @param {*} text Text value to escape. 1650 * @return {string} An escaped string. 1651 */ 1652 1653 1654 function escapeTextForBrowser(text) { 1655 if (typeof text === 'boolean' || typeof text === 'number') { 1656 // this shortcircuit helps perf for types that we know will never have 1657 // special characters, especially given that this function is used often 1658 // for numeric dom ids. 1659 return '' + text; 1660 } 1661 1662 return escapeHtml(text); 1663 } 1664 1665 var uppercasePattern = /([A-Z])/g; 1666 var msPattern$1 = /^ms-/; 1667 /** 1668 * Hyphenates a camelcased CSS property name, for example: 1669 * 1670 * > hyphenateStyleName('backgroundColor') 1671 * < "background-color" 1672 * > hyphenateStyleName('MozTransition') 1673 * < "-moz-transition" 1674 * > hyphenateStyleName('msTransition') 1675 * < "-ms-transition" 1676 * 1677 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 1678 * is converted to `-ms-`. 1679 */ 1680 1681 function hyphenateStyleName(name) { 1682 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern$1, '-ms-'); 1683 } 1684 1685 // and any newline or tab are filtered out as if they're not part of the URL. 1686 // https://url.spec.whatwg.org/#url-parsing 1687 // Tab or newline are defined as \r\n\t: 1688 // https://infra.spec.whatwg.org/#ascii-tab-or-newline 1689 // A C0 control is a code point in the range \u0000 NULL to \u001F 1690 // INFORMATION SEPARATOR ONE, inclusive: 1691 // https://infra.spec.whatwg.org/#c0-control-or-space 1692 1693 /* eslint-disable max-len */ 1694 1695 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; 1696 var didWarn = false; 1697 1698 function sanitizeURL(url) { 1699 { 1700 if (!didWarn && isJavaScriptProtocol.test(url)) { 1701 didWarn = true; 1702 1703 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)); 1704 } 1705 } 1706 } 1707 1708 var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare 1709 1710 function isArray(a) { 1711 return isArrayImpl(a); 1712 } 1713 1714 var startInlineScript = stringToPrecomputedChunk('<script>'); 1715 var endInlineScript = stringToPrecomputedChunk('</script>'); 1716 var startScriptSrc = stringToPrecomputedChunk('<script src="'); 1717 var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="'); 1718 var endAsyncScript = stringToPrecomputedChunk('" async=""></script>'); 1719 /** 1720 * This escaping function is designed to work with bootstrapScriptContent only. 1721 * because we know we are escaping the entire script. We can avoid for instance 1722 * escaping html comment string sequences that are valid javascript as well because 1723 * if there are no sebsequent <script sequences the html parser will never enter 1724 * script data double escaped state (see: https://www.w3.org/TR/html53/syntax.html#script-data-double-escaped-state) 1725 * 1726 * While untrusted script content should be made safe before using this api it will 1727 * ensure that the script cannot be early terminated or never terminated state 1728 */ 1729 1730 function escapeBootstrapScriptContent(scriptText) { 1731 { 1732 checkHtmlStringCoercion(scriptText); 1733 } 1734 1735 return ('' + scriptText).replace(scriptRegex, scriptReplacer); 1736 } 1737 1738 var scriptRegex = /(<\/|<)(s)(cript)/gi; 1739 1740 var scriptReplacer = function (match, prefix, s, suffix) { 1741 return "" + prefix + (s === 's' ? "\\u0073" : "\\u0053") + suffix; 1742 }; // Allows us to keep track of what we've already written so we can refer back to it. 1743 1744 1745 function createResponseState(identifierPrefix, nonce, bootstrapScriptContent, bootstrapScripts, bootstrapModules) { 1746 var idPrefix = identifierPrefix === undefined ? '' : identifierPrefix; 1747 var inlineScriptWithNonce = nonce === undefined ? startInlineScript : stringToPrecomputedChunk('<script nonce="' + escapeTextForBrowser(nonce) + '">'); 1748 var bootstrapChunks = []; 1749 1750 if (bootstrapScriptContent !== undefined) { 1751 bootstrapChunks.push(inlineScriptWithNonce, stringToChunk(escapeBootstrapScriptContent(bootstrapScriptContent)), endInlineScript); 1752 } 1753 1754 if (bootstrapScripts !== undefined) { 1755 for (var i = 0; i < bootstrapScripts.length; i++) { 1756 bootstrapChunks.push(startScriptSrc, stringToChunk(escapeTextForBrowser(bootstrapScripts[i])), endAsyncScript); 1757 } 1758 } 1759 1760 if (bootstrapModules !== undefined) { 1761 for (var _i = 0; _i < bootstrapModules.length; _i++) { 1762 bootstrapChunks.push(startModuleSrc, stringToChunk(escapeTextForBrowser(bootstrapModules[_i])), endAsyncScript); 1763 } 1764 } 1765 1766 return { 1767 bootstrapChunks: bootstrapChunks, 1768 startInlineScript: inlineScriptWithNonce, 1769 placeholderPrefix: stringToPrecomputedChunk(idPrefix + 'P:'), 1770 segmentPrefix: stringToPrecomputedChunk(idPrefix + 'S:'), 1771 boundaryPrefix: idPrefix + 'B:', 1772 idPrefix: idPrefix, 1773 nextSuspenseID: 0, 1774 sentCompleteSegmentFunction: false, 1775 sentCompleteBoundaryFunction: false, 1776 sentClientRenderFunction: false 1777 }; 1778 } // Constants for the insertion mode we're currently writing in. We don't encode all HTML5 insertion 1779 // modes. We only include the variants as they matter for the sake of our purposes. 1780 // We don't actually provide the namespace therefore we use constants instead of the string. 1781 1782 var ROOT_HTML_MODE = 0; // Used for the root most element tag. 1783 1784 var HTML_MODE = 1; 1785 var SVG_MODE = 2; 1786 var MATHML_MODE = 3; 1787 var HTML_TABLE_MODE = 4; 1788 var HTML_TABLE_BODY_MODE = 5; 1789 var HTML_TABLE_ROW_MODE = 6; 1790 var HTML_COLGROUP_MODE = 7; // We have a greater than HTML_TABLE_MODE check elsewhere. If you add more cases here, make sure it 1791 // still makes sense 1792 1793 function createFormatContext(insertionMode, selectedValue) { 1794 return { 1795 insertionMode: insertionMode, 1796 selectedValue: selectedValue 1797 }; 1798 } 1799 1800 function createRootFormatContext(namespaceURI) { 1801 var insertionMode = namespaceURI === 'http://www.w3.org/2000/svg' ? SVG_MODE : namespaceURI === 'http://www.w3.org/1998/Math/MathML' ? MATHML_MODE : ROOT_HTML_MODE; 1802 return createFormatContext(insertionMode, null); 1803 } 1804 function getChildFormatContext(parentContext, type, props) { 1805 switch (type) { 1806 case 'select': 1807 return createFormatContext(HTML_MODE, props.value != null ? props.value : props.defaultValue); 1808 1809 case 'svg': 1810 return createFormatContext(SVG_MODE, null); 1811 1812 case 'math': 1813 return createFormatContext(MATHML_MODE, null); 1814 1815 case 'foreignObject': 1816 return createFormatContext(HTML_MODE, null); 1817 // Table parents are special in that their children can only be created at all if they're 1818 // wrapped in a table parent. So we need to encode that we're entering this mode. 1819 1820 case 'table': 1821 return createFormatContext(HTML_TABLE_MODE, null); 1822 1823 case 'thead': 1824 case 'tbody': 1825 case 'tfoot': 1826 return createFormatContext(HTML_TABLE_BODY_MODE, null); 1827 1828 case 'colgroup': 1829 return createFormatContext(HTML_COLGROUP_MODE, null); 1830 1831 case 'tr': 1832 return createFormatContext(HTML_TABLE_ROW_MODE, null); 1833 } 1834 1835 if (parentContext.insertionMode >= HTML_TABLE_MODE) { 1836 // Whatever tag this was, it wasn't a table parent or other special parent, so we must have 1837 // entered plain HTML again. 1838 return createFormatContext(HTML_MODE, null); 1839 } 1840 1841 if (parentContext.insertionMode === ROOT_HTML_MODE) { 1842 // We've emitted the root and is now in plain HTML mode. 1843 return createFormatContext(HTML_MODE, null); 1844 } 1845 1846 return parentContext; 1847 } 1848 var UNINITIALIZED_SUSPENSE_BOUNDARY_ID = null; 1849 function assignSuspenseBoundaryID(responseState) { 1850 var generatedID = responseState.nextSuspenseID++; 1851 return stringToPrecomputedChunk(responseState.boundaryPrefix + generatedID.toString(16)); 1852 } 1853 function makeId(responseState, treeId, localId) { 1854 var idPrefix = responseState.idPrefix; 1855 var id = ':' + idPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end 1856 // that represents the position of this useId hook among all the useId 1857 // hooks for this fiber. 1858 1859 if (localId > 0) { 1860 id += 'H' + localId.toString(32); 1861 } 1862 1863 return id + ':'; 1864 } 1865 1866 function encodeHTMLTextNode(text) { 1867 return escapeTextForBrowser(text); 1868 } 1869 1870 var textSeparator = stringToPrecomputedChunk('<!-- -->'); 1871 function pushTextInstance(target, text, responseState, textEmbedded) { 1872 if (text === '') { 1873 // Empty text doesn't have a DOM node representation and the hydration is aware of this. 1874 return textEmbedded; 1875 } 1876 1877 if (textEmbedded) { 1878 target.push(textSeparator); 1879 } 1880 1881 target.push(stringToChunk(encodeHTMLTextNode(text))); 1882 return true; 1883 } // Called when Fizz is done with a Segment. Currently the only purpose is to conditionally 1884 // emit a text separator when we don't know for sure it is safe to omit 1885 1886 function pushSegmentFinale(target, responseState, lastPushedText, textEmbedded) { 1887 if (lastPushedText && textEmbedded) { 1888 target.push(textSeparator); 1889 } 1890 } 1891 var styleNameCache = new Map(); 1892 1893 function processStyleName(styleName) { 1894 var chunk = styleNameCache.get(styleName); 1895 1896 if (chunk !== undefined) { 1897 return chunk; 1898 } 1899 1900 var result = stringToPrecomputedChunk(escapeTextForBrowser(hyphenateStyleName(styleName))); 1901 styleNameCache.set(styleName, result); 1902 return result; 1903 } 1904 1905 var styleAttributeStart = stringToPrecomputedChunk(' style="'); 1906 var styleAssign = stringToPrecomputedChunk(':'); 1907 var styleSeparator = stringToPrecomputedChunk(';'); 1908 1909 function pushStyle(target, responseState, style) { 1910 if (typeof style !== 'object') { 1911 throw new Error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.'); 1912 } 1913 1914 var isFirst = true; 1915 1916 for (var styleName in style) { 1917 if (!hasOwnProperty.call(style, styleName)) { 1918 continue; 1919 } // If you provide unsafe user data here they can inject arbitrary CSS 1920 // which may be problematic (I couldn't repro this): 1921 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 1922 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 1923 // This is not an XSS hole but instead a potential CSS injection issue 1924 // which has lead to a greater discussion about how we're going to 1925 // trust URLs moving forward. See #2115901 1926 1927 1928 var styleValue = style[styleName]; 1929 1930 if (styleValue == null || typeof styleValue === 'boolean' || styleValue === '') { 1931 // TODO: We used to set empty string as a style with an empty value. Does that ever make sense? 1932 continue; 1933 } 1934 1935 var nameChunk = void 0; 1936 var valueChunk = void 0; 1937 var isCustomProperty = styleName.indexOf('--') === 0; 1938 1939 if (isCustomProperty) { 1940 nameChunk = stringToChunk(escapeTextForBrowser(styleName)); 1941 1942 { 1943 checkCSSPropertyStringCoercion(styleValue, styleName); 1944 } 1945 1946 valueChunk = stringToChunk(escapeTextForBrowser(('' + styleValue).trim())); 1947 } else { 1948 { 1949 warnValidStyle$1(styleName, styleValue); 1950 } 1951 1952 nameChunk = processStyleName(styleName); 1953 1954 if (typeof styleValue === 'number') { 1955 if (styleValue !== 0 && !hasOwnProperty.call(isUnitlessNumber, styleName)) { 1956 valueChunk = stringToChunk(styleValue + 'px'); // Presumes implicit 'px' suffix for unitless numbers 1957 } else { 1958 valueChunk = stringToChunk('' + styleValue); 1959 } 1960 } else { 1961 { 1962 checkCSSPropertyStringCoercion(styleValue, styleName); 1963 } 1964 1965 valueChunk = stringToChunk(escapeTextForBrowser(('' + styleValue).trim())); 1966 } 1967 } 1968 1969 if (isFirst) { 1970 isFirst = false; // If it's first, we don't need any separators prefixed. 1971 1972 target.push(styleAttributeStart, nameChunk, styleAssign, valueChunk); 1973 } else { 1974 target.push(styleSeparator, nameChunk, styleAssign, valueChunk); 1975 } 1976 } 1977 1978 if (!isFirst) { 1979 target.push(attributeEnd); 1980 } 1981 } 1982 1983 var attributeSeparator = stringToPrecomputedChunk(' '); 1984 var attributeAssign = stringToPrecomputedChunk('="'); 1985 var attributeEnd = stringToPrecomputedChunk('"'); 1986 var attributeEmptyString = stringToPrecomputedChunk('=""'); 1987 1988 function pushAttribute(target, responseState, name, value) { 1989 switch (name) { 1990 case 'style': 1991 { 1992 pushStyle(target, responseState, value); 1993 return; 1994 } 1995 1996 case 'defaultValue': 1997 case 'defaultChecked': // These shouldn't be set as attributes on generic HTML elements. 1998 1999 case 'innerHTML': // Must use dangerouslySetInnerHTML instead. 2000 2001 case 'suppressContentEditableWarning': 2002 case 'suppressHydrationWarning': 2003 // Ignored. These are built-in to React on the client. 2004 return; 2005 } 2006 2007 if ( // shouldIgnoreAttribute 2008 // We have already filtered out null/undefined and reserved words. 2009 name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 2010 return; 2011 } 2012 2013 var propertyInfo = getPropertyInfo(name); 2014 2015 if (propertyInfo !== null) { 2016 // shouldRemoveAttribute 2017 switch (typeof value) { 2018 case 'function': // $FlowIssue symbol is perfectly valid here 2019 2020 case 'symbol': 2021 // eslint-disable-line 2022 return; 2023 2024 case 'boolean': 2025 { 2026 if (!propertyInfo.acceptsBooleans) { 2027 return; 2028 } 2029 } 2030 } 2031 2032 var attributeName = propertyInfo.attributeName; 2033 var attributeNameChunk = stringToChunk(attributeName); // TODO: If it's known we can cache the chunk. 2034 2035 switch (propertyInfo.type) { 2036 case BOOLEAN: 2037 if (value) { 2038 target.push(attributeSeparator, attributeNameChunk, attributeEmptyString); 2039 } 2040 2041 return; 2042 2043 case OVERLOADED_BOOLEAN: 2044 if (value === true) { 2045 target.push(attributeSeparator, attributeNameChunk, attributeEmptyString); 2046 } else if (value === false) ; else { 2047 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2048 } 2049 2050 return; 2051 2052 case NUMERIC: 2053 if (!isNaN(value)) { 2054 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2055 } 2056 2057 break; 2058 2059 case POSITIVE_NUMERIC: 2060 if (!isNaN(value) && value >= 1) { 2061 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2062 } 2063 2064 break; 2065 2066 default: 2067 if (propertyInfo.sanitizeURL) { 2068 { 2069 checkAttributeStringCoercion(value, attributeName); 2070 } 2071 2072 value = '' + value; 2073 sanitizeURL(value); 2074 } 2075 2076 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2077 } 2078 } else if (isAttributeNameSafe(name)) { 2079 // shouldRemoveAttribute 2080 switch (typeof value) { 2081 case 'function': // $FlowIssue symbol is perfectly valid here 2082 2083 case 'symbol': 2084 // eslint-disable-line 2085 return; 2086 2087 case 'boolean': 2088 { 2089 var prefix = name.toLowerCase().slice(0, 5); 2090 2091 if (prefix !== 'data-' && prefix !== 'aria-') { 2092 return; 2093 } 2094 } 2095 } 2096 2097 target.push(attributeSeparator, stringToChunk(name), attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2098 } 2099 } 2100 2101 var endOfStartTag = stringToPrecomputedChunk('>'); 2102 var endOfStartTagSelfClosing = stringToPrecomputedChunk('/>'); 2103 2104 function pushInnerHTML(target, innerHTML, children) { 2105 if (innerHTML != null) { 2106 if (children != null) { 2107 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'); 2108 } 2109 2110 if (typeof innerHTML !== 'object' || !('__html' in innerHTML)) { 2111 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.'); 2112 } 2113 2114 var html = innerHTML.__html; 2115 2116 if (html !== null && html !== undefined) { 2117 { 2118 checkHtmlStringCoercion(html); 2119 } 2120 2121 target.push(stringToChunk('' + html)); 2122 } 2123 } 2124 } // TODO: Move these to ResponseState so that we warn for every request. 2125 // It would help debugging in stateful servers (e.g. service worker). 2126 2127 2128 var didWarnDefaultInputValue = false; 2129 var didWarnDefaultChecked = false; 2130 var didWarnDefaultSelectValue = false; 2131 var didWarnDefaultTextareaValue = false; 2132 var didWarnInvalidOptionChildren = false; 2133 var didWarnInvalidOptionInnerHTML = false; 2134 var didWarnSelectedSetOnOption = false; 2135 2136 function checkSelectProp(props, propName) { 2137 { 2138 var value = props[propName]; 2139 2140 if (value != null) { 2141 var array = isArray(value); 2142 2143 if (props.multiple && !array) { 2144 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.', propName); 2145 } else if (!props.multiple && array) { 2146 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.', propName); 2147 } 2148 } 2149 } 2150 } 2151 2152 function pushStartSelect(target, props, responseState) { 2153 { 2154 checkControlledValueProps('select', props); 2155 checkSelectProp(props, 'value'); 2156 checkSelectProp(props, 'defaultValue'); 2157 2158 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultSelectValue) { 2159 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'); 2160 2161 didWarnDefaultSelectValue = true; 2162 } 2163 } 2164 2165 target.push(startChunkForTag('select')); 2166 var children = null; 2167 var innerHTML = null; 2168 2169 for (var propKey in props) { 2170 if (hasOwnProperty.call(props, propKey)) { 2171 var propValue = props[propKey]; 2172 2173 if (propValue == null) { 2174 continue; 2175 } 2176 2177 switch (propKey) { 2178 case 'children': 2179 children = propValue; 2180 break; 2181 2182 case 'dangerouslySetInnerHTML': 2183 // TODO: This doesn't really make sense for select since it can't use the controlled 2184 // value in the innerHTML. 2185 innerHTML = propValue; 2186 break; 2187 2188 case 'defaultValue': 2189 case 'value': 2190 // These are set on the Context instead and applied to the nested options. 2191 break; 2192 2193 default: 2194 pushAttribute(target, responseState, propKey, propValue); 2195 break; 2196 } 2197 } 2198 } 2199 2200 target.push(endOfStartTag); 2201 pushInnerHTML(target, innerHTML, children); 2202 return children; 2203 } 2204 2205 function flattenOptionChildren(children) { 2206 var content = ''; // Flatten children and warn if they aren't strings or numbers; 2207 // invalid types are ignored. 2208 2209 React.Children.forEach(children, function (child) { 2210 if (child == null) { 2211 return; 2212 } 2213 2214 content += child; 2215 2216 { 2217 if (!didWarnInvalidOptionChildren && typeof child !== 'string' && typeof child !== 'number') { 2218 didWarnInvalidOptionChildren = true; 2219 2220 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.'); 2221 } 2222 } 2223 }); 2224 return content; 2225 } 2226 2227 var selectedMarkerAttribute = stringToPrecomputedChunk(' selected=""'); 2228 2229 function pushStartOption(target, props, responseState, formatContext) { 2230 var selectedValue = formatContext.selectedValue; 2231 target.push(startChunkForTag('option')); 2232 var children = null; 2233 var value = null; 2234 var selected = null; 2235 var innerHTML = null; 2236 2237 for (var propKey in props) { 2238 if (hasOwnProperty.call(props, propKey)) { 2239 var propValue = props[propKey]; 2240 2241 if (propValue == null) { 2242 continue; 2243 } 2244 2245 switch (propKey) { 2246 case 'children': 2247 children = propValue; 2248 break; 2249 2250 case 'selected': 2251 // ignore 2252 selected = propValue; 2253 2254 { 2255 // TODO: Remove support for `selected` in <option>. 2256 if (!didWarnSelectedSetOnOption) { 2257 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 2258 2259 didWarnSelectedSetOnOption = true; 2260 } 2261 } 2262 2263 break; 2264 2265 case 'dangerouslySetInnerHTML': 2266 innerHTML = propValue; 2267 break; 2268 // eslint-disable-next-line-no-fallthrough 2269 2270 case 'value': 2271 value = propValue; 2272 // We intentionally fallthrough to also set the attribute on the node. 2273 // eslint-disable-next-line-no-fallthrough 2274 2275 default: 2276 pushAttribute(target, responseState, propKey, propValue); 2277 break; 2278 } 2279 } 2280 } 2281 2282 if (selectedValue != null) { 2283 var stringValue; 2284 2285 if (value !== null) { 2286 { 2287 checkAttributeStringCoercion(value, 'value'); 2288 } 2289 2290 stringValue = '' + value; 2291 } else { 2292 { 2293 if (innerHTML !== null) { 2294 if (!didWarnInvalidOptionInnerHTML) { 2295 didWarnInvalidOptionInnerHTML = true; 2296 2297 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.'); 2298 } 2299 } 2300 } 2301 2302 stringValue = flattenOptionChildren(children); 2303 } 2304 2305 if (isArray(selectedValue)) { 2306 // multiple 2307 for (var i = 0; i < selectedValue.length; i++) { 2308 { 2309 checkAttributeStringCoercion(selectedValue[i], 'value'); 2310 } 2311 2312 var v = '' + selectedValue[i]; 2313 2314 if (v === stringValue) { 2315 target.push(selectedMarkerAttribute); 2316 break; 2317 } 2318 } 2319 } else { 2320 { 2321 checkAttributeStringCoercion(selectedValue, 'select.value'); 2322 } 2323 2324 if ('' + selectedValue === stringValue) { 2325 target.push(selectedMarkerAttribute); 2326 } 2327 } 2328 } else if (selected) { 2329 target.push(selectedMarkerAttribute); 2330 } 2331 2332 target.push(endOfStartTag); 2333 pushInnerHTML(target, innerHTML, children); 2334 return children; 2335 } 2336 2337 function pushInput(target, props, responseState) { 2338 { 2339 checkControlledValueProps('input', props); 2340 2341 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnDefaultChecked) { 2342 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', 'A component', props.type); 2343 2344 didWarnDefaultChecked = true; 2345 } 2346 2347 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultInputValue) { 2348 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', 'A component', props.type); 2349 2350 didWarnDefaultInputValue = true; 2351 } 2352 } 2353 2354 target.push(startChunkForTag('input')); 2355 var value = null; 2356 var defaultValue = null; 2357 var checked = null; 2358 var defaultChecked = null; 2359 2360 for (var propKey in props) { 2361 if (hasOwnProperty.call(props, propKey)) { 2362 var propValue = props[propKey]; 2363 2364 if (propValue == null) { 2365 continue; 2366 } 2367 2368 switch (propKey) { 2369 case 'children': 2370 case 'dangerouslySetInnerHTML': 2371 throw new Error('input' + " is a self-closing tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.'); 2372 // eslint-disable-next-line-no-fallthrough 2373 2374 case 'defaultChecked': 2375 defaultChecked = propValue; 2376 break; 2377 2378 case 'defaultValue': 2379 defaultValue = propValue; 2380 break; 2381 2382 case 'checked': 2383 checked = propValue; 2384 break; 2385 2386 case 'value': 2387 value = propValue; 2388 break; 2389 2390 default: 2391 pushAttribute(target, responseState, propKey, propValue); 2392 break; 2393 } 2394 } 2395 } 2396 2397 if (checked !== null) { 2398 pushAttribute(target, responseState, 'checked', checked); 2399 } else if (defaultChecked !== null) { 2400 pushAttribute(target, responseState, 'checked', defaultChecked); 2401 } 2402 2403 if (value !== null) { 2404 pushAttribute(target, responseState, 'value', value); 2405 } else if (defaultValue !== null) { 2406 pushAttribute(target, responseState, 'value', defaultValue); 2407 } 2408 2409 target.push(endOfStartTagSelfClosing); 2410 return null; 2411 } 2412 2413 function pushStartTextArea(target, props, responseState) { 2414 { 2415 checkControlledValueProps('textarea', props); 2416 2417 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultTextareaValue) { 2418 error('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'); 2419 2420 didWarnDefaultTextareaValue = true; 2421 } 2422 } 2423 2424 target.push(startChunkForTag('textarea')); 2425 var value = null; 2426 var defaultValue = null; 2427 var children = null; 2428 2429 for (var propKey in props) { 2430 if (hasOwnProperty.call(props, propKey)) { 2431 var propValue = props[propKey]; 2432 2433 if (propValue == null) { 2434 continue; 2435 } 2436 2437 switch (propKey) { 2438 case 'children': 2439 children = propValue; 2440 break; 2441 2442 case 'value': 2443 value = propValue; 2444 break; 2445 2446 case 'defaultValue': 2447 defaultValue = propValue; 2448 break; 2449 2450 case 'dangerouslySetInnerHTML': 2451 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.'); 2452 // eslint-disable-next-line-no-fallthrough 2453 2454 default: 2455 pushAttribute(target, responseState, propKey, propValue); 2456 break; 2457 } 2458 } 2459 } 2460 2461 if (value === null && defaultValue !== null) { 2462 value = defaultValue; 2463 } 2464 2465 target.push(endOfStartTag); // TODO (yungsters): Remove support for children content in <textarea>. 2466 2467 if (children != null) { 2468 { 2469 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 2470 } 2471 2472 if (value != null) { 2473 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.'); 2474 } 2475 2476 if (isArray(children)) { 2477 if (children.length > 1) { 2478 throw new Error('<textarea> can only have at most one child.'); 2479 } // TODO: remove the coercion and the DEV check below because it will 2480 // always be overwritten by the coercion several lines below it. #22309 2481 2482 2483 { 2484 checkHtmlStringCoercion(children[0]); 2485 } 2486 2487 value = '' + children[0]; 2488 } 2489 2490 { 2491 checkHtmlStringCoercion(children); 2492 } 2493 2494 value = '' + children; 2495 } 2496 2497 if (typeof value === 'string' && value[0] === '\n') { 2498 // text/html ignores the first character in these tags if it's a newline 2499 // Prefer to break application/xml over text/html (for now) by adding 2500 // a newline specifically to get eaten by the parser. (Alternately for 2501 // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first 2502 // \r is normalized out by HTMLTextAreaElement#value.) 2503 // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> 2504 // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> 2505 // See: <http://www.w3.org/TR/html5/syntax.html#newlines> 2506 // See: Parsing of "textarea" "listing" and "pre" elements 2507 // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> 2508 target.push(leadingNewline); 2509 } // ToString and push directly instead of recurse over children. 2510 // We don't really support complex children in the value anyway. 2511 // This also currently avoids a trailing comment node which breaks textarea. 2512 2513 2514 if (value !== null) { 2515 { 2516 checkAttributeStringCoercion(value, 'value'); 2517 } 2518 2519 target.push(stringToChunk(encodeHTMLTextNode('' + value))); 2520 } 2521 2522 return null; 2523 } 2524 2525 function pushSelfClosing(target, props, tag, responseState) { 2526 target.push(startChunkForTag(tag)); 2527 2528 for (var propKey in props) { 2529 if (hasOwnProperty.call(props, propKey)) { 2530 var propValue = props[propKey]; 2531 2532 if (propValue == null) { 2533 continue; 2534 } 2535 2536 switch (propKey) { 2537 case 'children': 2538 case 'dangerouslySetInnerHTML': 2539 throw new Error(tag + " is a self-closing tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.'); 2540 // eslint-disable-next-line-no-fallthrough 2541 2542 default: 2543 pushAttribute(target, responseState, propKey, propValue); 2544 break; 2545 } 2546 } 2547 } 2548 2549 target.push(endOfStartTagSelfClosing); 2550 return null; 2551 } 2552 2553 function pushStartMenuItem(target, props, responseState) { 2554 target.push(startChunkForTag('menuitem')); 2555 2556 for (var propKey in props) { 2557 if (hasOwnProperty.call(props, propKey)) { 2558 var propValue = props[propKey]; 2559 2560 if (propValue == null) { 2561 continue; 2562 } 2563 2564 switch (propKey) { 2565 case 'children': 2566 case 'dangerouslySetInnerHTML': 2567 throw new Error('menuitems cannot have `children` nor `dangerouslySetInnerHTML`.'); 2568 // eslint-disable-next-line-no-fallthrough 2569 2570 default: 2571 pushAttribute(target, responseState, propKey, propValue); 2572 break; 2573 } 2574 } 2575 } 2576 2577 target.push(endOfStartTag); 2578 return null; 2579 } 2580 2581 function pushStartTitle(target, props, responseState) { 2582 target.push(startChunkForTag('title')); 2583 var children = null; 2584 2585 for (var propKey in props) { 2586 if (hasOwnProperty.call(props, propKey)) { 2587 var propValue = props[propKey]; 2588 2589 if (propValue == null) { 2590 continue; 2591 } 2592 2593 switch (propKey) { 2594 case 'children': 2595 children = propValue; 2596 break; 2597 2598 case 'dangerouslySetInnerHTML': 2599 throw new Error('`dangerouslySetInnerHTML` does not make sense on <title>.'); 2600 // eslint-disable-next-line-no-fallthrough 2601 2602 default: 2603 pushAttribute(target, responseState, propKey, propValue); 2604 break; 2605 } 2606 } 2607 } 2608 2609 target.push(endOfStartTag); 2610 2611 { 2612 var child = Array.isArray(children) && children.length < 2 ? children[0] || null : children; 2613 2614 if (Array.isArray(children) && children.length > 1) { 2615 error('A title element received an array with more than 1 element as children. ' + 'In browsers title Elements can only have Text Nodes as children. If ' + 'the children being rendered output more than a single text node in aggregate the browser ' + 'will display markup and comments as text in the title and hydration will likely fail and ' + 'fall back to client rendering'); 2616 } else if (child != null && child.$$typeof != null) { 2617 error('A title element received a React element for children. ' + 'In the browser title Elements can only have Text Nodes as children. If ' + 'the children being rendered output more than a single text node in aggregate the browser ' + 'will display markup and comments as text in the title and hydration will likely fail and ' + 'fall back to client rendering'); 2618 } else if (child != null && typeof child !== 'string' && typeof child !== 'number') { 2619 error('A title element received a value that was not a string or number for children. ' + 'In the browser title Elements can only have Text Nodes as children. If ' + 'the children being rendered output more than a single text node in aggregate the browser ' + 'will display markup and comments as text in the title and hydration will likely fail and ' + 'fall back to client rendering'); 2620 } 2621 } 2622 2623 return children; 2624 } 2625 2626 function pushStartGenericElement(target, props, tag, responseState) { 2627 target.push(startChunkForTag(tag)); 2628 var children = null; 2629 var innerHTML = null; 2630 2631 for (var propKey in props) { 2632 if (hasOwnProperty.call(props, propKey)) { 2633 var propValue = props[propKey]; 2634 2635 if (propValue == null) { 2636 continue; 2637 } 2638 2639 switch (propKey) { 2640 case 'children': 2641 children = propValue; 2642 break; 2643 2644 case 'dangerouslySetInnerHTML': 2645 innerHTML = propValue; 2646 break; 2647 2648 default: 2649 pushAttribute(target, responseState, propKey, propValue); 2650 break; 2651 } 2652 } 2653 } 2654 2655 target.push(endOfStartTag); 2656 pushInnerHTML(target, innerHTML, children); 2657 2658 if (typeof children === 'string') { 2659 // Special case children as a string to avoid the unnecessary comment. 2660 // TODO: Remove this special case after the general optimization is in place. 2661 target.push(stringToChunk(encodeHTMLTextNode(children))); 2662 return null; 2663 } 2664 2665 return children; 2666 } 2667 2668 function pushStartCustomElement(target, props, tag, responseState) { 2669 target.push(startChunkForTag(tag)); 2670 var children = null; 2671 var innerHTML = null; 2672 2673 for (var propKey in props) { 2674 if (hasOwnProperty.call(props, propKey)) { 2675 var propValue = props[propKey]; 2676 2677 if (propValue == null) { 2678 continue; 2679 } 2680 2681 switch (propKey) { 2682 case 'children': 2683 children = propValue; 2684 break; 2685 2686 case 'dangerouslySetInnerHTML': 2687 innerHTML = propValue; 2688 break; 2689 2690 case 'style': 2691 pushStyle(target, responseState, propValue); 2692 break; 2693 2694 case 'suppressContentEditableWarning': 2695 case 'suppressHydrationWarning': 2696 // Ignored. These are built-in to React on the client. 2697 break; 2698 2699 default: 2700 if (isAttributeNameSafe(propKey) && typeof propValue !== 'function' && typeof propValue !== 'symbol') { 2701 target.push(attributeSeparator, stringToChunk(propKey), attributeAssign, stringToChunk(escapeTextForBrowser(propValue)), attributeEnd); 2702 } 2703 2704 break; 2705 } 2706 } 2707 } 2708 2709 target.push(endOfStartTag); 2710 pushInnerHTML(target, innerHTML, children); 2711 return children; 2712 } 2713 2714 var leadingNewline = stringToPrecomputedChunk('\n'); 2715 2716 function pushStartPreformattedElement(target, props, tag, responseState) { 2717 target.push(startChunkForTag(tag)); 2718 var children = null; 2719 var innerHTML = null; 2720 2721 for (var propKey in props) { 2722 if (hasOwnProperty.call(props, propKey)) { 2723 var propValue = props[propKey]; 2724 2725 if (propValue == null) { 2726 continue; 2727 } 2728 2729 switch (propKey) { 2730 case 'children': 2731 children = propValue; 2732 break; 2733 2734 case 'dangerouslySetInnerHTML': 2735 innerHTML = propValue; 2736 break; 2737 2738 default: 2739 pushAttribute(target, responseState, propKey, propValue); 2740 break; 2741 } 2742 } 2743 } 2744 2745 target.push(endOfStartTag); // text/html ignores the first character in these tags if it's a newline 2746 // Prefer to break application/xml over text/html (for now) by adding 2747 // a newline specifically to get eaten by the parser. (Alternately for 2748 // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first 2749 // \r is normalized out by HTMLTextAreaElement#value.) 2750 // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> 2751 // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> 2752 // See: <http://www.w3.org/TR/html5/syntax.html#newlines> 2753 // See: Parsing of "textarea" "listing" and "pre" elements 2754 // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> 2755 // TODO: This doesn't deal with the case where the child is an array 2756 // or component that returns a string. 2757 2758 if (innerHTML != null) { 2759 if (children != null) { 2760 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'); 2761 } 2762 2763 if (typeof innerHTML !== 'object' || !('__html' in innerHTML)) { 2764 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.'); 2765 } 2766 2767 var html = innerHTML.__html; 2768 2769 if (html !== null && html !== undefined) { 2770 if (typeof html === 'string' && html.length > 0 && html[0] === '\n') { 2771 target.push(leadingNewline, stringToChunk(html)); 2772 } else { 2773 { 2774 checkHtmlStringCoercion(html); 2775 } 2776 2777 target.push(stringToChunk('' + html)); 2778 } 2779 } 2780 } 2781 2782 if (typeof children === 'string' && children[0] === '\n') { 2783 target.push(leadingNewline); 2784 } 2785 2786 return children; 2787 } // We accept any tag to be rendered but since this gets injected into arbitrary 2788 // HTML, we want to make sure that it's a safe tag. 2789 // http://www.w3.org/TR/REC-xml/#NT-Name 2790 2791 2792 var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset 2793 2794 var validatedTagCache = new Map(); 2795 2796 function startChunkForTag(tag) { 2797 var tagStartChunk = validatedTagCache.get(tag); 2798 2799 if (tagStartChunk === undefined) { 2800 if (!VALID_TAG_REGEX.test(tag)) { 2801 throw new Error("Invalid tag: " + tag); 2802 } 2803 2804 tagStartChunk = stringToPrecomputedChunk('<' + tag); 2805 validatedTagCache.set(tag, tagStartChunk); 2806 } 2807 2808 return tagStartChunk; 2809 } 2810 2811 var DOCTYPE = stringToPrecomputedChunk('<!DOCTYPE html>'); 2812 function pushStartInstance(target, type, props, responseState, formatContext) { 2813 { 2814 validateProperties(type, props); 2815 validateProperties$1(type, props); 2816 validateProperties$2(type, props, null); 2817 2818 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) { 2819 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.'); 2820 } 2821 2822 if (formatContext.insertionMode !== SVG_MODE && formatContext.insertionMode !== MATHML_MODE) { 2823 if (type.indexOf('-') === -1 && typeof props.is !== 'string' && type.toLowerCase() !== type) { 2824 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type); 2825 } 2826 } 2827 } 2828 2829 switch (type) { 2830 // Special tags 2831 case 'select': 2832 return pushStartSelect(target, props, responseState); 2833 2834 case 'option': 2835 return pushStartOption(target, props, responseState, formatContext); 2836 2837 case 'textarea': 2838 return pushStartTextArea(target, props, responseState); 2839 2840 case 'input': 2841 return pushInput(target, props, responseState); 2842 2843 case 'menuitem': 2844 return pushStartMenuItem(target, props, responseState); 2845 2846 case 'title': 2847 return pushStartTitle(target, props, responseState); 2848 // Newline eating tags 2849 2850 case 'listing': 2851 case 'pre': 2852 { 2853 return pushStartPreformattedElement(target, props, type, responseState); 2854 } 2855 // Omitted close tags 2856 2857 case 'area': 2858 case 'base': 2859 case 'br': 2860 case 'col': 2861 case 'embed': 2862 case 'hr': 2863 case 'img': 2864 case 'keygen': 2865 case 'link': 2866 case 'meta': 2867 case 'param': 2868 case 'source': 2869 case 'track': 2870 case 'wbr': 2871 { 2872 return pushSelfClosing(target, props, type, responseState); 2873 } 2874 // These are reserved SVG and MathML elements, that are never custom elements. 2875 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 2876 2877 case 'annotation-xml': 2878 case 'color-profile': 2879 case 'font-face': 2880 case 'font-face-src': 2881 case 'font-face-uri': 2882 case 'font-face-format': 2883 case 'font-face-name': 2884 case 'missing-glyph': 2885 { 2886 return pushStartGenericElement(target, props, type, responseState); 2887 } 2888 2889 case 'html': 2890 { 2891 if (formatContext.insertionMode === ROOT_HTML_MODE) { 2892 // If we're rendering the html tag and we're at the root (i.e. not in foreignObject) 2893 // then we also emit the DOCTYPE as part of the root content as a convenience for 2894 // rendering the whole document. 2895 target.push(DOCTYPE); 2896 } 2897 2898 return pushStartGenericElement(target, props, type, responseState); 2899 } 2900 2901 default: 2902 { 2903 if (type.indexOf('-') === -1 && typeof props.is !== 'string') { 2904 // Generic element 2905 return pushStartGenericElement(target, props, type, responseState); 2906 } else { 2907 // Custom element 2908 return pushStartCustomElement(target, props, type, responseState); 2909 } 2910 } 2911 } 2912 } 2913 var endTag1 = stringToPrecomputedChunk('</'); 2914 var endTag2 = stringToPrecomputedChunk('>'); 2915 function pushEndInstance(target, type, props) { 2916 switch (type) { 2917 // Omitted close tags 2918 // TODO: Instead of repeating this switch we could try to pass a flag from above. 2919 // That would require returning a tuple. Which might be ok if it gets inlined. 2920 case 'area': 2921 case 'base': 2922 case 'br': 2923 case 'col': 2924 case 'embed': 2925 case 'hr': 2926 case 'img': 2927 case 'input': 2928 case 'keygen': 2929 case 'link': 2930 case 'meta': 2931 case 'param': 2932 case 'source': 2933 case 'track': 2934 case 'wbr': 2935 { 2936 // No close tag needed. 2937 break; 2938 } 2939 2940 default: 2941 { 2942 target.push(endTag1, stringToChunk(type), endTag2); 2943 } 2944 } 2945 } 2946 function writeCompletedRoot(destination, responseState) { 2947 var bootstrapChunks = responseState.bootstrapChunks; 2948 var i = 0; 2949 2950 for (; i < bootstrapChunks.length - 1; i++) { 2951 writeChunk(destination, bootstrapChunks[i]); 2952 } 2953 2954 if (i < bootstrapChunks.length) { 2955 return writeChunkAndReturn(destination, bootstrapChunks[i]); 2956 } 2957 2958 return true; 2959 } // Structural Nodes 2960 // A placeholder is a node inside a hidden partial tree that can be filled in later, but before 2961 // display. It's never visible to users. We use the template tag because it can be used in every 2962 // type of parent. <script> tags also work in every other tag except <colgroup>. 2963 2964 var placeholder1 = stringToPrecomputedChunk('<template id="'); 2965 var placeholder2 = stringToPrecomputedChunk('"></template>'); 2966 function writePlaceholder(destination, responseState, id) { 2967 writeChunk(destination, placeholder1); 2968 writeChunk(destination, responseState.placeholderPrefix); 2969 var formattedID = stringToChunk(id.toString(16)); 2970 writeChunk(destination, formattedID); 2971 return writeChunkAndReturn(destination, placeholder2); 2972 } // Suspense boundaries are encoded as comments. 2973 2974 var startCompletedSuspenseBoundary = stringToPrecomputedChunk('<!--$-->'); 2975 var startPendingSuspenseBoundary1 = stringToPrecomputedChunk('<!--$?--><template id="'); 2976 var startPendingSuspenseBoundary2 = stringToPrecomputedChunk('"></template>'); 2977 var startClientRenderedSuspenseBoundary = stringToPrecomputedChunk('<!--$!-->'); 2978 var endSuspenseBoundary = stringToPrecomputedChunk('<!--/$-->'); 2979 var clientRenderedSuspenseBoundaryError1 = stringToPrecomputedChunk('<template'); 2980 var clientRenderedSuspenseBoundaryErrorAttrInterstitial = stringToPrecomputedChunk('"'); 2981 var clientRenderedSuspenseBoundaryError1A = stringToPrecomputedChunk(' data-dgst="'); 2982 var clientRenderedSuspenseBoundaryError1B = stringToPrecomputedChunk(' data-msg="'); 2983 var clientRenderedSuspenseBoundaryError1C = stringToPrecomputedChunk(' data-stck="'); 2984 var clientRenderedSuspenseBoundaryError2 = stringToPrecomputedChunk('></template>'); 2985 function writeStartCompletedSuspenseBoundary(destination, responseState) { 2986 return writeChunkAndReturn(destination, startCompletedSuspenseBoundary); 2987 } 2988 function writeStartPendingSuspenseBoundary(destination, responseState, id) { 2989 writeChunk(destination, startPendingSuspenseBoundary1); 2990 2991 if (id === null) { 2992 throw new Error('An ID must have been assigned before we can complete the boundary.'); 2993 } 2994 2995 writeChunk(destination, id); 2996 return writeChunkAndReturn(destination, startPendingSuspenseBoundary2); 2997 } 2998 function writeStartClientRenderedSuspenseBoundary(destination, responseState, errorDigest, errorMesssage, errorComponentStack) { 2999 var result; 3000 result = writeChunkAndReturn(destination, startClientRenderedSuspenseBoundary); 3001 writeChunk(destination, clientRenderedSuspenseBoundaryError1); 3002 3003 if (errorDigest) { 3004 writeChunk(destination, clientRenderedSuspenseBoundaryError1A); 3005 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorDigest))); 3006 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 3007 } 3008 3009 { 3010 if (errorMesssage) { 3011 writeChunk(destination, clientRenderedSuspenseBoundaryError1B); 3012 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorMesssage))); 3013 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 3014 } 3015 3016 if (errorComponentStack) { 3017 writeChunk(destination, clientRenderedSuspenseBoundaryError1C); 3018 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorComponentStack))); 3019 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 3020 } 3021 } 3022 3023 result = writeChunkAndReturn(destination, clientRenderedSuspenseBoundaryError2); 3024 return result; 3025 } 3026 function writeEndCompletedSuspenseBoundary(destination, responseState) { 3027 return writeChunkAndReturn(destination, endSuspenseBoundary); 3028 } 3029 function writeEndPendingSuspenseBoundary(destination, responseState) { 3030 return writeChunkAndReturn(destination, endSuspenseBoundary); 3031 } 3032 function writeEndClientRenderedSuspenseBoundary(destination, responseState) { 3033 return writeChunkAndReturn(destination, endSuspenseBoundary); 3034 } 3035 var startSegmentHTML = stringToPrecomputedChunk('<div hidden id="'); 3036 var startSegmentHTML2 = stringToPrecomputedChunk('">'); 3037 var endSegmentHTML = stringToPrecomputedChunk('</div>'); 3038 var startSegmentSVG = stringToPrecomputedChunk('<svg aria-hidden="true" style="display:none" id="'); 3039 var startSegmentSVG2 = stringToPrecomputedChunk('">'); 3040 var endSegmentSVG = stringToPrecomputedChunk('</svg>'); 3041 var startSegmentMathML = stringToPrecomputedChunk('<math aria-hidden="true" style="display:none" id="'); 3042 var startSegmentMathML2 = stringToPrecomputedChunk('">'); 3043 var endSegmentMathML = stringToPrecomputedChunk('</math>'); 3044 var startSegmentTable = stringToPrecomputedChunk('<table hidden id="'); 3045 var startSegmentTable2 = stringToPrecomputedChunk('">'); 3046 var endSegmentTable = stringToPrecomputedChunk('</table>'); 3047 var startSegmentTableBody = stringToPrecomputedChunk('<table hidden><tbody id="'); 3048 var startSegmentTableBody2 = stringToPrecomputedChunk('">'); 3049 var endSegmentTableBody = stringToPrecomputedChunk('</tbody></table>'); 3050 var startSegmentTableRow = stringToPrecomputedChunk('<table hidden><tr id="'); 3051 var startSegmentTableRow2 = stringToPrecomputedChunk('">'); 3052 var endSegmentTableRow = stringToPrecomputedChunk('</tr></table>'); 3053 var startSegmentColGroup = stringToPrecomputedChunk('<table hidden><colgroup id="'); 3054 var startSegmentColGroup2 = stringToPrecomputedChunk('">'); 3055 var endSegmentColGroup = stringToPrecomputedChunk('</colgroup></table>'); 3056 function writeStartSegment(destination, responseState, formatContext, id) { 3057 switch (formatContext.insertionMode) { 3058 case ROOT_HTML_MODE: 3059 case HTML_MODE: 3060 { 3061 writeChunk(destination, startSegmentHTML); 3062 writeChunk(destination, responseState.segmentPrefix); 3063 writeChunk(destination, stringToChunk(id.toString(16))); 3064 return writeChunkAndReturn(destination, startSegmentHTML2); 3065 } 3066 3067 case SVG_MODE: 3068 { 3069 writeChunk(destination, startSegmentSVG); 3070 writeChunk(destination, responseState.segmentPrefix); 3071 writeChunk(destination, stringToChunk(id.toString(16))); 3072 return writeChunkAndReturn(destination, startSegmentSVG2); 3073 } 3074 3075 case MATHML_MODE: 3076 { 3077 writeChunk(destination, startSegmentMathML); 3078 writeChunk(destination, responseState.segmentPrefix); 3079 writeChunk(destination, stringToChunk(id.toString(16))); 3080 return writeChunkAndReturn(destination, startSegmentMathML2); 3081 } 3082 3083 case HTML_TABLE_MODE: 3084 { 3085 writeChunk(destination, startSegmentTable); 3086 writeChunk(destination, responseState.segmentPrefix); 3087 writeChunk(destination, stringToChunk(id.toString(16))); 3088 return writeChunkAndReturn(destination, startSegmentTable2); 3089 } 3090 // TODO: For the rest of these, there will be extra wrapper nodes that never 3091 // get deleted from the document. We need to delete the table too as part 3092 // of the injected scripts. They are invisible though so it's not too terrible 3093 // and it's kind of an edge case to suspend in a table. Totally supported though. 3094 3095 case HTML_TABLE_BODY_MODE: 3096 { 3097 writeChunk(destination, startSegmentTableBody); 3098 writeChunk(destination, responseState.segmentPrefix); 3099 writeChunk(destination, stringToChunk(id.toString(16))); 3100 return writeChunkAndReturn(destination, startSegmentTableBody2); 3101 } 3102 3103 case HTML_TABLE_ROW_MODE: 3104 { 3105 writeChunk(destination, startSegmentTableRow); 3106 writeChunk(destination, responseState.segmentPrefix); 3107 writeChunk(destination, stringToChunk(id.toString(16))); 3108 return writeChunkAndReturn(destination, startSegmentTableRow2); 3109 } 3110 3111 case HTML_COLGROUP_MODE: 3112 { 3113 writeChunk(destination, startSegmentColGroup); 3114 writeChunk(destination, responseState.segmentPrefix); 3115 writeChunk(destination, stringToChunk(id.toString(16))); 3116 return writeChunkAndReturn(destination, startSegmentColGroup2); 3117 } 3118 3119 default: 3120 { 3121 throw new Error('Unknown insertion mode. This is a bug in React.'); 3122 } 3123 } 3124 } 3125 function writeEndSegment(destination, formatContext) { 3126 switch (formatContext.insertionMode) { 3127 case ROOT_HTML_MODE: 3128 case HTML_MODE: 3129 { 3130 return writeChunkAndReturn(destination, endSegmentHTML); 3131 } 3132 3133 case SVG_MODE: 3134 { 3135 return writeChunkAndReturn(destination, endSegmentSVG); 3136 } 3137 3138 case MATHML_MODE: 3139 { 3140 return writeChunkAndReturn(destination, endSegmentMathML); 3141 } 3142 3143 case HTML_TABLE_MODE: 3144 { 3145 return writeChunkAndReturn(destination, endSegmentTable); 3146 } 3147 3148 case HTML_TABLE_BODY_MODE: 3149 { 3150 return writeChunkAndReturn(destination, endSegmentTableBody); 3151 } 3152 3153 case HTML_TABLE_ROW_MODE: 3154 { 3155 return writeChunkAndReturn(destination, endSegmentTableRow); 3156 } 3157 3158 case HTML_COLGROUP_MODE: 3159 { 3160 return writeChunkAndReturn(destination, endSegmentColGroup); 3161 } 3162 3163 default: 3164 { 3165 throw new Error('Unknown insertion mode. This is a bug in React.'); 3166 } 3167 } 3168 } // Instruction Set 3169 // The following code is the source scripts that we then minify and inline below, 3170 // with renamed function names that we hope don't collide: 3171 // const COMMENT_NODE = 8; 3172 // const SUSPENSE_START_DATA = '$'; 3173 // const SUSPENSE_END_DATA = '/$'; 3174 // const SUSPENSE_PENDING_START_DATA = '$?'; 3175 // const SUSPENSE_FALLBACK_START_DATA = '$!'; 3176 // 3177 // function clientRenderBoundary(suspenseBoundaryID, errorDigest, errorMsg, errorComponentStack) { 3178 // // Find the fallback's first element. 3179 // const suspenseIdNode = document.getElementById(suspenseBoundaryID); 3180 // if (!suspenseIdNode) { 3181 // // The user must have already navigated away from this tree. 3182 // // E.g. because the parent was hydrated. 3183 // return; 3184 // } 3185 // // Find the boundary around the fallback. This is always the previous node. 3186 // const suspenseNode = suspenseIdNode.previousSibling; 3187 // // Tag it to be client rendered. 3188 // suspenseNode.data = SUSPENSE_FALLBACK_START_DATA; 3189 // // assign error metadata to first sibling 3190 // let dataset = suspenseIdNode.dataset; 3191 // if (errorDigest) dataset.dgst = errorDigest; 3192 // if (errorMsg) dataset.msg = errorMsg; 3193 // if (errorComponentStack) dataset.stck = errorComponentStack; 3194 // // Tell React to retry it if the parent already hydrated. 3195 // if (suspenseNode._reactRetry) { 3196 // suspenseNode._reactRetry(); 3197 // } 3198 // } 3199 // 3200 // function completeBoundary(suspenseBoundaryID, contentID) { 3201 // // Find the fallback's first element. 3202 // const suspenseIdNode = document.getElementById(suspenseBoundaryID); 3203 // const contentNode = document.getElementById(contentID); 3204 // // We'll detach the content node so that regardless of what happens next we don't leave in the tree. 3205 // // This might also help by not causing recalcing each time we move a child from here to the target. 3206 // contentNode.parentNode.removeChild(contentNode); 3207 // if (!suspenseIdNode) { 3208 // // The user must have already navigated away from this tree. 3209 // // E.g. because the parent was hydrated. That's fine there's nothing to do 3210 // // but we have to make sure that we already deleted the container node. 3211 // return; 3212 // } 3213 // // Find the boundary around the fallback. This is always the previous node. 3214 // const suspenseNode = suspenseIdNode.previousSibling; 3215 // 3216 // // Clear all the existing children. This is complicated because 3217 // // there can be embedded Suspense boundaries in the fallback. 3218 // // This is similar to clearSuspenseBoundary in ReactDOMHostConfig. 3219 // // TODO: We could avoid this if we never emitted suspense boundaries in fallback trees. 3220 // // They never hydrate anyway. However, currently we support incrementally loading the fallback. 3221 // const parentInstance = suspenseNode.parentNode; 3222 // let node = suspenseNode.nextSibling; 3223 // let depth = 0; 3224 // do { 3225 // if (node && node.nodeType === COMMENT_NODE) { 3226 // const data = node.data; 3227 // if (data === SUSPENSE_END_DATA) { 3228 // if (depth === 0) { 3229 // break; 3230 // } else { 3231 // depth--; 3232 // } 3233 // } else if ( 3234 // data === SUSPENSE_START_DATA || 3235 // data === SUSPENSE_PENDING_START_DATA || 3236 // data === SUSPENSE_FALLBACK_START_DATA 3237 // ) { 3238 // depth++; 3239 // } 3240 // } 3241 // 3242 // const nextNode = node.nextSibling; 3243 // parentInstance.removeChild(node); 3244 // node = nextNode; 3245 // } while (node); 3246 // 3247 // const endOfBoundary = node; 3248 // 3249 // // Insert all the children from the contentNode between the start and end of suspense boundary. 3250 // while (contentNode.firstChild) { 3251 // parentInstance.insertBefore(contentNode.firstChild, endOfBoundary); 3252 // } 3253 // suspenseNode.data = SUSPENSE_START_DATA; 3254 // if (suspenseNode._reactRetry) { 3255 // suspenseNode._reactRetry(); 3256 // } 3257 // } 3258 // 3259 // function completeSegment(containerID, placeholderID) { 3260 // const segmentContainer = document.getElementById(containerID); 3261 // const placeholderNode = document.getElementById(placeholderID); 3262 // // We always expect both nodes to exist here because, while we might 3263 // // have navigated away from the main tree, we still expect the detached 3264 // // tree to exist. 3265 // segmentContainer.parentNode.removeChild(segmentContainer); 3266 // while (segmentContainer.firstChild) { 3267 // placeholderNode.parentNode.insertBefore( 3268 // segmentContainer.firstChild, 3269 // placeholderNode, 3270 // ); 3271 // } 3272 // placeholderNode.parentNode.removeChild(placeholderNode); 3273 // } 3274 3275 var completeSegmentFunction = 'function $RS(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)}'; 3276 var completeBoundaryFunction = 'function $RC(a,b){a=document.getElementById(a);b=document.getElementById(b);b.parentNode.removeChild(b);if(a){a=a.previousSibling;var f=a.parentNode,c=a.nextSibling,e=0;do{if(c&&8===c.nodeType){var d=c.data;if("/$"===d)if(0===e)break;else e--;else"$"!==d&&"$?"!==d&&"$!"!==d||e++}d=c.nextSibling;f.removeChild(c);c=d}while(c);for(;b.firstChild;)f.insertBefore(b.firstChild,c);a.data="$";a._reactRetry&&a._reactRetry()}}'; 3277 var clientRenderFunction = 'function $RX(b,c,d,e){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),b._reactRetry&&b._reactRetry())}'; 3278 var completeSegmentScript1Full = stringToPrecomputedChunk(completeSegmentFunction + ';$RS("'); 3279 var completeSegmentScript1Partial = stringToPrecomputedChunk('$RS("'); 3280 var completeSegmentScript2 = stringToPrecomputedChunk('","'); 3281 var completeSegmentScript3 = stringToPrecomputedChunk('")</script>'); 3282 function writeCompletedSegmentInstruction(destination, responseState, contentSegmentID) { 3283 writeChunk(destination, responseState.startInlineScript); 3284 3285 if (!responseState.sentCompleteSegmentFunction) { 3286 // The first time we write this, we'll need to include the full implementation. 3287 responseState.sentCompleteSegmentFunction = true; 3288 writeChunk(destination, completeSegmentScript1Full); 3289 } else { 3290 // Future calls can just reuse the same function. 3291 writeChunk(destination, completeSegmentScript1Partial); 3292 } 3293 3294 writeChunk(destination, responseState.segmentPrefix); 3295 var formattedID = stringToChunk(contentSegmentID.toString(16)); 3296 writeChunk(destination, formattedID); 3297 writeChunk(destination, completeSegmentScript2); 3298 writeChunk(destination, responseState.placeholderPrefix); 3299 writeChunk(destination, formattedID); 3300 return writeChunkAndReturn(destination, completeSegmentScript3); 3301 } 3302 var completeBoundaryScript1Full = stringToPrecomputedChunk(completeBoundaryFunction + ';$RC("'); 3303 var completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'); 3304 var completeBoundaryScript2 = stringToPrecomputedChunk('","'); 3305 var completeBoundaryScript3 = stringToPrecomputedChunk('")</script>'); 3306 function writeCompletedBoundaryInstruction(destination, responseState, boundaryID, contentSegmentID) { 3307 writeChunk(destination, responseState.startInlineScript); 3308 3309 if (!responseState.sentCompleteBoundaryFunction) { 3310 // The first time we write this, we'll need to include the full implementation. 3311 responseState.sentCompleteBoundaryFunction = true; 3312 writeChunk(destination, completeBoundaryScript1Full); 3313 } else { 3314 // Future calls can just reuse the same function. 3315 writeChunk(destination, completeBoundaryScript1Partial); 3316 } 3317 3318 if (boundaryID === null) { 3319 throw new Error('An ID must have been assigned before we can complete the boundary.'); 3320 } 3321 3322 var formattedContentID = stringToChunk(contentSegmentID.toString(16)); 3323 writeChunk(destination, boundaryID); 3324 writeChunk(destination, completeBoundaryScript2); 3325 writeChunk(destination, responseState.segmentPrefix); 3326 writeChunk(destination, formattedContentID); 3327 return writeChunkAndReturn(destination, completeBoundaryScript3); 3328 } 3329 var clientRenderScript1Full = stringToPrecomputedChunk(clientRenderFunction + ';$RX("'); 3330 var clientRenderScript1Partial = stringToPrecomputedChunk('$RX("'); 3331 var clientRenderScript1A = stringToPrecomputedChunk('"'); 3332 var clientRenderScript2 = stringToPrecomputedChunk(')</script>'); 3333 var clientRenderErrorScriptArgInterstitial = stringToPrecomputedChunk(','); 3334 function writeClientRenderBoundaryInstruction(destination, responseState, boundaryID, errorDigest, errorMessage, errorComponentStack) { 3335 writeChunk(destination, responseState.startInlineScript); 3336 3337 if (!responseState.sentClientRenderFunction) { 3338 // The first time we write this, we'll need to include the full implementation. 3339 responseState.sentClientRenderFunction = true; 3340 writeChunk(destination, clientRenderScript1Full); 3341 } else { 3342 // Future calls can just reuse the same function. 3343 writeChunk(destination, clientRenderScript1Partial); 3344 } 3345 3346 if (boundaryID === null) { 3347 throw new Error('An ID must have been assigned before we can complete the boundary.'); 3348 } 3349 3350 writeChunk(destination, boundaryID); 3351 writeChunk(destination, clientRenderScript1A); 3352 3353 if (errorDigest || errorMessage || errorComponentStack) { 3354 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3355 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorDigest || ''))); 3356 } 3357 3358 if (errorMessage || errorComponentStack) { 3359 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3360 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorMessage || ''))); 3361 } 3362 3363 if (errorComponentStack) { 3364 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3365 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorComponentStack))); 3366 } 3367 3368 return writeChunkAndReturn(destination, clientRenderScript2); 3369 } 3370 var regexForJSStringsInScripts = /[<\u2028\u2029]/g; 3371 3372 function escapeJSStringsForInstructionScripts(input) { 3373 var escaped = JSON.stringify(input); 3374 return escaped.replace(regexForJSStringsInScripts, function (match) { 3375 switch (match) { 3376 // santizing breaking out of strings and script tags 3377 case '<': 3378 return "\\u003c"; 3379 3380 case "\u2028": 3381 return "\\u2028"; 3382 3383 case "\u2029": 3384 return "\\u2029"; 3385 3386 default: 3387 { 3388 // eslint-disable-next-line react-internal/prod-error-codes 3389 throw new Error('escapeJSStringsForInstructionScripts encountered a match it does not know how to replace. this means the match regex and the replacement characters are no longer in sync. This is a bug in React'); 3390 } 3391 } 3392 }); 3393 } 3394 3395 var assign = Object.assign; 3396 3397 // ATTENTION 3398 // When adding new symbols to this file, 3399 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' 3400 // The Symbol used to tag the ReactElement-like types. 3401 var REACT_ELEMENT_TYPE = Symbol.for('react.element'); 3402 var REACT_PORTAL_TYPE = Symbol.for('react.portal'); 3403 var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); 3404 var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode'); 3405 var REACT_PROFILER_TYPE = Symbol.for('react.profiler'); 3406 var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); 3407 var REACT_CONTEXT_TYPE = Symbol.for('react.context'); 3408 var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); 3409 var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense'); 3410 var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list'); 3411 var REACT_MEMO_TYPE = Symbol.for('react.memo'); 3412 var REACT_LAZY_TYPE = Symbol.for('react.lazy'); 3413 var REACT_SCOPE_TYPE = Symbol.for('react.scope'); 3414 var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode'); 3415 var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden'); 3416 var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value'); 3417 var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; 3418 var FAUX_ITERATOR_SYMBOL = '@@iterator'; 3419 function getIteratorFn(maybeIterable) { 3420 if (maybeIterable === null || typeof maybeIterable !== 'object') { 3421 return null; 3422 } 3423 3424 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; 3425 3426 if (typeof maybeIterator === 'function') { 3427 return maybeIterator; 3428 } 3429 3430 return null; 3431 } 3432 3433 function getWrappedName(outerType, innerType, wrapperName) { 3434 var displayName = outerType.displayName; 3435 3436 if (displayName) { 3437 return displayName; 3438 } 3439 3440 var functionName = innerType.displayName || innerType.name || ''; 3441 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName; 3442 } // Keep in sync with react-reconciler/getComponentNameFromFiber 3443 3444 3445 function getContextName(type) { 3446 return type.displayName || 'Context'; 3447 } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. 3448 3449 3450 function getComponentNameFromType(type) { 3451 if (type == null) { 3452 // Host root, text node or just invalid type. 3453 return null; 3454 } 3455 3456 { 3457 if (typeof type.tag === 'number') { 3458 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.'); 3459 } 3460 } 3461 3462 if (typeof type === 'function') { 3463 return type.displayName || type.name || null; 3464 } 3465 3466 if (typeof type === 'string') { 3467 return type; 3468 } 3469 3470 switch (type) { 3471 case REACT_FRAGMENT_TYPE: 3472 return 'Fragment'; 3473 3474 case REACT_PORTAL_TYPE: 3475 return 'Portal'; 3476 3477 case REACT_PROFILER_TYPE: 3478 return 'Profiler'; 3479 3480 case REACT_STRICT_MODE_TYPE: 3481 return 'StrictMode'; 3482 3483 case REACT_SUSPENSE_TYPE: 3484 return 'Suspense'; 3485 3486 case REACT_SUSPENSE_LIST_TYPE: 3487 return 'SuspenseList'; 3488 3489 } 3490 3491 if (typeof type === 'object') { 3492 switch (type.$$typeof) { 3493 case REACT_CONTEXT_TYPE: 3494 var context = type; 3495 return getContextName(context) + '.Consumer'; 3496 3497 case REACT_PROVIDER_TYPE: 3498 var provider = type; 3499 return getContextName(provider._context) + '.Provider'; 3500 3501 case REACT_FORWARD_REF_TYPE: 3502 return getWrappedName(type, type.render, 'ForwardRef'); 3503 3504 case REACT_MEMO_TYPE: 3505 var outerName = type.displayName || null; 3506 3507 if (outerName !== null) { 3508 return outerName; 3509 } 3510 3511 return getComponentNameFromType(type.type) || 'Memo'; 3512 3513 case REACT_LAZY_TYPE: 3514 { 3515 var lazyComponent = type; 3516 var payload = lazyComponent._payload; 3517 var init = lazyComponent._init; 3518 3519 try { 3520 return getComponentNameFromType(init(payload)); 3521 } catch (x) { 3522 return null; 3523 } 3524 } 3525 3526 // eslint-disable-next-line no-fallthrough 3527 } 3528 } 3529 3530 return null; 3531 } 3532 3533 // Helpers to patch console.logs to avoid logging during side-effect free 3534 // replaying on render function. This currently only patches the object 3535 // lazily which won't cover if the log function was extracted eagerly. 3536 // We could also eagerly patch the method. 3537 var disabledDepth = 0; 3538 var prevLog; 3539 var prevInfo; 3540 var prevWarn; 3541 var prevError; 3542 var prevGroup; 3543 var prevGroupCollapsed; 3544 var prevGroupEnd; 3545 3546 function disabledLog() {} 3547 3548 disabledLog.__reactDisabledLog = true; 3549 function disableLogs() { 3550 { 3551 if (disabledDepth === 0) { 3552 /* eslint-disable react-internal/no-production-logging */ 3553 prevLog = console.log; 3554 prevInfo = console.info; 3555 prevWarn = console.warn; 3556 prevError = console.error; 3557 prevGroup = console.group; 3558 prevGroupCollapsed = console.groupCollapsed; 3559 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 3560 3561 var props = { 3562 configurable: true, 3563 enumerable: true, 3564 value: disabledLog, 3565 writable: true 3566 }; // $FlowFixMe Flow thinks console is immutable. 3567 3568 Object.defineProperties(console, { 3569 info: props, 3570 log: props, 3571 warn: props, 3572 error: props, 3573 group: props, 3574 groupCollapsed: props, 3575 groupEnd: props 3576 }); 3577 /* eslint-enable react-internal/no-production-logging */ 3578 } 3579 3580 disabledDepth++; 3581 } 3582 } 3583 function reenableLogs() { 3584 { 3585 disabledDepth--; 3586 3587 if (disabledDepth === 0) { 3588 /* eslint-disable react-internal/no-production-logging */ 3589 var props = { 3590 configurable: true, 3591 enumerable: true, 3592 writable: true 3593 }; // $FlowFixMe Flow thinks console is immutable. 3594 3595 Object.defineProperties(console, { 3596 log: assign({}, props, { 3597 value: prevLog 3598 }), 3599 info: assign({}, props, { 3600 value: prevInfo 3601 }), 3602 warn: assign({}, props, { 3603 value: prevWarn 3604 }), 3605 error: assign({}, props, { 3606 value: prevError 3607 }), 3608 group: assign({}, props, { 3609 value: prevGroup 3610 }), 3611 groupCollapsed: assign({}, props, { 3612 value: prevGroupCollapsed 3613 }), 3614 groupEnd: assign({}, props, { 3615 value: prevGroupEnd 3616 }) 3617 }); 3618 /* eslint-enable react-internal/no-production-logging */ 3619 } 3620 3621 if (disabledDepth < 0) { 3622 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.'); 3623 } 3624 } 3625 } 3626 3627 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 3628 var prefix; 3629 function describeBuiltInComponentFrame(name, source, ownerFn) { 3630 { 3631 if (prefix === undefined) { 3632 // Extract the VM specific prefix used by each line. 3633 try { 3634 throw Error(); 3635 } catch (x) { 3636 var match = x.stack.trim().match(/\n( *(at )?)/); 3637 prefix = match && match[1] || ''; 3638 } 3639 } // We use the prefix to ensure our stacks line up with native stack frames. 3640 3641 3642 return '\n' + prefix + name; 3643 } 3644 } 3645 var reentry = false; 3646 var componentFrameCache; 3647 3648 { 3649 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; 3650 componentFrameCache = new PossiblyWeakMap(); 3651 } 3652 3653 function describeNativeComponentFrame(fn, construct) { 3654 // If something asked for a stack inside a fake render, it should get ignored. 3655 if ( !fn || reentry) { 3656 return ''; 3657 } 3658 3659 { 3660 var frame = componentFrameCache.get(fn); 3661 3662 if (frame !== undefined) { 3663 return frame; 3664 } 3665 } 3666 3667 var control; 3668 reentry = true; 3669 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined. 3670 3671 Error.prepareStackTrace = undefined; 3672 var previousDispatcher; 3673 3674 { 3675 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function 3676 // for warnings. 3677 3678 ReactCurrentDispatcher.current = null; 3679 disableLogs(); 3680 } 3681 3682 try { 3683 // This should throw. 3684 if (construct) { 3685 // Something should be setting the props in the constructor. 3686 var Fake = function () { 3687 throw Error(); 3688 }; // $FlowFixMe 3689 3690 3691 Object.defineProperty(Fake.prototype, 'props', { 3692 set: function () { 3693 // We use a throwing setter instead of frozen or non-writable props 3694 // because that won't throw in a non-strict mode function. 3695 throw Error(); 3696 } 3697 }); 3698 3699 if (typeof Reflect === 'object' && Reflect.construct) { 3700 // We construct a different control for this case to include any extra 3701 // frames added by the construct call. 3702 try { 3703 Reflect.construct(Fake, []); 3704 } catch (x) { 3705 control = x; 3706 } 3707 3708 Reflect.construct(fn, [], Fake); 3709 } else { 3710 try { 3711 Fake.call(); 3712 } catch (x) { 3713 control = x; 3714 } 3715 3716 fn.call(Fake.prototype); 3717 } 3718 } else { 3719 try { 3720 throw Error(); 3721 } catch (x) { 3722 control = x; 3723 } 3724 3725 fn(); 3726 } 3727 } catch (sample) { 3728 // This is inlined manually because closure doesn't do it for us. 3729 if (sample && control && typeof sample.stack === 'string') { 3730 // This extracts the first frame from the sample that isn't also in the control. 3731 // Skipping one frame that we assume is the frame that calls the two. 3732 var sampleLines = sample.stack.split('\n'); 3733 var controlLines = control.stack.split('\n'); 3734 var s = sampleLines.length - 1; 3735 var c = controlLines.length - 1; 3736 3737 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) { 3738 // We expect at least one stack frame to be shared. 3739 // Typically this will be the root most one. However, stack frames may be 3740 // cut off due to maximum stack limits. In this case, one maybe cut off 3741 // earlier than the other. We assume that the sample is longer or the same 3742 // and there for cut off earlier. So we should find the root most frame in 3743 // the sample somewhere in the control. 3744 c--; 3745 } 3746 3747 for (; s >= 1 && c >= 0; s--, c--) { 3748 // Next we find the first one that isn't the same which should be the 3749 // frame that called our sample function and the control. 3750 if (sampleLines[s] !== controlLines[c]) { 3751 // In V8, the first line is describing the message but other VMs don't. 3752 // If we're about to return the first line, and the control is also on the same 3753 // line, that's a pretty good indicator that our sample threw at same line as 3754 // the control. I.e. before we entered the sample frame. So we ignore this result. 3755 // This can happen if you passed a class to function component, or non-function. 3756 if (s !== 1 || c !== 1) { 3757 do { 3758 s--; 3759 c--; // We may still have similar intermediate frames from the construct call. 3760 // The next one that isn't the same should be our match though. 3761 3762 if (c < 0 || sampleLines[s] !== controlLines[c]) { 3763 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. 3764 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>" 3765 // but we have a user-provided "displayName" 3766 // splice it in to make the stack more readable. 3767 3768 3769 if (fn.displayName && _frame.includes('<anonymous>')) { 3770 _frame = _frame.replace('<anonymous>', fn.displayName); 3771 } 3772 3773 { 3774 if (typeof fn === 'function') { 3775 componentFrameCache.set(fn, _frame); 3776 } 3777 } // Return the line we found. 3778 3779 3780 return _frame; 3781 } 3782 } while (s >= 1 && c >= 0); 3783 } 3784 3785 break; 3786 } 3787 } 3788 } 3789 } finally { 3790 reentry = false; 3791 3792 { 3793 ReactCurrentDispatcher.current = previousDispatcher; 3794 reenableLogs(); 3795 } 3796 3797 Error.prepareStackTrace = previousPrepareStackTrace; 3798 } // Fallback to just using the name if we couldn't make it throw. 3799 3800 3801 var name = fn ? fn.displayName || fn.name : ''; 3802 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; 3803 3804 { 3805 if (typeof fn === 'function') { 3806 componentFrameCache.set(fn, syntheticFrame); 3807 } 3808 } 3809 3810 return syntheticFrame; 3811 } 3812 3813 function describeClassComponentFrame(ctor, source, ownerFn) { 3814 { 3815 return describeNativeComponentFrame(ctor, true); 3816 } 3817 } 3818 function describeFunctionComponentFrame(fn, source, ownerFn) { 3819 { 3820 return describeNativeComponentFrame(fn, false); 3821 } 3822 } 3823 3824 function shouldConstruct(Component) { 3825 var prototype = Component.prototype; 3826 return !!(prototype && prototype.isReactComponent); 3827 } 3828 3829 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { 3830 3831 if (type == null) { 3832 return ''; 3833 } 3834 3835 if (typeof type === 'function') { 3836 { 3837 return describeNativeComponentFrame(type, shouldConstruct(type)); 3838 } 3839 } 3840 3841 if (typeof type === 'string') { 3842 return describeBuiltInComponentFrame(type); 3843 } 3844 3845 switch (type) { 3846 case REACT_SUSPENSE_TYPE: 3847 return describeBuiltInComponentFrame('Suspense'); 3848 3849 case REACT_SUSPENSE_LIST_TYPE: 3850 return describeBuiltInComponentFrame('SuspenseList'); 3851 } 3852 3853 if (typeof type === 'object') { 3854 switch (type.$$typeof) { 3855 case REACT_FORWARD_REF_TYPE: 3856 return describeFunctionComponentFrame(type.render); 3857 3858 case REACT_MEMO_TYPE: 3859 // Memo may contain any component type so we recursively resolve it. 3860 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); 3861 3862 case REACT_LAZY_TYPE: 3863 { 3864 var lazyComponent = type; 3865 var payload = lazyComponent._payload; 3866 var init = lazyComponent._init; 3867 3868 try { 3869 // Lazy may contain any component type so we recursively resolve it. 3870 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); 3871 } catch (x) {} 3872 } 3873 } 3874 } 3875 3876 return ''; 3877 } 3878 3879 var loggedTypeFailures = {}; 3880 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 3881 3882 function setCurrentlyValidatingElement(element) { 3883 { 3884 if (element) { 3885 var owner = element._owner; 3886 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); 3887 ReactDebugCurrentFrame.setExtraStackFrame(stack); 3888 } else { 3889 ReactDebugCurrentFrame.setExtraStackFrame(null); 3890 } 3891 } 3892 } 3893 3894 function checkPropTypes(typeSpecs, values, location, componentName, element) { 3895 { 3896 // $FlowFixMe This is okay but Flow doesn't know it. 3897 var has = Function.call.bind(hasOwnProperty); 3898 3899 for (var typeSpecName in typeSpecs) { 3900 if (has(typeSpecs, typeSpecName)) { 3901 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to 3902 // fail the render phase where it didn't fail before. So we log it. 3903 // After these have been cleaned up, we'll let them throw. 3904 3905 try { 3906 // This is intentionally an invariant that gets caught. It's the same 3907 // behavior as without this statement except with a better message. 3908 if (typeof typeSpecs[typeSpecName] !== 'function') { 3909 // eslint-disable-next-line react-internal/prod-error-codes 3910 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`.'); 3911 err.name = 'Invariant Violation'; 3912 throw err; 3913 } 3914 3915 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'); 3916 } catch (ex) { 3917 error$1 = ex; 3918 } 3919 3920 if (error$1 && !(error$1 instanceof Error)) { 3921 setCurrentlyValidatingElement(element); 3922 3923 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); 3924 3925 setCurrentlyValidatingElement(null); 3926 } 3927 3928 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { 3929 // Only monitor this failure once because there tends to be a lot of the 3930 // same error. 3931 loggedTypeFailures[error$1.message] = true; 3932 setCurrentlyValidatingElement(element); 3933 3934 error('Failed %s type: %s', location, error$1.message); 3935 3936 setCurrentlyValidatingElement(null); 3937 } 3938 } 3939 } 3940 } 3941 } 3942 3943 var warnedAboutMissingGetChildContext; 3944 3945 { 3946 warnedAboutMissingGetChildContext = {}; 3947 } 3948 3949 var emptyContextObject = {}; 3950 3951 { 3952 Object.freeze(emptyContextObject); 3953 } 3954 3955 function getMaskedContext(type, unmaskedContext) { 3956 { 3957 var contextTypes = type.contextTypes; 3958 3959 if (!contextTypes) { 3960 return emptyContextObject; 3961 } 3962 3963 var context = {}; 3964 3965 for (var key in contextTypes) { 3966 context[key] = unmaskedContext[key]; 3967 } 3968 3969 { 3970 var name = getComponentNameFromType(type) || 'Unknown'; 3971 checkPropTypes(contextTypes, context, 'context', name); 3972 } 3973 3974 return context; 3975 } 3976 } 3977 function processChildContext(instance, type, parentContext, childContextTypes) { 3978 { 3979 // TODO (bvaughn) Replace this behavior with an invariant() in the future. 3980 // It has only been added in Fiber to match the (unintentional) behavior in Stack. 3981 if (typeof instance.getChildContext !== 'function') { 3982 { 3983 var componentName = getComponentNameFromType(type) || 'Unknown'; 3984 3985 if (!warnedAboutMissingGetChildContext[componentName]) { 3986 warnedAboutMissingGetChildContext[componentName] = true; 3987 3988 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); 3989 } 3990 } 3991 3992 return parentContext; 3993 } 3994 3995 var childContext = instance.getChildContext(); 3996 3997 for (var contextKey in childContext) { 3998 if (!(contextKey in childContextTypes)) { 3999 throw new Error((getComponentNameFromType(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes."); 4000 } 4001 } 4002 4003 { 4004 var name = getComponentNameFromType(type) || 'Unknown'; 4005 checkPropTypes(childContextTypes, childContext, 'child context', name); 4006 } 4007 4008 return assign({}, parentContext, childContext); 4009 } 4010 } 4011 4012 var rendererSigil; 4013 4014 { 4015 // Use this to detect multiple renderers using the same context 4016 rendererSigil = {}; 4017 } // Used to store the parent path of all context overrides in a shared linked list. 4018 // Forming a reverse tree. 4019 4020 4021 var rootContextSnapshot = null; // We assume that this runtime owns the "current" field on all ReactContext instances. 4022 // This global (actually thread local) state represents what state all those "current", 4023 // fields are currently in. 4024 4025 var currentActiveSnapshot = null; 4026 4027 function popNode(prev) { 4028 { 4029 prev.context._currentValue = prev.parentValue; 4030 } 4031 } 4032 4033 function pushNode(next) { 4034 { 4035 next.context._currentValue = next.value; 4036 } 4037 } 4038 4039 function popToNearestCommonAncestor(prev, next) { 4040 if (prev === next) ; else { 4041 popNode(prev); 4042 var parentPrev = prev.parent; 4043 var parentNext = next.parent; 4044 4045 if (parentPrev === null) { 4046 if (parentNext !== null) { 4047 throw new Error('The stacks must reach the root at the same time. This is a bug in React.'); 4048 } 4049 } else { 4050 if (parentNext === null) { 4051 throw new Error('The stacks must reach the root at the same time. This is a bug in React.'); 4052 } 4053 4054 popToNearestCommonAncestor(parentPrev, parentNext); 4055 } // On the way back, we push the new ones that weren't common. 4056 4057 4058 pushNode(next); 4059 } 4060 } 4061 4062 function popAllPrevious(prev) { 4063 popNode(prev); 4064 var parentPrev = prev.parent; 4065 4066 if (parentPrev !== null) { 4067 popAllPrevious(parentPrev); 4068 } 4069 } 4070 4071 function pushAllNext(next) { 4072 var parentNext = next.parent; 4073 4074 if (parentNext !== null) { 4075 pushAllNext(parentNext); 4076 } 4077 4078 pushNode(next); 4079 } 4080 4081 function popPreviousToCommonLevel(prev, next) { 4082 popNode(prev); 4083 var parentPrev = prev.parent; 4084 4085 if (parentPrev === null) { 4086 throw new Error('The depth must equal at least at zero before reaching the root. This is a bug in React.'); 4087 } 4088 4089 if (parentPrev.depth === next.depth) { 4090 // We found the same level. Now we just need to find a shared ancestor. 4091 popToNearestCommonAncestor(parentPrev, next); 4092 } else { 4093 // We must still be deeper. 4094 popPreviousToCommonLevel(parentPrev, next); 4095 } 4096 } 4097 4098 function popNextToCommonLevel(prev, next) { 4099 var parentNext = next.parent; 4100 4101 if (parentNext === null) { 4102 throw new Error('The depth must equal at least at zero before reaching the root. This is a bug in React.'); 4103 } 4104 4105 if (prev.depth === parentNext.depth) { 4106 // We found the same level. Now we just need to find a shared ancestor. 4107 popToNearestCommonAncestor(prev, parentNext); 4108 } else { 4109 // We must still be deeper. 4110 popNextToCommonLevel(prev, parentNext); 4111 } 4112 4113 pushNode(next); 4114 } // Perform context switching to the new snapshot. 4115 // To make it cheap to read many contexts, while not suspending, we make the switch eagerly by 4116 // updating all the context's current values. That way reads, always just read the current value. 4117 // At the cost of updating contexts even if they're never read by this subtree. 4118 4119 4120 function switchContext(newSnapshot) { 4121 // The basic algorithm we need to do is to pop back any contexts that are no longer on the stack. 4122 // We also need to update any new contexts that are now on the stack with the deepest value. 4123 // The easiest way to update new contexts is to just reapply them in reverse order from the 4124 // perspective of the backpointers. To avoid allocating a lot when switching, we use the stack 4125 // for that. Therefore this algorithm is recursive. 4126 // 1) First we pop which ever snapshot tree was deepest. Popping old contexts as we go. 4127 // 2) Then we find the nearest common ancestor from there. Popping old contexts as we go. 4128 // 3) Then we reapply new contexts on the way back up the stack. 4129 var prev = currentActiveSnapshot; 4130 var next = newSnapshot; 4131 4132 if (prev !== next) { 4133 if (prev === null) { 4134 // $FlowFixMe: This has to be non-null since it's not equal to prev. 4135 pushAllNext(next); 4136 } else if (next === null) { 4137 popAllPrevious(prev); 4138 } else if (prev.depth === next.depth) { 4139 popToNearestCommonAncestor(prev, next); 4140 } else if (prev.depth > next.depth) { 4141 popPreviousToCommonLevel(prev, next); 4142 } else { 4143 popNextToCommonLevel(prev, next); 4144 } 4145 4146 currentActiveSnapshot = next; 4147 } 4148 } 4149 function pushProvider(context, nextValue) { 4150 var prevValue; 4151 4152 { 4153 prevValue = context._currentValue; 4154 context._currentValue = nextValue; 4155 4156 { 4157 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) { 4158 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 4159 } 4160 4161 context._currentRenderer = rendererSigil; 4162 } 4163 } 4164 4165 var prevNode = currentActiveSnapshot; 4166 var newNode = { 4167 parent: prevNode, 4168 depth: prevNode === null ? 0 : prevNode.depth + 1, 4169 context: context, 4170 parentValue: prevValue, 4171 value: nextValue 4172 }; 4173 currentActiveSnapshot = newNode; 4174 return newNode; 4175 } 4176 function popProvider(context) { 4177 var prevSnapshot = currentActiveSnapshot; 4178 4179 if (prevSnapshot === null) { 4180 throw new Error('Tried to pop a Context at the root of the app. This is a bug in React.'); 4181 } 4182 4183 { 4184 if (prevSnapshot.context !== context) { 4185 error('The parent context is not the expected context. This is probably a bug in React.'); 4186 } 4187 } 4188 4189 { 4190 var value = prevSnapshot.parentValue; 4191 4192 if (value === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { 4193 prevSnapshot.context._currentValue = prevSnapshot.context._defaultValue; 4194 } else { 4195 prevSnapshot.context._currentValue = value; 4196 } 4197 4198 { 4199 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) { 4200 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 4201 } 4202 4203 context._currentRenderer = rendererSigil; 4204 } 4205 } 4206 4207 return currentActiveSnapshot = prevSnapshot.parent; 4208 } 4209 function getActiveContext() { 4210 return currentActiveSnapshot; 4211 } 4212 function readContext(context) { 4213 var value = context._currentValue ; 4214 return value; 4215 } 4216 4217 /** 4218 * `ReactInstanceMap` maintains a mapping from a public facing stateful 4219 * instance (key) and the internal representation (value). This allows public 4220 * methods to accept the user facing instance as an argument and map them back 4221 * to internal methods. 4222 * 4223 * Note that this module is currently shared and assumed to be stateless. 4224 * If this becomes an actual Map, that will break. 4225 */ 4226 function get(key) { 4227 return key._reactInternals; 4228 } 4229 function set(key, value) { 4230 key._reactInternals = value; 4231 } 4232 4233 var didWarnAboutNoopUpdateForComponent = {}; 4234 var didWarnAboutDeprecatedWillMount = {}; 4235 var didWarnAboutUninitializedState; 4236 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; 4237 var didWarnAboutLegacyLifecyclesAndDerivedState; 4238 var didWarnAboutUndefinedDerivedState; 4239 var warnOnUndefinedDerivedState; 4240 var warnOnInvalidCallback; 4241 var didWarnAboutDirectlyAssigningPropsToState; 4242 var didWarnAboutContextTypeAndContextTypes; 4243 var didWarnAboutInvalidateContextType; 4244 4245 { 4246 didWarnAboutUninitializedState = new Set(); 4247 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); 4248 didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); 4249 didWarnAboutDirectlyAssigningPropsToState = new Set(); 4250 didWarnAboutUndefinedDerivedState = new Set(); 4251 didWarnAboutContextTypeAndContextTypes = new Set(); 4252 didWarnAboutInvalidateContextType = new Set(); 4253 var didWarnOnInvalidCallback = new Set(); 4254 4255 warnOnInvalidCallback = function (callback, callerName) { 4256 if (callback === null || typeof callback === 'function') { 4257 return; 4258 } 4259 4260 var key = callerName + '_' + callback; 4261 4262 if (!didWarnOnInvalidCallback.has(key)) { 4263 didWarnOnInvalidCallback.add(key); 4264 4265 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 4266 } 4267 }; 4268 4269 warnOnUndefinedDerivedState = function (type, partialState) { 4270 if (partialState === undefined) { 4271 var componentName = getComponentNameFromType(type) || 'Component'; 4272 4273 if (!didWarnAboutUndefinedDerivedState.has(componentName)) { 4274 didWarnAboutUndefinedDerivedState.add(componentName); 4275 4276 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName); 4277 } 4278 } 4279 }; 4280 } 4281 4282 function warnNoop(publicInstance, callerName) { 4283 { 4284 var _constructor = publicInstance.constructor; 4285 var componentName = _constructor && getComponentNameFromType(_constructor) || 'ReactClass'; 4286 var warningKey = componentName + '.' + callerName; 4287 4288 if (didWarnAboutNoopUpdateForComponent[warningKey]) { 4289 return; 4290 } 4291 4292 error('%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op.\n\nPlease check the code for the %s component.', callerName, callerName, componentName); 4293 4294 didWarnAboutNoopUpdateForComponent[warningKey] = true; 4295 } 4296 } 4297 4298 var classComponentUpdater = { 4299 isMounted: function (inst) { 4300 return false; 4301 }, 4302 enqueueSetState: function (inst, payload, callback) { 4303 var internals = get(inst); 4304 4305 if (internals.queue === null) { 4306 warnNoop(inst, 'setState'); 4307 } else { 4308 internals.queue.push(payload); 4309 4310 { 4311 if (callback !== undefined && callback !== null) { 4312 warnOnInvalidCallback(callback, 'setState'); 4313 } 4314 } 4315 } 4316 }, 4317 enqueueReplaceState: function (inst, payload, callback) { 4318 var internals = get(inst); 4319 internals.replace = true; 4320 internals.queue = [payload]; 4321 4322 { 4323 if (callback !== undefined && callback !== null) { 4324 warnOnInvalidCallback(callback, 'setState'); 4325 } 4326 } 4327 }, 4328 enqueueForceUpdate: function (inst, callback) { 4329 var internals = get(inst); 4330 4331 if (internals.queue === null) { 4332 warnNoop(inst, 'forceUpdate'); 4333 } else { 4334 { 4335 if (callback !== undefined && callback !== null) { 4336 warnOnInvalidCallback(callback, 'setState'); 4337 } 4338 } 4339 } 4340 } 4341 }; 4342 4343 function applyDerivedStateFromProps(instance, ctor, getDerivedStateFromProps, prevState, nextProps) { 4344 var partialState = getDerivedStateFromProps(nextProps, prevState); 4345 4346 { 4347 warnOnUndefinedDerivedState(ctor, partialState); 4348 } // Merge the partial state and the previous state. 4349 4350 4351 var newState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState); 4352 return newState; 4353 } 4354 4355 function constructClassInstance(ctor, props, maskedLegacyContext) { 4356 var context = emptyContextObject; 4357 var contextType = ctor.contextType; 4358 4359 { 4360 if ('contextType' in ctor) { 4361 var isValid = // Allow null for conditional declaration 4362 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer> 4363 4364 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { 4365 didWarnAboutInvalidateContextType.add(ctor); 4366 var addendum = ''; 4367 4368 if (contextType === undefined) { 4369 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.'; 4370 } else if (typeof contextType !== 'object') { 4371 addendum = ' However, it is set to a ' + typeof contextType + '.'; 4372 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) { 4373 addendum = ' Did you accidentally pass the Context.Provider instead?'; 4374 } else if (contextType._context !== undefined) { 4375 // <Context.Consumer> 4376 addendum = ' Did you accidentally pass the Context.Consumer instead?'; 4377 } else { 4378 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.'; 4379 } 4380 4381 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum); 4382 } 4383 } 4384 } 4385 4386 if (typeof contextType === 'object' && contextType !== null) { 4387 context = readContext(contextType); 4388 } else { 4389 context = maskedLegacyContext; 4390 } 4391 4392 var instance = new ctor(props, context); 4393 4394 { 4395 if (typeof ctor.getDerivedStateFromProps === 'function' && (instance.state === null || instance.state === undefined)) { 4396 var componentName = getComponentNameFromType(ctor) || 'Component'; 4397 4398 if (!didWarnAboutUninitializedState.has(componentName)) { 4399 didWarnAboutUninitializedState.add(componentName); 4400 4401 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); 4402 } 4403 } // If new component APIs are defined, "unsafe" lifecycles won't be called. 4404 // Warn about these lifecycles if they are present. 4405 // Don't warn about react-lifecycles-compat polyfilled methods though. 4406 4407 4408 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') { 4409 var foundWillMountName = null; 4410 var foundWillReceivePropsName = null; 4411 var foundWillUpdateName = null; 4412 4413 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 4414 foundWillMountName = 'componentWillMount'; 4415 } else if (typeof instance.UNSAFE_componentWillMount === 'function') { 4416 foundWillMountName = 'UNSAFE_componentWillMount'; 4417 } 4418 4419 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 4420 foundWillReceivePropsName = 'componentWillReceiveProps'; 4421 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 4422 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; 4423 } 4424 4425 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 4426 foundWillUpdateName = 'componentWillUpdate'; 4427 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 4428 foundWillUpdateName = 'UNSAFE_componentWillUpdate'; 4429 } 4430 4431 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { 4432 var _componentName = getComponentNameFromType(ctor) || 'Component'; 4433 4434 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; 4435 4436 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { 4437 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); 4438 4439 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 : ''); 4440 } 4441 } 4442 } 4443 } 4444 4445 return instance; 4446 } 4447 4448 function checkClassInstance(instance, ctor, newProps) { 4449 { 4450 var name = getComponentNameFromType(ctor) || 'Component'; 4451 var renderPresent = instance.render; 4452 4453 if (!renderPresent) { 4454 if (ctor.prototype && typeof ctor.prototype.render === 'function') { 4455 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name); 4456 } else { 4457 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); 4458 } 4459 } 4460 4461 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) { 4462 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); 4463 } 4464 4465 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) { 4466 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); 4467 } 4468 4469 if (instance.propTypes) { 4470 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name); 4471 } 4472 4473 if (instance.contextType) { 4474 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name); 4475 } 4476 4477 { 4478 if (instance.contextTypes) { 4479 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name); 4480 } 4481 4482 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) { 4483 didWarnAboutContextTypeAndContextTypes.add(ctor); 4484 4485 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name); 4486 } 4487 } 4488 4489 if (typeof instance.componentShouldUpdate === 'function') { 4490 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); 4491 } 4492 4493 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { 4494 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component'); 4495 } 4496 4497 if (typeof instance.componentDidUnmount === 'function') { 4498 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name); 4499 } 4500 4501 if (typeof instance.componentDidReceiveProps === 'function') { 4502 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); 4503 } 4504 4505 if (typeof instance.componentWillRecieveProps === 'function') { 4506 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name); 4507 } 4508 4509 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') { 4510 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name); 4511 } 4512 4513 var hasMutatedProps = instance.props !== newProps; 4514 4515 if (instance.props !== undefined && hasMutatedProps) { 4516 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name); 4517 } 4518 4519 if (instance.defaultProps) { 4520 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); 4521 } 4522 4523 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { 4524 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); 4525 4526 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor)); 4527 } 4528 4529 if (typeof instance.getDerivedStateFromProps === 'function') { 4530 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 4531 } 4532 4533 if (typeof instance.getDerivedStateFromError === 'function') { 4534 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 4535 } 4536 4537 if (typeof ctor.getSnapshotBeforeUpdate === 'function') { 4538 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name); 4539 } 4540 4541 var _state = instance.state; 4542 4543 if (_state && (typeof _state !== 'object' || isArray(_state))) { 4544 error('%s.state: must be set to an object or null', name); 4545 } 4546 4547 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') { 4548 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name); 4549 } 4550 } 4551 } 4552 4553 function callComponentWillMount(type, instance) { 4554 var oldState = instance.state; 4555 4556 if (typeof instance.componentWillMount === 'function') { 4557 { 4558 if ( instance.componentWillMount.__suppressDeprecationWarning !== true) { 4559 var componentName = getComponentNameFromType(type) || 'Unknown'; 4560 4561 if (!didWarnAboutDeprecatedWillMount[componentName]) { 4562 warn( // keep this warning in sync with ReactStrictModeWarning.js 4563 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code from componentWillMount to componentDidMount (preferred in most cases) ' + 'or the constructor.\n' + '\nPlease update the following components: %s', componentName); 4564 4565 didWarnAboutDeprecatedWillMount[componentName] = true; 4566 } 4567 } 4568 } 4569 4570 instance.componentWillMount(); 4571 } 4572 4573 if (typeof instance.UNSAFE_componentWillMount === 'function') { 4574 instance.UNSAFE_componentWillMount(); 4575 } 4576 4577 if (oldState !== instance.state) { 4578 { 4579 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromType(type) || 'Component'); 4580 } 4581 4582 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 4583 } 4584 } 4585 4586 function processUpdateQueue(internalInstance, inst, props, maskedLegacyContext) { 4587 if (internalInstance.queue !== null && internalInstance.queue.length > 0) { 4588 var oldQueue = internalInstance.queue; 4589 var oldReplace = internalInstance.replace; 4590 internalInstance.queue = null; 4591 internalInstance.replace = false; 4592 4593 if (oldReplace && oldQueue.length === 1) { 4594 inst.state = oldQueue[0]; 4595 } else { 4596 var nextState = oldReplace ? oldQueue[0] : inst.state; 4597 var dontMutate = true; 4598 4599 for (var i = oldReplace ? 1 : 0; i < oldQueue.length; i++) { 4600 var partial = oldQueue[i]; 4601 var partialState = typeof partial === 'function' ? partial.call(inst, nextState, props, maskedLegacyContext) : partial; 4602 4603 if (partialState != null) { 4604 if (dontMutate) { 4605 dontMutate = false; 4606 nextState = assign({}, nextState, partialState); 4607 } else { 4608 assign(nextState, partialState); 4609 } 4610 } 4611 } 4612 4613 inst.state = nextState; 4614 } 4615 } else { 4616 internalInstance.queue = null; 4617 } 4618 } // Invokes the mount life-cycles on a previously never rendered instance. 4619 4620 4621 function mountClassInstance(instance, ctor, newProps, maskedLegacyContext) { 4622 { 4623 checkClassInstance(instance, ctor, newProps); 4624 } 4625 4626 var initialState = instance.state !== undefined ? instance.state : null; 4627 instance.updater = classComponentUpdater; 4628 instance.props = newProps; 4629 instance.state = initialState; // We don't bother initializing the refs object on the server, since we're not going to resolve them anyway. 4630 // The internal instance will be used to manage updates that happen during this mount. 4631 4632 var internalInstance = { 4633 queue: [], 4634 replace: false 4635 }; 4636 set(instance, internalInstance); 4637 var contextType = ctor.contextType; 4638 4639 if (typeof contextType === 'object' && contextType !== null) { 4640 instance.context = readContext(contextType); 4641 } else { 4642 instance.context = maskedLegacyContext; 4643 } 4644 4645 { 4646 if (instance.state === newProps) { 4647 var componentName = getComponentNameFromType(ctor) || 'Component'; 4648 4649 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { 4650 didWarnAboutDirectlyAssigningPropsToState.add(componentName); 4651 4652 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); 4653 } 4654 } 4655 } 4656 4657 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 4658 4659 if (typeof getDerivedStateFromProps === 'function') { 4660 instance.state = applyDerivedStateFromProps(instance, ctor, getDerivedStateFromProps, initialState, newProps); 4661 } // In order to support react-lifecycles-compat polyfilled components, 4662 // Unsafe lifecycles should not be invoked for components using the new APIs. 4663 4664 4665 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 4666 callComponentWillMount(ctor, instance); // If we had additional state updates during this life-cycle, let's 4667 // process them now. 4668 4669 processUpdateQueue(internalInstance, instance, newProps, maskedLegacyContext); 4670 } 4671 } 4672 4673 // Ids are base 32 strings whose binary representation corresponds to the 4674 // position of a node in a tree. 4675 // Every time the tree forks into multiple children, we add additional bits to 4676 // the left of the sequence that represent the position of the child within the 4677 // current level of children. 4678 // 4679 // 00101 00010001011010101 4680 // ╰─┬─╯ ╰───────┬───────╯ 4681 // Fork 5 of 20 Parent id 4682 // 4683 // The leading 0s are important. In the above example, you only need 3 bits to 4684 // represent slot 5. However, you need 5 bits to represent all the forks at 4685 // the current level, so we must account for the empty bits at the end. 4686 // 4687 // For this same reason, slots are 1-indexed instead of 0-indexed. Otherwise, 4688 // the zeroth id at a level would be indistinguishable from its parent. 4689 // 4690 // If a node has only one child, and does not materialize an id (i.e. does not 4691 // contain a useId hook), then we don't need to allocate any space in the 4692 // sequence. It's treated as a transparent indirection. For example, these two 4693 // trees produce the same ids: 4694 // 4695 // <> <> 4696 // <Indirection> <A /> 4697 // <A /> <B /> 4698 // </Indirection> </> 4699 // <B /> 4700 // </> 4701 // 4702 // However, we cannot skip any node that materializes an id. Otherwise, a parent 4703 // id that does not fork would be indistinguishable from its child id. For 4704 // example, this tree does not fork, but the parent and child must have 4705 // different ids. 4706 // 4707 // <Parent> 4708 // <Child /> 4709 // </Parent> 4710 // 4711 // To handle this scenario, every time we materialize an id, we allocate a 4712 // new level with a single slot. You can think of this as a fork with only one 4713 // prong, or an array of children with length 1. 4714 // 4715 // It's possible for the size of the sequence to exceed 32 bits, the max 4716 // size for bitwise operations. When this happens, we make more room by 4717 // converting the right part of the id to a string and storing it in an overflow 4718 // variable. We use a base 32 string representation, because 32 is the largest 4719 // power of 2 that is supported by toString(). We want the base to be large so 4720 // that the resulting ids are compact, and we want the base to be a power of 2 4721 // because every log2(base) bits corresponds to a single character, i.e. every 4722 // log2(32) = 5 bits. That means we can lop bits off the end 5 at a time without 4723 // affecting the final result. 4724 var emptyTreeContext = { 4725 id: 1, 4726 overflow: '' 4727 }; 4728 function getTreeId(context) { 4729 var overflow = context.overflow; 4730 var idWithLeadingBit = context.id; 4731 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit); 4732 return id.toString(32) + overflow; 4733 } 4734 function pushTreeContext(baseContext, totalChildren, index) { 4735 var baseIdWithLeadingBit = baseContext.id; 4736 var baseOverflow = baseContext.overflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part 4737 // of the id; we use it to account for leading 0s. 4738 4739 var baseLength = getBitLength(baseIdWithLeadingBit) - 1; 4740 var baseId = baseIdWithLeadingBit & ~(1 << baseLength); 4741 var slot = index + 1; 4742 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into 4743 // consideration the leading 1 we use to mark the end of the sequence. 4744 4745 if (length > 30) { 4746 // We overflowed the bitwise-safe range. Fall back to slower algorithm. 4747 // This branch assumes the length of the base id is greater than 5; it won't 4748 // work for smaller ids, because you need 5 bits per character. 4749 // 4750 // We encode the id in multiple steps: first the base id, then the 4751 // remaining digits. 4752 // 4753 // Each 5 bit sequence corresponds to a single base 32 character. So for 4754 // example, if the current id is 23 bits long, we can convert 20 of those 4755 // bits into a string of 4 characters, with 3 bits left over. 4756 // 4757 // First calculate how many bits in the base id represent a complete 4758 // sequence of characters. 4759 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits. 4760 4761 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string. 4762 4763 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id. 4764 4765 var restOfBaseId = baseId >> numberOfOverflowBits; 4766 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because 4767 // we made more room, this time it won't overflow. 4768 4769 var restOfLength = getBitLength(totalChildren) + restOfBaseLength; 4770 var restOfNewBits = slot << restOfBaseLength; 4771 var id = restOfNewBits | restOfBaseId; 4772 var overflow = newOverflow + baseOverflow; 4773 return { 4774 id: 1 << restOfLength | id, 4775 overflow: overflow 4776 }; 4777 } else { 4778 // Normal path 4779 var newBits = slot << baseLength; 4780 4781 var _id = newBits | baseId; 4782 4783 var _overflow = baseOverflow; 4784 return { 4785 id: 1 << length | _id, 4786 overflow: _overflow 4787 }; 4788 } 4789 } 4790 4791 function getBitLength(number) { 4792 return 32 - clz32(number); 4793 } 4794 4795 function getLeadingBit(id) { 4796 return 1 << getBitLength(id) - 1; 4797 } // TODO: Math.clz32 is supported in Node 12+. Maybe we can drop the fallback. 4798 4799 4800 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. 4801 // Based on: 4802 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 4803 4804 var log = Math.log; 4805 var LN2 = Math.LN2; 4806 4807 function clz32Fallback(x) { 4808 var asUint = x >>> 0; 4809 4810 if (asUint === 0) { 4811 return 32; 4812 } 4813 4814 return 31 - (log(asUint) / LN2 | 0) | 0; 4815 } 4816 4817 /** 4818 * inlined Object.is polyfill to avoid requiring consumers ship their own 4819 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 4820 */ 4821 function is(x, y) { 4822 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare 4823 ; 4824 } 4825 4826 var objectIs = typeof Object.is === 'function' ? Object.is : is; 4827 4828 var currentlyRenderingComponent = null; 4829 var currentlyRenderingTask = null; 4830 var firstWorkInProgressHook = null; 4831 var workInProgressHook = null; // Whether the work-in-progress hook is a re-rendered hook 4832 4833 var isReRender = false; // Whether an update was scheduled during the currently executing render pass. 4834 4835 var didScheduleRenderPhaseUpdate = false; // Counts the number of useId hooks in this component 4836 4837 var localIdCounter = 0; // Lazily created map of render-phase updates 4838 4839 var renderPhaseUpdates = null; // Counter to prevent infinite loops. 4840 4841 var numberOfReRenders = 0; 4842 var RE_RENDER_LIMIT = 25; 4843 var isInHookUserCodeInDev = false; // In DEV, this is the name of the currently executing primitive hook 4844 4845 var currentHookNameInDev; 4846 4847 function resolveCurrentlyRenderingComponent() { 4848 if (currentlyRenderingComponent === null) { 4849 throw new Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.'); 4850 } 4851 4852 { 4853 if (isInHookUserCodeInDev) { 4854 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'); 4855 } 4856 } 4857 4858 return currentlyRenderingComponent; 4859 } 4860 4861 function areHookInputsEqual(nextDeps, prevDeps) { 4862 if (prevDeps === null) { 4863 { 4864 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); 4865 } 4866 4867 return false; 4868 } 4869 4870 { 4871 // Don't bother comparing lengths in prod because these arrays should be 4872 // passed inline. 4873 if (nextDeps.length !== prevDeps.length) { 4874 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, "[" + nextDeps.join(', ') + "]", "[" + prevDeps.join(', ') + "]"); 4875 } 4876 } 4877 4878 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { 4879 if (objectIs(nextDeps[i], prevDeps[i])) { 4880 continue; 4881 } 4882 4883 return false; 4884 } 4885 4886 return true; 4887 } 4888 4889 function createHook() { 4890 if (numberOfReRenders > 0) { 4891 throw new Error('Rendered more hooks than during the previous render'); 4892 } 4893 4894 return { 4895 memoizedState: null, 4896 queue: null, 4897 next: null 4898 }; 4899 } 4900 4901 function createWorkInProgressHook() { 4902 if (workInProgressHook === null) { 4903 // This is the first hook in the list 4904 if (firstWorkInProgressHook === null) { 4905 isReRender = false; 4906 firstWorkInProgressHook = workInProgressHook = createHook(); 4907 } else { 4908 // There's already a work-in-progress. Reuse it. 4909 isReRender = true; 4910 workInProgressHook = firstWorkInProgressHook; 4911 } 4912 } else { 4913 if (workInProgressHook.next === null) { 4914 isReRender = false; // Append to the end of the list 4915 4916 workInProgressHook = workInProgressHook.next = createHook(); 4917 } else { 4918 // There's already a work-in-progress. Reuse it. 4919 isReRender = true; 4920 workInProgressHook = workInProgressHook.next; 4921 } 4922 } 4923 4924 return workInProgressHook; 4925 } 4926 4927 function prepareToUseHooks(task, componentIdentity) { 4928 currentlyRenderingComponent = componentIdentity; 4929 currentlyRenderingTask = task; 4930 4931 { 4932 isInHookUserCodeInDev = false; 4933 } // The following should have already been reset 4934 // didScheduleRenderPhaseUpdate = false; 4935 // localIdCounter = 0; 4936 // firstWorkInProgressHook = null; 4937 // numberOfReRenders = 0; 4938 // renderPhaseUpdates = null; 4939 // workInProgressHook = null; 4940 4941 4942 localIdCounter = 0; 4943 } 4944 function finishHooks(Component, props, children, refOrContext) { 4945 // This must be called after every function component to prevent hooks from 4946 // being used in classes. 4947 while (didScheduleRenderPhaseUpdate) { 4948 // Updates were scheduled during the render phase. They are stored in 4949 // the `renderPhaseUpdates` map. Call the component again, reusing the 4950 // work-in-progress hooks and applying the additional updates on top. Keep 4951 // restarting until no more updates are scheduled. 4952 didScheduleRenderPhaseUpdate = false; 4953 localIdCounter = 0; 4954 numberOfReRenders += 1; // Start over from the beginning of the list 4955 4956 workInProgressHook = null; 4957 children = Component(props, refOrContext); 4958 } 4959 4960 resetHooksState(); 4961 return children; 4962 } 4963 function checkDidRenderIdHook() { 4964 // This should be called immediately after every finishHooks call. 4965 // Conceptually, it's part of the return value of finishHooks; it's only a 4966 // separate function to avoid using an array tuple. 4967 var didRenderIdHook = localIdCounter !== 0; 4968 return didRenderIdHook; 4969 } // Reset the internal hooks state if an error occurs while rendering a component 4970 4971 function resetHooksState() { 4972 { 4973 isInHookUserCodeInDev = false; 4974 } 4975 4976 currentlyRenderingComponent = null; 4977 currentlyRenderingTask = null; 4978 didScheduleRenderPhaseUpdate = false; 4979 firstWorkInProgressHook = null; 4980 numberOfReRenders = 0; 4981 renderPhaseUpdates = null; 4982 workInProgressHook = null; 4983 } 4984 4985 function readContext$1(context) { 4986 { 4987 if (isInHookUserCodeInDev) { 4988 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().'); 4989 } 4990 } 4991 4992 return readContext(context); 4993 } 4994 4995 function useContext(context) { 4996 { 4997 currentHookNameInDev = 'useContext'; 4998 } 4999 5000 resolveCurrentlyRenderingComponent(); 5001 return readContext(context); 5002 } 5003 5004 function basicStateReducer(state, action) { 5005 // $FlowFixMe: Flow doesn't like mixed types 5006 return typeof action === 'function' ? action(state) : action; 5007 } 5008 5009 function useState(initialState) { 5010 { 5011 currentHookNameInDev = 'useState'; 5012 } 5013 5014 return useReducer(basicStateReducer, // useReducer has a special case to support lazy useState initializers 5015 initialState); 5016 } 5017 function useReducer(reducer, initialArg, init) { 5018 { 5019 if (reducer !== basicStateReducer) { 5020 currentHookNameInDev = 'useReducer'; 5021 } 5022 } 5023 5024 currentlyRenderingComponent = resolveCurrentlyRenderingComponent(); 5025 workInProgressHook = createWorkInProgressHook(); 5026 5027 if (isReRender) { 5028 // This is a re-render. Apply the new render phase updates to the previous 5029 // current hook. 5030 var queue = workInProgressHook.queue; 5031 var dispatch = queue.dispatch; 5032 5033 if (renderPhaseUpdates !== null) { 5034 // Render phase updates are stored in a map of queue -> linked list 5035 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); 5036 5037 if (firstRenderPhaseUpdate !== undefined) { 5038 renderPhaseUpdates.delete(queue); 5039 var newState = workInProgressHook.memoizedState; 5040 var update = firstRenderPhaseUpdate; 5041 5042 do { 5043 // Process this render phase update. We don't have to check the 5044 // priority because it will always be the same as the current 5045 // render's. 5046 var action = update.action; 5047 5048 { 5049 isInHookUserCodeInDev = true; 5050 } 5051 5052 newState = reducer(newState, action); 5053 5054 { 5055 isInHookUserCodeInDev = false; 5056 } 5057 5058 update = update.next; 5059 } while (update !== null); 5060 5061 workInProgressHook.memoizedState = newState; 5062 return [newState, dispatch]; 5063 } 5064 } 5065 5066 return [workInProgressHook.memoizedState, dispatch]; 5067 } else { 5068 { 5069 isInHookUserCodeInDev = true; 5070 } 5071 5072 var initialState; 5073 5074 if (reducer === basicStateReducer) { 5075 // Special case for `useState`. 5076 initialState = typeof initialArg === 'function' ? initialArg() : initialArg; 5077 } else { 5078 initialState = init !== undefined ? init(initialArg) : initialArg; 5079 } 5080 5081 { 5082 isInHookUserCodeInDev = false; 5083 } 5084 5085 workInProgressHook.memoizedState = initialState; 5086 5087 var _queue = workInProgressHook.queue = { 5088 last: null, 5089 dispatch: null 5090 }; 5091 5092 var _dispatch = _queue.dispatch = dispatchAction.bind(null, currentlyRenderingComponent, _queue); 5093 5094 return [workInProgressHook.memoizedState, _dispatch]; 5095 } 5096 } 5097 5098 function useMemo(nextCreate, deps) { 5099 currentlyRenderingComponent = resolveCurrentlyRenderingComponent(); 5100 workInProgressHook = createWorkInProgressHook(); 5101 var nextDeps = deps === undefined ? null : deps; 5102 5103 if (workInProgressHook !== null) { 5104 var prevState = workInProgressHook.memoizedState; 5105 5106 if (prevState !== null) { 5107 if (nextDeps !== null) { 5108 var prevDeps = prevState[1]; 5109 5110 if (areHookInputsEqual(nextDeps, prevDeps)) { 5111 return prevState[0]; 5112 } 5113 } 5114 } 5115 } 5116 5117 { 5118 isInHookUserCodeInDev = true; 5119 } 5120 5121 var nextValue = nextCreate(); 5122 5123 { 5124 isInHookUserCodeInDev = false; 5125 } 5126 5127 workInProgressHook.memoizedState = [nextValue, nextDeps]; 5128 return nextValue; 5129 } 5130 5131 function useRef(initialValue) { 5132 currentlyRenderingComponent = resolveCurrentlyRenderingComponent(); 5133 workInProgressHook = createWorkInProgressHook(); 5134 var previousRef = workInProgressHook.memoizedState; 5135 5136 if (previousRef === null) { 5137 var ref = { 5138 current: initialValue 5139 }; 5140 5141 { 5142 Object.seal(ref); 5143 } 5144 5145 workInProgressHook.memoizedState = ref; 5146 return ref; 5147 } else { 5148 return previousRef; 5149 } 5150 } 5151 5152 function useLayoutEffect(create, inputs) { 5153 { 5154 currentHookNameInDev = 'useLayoutEffect'; 5155 5156 error('useLayoutEffect does nothing on the server, because its effect cannot ' + "be encoded into the server renderer's output format. This will lead " + 'to a mismatch between the initial, non-hydrated UI and the intended ' + 'UI. To avoid this, useLayoutEffect should only be used in ' + 'components that render exclusively on the client. ' + 'See https://reactjs.org/link/uselayouteffect-ssr for common fixes.'); 5157 } 5158 } 5159 5160 function dispatchAction(componentIdentity, queue, action) { 5161 if (numberOfReRenders >= RE_RENDER_LIMIT) { 5162 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.'); 5163 } 5164 5165 if (componentIdentity === currentlyRenderingComponent) { 5166 // This is a render phase update. Stash it in a lazily-created map of 5167 // queue -> linked list of updates. After this render pass, we'll restart 5168 // and apply the stashed updates on top of the work-in-progress hook. 5169 didScheduleRenderPhaseUpdate = true; 5170 var update = { 5171 action: action, 5172 next: null 5173 }; 5174 5175 if (renderPhaseUpdates === null) { 5176 renderPhaseUpdates = new Map(); 5177 } 5178 5179 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); 5180 5181 if (firstRenderPhaseUpdate === undefined) { 5182 renderPhaseUpdates.set(queue, update); 5183 } else { 5184 // Append the update to the end of the list. 5185 var lastRenderPhaseUpdate = firstRenderPhaseUpdate; 5186 5187 while (lastRenderPhaseUpdate.next !== null) { 5188 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; 5189 } 5190 5191 lastRenderPhaseUpdate.next = update; 5192 } 5193 } 5194 } 5195 5196 function useCallback(callback, deps) { 5197 return useMemo(function () { 5198 return callback; 5199 }, deps); 5200 } // TODO Decide on how to implement this hook for server rendering. 5201 // If a mutation occurs during render, consider triggering a Suspense boundary 5202 // and falling back to client rendering. 5203 5204 function useMutableSource(source, getSnapshot, subscribe) { 5205 resolveCurrentlyRenderingComponent(); 5206 return getSnapshot(source._source); 5207 } 5208 5209 function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { 5210 if (getServerSnapshot === undefined) { 5211 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.'); 5212 } 5213 5214 return getServerSnapshot(); 5215 } 5216 5217 function useDeferredValue(value) { 5218 resolveCurrentlyRenderingComponent(); 5219 return value; 5220 } 5221 5222 function unsupportedStartTransition() { 5223 throw new Error('startTransition cannot be called during server rendering.'); 5224 } 5225 5226 function useTransition() { 5227 resolveCurrentlyRenderingComponent(); 5228 return [false, unsupportedStartTransition]; 5229 } 5230 5231 function useId() { 5232 var task = currentlyRenderingTask; 5233 var treeId = getTreeId(task.treeContext); 5234 var responseState = currentResponseState; 5235 5236 if (responseState === null) { 5237 throw new Error('Invalid hook call. Hooks can only be called inside of the body of a function component.'); 5238 } 5239 5240 var localId = localIdCounter++; 5241 return makeId(responseState, treeId, localId); 5242 } 5243 5244 function noop() {} 5245 5246 var Dispatcher = { 5247 readContext: readContext$1, 5248 useContext: useContext, 5249 useMemo: useMemo, 5250 useReducer: useReducer, 5251 useRef: useRef, 5252 useState: useState, 5253 useInsertionEffect: noop, 5254 useLayoutEffect: useLayoutEffect, 5255 useCallback: useCallback, 5256 // useImperativeHandle is not run in the server environment 5257 useImperativeHandle: noop, 5258 // Effects are not run in the server environment. 5259 useEffect: noop, 5260 // Debugging effect 5261 useDebugValue: noop, 5262 useDeferredValue: useDeferredValue, 5263 useTransition: useTransition, 5264 useId: useId, 5265 // Subscriptions are not setup in a server environment. 5266 useMutableSource: useMutableSource, 5267 useSyncExternalStore: useSyncExternalStore 5268 }; 5269 5270 var currentResponseState = null; 5271 function setCurrentResponseState(responseState) { 5272 currentResponseState = responseState; 5273 } 5274 5275 function getStackByComponentStackNode(componentStack) { 5276 try { 5277 var info = ''; 5278 var node = componentStack; 5279 5280 do { 5281 switch (node.tag) { 5282 case 0: 5283 info += describeBuiltInComponentFrame(node.type, null, null); 5284 break; 5285 5286 case 1: 5287 info += describeFunctionComponentFrame(node.type, null, null); 5288 break; 5289 5290 case 2: 5291 info += describeClassComponentFrame(node.type, null, null); 5292 break; 5293 } 5294 5295 node = node.parent; 5296 } while (node); 5297 5298 return info; 5299 } catch (x) { 5300 return '\nError generating stack: ' + x.message + '\n' + x.stack; 5301 } 5302 } 5303 5304 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; 5305 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 5306 var PENDING = 0; 5307 var COMPLETED = 1; 5308 var FLUSHED = 2; 5309 var ABORTED = 3; 5310 var ERRORED = 4; 5311 var OPEN = 0; 5312 var CLOSING = 1; 5313 var CLOSED = 2; 5314 // This is a default heuristic for how to split up the HTML content into progressive 5315 // loading. Our goal is to be able to display additional new content about every 500ms. 5316 // Faster than that is unnecessary and should be throttled on the client. It also 5317 // adds unnecessary overhead to do more splits. We don't know if it's a higher or lower 5318 // end device but higher end suffer less from the overhead than lower end does from 5319 // not getting small enough pieces. We error on the side of low end. 5320 // We base this on low end 3G speeds which is about 500kbits per second. We assume 5321 // that there can be a reasonable drop off from max bandwidth which leaves you with 5322 // as little as 80%. We can receive half of that each 500ms - at best. In practice, 5323 // a little bandwidth is lost to processing and contention - e.g. CSS and images that 5324 // are downloaded along with the main content. So we estimate about half of that to be 5325 // the lower end throughput. In other words, we expect that you can at least show 5326 // about 12.5kb of content per 500ms. Not counting starting latency for the first 5327 // paint. 5328 // 500 * 1024 / 8 * .8 * 0.5 / 2 5329 var DEFAULT_PROGRESSIVE_CHUNK_SIZE = 12800; 5330 5331 function defaultErrorHandler(error) { 5332 console['error'](error); // Don't transform to our wrapper 5333 5334 return null; 5335 } 5336 5337 function noop$1() {} 5338 5339 function createRequest(children, responseState, rootFormatContext, progressiveChunkSize, onError, onAllReady, onShellReady, onShellError, onFatalError) { 5340 var pingedTasks = []; 5341 var abortSet = new Set(); 5342 var request = { 5343 destination: null, 5344 responseState: responseState, 5345 progressiveChunkSize: progressiveChunkSize === undefined ? DEFAULT_PROGRESSIVE_CHUNK_SIZE : progressiveChunkSize, 5346 status: OPEN, 5347 fatalError: null, 5348 nextSegmentId: 0, 5349 allPendingTasks: 0, 5350 pendingRootTasks: 0, 5351 completedRootSegment: null, 5352 abortableTasks: abortSet, 5353 pingedTasks: pingedTasks, 5354 clientRenderedBoundaries: [], 5355 completedBoundaries: [], 5356 partialBoundaries: [], 5357 onError: onError === undefined ? defaultErrorHandler : onError, 5358 onAllReady: onAllReady === undefined ? noop$1 : onAllReady, 5359 onShellReady: onShellReady === undefined ? noop$1 : onShellReady, 5360 onShellError: onShellError === undefined ? noop$1 : onShellError, 5361 onFatalError: onFatalError === undefined ? noop$1 : onFatalError 5362 }; // This segment represents the root fallback. 5363 5364 var rootSegment = createPendingSegment(request, 0, null, rootFormatContext, // Root segments are never embedded in Text on either edge 5365 false, false); // There is no parent so conceptually, we're unblocked to flush this segment. 5366 5367 rootSegment.parentFlushed = true; 5368 var rootTask = createTask(request, children, null, rootSegment, abortSet, emptyContextObject, rootContextSnapshot, emptyTreeContext); 5369 pingedTasks.push(rootTask); 5370 return request; 5371 } 5372 5373 function pingTask(request, task) { 5374 var pingedTasks = request.pingedTasks; 5375 pingedTasks.push(task); 5376 5377 if (pingedTasks.length === 1) { 5378 scheduleWork(function () { 5379 return performWork(request); 5380 }); 5381 } 5382 } 5383 5384 function createSuspenseBoundary(request, fallbackAbortableTasks) { 5385 return { 5386 id: UNINITIALIZED_SUSPENSE_BOUNDARY_ID, 5387 rootSegmentID: -1, 5388 parentFlushed: false, 5389 pendingTasks: 0, 5390 forceClientRender: false, 5391 completedSegments: [], 5392 byteSize: 0, 5393 fallbackAbortableTasks: fallbackAbortableTasks, 5394 errorDigest: null 5395 }; 5396 } 5397 5398 function createTask(request, node, blockedBoundary, blockedSegment, abortSet, legacyContext, context, treeContext) { 5399 request.allPendingTasks++; 5400 5401 if (blockedBoundary === null) { 5402 request.pendingRootTasks++; 5403 } else { 5404 blockedBoundary.pendingTasks++; 5405 } 5406 5407 var task = { 5408 node: node, 5409 ping: function () { 5410 return pingTask(request, task); 5411 }, 5412 blockedBoundary: blockedBoundary, 5413 blockedSegment: blockedSegment, 5414 abortSet: abortSet, 5415 legacyContext: legacyContext, 5416 context: context, 5417 treeContext: treeContext 5418 }; 5419 5420 { 5421 task.componentStack = null; 5422 } 5423 5424 abortSet.add(task); 5425 return task; 5426 } 5427 5428 function createPendingSegment(request, index, boundary, formatContext, lastPushedText, textEmbedded) { 5429 return { 5430 status: PENDING, 5431 id: -1, 5432 // lazily assigned later 5433 index: index, 5434 parentFlushed: false, 5435 chunks: [], 5436 children: [], 5437 formatContext: formatContext, 5438 boundary: boundary, 5439 lastPushedText: lastPushedText, 5440 textEmbedded: textEmbedded 5441 }; 5442 } // DEV-only global reference to the currently executing task 5443 5444 5445 var currentTaskInDEV = null; 5446 5447 function getCurrentStackInDEV() { 5448 { 5449 if (currentTaskInDEV === null || currentTaskInDEV.componentStack === null) { 5450 return ''; 5451 } 5452 5453 return getStackByComponentStackNode(currentTaskInDEV.componentStack); 5454 } 5455 } 5456 5457 function pushBuiltInComponentStackInDEV(task, type) { 5458 { 5459 task.componentStack = { 5460 tag: 0, 5461 parent: task.componentStack, 5462 type: type 5463 }; 5464 } 5465 } 5466 5467 function pushFunctionComponentStackInDEV(task, type) { 5468 { 5469 task.componentStack = { 5470 tag: 1, 5471 parent: task.componentStack, 5472 type: type 5473 }; 5474 } 5475 } 5476 5477 function pushClassComponentStackInDEV(task, type) { 5478 { 5479 task.componentStack = { 5480 tag: 2, 5481 parent: task.componentStack, 5482 type: type 5483 }; 5484 } 5485 } 5486 5487 function popComponentStackInDEV(task) { 5488 { 5489 if (task.componentStack === null) { 5490 error('Unexpectedly popped too many stack frames. This is a bug in React.'); 5491 } else { 5492 task.componentStack = task.componentStack.parent; 5493 } 5494 } 5495 } // stash the component stack of an unwinding error until it is processed 5496 5497 5498 var lastBoundaryErrorComponentStackDev = null; 5499 5500 function captureBoundaryErrorDetailsDev(boundary, error) { 5501 { 5502 var errorMessage; 5503 5504 if (typeof error === 'string') { 5505 errorMessage = error; 5506 } else if (error && typeof error.message === 'string') { 5507 errorMessage = error.message; 5508 } else { 5509 // eslint-disable-next-line react-internal/safe-string-coercion 5510 errorMessage = String(error); 5511 } 5512 5513 var errorComponentStack = lastBoundaryErrorComponentStackDev || getCurrentStackInDEV(); 5514 lastBoundaryErrorComponentStackDev = null; 5515 boundary.errorMessage = errorMessage; 5516 boundary.errorComponentStack = errorComponentStack; 5517 } 5518 } 5519 5520 function logRecoverableError(request, error) { 5521 // If this callback errors, we intentionally let that error bubble up to become a fatal error 5522 // so that someone fixes the error reporting instead of hiding it. 5523 var errorDigest = request.onError(error); 5524 5525 if (errorDigest != null && typeof errorDigest !== 'string') { 5526 // eslint-disable-next-line react-internal/prod-error-codes 5527 throw new Error("onError returned something with a type other than \"string\". onError should return a string and may return null or undefined but must not return anything else. It received something of type \"" + typeof errorDigest + "\" instead"); 5528 } 5529 5530 return errorDigest; 5531 } 5532 5533 function fatalError(request, error) { 5534 // This is called outside error handling code such as if the root errors outside 5535 // a suspense boundary or if the root suspense boundary's fallback errors. 5536 // It's also called if React itself or its host configs errors. 5537 var onShellError = request.onShellError; 5538 onShellError(error); 5539 var onFatalError = request.onFatalError; 5540 onFatalError(error); 5541 5542 if (request.destination !== null) { 5543 request.status = CLOSED; 5544 closeWithError(request.destination, error); 5545 } else { 5546 request.status = CLOSING; 5547 request.fatalError = error; 5548 } 5549 } 5550 5551 function renderSuspenseBoundary(request, task, props) { 5552 pushBuiltInComponentStackInDEV(task, 'Suspense'); 5553 var parentBoundary = task.blockedBoundary; 5554 var parentSegment = task.blockedSegment; // Each time we enter a suspense boundary, we split out into a new segment for 5555 // the fallback so that we can later replace that segment with the content. 5556 // This also lets us split out the main content even if it doesn't suspend, 5557 // in case it ends up generating a large subtree of content. 5558 5559 var fallback = props.fallback; 5560 var content = props.children; 5561 var fallbackAbortSet = new Set(); 5562 var newBoundary = createSuspenseBoundary(request, fallbackAbortSet); 5563 var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback. 5564 5565 var boundarySegment = createPendingSegment(request, insertionIndex, newBoundary, parentSegment.formatContext, // boundaries never require text embedding at their edges because comment nodes bound them 5566 false, false); 5567 parentSegment.children.push(boundarySegment); // The parentSegment has a child Segment at this index so we reset the lastPushedText marker on the parent 5568 5569 parentSegment.lastPushedText = false; // This segment is the actual child content. We can start rendering that immediately. 5570 5571 var contentRootSegment = createPendingSegment(request, 0, null, parentSegment.formatContext, // boundaries never require text embedding at their edges because comment nodes bound them 5572 false, false); // We mark the root segment as having its parent flushed. It's not really flushed but there is 5573 // no parent segment so there's nothing to wait on. 5574 5575 contentRootSegment.parentFlushed = true; // Currently this is running synchronously. We could instead schedule this to pingedTasks. 5576 // I suspect that there might be some efficiency benefits from not creating the suspended task 5577 // and instead just using the stack if possible. 5578 // TODO: Call this directly instead of messing with saving and restoring contexts. 5579 // We can reuse the current context and task to render the content immediately without 5580 // context switching. We just need to temporarily switch which boundary and which segment 5581 // we're writing to. If something suspends, it'll spawn new suspended task with that context. 5582 5583 task.blockedBoundary = newBoundary; 5584 task.blockedSegment = contentRootSegment; 5585 5586 try { 5587 // We use the safe form because we don't handle suspending here. Only error handling. 5588 renderNode(request, task, content); 5589 pushSegmentFinale(contentRootSegment.chunks, request.responseState, contentRootSegment.lastPushedText, contentRootSegment.textEmbedded); 5590 contentRootSegment.status = COMPLETED; 5591 queueCompletedSegment(newBoundary, contentRootSegment); 5592 5593 if (newBoundary.pendingTasks === 0) { 5594 // This must have been the last segment we were waiting on. This boundary is now complete. 5595 // Therefore we won't need the fallback. We early return so that we don't have to create 5596 // the fallback. 5597 popComponentStackInDEV(task); 5598 return; 5599 } 5600 } catch (error) { 5601 contentRootSegment.status = ERRORED; 5602 newBoundary.forceClientRender = true; 5603 newBoundary.errorDigest = logRecoverableError(request, error); 5604 5605 { 5606 captureBoundaryErrorDetailsDev(newBoundary, error); 5607 } // We don't need to decrement any task numbers because we didn't spawn any new task. 5608 // We don't need to schedule any task because we know the parent has written yet. 5609 // We do need to fallthrough to create the fallback though. 5610 5611 } finally { 5612 task.blockedBoundary = parentBoundary; 5613 task.blockedSegment = parentSegment; 5614 } // We create suspended task for the fallback because we don't want to actually work 5615 // on it yet in case we finish the main content, so we queue for later. 5616 5617 5618 var suspendedFallbackTask = createTask(request, fallback, parentBoundary, boundarySegment, fallbackAbortSet, task.legacyContext, task.context, task.treeContext); 5619 5620 { 5621 suspendedFallbackTask.componentStack = task.componentStack; 5622 } // TODO: This should be queued at a separate lower priority queue so that we only work 5623 // on preparing fallbacks if we don't have any more main content to task on. 5624 5625 5626 request.pingedTasks.push(suspendedFallbackTask); 5627 popComponentStackInDEV(task); 5628 } 5629 5630 function renderHostElement(request, task, type, props) { 5631 pushBuiltInComponentStackInDEV(task, type); 5632 var segment = task.blockedSegment; 5633 var children = pushStartInstance(segment.chunks, type, props, request.responseState, segment.formatContext); 5634 segment.lastPushedText = false; 5635 var prevContext = segment.formatContext; 5636 segment.formatContext = getChildFormatContext(prevContext, type, props); // We use the non-destructive form because if something suspends, we still 5637 // need to pop back up and finish this subtree of HTML. 5638 5639 renderNode(request, task, children); // We expect that errors will fatal the whole task and that we don't need 5640 // the correct context. Therefore this is not in a finally. 5641 5642 segment.formatContext = prevContext; 5643 pushEndInstance(segment.chunks, type); 5644 segment.lastPushedText = false; 5645 popComponentStackInDEV(task); 5646 } 5647 5648 function shouldConstruct$1(Component) { 5649 return Component.prototype && Component.prototype.isReactComponent; 5650 } 5651 5652 function renderWithHooks(request, task, Component, props, secondArg) { 5653 var componentIdentity = {}; 5654 prepareToUseHooks(task, componentIdentity); 5655 var result = Component(props, secondArg); 5656 return finishHooks(Component, props, result, secondArg); 5657 } 5658 5659 function finishClassComponent(request, task, instance, Component, props) { 5660 var nextChildren = instance.render(); 5661 5662 { 5663 if (instance.props !== props) { 5664 if (!didWarnAboutReassigningProps) { 5665 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromType(Component) || 'a component'); 5666 } 5667 5668 didWarnAboutReassigningProps = true; 5669 } 5670 } 5671 5672 { 5673 var childContextTypes = Component.childContextTypes; 5674 5675 if (childContextTypes !== null && childContextTypes !== undefined) { 5676 var previousContext = task.legacyContext; 5677 var mergedContext = processChildContext(instance, Component, previousContext, childContextTypes); 5678 task.legacyContext = mergedContext; 5679 renderNodeDestructive(request, task, nextChildren); 5680 task.legacyContext = previousContext; 5681 return; 5682 } 5683 } 5684 5685 renderNodeDestructive(request, task, nextChildren); 5686 } 5687 5688 function renderClassComponent(request, task, Component, props) { 5689 pushClassComponentStackInDEV(task, Component); 5690 var maskedContext = getMaskedContext(Component, task.legacyContext) ; 5691 var instance = constructClassInstance(Component, props, maskedContext); 5692 mountClassInstance(instance, Component, props, maskedContext); 5693 finishClassComponent(request, task, instance, Component, props); 5694 popComponentStackInDEV(task); 5695 } 5696 5697 var didWarnAboutBadClass = {}; 5698 var didWarnAboutModulePatternComponent = {}; 5699 var didWarnAboutContextTypeOnFunctionComponent = {}; 5700 var didWarnAboutGetDerivedStateOnFunctionComponent = {}; 5701 var didWarnAboutReassigningProps = false; 5702 var didWarnAboutGenerators = false; 5703 var didWarnAboutMaps = false; 5704 var hasWarnedAboutUsingContextAsConsumer = false; // This would typically be a function component but we still support module pattern 5705 // components for some reason. 5706 5707 function renderIndeterminateComponent(request, task, Component, props) { 5708 var legacyContext; 5709 5710 { 5711 legacyContext = getMaskedContext(Component, task.legacyContext); 5712 } 5713 5714 pushFunctionComponentStackInDEV(task, Component); 5715 5716 { 5717 if (Component.prototype && typeof Component.prototype.render === 'function') { 5718 var componentName = getComponentNameFromType(Component) || 'Unknown'; 5719 5720 if (!didWarnAboutBadClass[componentName]) { 5721 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); 5722 5723 didWarnAboutBadClass[componentName] = true; 5724 } 5725 } 5726 } 5727 5728 var value = renderWithHooks(request, task, Component, props, legacyContext); 5729 var hasId = checkDidRenderIdHook(); 5730 5731 { 5732 // Support for module components is deprecated and is removed behind a flag. 5733 // Whether or not it would crash later, we want to show a good message in DEV first. 5734 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 5735 var _componentName = getComponentNameFromType(Component) || 'Unknown'; 5736 5737 if (!didWarnAboutModulePatternComponent[_componentName]) { 5738 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); 5739 5740 didWarnAboutModulePatternComponent[_componentName] = true; 5741 } 5742 } 5743 } 5744 5745 if ( // Run these checks in production only if the flag is off. 5746 // Eventually we'll delete this branch altogether. 5747 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 5748 { 5749 var _componentName2 = getComponentNameFromType(Component) || 'Unknown'; 5750 5751 if (!didWarnAboutModulePatternComponent[_componentName2]) { 5752 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); 5753 5754 didWarnAboutModulePatternComponent[_componentName2] = true; 5755 } 5756 } 5757 5758 mountClassInstance(value, Component, props, legacyContext); 5759 finishClassComponent(request, task, value, Component, props); 5760 } else { 5761 5762 { 5763 validateFunctionComponentInDev(Component); 5764 } // We're now successfully past this task, and we don't have to pop back to 5765 // the previous task every again, so we can use the destructive recursive form. 5766 5767 5768 if (hasId) { 5769 // This component materialized an id. We treat this as its own level, with 5770 // a single "child" slot. 5771 var prevTreeContext = task.treeContext; 5772 var totalChildren = 1; 5773 var index = 0; 5774 task.treeContext = pushTreeContext(prevTreeContext, totalChildren, index); 5775 5776 try { 5777 renderNodeDestructive(request, task, value); 5778 } finally { 5779 task.treeContext = prevTreeContext; 5780 } 5781 } else { 5782 renderNodeDestructive(request, task, value); 5783 } 5784 } 5785 5786 popComponentStackInDEV(task); 5787 } 5788 5789 function validateFunctionComponentInDev(Component) { 5790 { 5791 if (Component) { 5792 if (Component.childContextTypes) { 5793 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component'); 5794 } 5795 } 5796 5797 if (typeof Component.getDerivedStateFromProps === 'function') { 5798 var _componentName3 = getComponentNameFromType(Component) || 'Unknown'; 5799 5800 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { 5801 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3); 5802 5803 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; 5804 } 5805 } 5806 5807 if (typeof Component.contextType === 'object' && Component.contextType !== null) { 5808 var _componentName4 = getComponentNameFromType(Component) || 'Unknown'; 5809 5810 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { 5811 error('%s: Function components do not support contextType.', _componentName4); 5812 5813 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; 5814 } 5815 } 5816 } 5817 } 5818 5819 function resolveDefaultProps(Component, baseProps) { 5820 if (Component && Component.defaultProps) { 5821 // Resolve default props. Taken from ReactElement 5822 var props = assign({}, baseProps); 5823 var defaultProps = Component.defaultProps; 5824 5825 for (var propName in defaultProps) { 5826 if (props[propName] === undefined) { 5827 props[propName] = defaultProps[propName]; 5828 } 5829 } 5830 5831 return props; 5832 } 5833 5834 return baseProps; 5835 } 5836 5837 function renderForwardRef(request, task, type, props, ref) { 5838 pushFunctionComponentStackInDEV(task, type.render); 5839 var children = renderWithHooks(request, task, type.render, props, ref); 5840 var hasId = checkDidRenderIdHook(); 5841 5842 if (hasId) { 5843 // This component materialized an id. We treat this as its own level, with 5844 // a single "child" slot. 5845 var prevTreeContext = task.treeContext; 5846 var totalChildren = 1; 5847 var index = 0; 5848 task.treeContext = pushTreeContext(prevTreeContext, totalChildren, index); 5849 5850 try { 5851 renderNodeDestructive(request, task, children); 5852 } finally { 5853 task.treeContext = prevTreeContext; 5854 } 5855 } else { 5856 renderNodeDestructive(request, task, children); 5857 } 5858 5859 popComponentStackInDEV(task); 5860 } 5861 5862 function renderMemo(request, task, type, props, ref) { 5863 var innerType = type.type; 5864 var resolvedProps = resolveDefaultProps(innerType, props); 5865 renderElement(request, task, innerType, resolvedProps, ref); 5866 } 5867 5868 function renderContextConsumer(request, task, context, props) { 5869 // The logic below for Context differs depending on PROD or DEV mode. In 5870 // DEV mode, we create a separate object for Context.Consumer that acts 5871 // like a proxy to Context. This proxy object adds unnecessary code in PROD 5872 // so we use the old behaviour (Context.Consumer references Context) to 5873 // reduce size and overhead. The separate object references context via 5874 // a property called "_context", which also gives us the ability to check 5875 // in DEV mode if this property exists or not and warn if it does not. 5876 { 5877 if (context._context === undefined) { 5878 // This may be because it's a Context (rather than a Consumer). 5879 // Or it may be because it's older React where they're the same thing. 5880 // We only want to warn if we're sure it's a new React. 5881 if (context !== context.Consumer) { 5882 if (!hasWarnedAboutUsingContextAsConsumer) { 5883 hasWarnedAboutUsingContextAsConsumer = true; 5884 5885 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?'); 5886 } 5887 } 5888 } else { 5889 context = context._context; 5890 } 5891 } 5892 5893 var render = props.children; 5894 5895 { 5896 if (typeof render !== 'function') { 5897 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.'); 5898 } 5899 } 5900 5901 var newValue = readContext(context); 5902 var newChildren = render(newValue); 5903 renderNodeDestructive(request, task, newChildren); 5904 } 5905 5906 function renderContextProvider(request, task, type, props) { 5907 var context = type._context; 5908 var value = props.value; 5909 var children = props.children; 5910 var prevSnapshot; 5911 5912 { 5913 prevSnapshot = task.context; 5914 } 5915 5916 task.context = pushProvider(context, value); 5917 renderNodeDestructive(request, task, children); 5918 task.context = popProvider(context); 5919 5920 { 5921 if (prevSnapshot !== task.context) { 5922 error('Popping the context provider did not return back to the original snapshot. This is a bug in React.'); 5923 } 5924 } 5925 } 5926 5927 function renderLazyComponent(request, task, lazyComponent, props, ref) { 5928 pushBuiltInComponentStackInDEV(task, 'Lazy'); 5929 var payload = lazyComponent._payload; 5930 var init = lazyComponent._init; 5931 var Component = init(payload); 5932 var resolvedProps = resolveDefaultProps(Component, props); 5933 renderElement(request, task, Component, resolvedProps, ref); 5934 popComponentStackInDEV(task); 5935 } 5936 5937 function renderElement(request, task, type, props, ref) { 5938 if (typeof type === 'function') { 5939 if (shouldConstruct$1(type)) { 5940 renderClassComponent(request, task, type, props); 5941 return; 5942 } else { 5943 renderIndeterminateComponent(request, task, type, props); 5944 return; 5945 } 5946 } 5947 5948 if (typeof type === 'string') { 5949 renderHostElement(request, task, type, props); 5950 return; 5951 } 5952 5953 switch (type) { 5954 // TODO: LegacyHidden acts the same as a fragment. This only works 5955 // because we currently assume that every instance of LegacyHidden is 5956 // accompanied by a host component wrapper. In the hidden mode, the host 5957 // component is given a `hidden` attribute, which ensures that the 5958 // initial HTML is not visible. To support the use of LegacyHidden as a 5959 // true fragment, without an extra DOM node, we would have to hide the 5960 // initial HTML in some other way. 5961 // TODO: Add REACT_OFFSCREEN_TYPE here too with the same capability. 5962 case REACT_LEGACY_HIDDEN_TYPE: 5963 case REACT_DEBUG_TRACING_MODE_TYPE: 5964 case REACT_STRICT_MODE_TYPE: 5965 case REACT_PROFILER_TYPE: 5966 case REACT_FRAGMENT_TYPE: 5967 { 5968 renderNodeDestructive(request, task, props.children); 5969 return; 5970 } 5971 5972 case REACT_SUSPENSE_LIST_TYPE: 5973 { 5974 pushBuiltInComponentStackInDEV(task, 'SuspenseList'); // TODO: SuspenseList should control the boundaries. 5975 5976 renderNodeDestructive(request, task, props.children); 5977 popComponentStackInDEV(task); 5978 return; 5979 } 5980 5981 case REACT_SCOPE_TYPE: 5982 { 5983 5984 throw new Error('ReactDOMServer does not yet support scope components.'); 5985 } 5986 // eslint-disable-next-line-no-fallthrough 5987 5988 case REACT_SUSPENSE_TYPE: 5989 { 5990 { 5991 renderSuspenseBoundary(request, task, props); 5992 } 5993 5994 return; 5995 } 5996 } 5997 5998 if (typeof type === 'object' && type !== null) { 5999 switch (type.$$typeof) { 6000 case REACT_FORWARD_REF_TYPE: 6001 { 6002 renderForwardRef(request, task, type, props, ref); 6003 return; 6004 } 6005 6006 case REACT_MEMO_TYPE: 6007 { 6008 renderMemo(request, task, type, props, ref); 6009 return; 6010 } 6011 6012 case REACT_PROVIDER_TYPE: 6013 { 6014 renderContextProvider(request, task, type, props); 6015 return; 6016 } 6017 6018 case REACT_CONTEXT_TYPE: 6019 { 6020 renderContextConsumer(request, task, type, props); 6021 return; 6022 } 6023 6024 case REACT_LAZY_TYPE: 6025 { 6026 renderLazyComponent(request, task, type, props); 6027 return; 6028 } 6029 } 6030 } 6031 6032 var info = ''; 6033 6034 { 6035 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { 6036 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.'; 6037 } 6038 } 6039 6040 throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info)); 6041 } 6042 6043 function validateIterable(iterable, iteratorFn) { 6044 { 6045 // We don't support rendering Generators because it's a mutation. 6046 // See https://github.com/facebook/react/issues/12995 6047 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag 6048 iterable[Symbol.toStringTag] === 'Generator') { 6049 if (!didWarnAboutGenerators) { 6050 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.'); 6051 } 6052 6053 didWarnAboutGenerators = true; 6054 } // Warn about using Maps as children 6055 6056 6057 if (iterable.entries === iteratorFn) { 6058 if (!didWarnAboutMaps) { 6059 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.'); 6060 } 6061 6062 didWarnAboutMaps = true; 6063 } 6064 } 6065 } 6066 6067 function renderNodeDestructive(request, task, node) { 6068 { 6069 // In Dev we wrap renderNodeDestructiveImpl in a try / catch so we can capture 6070 // a component stack at the right place in the tree. We don't do this in renderNode 6071 // becuase it is not called at every layer of the tree and we may lose frames 6072 try { 6073 return renderNodeDestructiveImpl(request, task, node); 6074 } catch (x) { 6075 if (typeof x === 'object' && x !== null && typeof x.then === 'function') ; else { 6076 // This is an error, stash the component stack if it is null. 6077 lastBoundaryErrorComponentStackDev = lastBoundaryErrorComponentStackDev !== null ? lastBoundaryErrorComponentStackDev : getCurrentStackInDEV(); 6078 } // rethrow so normal suspense logic can handle thrown value accordingly 6079 6080 6081 throw x; 6082 } 6083 } 6084 } // This function by it self renders a node and consumes the task by mutating it 6085 // to update the current execution state. 6086 6087 6088 function renderNodeDestructiveImpl(request, task, node) { 6089 // Stash the node we're working on. We'll pick up from this task in case 6090 // something suspends. 6091 task.node = node; // Handle object types 6092 6093 if (typeof node === 'object' && node !== null) { 6094 switch (node.$$typeof) { 6095 case REACT_ELEMENT_TYPE: 6096 { 6097 var element = node; 6098 var type = element.type; 6099 var props = element.props; 6100 var ref = element.ref; 6101 renderElement(request, task, type, props, ref); 6102 return; 6103 } 6104 6105 case REACT_PORTAL_TYPE: 6106 throw new Error('Portals are not currently supported by the server renderer. ' + 'Render them conditionally so that they only appear on the client render.'); 6107 // eslint-disable-next-line-no-fallthrough 6108 6109 case REACT_LAZY_TYPE: 6110 { 6111 var lazyNode = node; 6112 var payload = lazyNode._payload; 6113 var init = lazyNode._init; 6114 var resolvedNode; 6115 6116 { 6117 try { 6118 resolvedNode = init(payload); 6119 } catch (x) { 6120 if (typeof x === 'object' && x !== null && typeof x.then === 'function') { 6121 // this Lazy initializer is suspending. push a temporary frame onto the stack so it can be 6122 // popped off in spawnNewSuspendedTask. This aligns stack behavior between Lazy in element position 6123 // vs Component position. We do not want the frame for Errors so we exclusively do this in 6124 // the wakeable branch 6125 pushBuiltInComponentStackInDEV(task, 'Lazy'); 6126 } 6127 6128 throw x; 6129 } 6130 } 6131 6132 renderNodeDestructive(request, task, resolvedNode); 6133 return; 6134 } 6135 } 6136 6137 if (isArray(node)) { 6138 renderChildrenArray(request, task, node); 6139 return; 6140 } 6141 6142 var iteratorFn = getIteratorFn(node); 6143 6144 if (iteratorFn) { 6145 { 6146 validateIterable(node, iteratorFn); 6147 } 6148 6149 var iterator = iteratorFn.call(node); 6150 6151 if (iterator) { 6152 // We need to know how many total children are in this set, so that we 6153 // can allocate enough id slots to acommodate them. So we must exhaust 6154 // the iterator before we start recursively rendering the children. 6155 // TODO: This is not great but I think it's inherent to the id 6156 // generation algorithm. 6157 var step = iterator.next(); // If there are not entries, we need to push an empty so we start by checking that. 6158 6159 if (!step.done) { 6160 var children = []; 6161 6162 do { 6163 children.push(step.value); 6164 step = iterator.next(); 6165 } while (!step.done); 6166 6167 renderChildrenArray(request, task, children); 6168 return; 6169 } 6170 6171 return; 6172 } 6173 } 6174 6175 var childString = Object.prototype.toString.call(node); 6176 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(node).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.'); 6177 } 6178 6179 if (typeof node === 'string') { 6180 var segment = task.blockedSegment; 6181 segment.lastPushedText = pushTextInstance(task.blockedSegment.chunks, node, request.responseState, segment.lastPushedText); 6182 return; 6183 } 6184 6185 if (typeof node === 'number') { 6186 var _segment = task.blockedSegment; 6187 _segment.lastPushedText = pushTextInstance(task.blockedSegment.chunks, '' + node, request.responseState, _segment.lastPushedText); 6188 return; 6189 } 6190 6191 { 6192 if (typeof node === 'function') { 6193 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.'); 6194 } 6195 } 6196 } 6197 6198 function renderChildrenArray(request, task, children) { 6199 var totalChildren = children.length; 6200 6201 for (var i = 0; i < totalChildren; i++) { 6202 var prevTreeContext = task.treeContext; 6203 task.treeContext = pushTreeContext(prevTreeContext, totalChildren, i); 6204 6205 try { 6206 // We need to use the non-destructive form so that we can safely pop back 6207 // up and render the sibling if something suspends. 6208 renderNode(request, task, children[i]); 6209 } finally { 6210 task.treeContext = prevTreeContext; 6211 } 6212 } 6213 } 6214 6215 function spawnNewSuspendedTask(request, task, x) { 6216 // Something suspended, we'll need to create a new segment and resolve it later. 6217 var segment = task.blockedSegment; 6218 var insertionIndex = segment.chunks.length; 6219 var newSegment = createPendingSegment(request, insertionIndex, null, segment.formatContext, // Adopt the parent segment's leading text embed 6220 segment.lastPushedText, // Assume we are text embedded at the trailing edge 6221 true); 6222 segment.children.push(newSegment); // Reset lastPushedText for current Segment since the new Segment "consumed" it 6223 6224 segment.lastPushedText = false; 6225 var newTask = createTask(request, task.node, task.blockedBoundary, newSegment, task.abortSet, task.legacyContext, task.context, task.treeContext); 6226 6227 { 6228 if (task.componentStack !== null) { 6229 // We pop one task off the stack because the node that suspended will be tried again, 6230 // which will add it back onto the stack. 6231 newTask.componentStack = task.componentStack.parent; 6232 } 6233 } 6234 6235 var ping = newTask.ping; 6236 x.then(ping, ping); 6237 } // This is a non-destructive form of rendering a node. If it suspends it spawns 6238 // a new task and restores the context of this task to what it was before. 6239 6240 6241 function renderNode(request, task, node) { 6242 // TODO: Store segment.children.length here and reset it in case something 6243 // suspended partially through writing something. 6244 // Snapshot the current context in case something throws to interrupt the 6245 // process. 6246 var previousFormatContext = task.blockedSegment.formatContext; 6247 var previousLegacyContext = task.legacyContext; 6248 var previousContext = task.context; 6249 var previousComponentStack = null; 6250 6251 { 6252 previousComponentStack = task.componentStack; 6253 } 6254 6255 try { 6256 return renderNodeDestructive(request, task, node); 6257 } catch (x) { 6258 resetHooksState(); 6259 6260 if (typeof x === 'object' && x !== null && typeof x.then === 'function') { 6261 spawnNewSuspendedTask(request, task, x); // Restore the context. We assume that this will be restored by the inner 6262 // functions in case nothing throws so we don't use "finally" here. 6263 6264 task.blockedSegment.formatContext = previousFormatContext; 6265 task.legacyContext = previousLegacyContext; 6266 task.context = previousContext; // Restore all active ReactContexts to what they were before. 6267 6268 switchContext(previousContext); 6269 6270 { 6271 task.componentStack = previousComponentStack; 6272 } 6273 6274 return; 6275 } else { 6276 // Restore the context. We assume that this will be restored by the inner 6277 // functions in case nothing throws so we don't use "finally" here. 6278 task.blockedSegment.formatContext = previousFormatContext; 6279 task.legacyContext = previousLegacyContext; 6280 task.context = previousContext; // Restore all active ReactContexts to what they were before. 6281 6282 switchContext(previousContext); 6283 6284 { 6285 task.componentStack = previousComponentStack; 6286 } // We assume that we don't need the correct context. 6287 // Let's terminate the rest of the tree and don't render any siblings. 6288 6289 6290 throw x; 6291 } 6292 } 6293 } 6294 6295 function erroredTask(request, boundary, segment, error) { 6296 // Report the error to a global handler. 6297 var errorDigest = logRecoverableError(request, error); 6298 6299 if (boundary === null) { 6300 fatalError(request, error); 6301 } else { 6302 boundary.pendingTasks--; 6303 6304 if (!boundary.forceClientRender) { 6305 boundary.forceClientRender = true; 6306 boundary.errorDigest = errorDigest; 6307 6308 { 6309 captureBoundaryErrorDetailsDev(boundary, error); 6310 } // Regardless of what happens next, this boundary won't be displayed, 6311 // so we can flush it, if the parent already flushed. 6312 6313 6314 if (boundary.parentFlushed) { 6315 // We don't have a preference where in the queue this goes since it's likely 6316 // to error on the client anyway. However, intentionally client-rendered 6317 // boundaries should be flushed earlier so that they can start on the client. 6318 // We reuse the same queue for errors. 6319 request.clientRenderedBoundaries.push(boundary); 6320 } 6321 } 6322 } 6323 6324 request.allPendingTasks--; 6325 6326 if (request.allPendingTasks === 0) { 6327 var onAllReady = request.onAllReady; 6328 onAllReady(); 6329 } 6330 } 6331 6332 function abortTaskSoft(task) { 6333 // This aborts task without aborting the parent boundary that it blocks. 6334 // It's used for when we didn't need this task to complete the tree. 6335 // If task was needed, then it should use abortTask instead. 6336 var request = this; 6337 var boundary = task.blockedBoundary; 6338 var segment = task.blockedSegment; 6339 segment.status = ABORTED; 6340 finishedTask(request, boundary, segment); 6341 } 6342 6343 function abortTask(task, request, reason) { 6344 // This aborts the task and aborts the parent that it blocks, putting it into 6345 // client rendered mode. 6346 var boundary = task.blockedBoundary; 6347 var segment = task.blockedSegment; 6348 segment.status = ABORTED; 6349 6350 if (boundary === null) { 6351 request.allPendingTasks--; // We didn't complete the root so we have nothing to show. We can close 6352 // the request; 6353 6354 if (request.status !== CLOSED) { 6355 request.status = CLOSED; 6356 6357 if (request.destination !== null) { 6358 close(request.destination); 6359 } 6360 } 6361 } else { 6362 boundary.pendingTasks--; 6363 6364 if (!boundary.forceClientRender) { 6365 boundary.forceClientRender = true; 6366 6367 var _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; 6368 6369 boundary.errorDigest = request.onError(_error); 6370 6371 { 6372 var errorPrefix = 'The server did not finish this Suspense boundary: '; 6373 6374 if (_error && typeof _error.message === 'string') { 6375 _error = errorPrefix + _error.message; 6376 } else { 6377 // eslint-disable-next-line react-internal/safe-string-coercion 6378 _error = errorPrefix + String(_error); 6379 } 6380 6381 var previousTaskInDev = currentTaskInDEV; 6382 currentTaskInDEV = task; 6383 6384 try { 6385 captureBoundaryErrorDetailsDev(boundary, _error); 6386 } finally { 6387 currentTaskInDEV = previousTaskInDev; 6388 } 6389 } 6390 6391 if (boundary.parentFlushed) { 6392 request.clientRenderedBoundaries.push(boundary); 6393 } 6394 } // If this boundary was still pending then we haven't already cancelled its fallbacks. 6395 // We'll need to abort the fallbacks, which will also error that parent boundary. 6396 6397 6398 boundary.fallbackAbortableTasks.forEach(function (fallbackTask) { 6399 return abortTask(fallbackTask, request, reason); 6400 }); 6401 boundary.fallbackAbortableTasks.clear(); 6402 request.allPendingTasks--; 6403 6404 if (request.allPendingTasks === 0) { 6405 var onAllReady = request.onAllReady; 6406 onAllReady(); 6407 } 6408 } 6409 } 6410 6411 function queueCompletedSegment(boundary, segment) { 6412 if (segment.chunks.length === 0 && segment.children.length === 1 && segment.children[0].boundary === null) { 6413 // This is an empty segment. There's nothing to write, so we can instead transfer the ID 6414 // to the child. That way any existing references point to the child. 6415 var childSegment = segment.children[0]; 6416 childSegment.id = segment.id; 6417 childSegment.parentFlushed = true; 6418 6419 if (childSegment.status === COMPLETED) { 6420 queueCompletedSegment(boundary, childSegment); 6421 } 6422 } else { 6423 var completedSegments = boundary.completedSegments; 6424 completedSegments.push(segment); 6425 } 6426 } 6427 6428 function finishedTask(request, boundary, segment) { 6429 if (boundary === null) { 6430 if (segment.parentFlushed) { 6431 if (request.completedRootSegment !== null) { 6432 throw new Error('There can only be one root segment. This is a bug in React.'); 6433 } 6434 6435 request.completedRootSegment = segment; 6436 } 6437 6438 request.pendingRootTasks--; 6439 6440 if (request.pendingRootTasks === 0) { 6441 // We have completed the shell so the shell can't error anymore. 6442 request.onShellError = noop$1; 6443 var onShellReady = request.onShellReady; 6444 onShellReady(); 6445 } 6446 } else { 6447 boundary.pendingTasks--; 6448 6449 if (boundary.forceClientRender) ; else if (boundary.pendingTasks === 0) { 6450 // This must have been the last segment we were waiting on. This boundary is now complete. 6451 if (segment.parentFlushed) { 6452 // Our parent segment already flushed, so we need to schedule this segment to be emitted. 6453 // If it is a segment that was aborted, we'll write other content instead so we don't need 6454 // to emit it. 6455 if (segment.status === COMPLETED) { 6456 queueCompletedSegment(boundary, segment); 6457 } 6458 } 6459 6460 if (boundary.parentFlushed) { 6461 // The segment might be part of a segment that didn't flush yet, but if the boundary's 6462 // parent flushed, we need to schedule the boundary to be emitted. 6463 request.completedBoundaries.push(boundary); 6464 } // We can now cancel any pending task on the fallback since we won't need to show it anymore. 6465 // This needs to happen after we read the parentFlushed flags because aborting can finish 6466 // work which can trigger user code, which can start flushing, which can change those flags. 6467 6468 6469 boundary.fallbackAbortableTasks.forEach(abortTaskSoft, request); 6470 boundary.fallbackAbortableTasks.clear(); 6471 } else { 6472 if (segment.parentFlushed) { 6473 // Our parent already flushed, so we need to schedule this segment to be emitted. 6474 // If it is a segment that was aborted, we'll write other content instead so we don't need 6475 // to emit it. 6476 if (segment.status === COMPLETED) { 6477 queueCompletedSegment(boundary, segment); 6478 var completedSegments = boundary.completedSegments; 6479 6480 if (completedSegments.length === 1) { 6481 // This is the first time since we last flushed that we completed anything. 6482 // We can schedule this boundary to emit its partially completed segments early 6483 // in case the parent has already been flushed. 6484 if (boundary.parentFlushed) { 6485 request.partialBoundaries.push(boundary); 6486 } 6487 } 6488 } 6489 } 6490 } 6491 } 6492 6493 request.allPendingTasks--; 6494 6495 if (request.allPendingTasks === 0) { 6496 // This needs to be called at the very end so that we can synchronously write the result 6497 // in the callback if needed. 6498 var onAllReady = request.onAllReady; 6499 onAllReady(); 6500 } 6501 } 6502 6503 function retryTask(request, task) { 6504 var segment = task.blockedSegment; 6505 6506 if (segment.status !== PENDING) { 6507 // We completed this by other means before we had a chance to retry it. 6508 return; 6509 } // We restore the context to what it was when we suspended. 6510 // We don't restore it after we leave because it's likely that we'll end up 6511 // needing a very similar context soon again. 6512 6513 6514 switchContext(task.context); 6515 var prevTaskInDEV = null; 6516 6517 { 6518 prevTaskInDEV = currentTaskInDEV; 6519 currentTaskInDEV = task; 6520 } 6521 6522 try { 6523 // We call the destructive form that mutates this task. That way if something 6524 // suspends again, we can reuse the same task instead of spawning a new one. 6525 renderNodeDestructive(request, task, task.node); 6526 pushSegmentFinale(segment.chunks, request.responseState, segment.lastPushedText, segment.textEmbedded); 6527 task.abortSet.delete(task); 6528 segment.status = COMPLETED; 6529 finishedTask(request, task.blockedBoundary, segment); 6530 } catch (x) { 6531 resetHooksState(); 6532 6533 if (typeof x === 'object' && x !== null && typeof x.then === 'function') { 6534 // Something suspended again, let's pick it back up later. 6535 var ping = task.ping; 6536 x.then(ping, ping); 6537 } else { 6538 task.abortSet.delete(task); 6539 segment.status = ERRORED; 6540 erroredTask(request, task.blockedBoundary, segment, x); 6541 } 6542 } finally { 6543 { 6544 currentTaskInDEV = prevTaskInDEV; 6545 } 6546 } 6547 } 6548 6549 function performWork(request) { 6550 if (request.status === CLOSED) { 6551 return; 6552 } 6553 6554 var prevContext = getActiveContext(); 6555 var prevDispatcher = ReactCurrentDispatcher$1.current; 6556 ReactCurrentDispatcher$1.current = Dispatcher; 6557 var prevGetCurrentStackImpl; 6558 6559 { 6560 prevGetCurrentStackImpl = ReactDebugCurrentFrame$1.getCurrentStack; 6561 ReactDebugCurrentFrame$1.getCurrentStack = getCurrentStackInDEV; 6562 } 6563 6564 var prevResponseState = currentResponseState; 6565 setCurrentResponseState(request.responseState); 6566 6567 try { 6568 var pingedTasks = request.pingedTasks; 6569 var i; 6570 6571 for (i = 0; i < pingedTasks.length; i++) { 6572 var task = pingedTasks[i]; 6573 retryTask(request, task); 6574 } 6575 6576 pingedTasks.splice(0, i); 6577 6578 if (request.destination !== null) { 6579 flushCompletedQueues(request, request.destination); 6580 } 6581 } catch (error) { 6582 logRecoverableError(request, error); 6583 fatalError(request, error); 6584 } finally { 6585 setCurrentResponseState(prevResponseState); 6586 ReactCurrentDispatcher$1.current = prevDispatcher; 6587 6588 { 6589 ReactDebugCurrentFrame$1.getCurrentStack = prevGetCurrentStackImpl; 6590 } 6591 6592 if (prevDispatcher === Dispatcher) { 6593 // This means that we were in a reentrant work loop. This could happen 6594 // in a renderer that supports synchronous work like renderToString, 6595 // when it's called from within another renderer. 6596 // Normally we don't bother switching the contexts to their root/default 6597 // values when leaving because we'll likely need the same or similar 6598 // context again. However, when we're inside a synchronous loop like this 6599 // we'll to restore the context to what it was before returning. 6600 switchContext(prevContext); 6601 } 6602 } 6603 } 6604 6605 function flushSubtree(request, destination, segment) { 6606 segment.parentFlushed = true; 6607 6608 switch (segment.status) { 6609 case PENDING: 6610 { 6611 // We're emitting a placeholder for this segment to be filled in later. 6612 // Therefore we'll need to assign it an ID - to refer to it by. 6613 var segmentID = segment.id = request.nextSegmentId++; // When this segment finally completes it won't be embedded in text since it will flush separately 6614 6615 segment.lastPushedText = false; 6616 segment.textEmbedded = false; 6617 return writePlaceholder(destination, request.responseState, segmentID); 6618 } 6619 6620 case COMPLETED: 6621 { 6622 segment.status = FLUSHED; 6623 var r = true; 6624 var chunks = segment.chunks; 6625 var chunkIdx = 0; 6626 var children = segment.children; 6627 6628 for (var childIdx = 0; childIdx < children.length; childIdx++) { 6629 var nextChild = children[childIdx]; // Write all the chunks up until the next child. 6630 6631 for (; chunkIdx < nextChild.index; chunkIdx++) { 6632 writeChunk(destination, chunks[chunkIdx]); 6633 } 6634 6635 r = flushSegment(request, destination, nextChild); 6636 } // Finally just write all the remaining chunks 6637 6638 6639 for (; chunkIdx < chunks.length - 1; chunkIdx++) { 6640 writeChunk(destination, chunks[chunkIdx]); 6641 } 6642 6643 if (chunkIdx < chunks.length) { 6644 r = writeChunkAndReturn(destination, chunks[chunkIdx]); 6645 } 6646 6647 return r; 6648 } 6649 6650 default: 6651 { 6652 throw new Error('Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.'); 6653 } 6654 } 6655 } 6656 6657 function flushSegment(request, destination, segment) { 6658 var boundary = segment.boundary; 6659 6660 if (boundary === null) { 6661 // Not a suspense boundary. 6662 return flushSubtree(request, destination, segment); 6663 } 6664 6665 boundary.parentFlushed = true; // This segment is a Suspense boundary. We need to decide whether to 6666 // emit the content or the fallback now. 6667 6668 if (boundary.forceClientRender) { 6669 // Emit a client rendered suspense boundary wrapper. 6670 // We never queue the inner boundary so we'll never emit its content or partial segments. 6671 writeStartClientRenderedSuspenseBoundary(destination, request.responseState, boundary.errorDigest, boundary.errorMessage, boundary.errorComponentStack); // Flush the fallback. 6672 6673 flushSubtree(request, destination, segment); 6674 return writeEndClientRenderedSuspenseBoundary(destination, request.responseState); 6675 } else if (boundary.pendingTasks > 0) { 6676 // This boundary is still loading. Emit a pending suspense boundary wrapper. 6677 // Assign an ID to refer to the future content by. 6678 boundary.rootSegmentID = request.nextSegmentId++; 6679 6680 if (boundary.completedSegments.length > 0) { 6681 // If this is at least partially complete, we can queue it to be partially emitted early. 6682 request.partialBoundaries.push(boundary); 6683 } /// This is the first time we should have referenced this ID. 6684 6685 6686 var id = boundary.id = assignSuspenseBoundaryID(request.responseState); 6687 writeStartPendingSuspenseBoundary(destination, request.responseState, id); // Flush the fallback. 6688 6689 flushSubtree(request, destination, segment); 6690 return writeEndPendingSuspenseBoundary(destination, request.responseState); 6691 } else if (boundary.byteSize > request.progressiveChunkSize) { 6692 // This boundary is large and will be emitted separately so that we can progressively show 6693 // other content. We add it to the queue during the flush because we have to ensure that 6694 // the parent flushes first so that there's something to inject it into. 6695 // We also have to make sure that it's emitted into the queue in a deterministic slot. 6696 // I.e. we can't insert it here when it completes. 6697 // Assign an ID to refer to the future content by. 6698 boundary.rootSegmentID = request.nextSegmentId++; 6699 request.completedBoundaries.push(boundary); // Emit a pending rendered suspense boundary wrapper. 6700 6701 writeStartPendingSuspenseBoundary(destination, request.responseState, boundary.id); // Flush the fallback. 6702 6703 flushSubtree(request, destination, segment); 6704 return writeEndPendingSuspenseBoundary(destination, request.responseState); 6705 } else { 6706 // We can inline this boundary's content as a complete boundary. 6707 writeStartCompletedSuspenseBoundary(destination, request.responseState); 6708 var completedSegments = boundary.completedSegments; 6709 6710 if (completedSegments.length !== 1) { 6711 throw new Error('A previously unvisited boundary must have exactly one root segment. This is a bug in React.'); 6712 } 6713 6714 var contentSegment = completedSegments[0]; 6715 flushSegment(request, destination, contentSegment); 6716 return writeEndCompletedSuspenseBoundary(destination, request.responseState); 6717 } 6718 } 6719 6720 function flushClientRenderedBoundary(request, destination, boundary) { 6721 return writeClientRenderBoundaryInstruction(destination, request.responseState, boundary.id, boundary.errorDigest, boundary.errorMessage, boundary.errorComponentStack); 6722 } 6723 6724 function flushSegmentContainer(request, destination, segment) { 6725 writeStartSegment(destination, request.responseState, segment.formatContext, segment.id); 6726 flushSegment(request, destination, segment); 6727 return writeEndSegment(destination, segment.formatContext); 6728 } 6729 6730 function flushCompletedBoundary(request, destination, boundary) { 6731 var completedSegments = boundary.completedSegments; 6732 var i = 0; 6733 6734 for (; i < completedSegments.length; i++) { 6735 var segment = completedSegments[i]; 6736 flushPartiallyCompletedSegment(request, destination, boundary, segment); 6737 } 6738 6739 completedSegments.length = 0; 6740 return writeCompletedBoundaryInstruction(destination, request.responseState, boundary.id, boundary.rootSegmentID); 6741 } 6742 6743 function flushPartialBoundary(request, destination, boundary) { 6744 var completedSegments = boundary.completedSegments; 6745 var i = 0; 6746 6747 for (; i < completedSegments.length; i++) { 6748 var segment = completedSegments[i]; 6749 6750 if (!flushPartiallyCompletedSegment(request, destination, boundary, segment)) { 6751 i++; 6752 completedSegments.splice(0, i); // Only write as much as the buffer wants. Something higher priority 6753 // might want to write later. 6754 6755 return false; 6756 } 6757 } 6758 6759 completedSegments.splice(0, i); 6760 return true; 6761 } 6762 6763 function flushPartiallyCompletedSegment(request, destination, boundary, segment) { 6764 if (segment.status === FLUSHED) { 6765 // We've already flushed this inline. 6766 return true; 6767 } 6768 6769 var segmentID = segment.id; 6770 6771 if (segmentID === -1) { 6772 // This segment wasn't previously referred to. This happens at the root of 6773 // a boundary. We make kind of a leap here and assume this is the root. 6774 var rootSegmentID = segment.id = boundary.rootSegmentID; 6775 6776 if (rootSegmentID === -1) { 6777 throw new Error('A root segment ID must have been assigned by now. This is a bug in React.'); 6778 } 6779 6780 return flushSegmentContainer(request, destination, segment); 6781 } else { 6782 flushSegmentContainer(request, destination, segment); 6783 return writeCompletedSegmentInstruction(destination, request.responseState, segmentID); 6784 } 6785 } 6786 6787 function flushCompletedQueues(request, destination) { 6788 beginWriting(); 6789 6790 try { 6791 // The structure of this is to go through each queue one by one and write 6792 // until the sink tells us to stop. When we should stop, we still finish writing 6793 // that item fully and then yield. At that point we remove the already completed 6794 // items up until the point we completed them. 6795 // TODO: Emit preloading. 6796 // TODO: It's kind of unfortunate to keep checking this array after we've already 6797 // emitted the root. 6798 var completedRootSegment = request.completedRootSegment; 6799 6800 if (completedRootSegment !== null && request.pendingRootTasks === 0) { 6801 flushSegment(request, destination, completedRootSegment); 6802 request.completedRootSegment = null; 6803 writeCompletedRoot(destination, request.responseState); 6804 } // We emit client rendering instructions for already emitted boundaries first. 6805 // This is so that we can signal to the client to start client rendering them as 6806 // soon as possible. 6807 6808 6809 var clientRenderedBoundaries = request.clientRenderedBoundaries; 6810 var i; 6811 6812 for (i = 0; i < clientRenderedBoundaries.length; i++) { 6813 var boundary = clientRenderedBoundaries[i]; 6814 6815 if (!flushClientRenderedBoundary(request, destination, boundary)) { 6816 request.destination = null; 6817 i++; 6818 clientRenderedBoundaries.splice(0, i); 6819 return; 6820 } 6821 } 6822 6823 clientRenderedBoundaries.splice(0, i); // Next we emit any complete boundaries. It's better to favor boundaries 6824 // that are completely done since we can actually show them, than it is to emit 6825 // any individual segments from a partially complete boundary. 6826 6827 var completedBoundaries = request.completedBoundaries; 6828 6829 for (i = 0; i < completedBoundaries.length; i++) { 6830 var _boundary = completedBoundaries[i]; 6831 6832 if (!flushCompletedBoundary(request, destination, _boundary)) { 6833 request.destination = null; 6834 i++; 6835 completedBoundaries.splice(0, i); 6836 return; 6837 } 6838 } 6839 6840 completedBoundaries.splice(0, i); // Allow anything written so far to flush to the underlying sink before 6841 // we continue with lower priorities. 6842 6843 completeWriting(destination); 6844 beginWriting(destination); // TODO: Here we'll emit data used by hydration. 6845 // Next we emit any segments of any boundaries that are partially complete 6846 // but not deeply complete. 6847 6848 var partialBoundaries = request.partialBoundaries; 6849 6850 for (i = 0; i < partialBoundaries.length; i++) { 6851 var _boundary2 = partialBoundaries[i]; 6852 6853 if (!flushPartialBoundary(request, destination, _boundary2)) { 6854 request.destination = null; 6855 i++; 6856 partialBoundaries.splice(0, i); 6857 return; 6858 } 6859 } 6860 6861 partialBoundaries.splice(0, i); // Next we check the completed boundaries again. This may have had 6862 // boundaries added to it in case they were too larged to be inlined. 6863 // New ones might be added in this loop. 6864 6865 var largeBoundaries = request.completedBoundaries; 6866 6867 for (i = 0; i < largeBoundaries.length; i++) { 6868 var _boundary3 = largeBoundaries[i]; 6869 6870 if (!flushCompletedBoundary(request, destination, _boundary3)) { 6871 request.destination = null; 6872 i++; 6873 largeBoundaries.splice(0, i); 6874 return; 6875 } 6876 } 6877 6878 largeBoundaries.splice(0, i); 6879 } finally { 6880 completeWriting(destination); 6881 6882 if (request.allPendingTasks === 0 && request.pingedTasks.length === 0 && request.clientRenderedBoundaries.length === 0 && request.completedBoundaries.length === 0 // We don't need to check any partially completed segments because 6883 // either they have pending task or they're complete. 6884 ) { 6885 { 6886 if (request.abortableTasks.size !== 0) { 6887 error('There was still abortable task at the root when we closed. This is a bug in React.'); 6888 } 6889 } // We're done. 6890 6891 6892 close(destination); 6893 } 6894 } 6895 } 6896 6897 function startWork(request) { 6898 scheduleWork(function () { 6899 return performWork(request); 6900 }); 6901 } 6902 function startFlowing(request, destination) { 6903 if (request.status === CLOSING) { 6904 request.status = CLOSED; 6905 closeWithError(destination, request.fatalError); 6906 return; 6907 } 6908 6909 if (request.status === CLOSED) { 6910 return; 6911 } 6912 6913 if (request.destination !== null) { 6914 // We're already flowing. 6915 return; 6916 } 6917 6918 request.destination = destination; 6919 6920 try { 6921 flushCompletedQueues(request, destination); 6922 } catch (error) { 6923 logRecoverableError(request, error); 6924 fatalError(request, error); 6925 } 6926 } // This is called to early terminate a request. It puts all pending boundaries in client rendered state. 6927 6928 function abort(request, reason) { 6929 try { 6930 var abortableTasks = request.abortableTasks; 6931 abortableTasks.forEach(function (task) { 6932 return abortTask(task, request, reason); 6933 }); 6934 abortableTasks.clear(); 6935 6936 if (request.destination !== null) { 6937 flushCompletedQueues(request, request.destination); 6938 } 6939 } catch (error) { 6940 logRecoverableError(request, error); 6941 fatalError(request, error); 6942 } 6943 } 6944 6945 function renderToReadableStream(children, options) { 6946 return new Promise(function (resolve, reject) { 6947 var onFatalError; 6948 var onAllReady; 6949 var allReady = new Promise(function (res, rej) { 6950 onAllReady = res; 6951 onFatalError = rej; 6952 }); 6953 6954 function onShellReady() { 6955 var stream = new ReadableStream({ 6956 type: 'bytes', 6957 pull: function (controller) { 6958 startFlowing(request, controller); 6959 }, 6960 cancel: function (reason) { 6961 abort(request); 6962 } 6963 }, // $FlowFixMe size() methods are not allowed on byte streams. 6964 { 6965 highWaterMark: 0 6966 }); // TODO: Move to sub-classing ReadableStream. 6967 6968 stream.allReady = allReady; 6969 resolve(stream); 6970 } 6971 6972 function onShellError(error) { 6973 // If the shell errors the caller of `renderToReadableStream` won't have access to `allReady`. 6974 // However, `allReady` will be rejected by `onFatalError` as well. 6975 // So we need to catch the duplicate, uncatchable fatal error in `allReady` to prevent a `UnhandledPromiseRejection`. 6976 allReady.catch(function () {}); 6977 reject(error); 6978 } 6979 6980 var request = createRequest(children, createResponseState(options ? options.identifierPrefix : undefined, options ? options.nonce : undefined, options ? options.bootstrapScriptContent : undefined, options ? options.bootstrapScripts : undefined, options ? options.bootstrapModules : undefined), createRootFormatContext(options ? options.namespaceURI : undefined), options ? options.progressiveChunkSize : undefined, options ? options.onError : undefined, onAllReady, onShellReady, onShellError, onFatalError); 6981 6982 if (options && options.signal) { 6983 var signal = options.signal; 6984 6985 var listener = function () { 6986 abort(request, signal.reason); 6987 signal.removeEventListener('abort', listener); 6988 }; 6989 6990 signal.addEventListener('abort', listener); 6991 } 6992 6993 startWork(request); 6994 }); 6995 } 6996 6997 exports.renderToReadableStream = renderToReadableStream; 6998 exports.version = ReactVersion; 6999 7000})));