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