react-dom-server-legacy.browser.development.js (255793B)
1/** 2 * @license React 3 * react-dom-server-legacy.browser.development.js 4 * 5 * Copyright (c) Facebook, Inc. and its affiliates. 6 * 7 * This source code is licensed under the MIT license found in the 8 * LICENSE file in the root directory of this source tree. 9 */ 10(function (global, factory) { 11 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) : 12 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) : 13 (global = global || self, factory(global.ReactDOMServer = {}, global.React)); 14}(this, (function (exports, React) { 'use strict'; 15 16 var ReactVersion = '18.2.0'; 17 18 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 19 20 // by calls to these methods by a Babel plugin. 21 // 22 // In PROD (or in packages without access to React internals), 23 // they are left as they are instead. 24 25 function warn(format) { 26 { 27 { 28 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 29 args[_key - 1] = arguments[_key]; 30 } 31 32 printWarning('warn', format, args); 33 } 34 } 35 } 36 function error(format) { 37 { 38 { 39 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 40 args[_key2 - 1] = arguments[_key2]; 41 } 42 43 printWarning('error', format, args); 44 } 45 } 46 } 47 48 function printWarning(level, format, args) { 49 // When changing this logic, you might want to also 50 // update consoleWithStackDev.www.js as well. 51 { 52 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 53 var stack = ReactDebugCurrentFrame.getStackAddendum(); 54 55 if (stack !== '') { 56 format += '%s'; 57 args = args.concat([stack]); 58 } // eslint-disable-next-line react-internal/safe-string-coercion 59 60 61 var argsWithFormat = args.map(function (item) { 62 return String(item); 63 }); // Careful: RN currently depends on this prefix 64 65 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it 66 // breaks IE9: https://github.com/facebook/react/issues/13610 67 // eslint-disable-next-line react-internal/no-production-logging 68 69 Function.prototype.apply.call(console[level], console, argsWithFormat); 70 } 71 } 72 73 function scheduleWork(callback) { 74 callback(); 75 } 76 function beginWriting(destination) {} 77 function writeChunk(destination, chunk) { 78 writeChunkAndReturn(destination, chunk); 79 } 80 function writeChunkAndReturn(destination, chunk) { 81 return destination.push(chunk); 82 } 83 function completeWriting(destination) {} 84 function close(destination) { 85 destination.push(null); 86 } 87 function stringToChunk(content) { 88 return content; 89 } 90 function stringToPrecomputedChunk(content) { 91 return content; 92 } 93 function closeWithError(destination, error) { 94 // $FlowFixMe: This is an Error object or the destination accepts other types. 95 destination.destroy(error); 96 } 97 98 /* 99 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol 100 * and Temporal.* types. See https://github.com/facebook/react/pull/22064. 101 * 102 * The functions in this module will throw an easier-to-understand, 103 * easier-to-debug exception with a clear errors message message explaining the 104 * problem. (Instead of a confusing exception thrown inside the implementation 105 * of the `value` object). 106 */ 107 // $FlowFixMe only called in DEV, so void return is not possible. 108 function typeName(value) { 109 { 110 // toStringTag is needed for namespaced types like Temporal.Instant 111 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag; 112 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object'; 113 return type; 114 } 115 } // $FlowFixMe only called in DEV, so void return is not possible. 116 117 118 function willCoercionThrow(value) { 119 { 120 try { 121 testStringCoercion(value); 122 return false; 123 } catch (e) { 124 return true; 125 } 126 } 127 } 128 129 function testStringCoercion(value) { 130 // If you ended up here by following an exception call stack, here's what's 131 // happened: you supplied an object or symbol value to React (as a prop, key, 132 // DOM attribute, CSS property, string ref, etc.) and when React tried to 133 // coerce it to a string using `'' + value`, an exception was thrown. 134 // 135 // The most common types that will cause this exception are `Symbol` instances 136 // and Temporal objects like `Temporal.Instant`. But any object that has a 137 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this 138 // exception. (Library authors do this to prevent users from using built-in 139 // numeric operators like `+` or comparison operators like `>=` because custom 140 // methods are needed to perform accurate arithmetic or comparison.) 141 // 142 // To fix the problem, coerce this object or symbol value to a string before 143 // passing it to React. The most reliable way is usually `String(value)`. 144 // 145 // To find which value is throwing, check the browser or debugger console. 146 // Before this exception was thrown, there should be `console.error` output 147 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the 148 // problem and how that type was used: key, atrribute, input value prop, etc. 149 // In most cases, this console output also shows the component and its 150 // ancestor components where the exception happened. 151 // 152 // eslint-disable-next-line react-internal/safe-string-coercion 153 return '' + value; 154 } 155 156 function checkAttributeStringCoercion(value, attributeName) { 157 { 158 if (willCoercionThrow(value)) { 159 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)); 160 161 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 162 } 163 } 164 } 165 function checkCSSPropertyStringCoercion(value, propName) { 166 { 167 if (willCoercionThrow(value)) { 168 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)); 169 170 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 171 } 172 } 173 } 174 function checkHtmlStringCoercion(value) { 175 { 176 if (willCoercionThrow(value)) { 177 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)); 178 179 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 180 } 181 } 182 } 183 184 var hasOwnProperty = Object.prototype.hasOwnProperty; 185 186 // A reserved attribute. 187 // It is handled by React separately and shouldn't be written to the DOM. 188 var RESERVED = 0; // A simple string attribute. 189 // Attributes that aren't in the filter are presumed to have this type. 190 191 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called 192 // "enumerated" attributes with "true" and "false" as possible values. 193 // When true, it should be set to a "true" string. 194 // When false, it should be set to a "false" string. 195 196 var BOOLEANISH_STRING = 2; // A real boolean attribute. 197 // When true, it should be present (set either to an empty string or its name). 198 // When false, it should be omitted. 199 200 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value. 201 // When true, it should be present (set either to an empty string or its name). 202 // When false, it should be omitted. 203 // For any other value, should be present with that value. 204 205 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric. 206 // When falsy, it should be removed. 207 208 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric. 209 // When falsy, it should be removed. 210 211 var POSITIVE_NUMERIC = 6; 212 213 /* eslint-disable max-len */ 214 var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; 215 /* eslint-enable max-len */ 216 217 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; 218 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 219 var illegalAttributeNameCache = {}; 220 var validatedAttributeNameCache = {}; 221 function isAttributeNameSafe(attributeName) { 222 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 223 return true; 224 } 225 226 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 227 return false; 228 } 229 230 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 231 validatedAttributeNameCache[attributeName] = true; 232 return true; 233 } 234 235 illegalAttributeNameCache[attributeName] = true; 236 237 { 238 error('Invalid attribute name: `%s`', attributeName); 239 } 240 241 return false; 242 } 243 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 244 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 245 return false; 246 } 247 248 switch (typeof value) { 249 case 'function': // $FlowIssue symbol is perfectly valid here 250 251 case 'symbol': 252 // eslint-disable-line 253 return true; 254 255 case 'boolean': 256 { 257 if (isCustomComponentTag) { 258 return false; 259 } 260 261 if (propertyInfo !== null) { 262 return !propertyInfo.acceptsBooleans; 263 } else { 264 var prefix = name.toLowerCase().slice(0, 5); 265 return prefix !== 'data-' && prefix !== 'aria-'; 266 } 267 } 268 269 default: 270 return false; 271 } 272 } 273 function getPropertyInfo(name) { 274 return properties.hasOwnProperty(name) ? properties[name] : null; 275 } 276 277 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) { 278 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 279 this.attributeName = attributeName; 280 this.attributeNamespace = attributeNamespace; 281 this.mustUseProperty = mustUseProperty; 282 this.propertyName = name; 283 this.type = type; 284 this.sanitizeURL = sanitizeURL; 285 this.removeEmptyString = removeEmptyString; 286 } // When adding attributes to this list, be sure to also add them to 287 // the `possibleStandardNames` module to ensure casing and incorrect 288 // name warnings. 289 290 291 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM. 292 293 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular 294 // elements (not just inputs). Now that ReactDOMInput assigns to the 295 // defaultValue property -- do we need this? 296 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style']; 297 298 reservedProps.forEach(function (name) { 299 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 300 name, // attributeName 301 null, // attributeNamespace 302 false, // sanitizeURL 303 false); 304 }); // A few React string attributes have a different name. 305 // This is a mapping from React prop names to the attribute names. 306 307 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 308 var name = _ref[0], 309 attributeName = _ref[1]; 310 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 311 attributeName, // attributeName 312 null, // attributeNamespace 313 false, // sanitizeURL 314 false); 315 }); // These are "enumerated" HTML attributes that accept "true" and "false". 316 // In React, we let users pass `true` and `false` even though technically 317 // these aren't boolean attributes (they are coerced to strings). 318 319 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 320 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 321 name.toLowerCase(), // attributeName 322 null, // attributeNamespace 323 false, // sanitizeURL 324 false); 325 }); // These are "enumerated" SVG attributes that accept "true" and "false". 326 // In React, we let users pass `true` and `false` even though technically 327 // these aren't boolean attributes (they are coerced to strings). 328 // Since these are SVG attributes, their attribute names are case-sensitive. 329 330 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 331 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 332 name, // attributeName 333 null, // attributeNamespace 334 false, // sanitizeURL 335 false); 336 }); // These are HTML boolean attributes. 337 338 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM 339 // on the client side because the browsers are inconsistent. Instead we call focus(). 340 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata 341 'itemScope'].forEach(function (name) { 342 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 343 name.toLowerCase(), // attributeName 344 null, // attributeNamespace 345 false, // sanitizeURL 346 false); 347 }); // These are the few React props that we set as DOM properties 348 // rather than attributes. These are all booleans. 349 350 ['checked', // Note: `option.selected` is not updated if `select.multiple` is 351 // disabled with `removeAttribute`. We have special logic for handling this. 352 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list, 353 // you'll need to set attributeName to name.toLowerCase() 354 // instead in the assignment below. 355 ].forEach(function (name) { 356 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 357 name, // attributeName 358 null, // attributeNamespace 359 false, // sanitizeURL 360 false); 361 }); // These are HTML attributes that are "overloaded booleans": they behave like 362 // booleans, but can also accept a string value. 363 364 ['capture', 'download' // NOTE: if you add a camelCased prop to this list, 365 // you'll need to set attributeName to name.toLowerCase() 366 // instead in the assignment below. 367 ].forEach(function (name) { 368 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 369 name, // attributeName 370 null, // attributeNamespace 371 false, // sanitizeURL 372 false); 373 }); // These are HTML attributes that must be positive numbers. 374 375 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list, 376 // you'll need to set attributeName to name.toLowerCase() 377 // instead in the assignment below. 378 ].forEach(function (name) { 379 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 380 name, // attributeName 381 null, // attributeNamespace 382 false, // sanitizeURL 383 false); 384 }); // These are HTML attributes that must be numbers. 385 386 ['rowSpan', 'start'].forEach(function (name) { 387 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 388 name.toLowerCase(), // attributeName 389 null, // attributeNamespace 390 false, // sanitizeURL 391 false); 392 }); 393 var CAMELIZE = /[\-\:]([a-z])/g; 394 395 var capitalize = function (token) { 396 return token[1].toUpperCase(); 397 }; // This is a list of all SVG attributes that need special casing, namespacing, 398 // or boolean value assignment. Regular attributes that just accept strings 399 // and have the same names are omitted, just like in the HTML attribute filter. 400 // Some of these attributes can be hard to find. This list was created by 401 // scraping the MDN documentation. 402 403 404 ['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, 405 // you'll need to set attributeName to name.toLowerCase() 406 // instead in the assignment below. 407 ].forEach(function (attributeName) { 408 var name = attributeName.replace(CAMELIZE, capitalize); 409 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 410 attributeName, null, // attributeNamespace 411 false, // sanitizeURL 412 false); 413 }); // String SVG attributes with the xlink namespace. 414 415 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list, 416 // you'll need to set attributeName to name.toLowerCase() 417 // instead in the assignment below. 418 ].forEach(function (attributeName) { 419 var name = attributeName.replace(CAMELIZE, capitalize); 420 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 421 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL 422 false); 423 }); // String SVG attributes with the xml namespace. 424 425 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list, 426 // you'll need to set attributeName to name.toLowerCase() 427 // instead in the assignment below. 428 ].forEach(function (attributeName) { 429 var name = attributeName.replace(CAMELIZE, capitalize); 430 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 431 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL 432 false); 433 }); // These attribute exists both in HTML and SVG. 434 // The attribute name is case-sensitive in SVG so we can't just use 435 // the React name like we do for attributes that exist only in HTML. 436 437 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) { 438 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 439 attributeName.toLowerCase(), // attributeName 440 null, // attributeNamespace 441 false, // sanitizeURL 442 false); 443 }); // These attributes accept URLs. These must not allow javascript: URLS. 444 // These will also need to accept Trusted Types object in the future. 445 446 var xlinkHref = 'xlinkHref'; 447 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty 448 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL 449 false); 450 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) { 451 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 452 attributeName.toLowerCase(), // attributeName 453 null, // attributeNamespace 454 true, // sanitizeURL 455 true); 456 }); 457 458 /** 459 * CSS properties which accept numbers but are not in units of "px". 460 */ 461 var isUnitlessNumber = { 462 animationIterationCount: true, 463 aspectRatio: true, 464 borderImageOutset: true, 465 borderImageSlice: true, 466 borderImageWidth: true, 467 boxFlex: true, 468 boxFlexGroup: true, 469 boxOrdinalGroup: true, 470 columnCount: true, 471 columns: true, 472 flex: true, 473 flexGrow: true, 474 flexPositive: true, 475 flexShrink: true, 476 flexNegative: true, 477 flexOrder: true, 478 gridArea: true, 479 gridRow: true, 480 gridRowEnd: true, 481 gridRowSpan: true, 482 gridRowStart: true, 483 gridColumn: true, 484 gridColumnEnd: true, 485 gridColumnSpan: true, 486 gridColumnStart: true, 487 fontWeight: true, 488 lineClamp: true, 489 lineHeight: true, 490 opacity: true, 491 order: true, 492 orphans: true, 493 tabSize: true, 494 widows: true, 495 zIndex: true, 496 zoom: true, 497 // SVG-related properties 498 fillOpacity: true, 499 floodOpacity: true, 500 stopOpacity: true, 501 strokeDasharray: true, 502 strokeDashoffset: true, 503 strokeMiterlimit: true, 504 strokeOpacity: true, 505 strokeWidth: true 506 }; 507 /** 508 * @param {string} prefix vendor-specific prefix, eg: Webkit 509 * @param {string} key style name, eg: transitionDuration 510 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 511 * WebkitTransitionDuration 512 */ 513 514 function prefixKey(prefix, key) { 515 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 516 } 517 /** 518 * Support style names that may come passed in prefixed by adding permutations 519 * of vendor prefixes. 520 */ 521 522 523 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 524 // infinite loop, because it iterates over the newly added props too. 525 526 Object.keys(isUnitlessNumber).forEach(function (prop) { 527 prefixes.forEach(function (prefix) { 528 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 529 }); 530 }); 531 532 var hasReadOnlyValue = { 533 button: true, 534 checkbox: true, 535 image: true, 536 hidden: true, 537 radio: true, 538 reset: true, 539 submit: true 540 }; 541 function checkControlledValueProps(tagName, props) { 542 { 543 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { 544 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`.'); 545 } 546 547 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { 548 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`.'); 549 } 550 } 551 } 552 553 function isCustomComponent(tagName, props) { 554 if (tagName.indexOf('-') === -1) { 555 return typeof props.is === 'string'; 556 } 557 558 switch (tagName) { 559 // These are reserved SVG and MathML elements. 560 // We don't mind this list too much because we expect it to never grow. 561 // The alternative is to track the namespace in a few places which is convoluted. 562 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 563 case 'annotation-xml': 564 case 'color-profile': 565 case 'font-face': 566 case 'font-face-src': 567 case 'font-face-uri': 568 case 'font-face-format': 569 case 'font-face-name': 570 case 'missing-glyph': 571 return false; 572 573 default: 574 return true; 575 } 576 } 577 578 var ariaProperties = { 579 'aria-current': 0, 580 // state 581 'aria-description': 0, 582 'aria-details': 0, 583 'aria-disabled': 0, 584 // state 585 'aria-hidden': 0, 586 // state 587 'aria-invalid': 0, 588 // state 589 'aria-keyshortcuts': 0, 590 'aria-label': 0, 591 'aria-roledescription': 0, 592 // Widget Attributes 593 'aria-autocomplete': 0, 594 'aria-checked': 0, 595 'aria-expanded': 0, 596 'aria-haspopup': 0, 597 'aria-level': 0, 598 'aria-modal': 0, 599 'aria-multiline': 0, 600 'aria-multiselectable': 0, 601 'aria-orientation': 0, 602 'aria-placeholder': 0, 603 'aria-pressed': 0, 604 'aria-readonly': 0, 605 'aria-required': 0, 606 'aria-selected': 0, 607 'aria-sort': 0, 608 'aria-valuemax': 0, 609 'aria-valuemin': 0, 610 'aria-valuenow': 0, 611 'aria-valuetext': 0, 612 // Live Region Attributes 613 'aria-atomic': 0, 614 'aria-busy': 0, 615 'aria-live': 0, 616 'aria-relevant': 0, 617 // Drag-and-Drop Attributes 618 'aria-dropeffect': 0, 619 'aria-grabbed': 0, 620 // Relationship Attributes 621 'aria-activedescendant': 0, 622 'aria-colcount': 0, 623 'aria-colindex': 0, 624 'aria-colspan': 0, 625 'aria-controls': 0, 626 'aria-describedby': 0, 627 'aria-errormessage': 0, 628 'aria-flowto': 0, 629 'aria-labelledby': 0, 630 'aria-owns': 0, 631 'aria-posinset': 0, 632 'aria-rowcount': 0, 633 'aria-rowindex': 0, 634 'aria-rowspan': 0, 635 'aria-setsize': 0 636 }; 637 638 var warnedProperties = {}; 639 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 640 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 641 642 function validateProperty(tagName, name) { 643 { 644 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { 645 return true; 646 } 647 648 if (rARIACamel.test(name)) { 649 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 650 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM 651 // DOM properties, then it is an invalid aria-* attribute. 652 653 if (correctName == null) { 654 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 655 656 warnedProperties[name] = true; 657 return true; 658 } // aria-* attributes should be lowercase; suggest the lowercase version. 659 660 661 if (name !== correctName) { 662 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 663 664 warnedProperties[name] = true; 665 return true; 666 } 667 } 668 669 if (rARIA.test(name)) { 670 var lowerCasedName = name.toLowerCase(); 671 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM 672 // DOM properties, then it is an invalid aria-* attribute. 673 674 if (standardName == null) { 675 warnedProperties[name] = true; 676 return false; 677 } // aria-* attributes should be lowercase; suggest the lowercase version. 678 679 680 if (name !== standardName) { 681 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 682 683 warnedProperties[name] = true; 684 return true; 685 } 686 } 687 } 688 689 return true; 690 } 691 692 function warnInvalidARIAProps(type, props) { 693 { 694 var invalidProps = []; 695 696 for (var key in props) { 697 var isValid = validateProperty(type, key); 698 699 if (!isValid) { 700 invalidProps.push(key); 701 } 702 } 703 704 var unknownPropString = invalidProps.map(function (prop) { 705 return '`' + prop + '`'; 706 }).join(', '); 707 708 if (invalidProps.length === 1) { 709 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 710 } else if (invalidProps.length > 1) { 711 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 712 } 713 } 714 } 715 716 function validateProperties(type, props) { 717 if (isCustomComponent(type, props)) { 718 return; 719 } 720 721 warnInvalidARIAProps(type, props); 722 } 723 724 var didWarnValueNull = false; 725 function validateProperties$1(type, props) { 726 { 727 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 728 return; 729 } 730 731 if (props != null && props.value === null && !didWarnValueNull) { 732 didWarnValueNull = true; 733 734 if (type === 'select' && props.multiple) { 735 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); 736 } else { 737 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); 738 } 739 } 740 } 741 } 742 743 // When adding attributes to the HTML or SVG allowed attribute list, be sure to 744 // also add them to this module to ensure casing and incorrect name 745 // warnings. 746 var possibleStandardNames = { 747 // HTML 748 accept: 'accept', 749 acceptcharset: 'acceptCharset', 750 'accept-charset': 'acceptCharset', 751 accesskey: 'accessKey', 752 action: 'action', 753 allowfullscreen: 'allowFullScreen', 754 alt: 'alt', 755 as: 'as', 756 async: 'async', 757 autocapitalize: 'autoCapitalize', 758 autocomplete: 'autoComplete', 759 autocorrect: 'autoCorrect', 760 autofocus: 'autoFocus', 761 autoplay: 'autoPlay', 762 autosave: 'autoSave', 763 capture: 'capture', 764 cellpadding: 'cellPadding', 765 cellspacing: 'cellSpacing', 766 challenge: 'challenge', 767 charset: 'charSet', 768 checked: 'checked', 769 children: 'children', 770 cite: 'cite', 771 class: 'className', 772 classid: 'classID', 773 classname: 'className', 774 cols: 'cols', 775 colspan: 'colSpan', 776 content: 'content', 777 contenteditable: 'contentEditable', 778 contextmenu: 'contextMenu', 779 controls: 'controls', 780 controlslist: 'controlsList', 781 coords: 'coords', 782 crossorigin: 'crossOrigin', 783 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 784 data: 'data', 785 datetime: 'dateTime', 786 default: 'default', 787 defaultchecked: 'defaultChecked', 788 defaultvalue: 'defaultValue', 789 defer: 'defer', 790 dir: 'dir', 791 disabled: 'disabled', 792 disablepictureinpicture: 'disablePictureInPicture', 793 disableremoteplayback: 'disableRemotePlayback', 794 download: 'download', 795 draggable: 'draggable', 796 enctype: 'encType', 797 enterkeyhint: 'enterKeyHint', 798 for: 'htmlFor', 799 form: 'form', 800 formmethod: 'formMethod', 801 formaction: 'formAction', 802 formenctype: 'formEncType', 803 formnovalidate: 'formNoValidate', 804 formtarget: 'formTarget', 805 frameborder: 'frameBorder', 806 headers: 'headers', 807 height: 'height', 808 hidden: 'hidden', 809 high: 'high', 810 href: 'href', 811 hreflang: 'hrefLang', 812 htmlfor: 'htmlFor', 813 httpequiv: 'httpEquiv', 814 'http-equiv': 'httpEquiv', 815 icon: 'icon', 816 id: 'id', 817 imagesizes: 'imageSizes', 818 imagesrcset: 'imageSrcSet', 819 innerhtml: 'innerHTML', 820 inputmode: 'inputMode', 821 integrity: 'integrity', 822 is: 'is', 823 itemid: 'itemID', 824 itemprop: 'itemProp', 825 itemref: 'itemRef', 826 itemscope: 'itemScope', 827 itemtype: 'itemType', 828 keyparams: 'keyParams', 829 keytype: 'keyType', 830 kind: 'kind', 831 label: 'label', 832 lang: 'lang', 833 list: 'list', 834 loop: 'loop', 835 low: 'low', 836 manifest: 'manifest', 837 marginwidth: 'marginWidth', 838 marginheight: 'marginHeight', 839 max: 'max', 840 maxlength: 'maxLength', 841 media: 'media', 842 mediagroup: 'mediaGroup', 843 method: 'method', 844 min: 'min', 845 minlength: 'minLength', 846 multiple: 'multiple', 847 muted: 'muted', 848 name: 'name', 849 nomodule: 'noModule', 850 nonce: 'nonce', 851 novalidate: 'noValidate', 852 open: 'open', 853 optimum: 'optimum', 854 pattern: 'pattern', 855 placeholder: 'placeholder', 856 playsinline: 'playsInline', 857 poster: 'poster', 858 preload: 'preload', 859 profile: 'profile', 860 radiogroup: 'radioGroup', 861 readonly: 'readOnly', 862 referrerpolicy: 'referrerPolicy', 863 rel: 'rel', 864 required: 'required', 865 reversed: 'reversed', 866 role: 'role', 867 rows: 'rows', 868 rowspan: 'rowSpan', 869 sandbox: 'sandbox', 870 scope: 'scope', 871 scoped: 'scoped', 872 scrolling: 'scrolling', 873 seamless: 'seamless', 874 selected: 'selected', 875 shape: 'shape', 876 size: 'size', 877 sizes: 'sizes', 878 span: 'span', 879 spellcheck: 'spellCheck', 880 src: 'src', 881 srcdoc: 'srcDoc', 882 srclang: 'srcLang', 883 srcset: 'srcSet', 884 start: 'start', 885 step: 'step', 886 style: 'style', 887 summary: 'summary', 888 tabindex: 'tabIndex', 889 target: 'target', 890 title: 'title', 891 type: 'type', 892 usemap: 'useMap', 893 value: 'value', 894 width: 'width', 895 wmode: 'wmode', 896 wrap: 'wrap', 897 // SVG 898 about: 'about', 899 accentheight: 'accentHeight', 900 'accent-height': 'accentHeight', 901 accumulate: 'accumulate', 902 additive: 'additive', 903 alignmentbaseline: 'alignmentBaseline', 904 'alignment-baseline': 'alignmentBaseline', 905 allowreorder: 'allowReorder', 906 alphabetic: 'alphabetic', 907 amplitude: 'amplitude', 908 arabicform: 'arabicForm', 909 'arabic-form': 'arabicForm', 910 ascent: 'ascent', 911 attributename: 'attributeName', 912 attributetype: 'attributeType', 913 autoreverse: 'autoReverse', 914 azimuth: 'azimuth', 915 basefrequency: 'baseFrequency', 916 baselineshift: 'baselineShift', 917 'baseline-shift': 'baselineShift', 918 baseprofile: 'baseProfile', 919 bbox: 'bbox', 920 begin: 'begin', 921 bias: 'bias', 922 by: 'by', 923 calcmode: 'calcMode', 924 capheight: 'capHeight', 925 'cap-height': 'capHeight', 926 clip: 'clip', 927 clippath: 'clipPath', 928 'clip-path': 'clipPath', 929 clippathunits: 'clipPathUnits', 930 cliprule: 'clipRule', 931 'clip-rule': 'clipRule', 932 color: 'color', 933 colorinterpolation: 'colorInterpolation', 934 'color-interpolation': 'colorInterpolation', 935 colorinterpolationfilters: 'colorInterpolationFilters', 936 'color-interpolation-filters': 'colorInterpolationFilters', 937 colorprofile: 'colorProfile', 938 'color-profile': 'colorProfile', 939 colorrendering: 'colorRendering', 940 'color-rendering': 'colorRendering', 941 contentscripttype: 'contentScriptType', 942 contentstyletype: 'contentStyleType', 943 cursor: 'cursor', 944 cx: 'cx', 945 cy: 'cy', 946 d: 'd', 947 datatype: 'datatype', 948 decelerate: 'decelerate', 949 descent: 'descent', 950 diffuseconstant: 'diffuseConstant', 951 direction: 'direction', 952 display: 'display', 953 divisor: 'divisor', 954 dominantbaseline: 'dominantBaseline', 955 'dominant-baseline': 'dominantBaseline', 956 dur: 'dur', 957 dx: 'dx', 958 dy: 'dy', 959 edgemode: 'edgeMode', 960 elevation: 'elevation', 961 enablebackground: 'enableBackground', 962 'enable-background': 'enableBackground', 963 end: 'end', 964 exponent: 'exponent', 965 externalresourcesrequired: 'externalResourcesRequired', 966 fill: 'fill', 967 fillopacity: 'fillOpacity', 968 'fill-opacity': 'fillOpacity', 969 fillrule: 'fillRule', 970 'fill-rule': 'fillRule', 971 filter: 'filter', 972 filterres: 'filterRes', 973 filterunits: 'filterUnits', 974 floodopacity: 'floodOpacity', 975 'flood-opacity': 'floodOpacity', 976 floodcolor: 'floodColor', 977 'flood-color': 'floodColor', 978 focusable: 'focusable', 979 fontfamily: 'fontFamily', 980 'font-family': 'fontFamily', 981 fontsize: 'fontSize', 982 'font-size': 'fontSize', 983 fontsizeadjust: 'fontSizeAdjust', 984 'font-size-adjust': 'fontSizeAdjust', 985 fontstretch: 'fontStretch', 986 'font-stretch': 'fontStretch', 987 fontstyle: 'fontStyle', 988 'font-style': 'fontStyle', 989 fontvariant: 'fontVariant', 990 'font-variant': 'fontVariant', 991 fontweight: 'fontWeight', 992 'font-weight': 'fontWeight', 993 format: 'format', 994 from: 'from', 995 fx: 'fx', 996 fy: 'fy', 997 g1: 'g1', 998 g2: 'g2', 999 glyphname: 'glyphName', 1000 'glyph-name': 'glyphName', 1001 glyphorientationhorizontal: 'glyphOrientationHorizontal', 1002 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 1003 glyphorientationvertical: 'glyphOrientationVertical', 1004 'glyph-orientation-vertical': 'glyphOrientationVertical', 1005 glyphref: 'glyphRef', 1006 gradienttransform: 'gradientTransform', 1007 gradientunits: 'gradientUnits', 1008 hanging: 'hanging', 1009 horizadvx: 'horizAdvX', 1010 'horiz-adv-x': 'horizAdvX', 1011 horizoriginx: 'horizOriginX', 1012 'horiz-origin-x': 'horizOriginX', 1013 ideographic: 'ideographic', 1014 imagerendering: 'imageRendering', 1015 'image-rendering': 'imageRendering', 1016 in2: 'in2', 1017 in: 'in', 1018 inlist: 'inlist', 1019 intercept: 'intercept', 1020 k1: 'k1', 1021 k2: 'k2', 1022 k3: 'k3', 1023 k4: 'k4', 1024 k: 'k', 1025 kernelmatrix: 'kernelMatrix', 1026 kernelunitlength: 'kernelUnitLength', 1027 kerning: 'kerning', 1028 keypoints: 'keyPoints', 1029 keysplines: 'keySplines', 1030 keytimes: 'keyTimes', 1031 lengthadjust: 'lengthAdjust', 1032 letterspacing: 'letterSpacing', 1033 'letter-spacing': 'letterSpacing', 1034 lightingcolor: 'lightingColor', 1035 'lighting-color': 'lightingColor', 1036 limitingconeangle: 'limitingConeAngle', 1037 local: 'local', 1038 markerend: 'markerEnd', 1039 'marker-end': 'markerEnd', 1040 markerheight: 'markerHeight', 1041 markermid: 'markerMid', 1042 'marker-mid': 'markerMid', 1043 markerstart: 'markerStart', 1044 'marker-start': 'markerStart', 1045 markerunits: 'markerUnits', 1046 markerwidth: 'markerWidth', 1047 mask: 'mask', 1048 maskcontentunits: 'maskContentUnits', 1049 maskunits: 'maskUnits', 1050 mathematical: 'mathematical', 1051 mode: 'mode', 1052 numoctaves: 'numOctaves', 1053 offset: 'offset', 1054 opacity: 'opacity', 1055 operator: 'operator', 1056 order: 'order', 1057 orient: 'orient', 1058 orientation: 'orientation', 1059 origin: 'origin', 1060 overflow: 'overflow', 1061 overlineposition: 'overlinePosition', 1062 'overline-position': 'overlinePosition', 1063 overlinethickness: 'overlineThickness', 1064 'overline-thickness': 'overlineThickness', 1065 paintorder: 'paintOrder', 1066 'paint-order': 'paintOrder', 1067 panose1: 'panose1', 1068 'panose-1': 'panose1', 1069 pathlength: 'pathLength', 1070 patterncontentunits: 'patternContentUnits', 1071 patterntransform: 'patternTransform', 1072 patternunits: 'patternUnits', 1073 pointerevents: 'pointerEvents', 1074 'pointer-events': 'pointerEvents', 1075 points: 'points', 1076 pointsatx: 'pointsAtX', 1077 pointsaty: 'pointsAtY', 1078 pointsatz: 'pointsAtZ', 1079 prefix: 'prefix', 1080 preservealpha: 'preserveAlpha', 1081 preserveaspectratio: 'preserveAspectRatio', 1082 primitiveunits: 'primitiveUnits', 1083 property: 'property', 1084 r: 'r', 1085 radius: 'radius', 1086 refx: 'refX', 1087 refy: 'refY', 1088 renderingintent: 'renderingIntent', 1089 'rendering-intent': 'renderingIntent', 1090 repeatcount: 'repeatCount', 1091 repeatdur: 'repeatDur', 1092 requiredextensions: 'requiredExtensions', 1093 requiredfeatures: 'requiredFeatures', 1094 resource: 'resource', 1095 restart: 'restart', 1096 result: 'result', 1097 results: 'results', 1098 rotate: 'rotate', 1099 rx: 'rx', 1100 ry: 'ry', 1101 scale: 'scale', 1102 security: 'security', 1103 seed: 'seed', 1104 shaperendering: 'shapeRendering', 1105 'shape-rendering': 'shapeRendering', 1106 slope: 'slope', 1107 spacing: 'spacing', 1108 specularconstant: 'specularConstant', 1109 specularexponent: 'specularExponent', 1110 speed: 'speed', 1111 spreadmethod: 'spreadMethod', 1112 startoffset: 'startOffset', 1113 stddeviation: 'stdDeviation', 1114 stemh: 'stemh', 1115 stemv: 'stemv', 1116 stitchtiles: 'stitchTiles', 1117 stopcolor: 'stopColor', 1118 'stop-color': 'stopColor', 1119 stopopacity: 'stopOpacity', 1120 'stop-opacity': 'stopOpacity', 1121 strikethroughposition: 'strikethroughPosition', 1122 'strikethrough-position': 'strikethroughPosition', 1123 strikethroughthickness: 'strikethroughThickness', 1124 'strikethrough-thickness': 'strikethroughThickness', 1125 string: 'string', 1126 stroke: 'stroke', 1127 strokedasharray: 'strokeDasharray', 1128 'stroke-dasharray': 'strokeDasharray', 1129 strokedashoffset: 'strokeDashoffset', 1130 'stroke-dashoffset': 'strokeDashoffset', 1131 strokelinecap: 'strokeLinecap', 1132 'stroke-linecap': 'strokeLinecap', 1133 strokelinejoin: 'strokeLinejoin', 1134 'stroke-linejoin': 'strokeLinejoin', 1135 strokemiterlimit: 'strokeMiterlimit', 1136 'stroke-miterlimit': 'strokeMiterlimit', 1137 strokewidth: 'strokeWidth', 1138 'stroke-width': 'strokeWidth', 1139 strokeopacity: 'strokeOpacity', 1140 'stroke-opacity': 'strokeOpacity', 1141 suppresscontenteditablewarning: 'suppressContentEditableWarning', 1142 suppresshydrationwarning: 'suppressHydrationWarning', 1143 surfacescale: 'surfaceScale', 1144 systemlanguage: 'systemLanguage', 1145 tablevalues: 'tableValues', 1146 targetx: 'targetX', 1147 targety: 'targetY', 1148 textanchor: 'textAnchor', 1149 'text-anchor': 'textAnchor', 1150 textdecoration: 'textDecoration', 1151 'text-decoration': 'textDecoration', 1152 textlength: 'textLength', 1153 textrendering: 'textRendering', 1154 'text-rendering': 'textRendering', 1155 to: 'to', 1156 transform: 'transform', 1157 typeof: 'typeof', 1158 u1: 'u1', 1159 u2: 'u2', 1160 underlineposition: 'underlinePosition', 1161 'underline-position': 'underlinePosition', 1162 underlinethickness: 'underlineThickness', 1163 'underline-thickness': 'underlineThickness', 1164 unicode: 'unicode', 1165 unicodebidi: 'unicodeBidi', 1166 'unicode-bidi': 'unicodeBidi', 1167 unicoderange: 'unicodeRange', 1168 'unicode-range': 'unicodeRange', 1169 unitsperem: 'unitsPerEm', 1170 'units-per-em': 'unitsPerEm', 1171 unselectable: 'unselectable', 1172 valphabetic: 'vAlphabetic', 1173 'v-alphabetic': 'vAlphabetic', 1174 values: 'values', 1175 vectoreffect: 'vectorEffect', 1176 'vector-effect': 'vectorEffect', 1177 version: 'version', 1178 vertadvy: 'vertAdvY', 1179 'vert-adv-y': 'vertAdvY', 1180 vertoriginx: 'vertOriginX', 1181 'vert-origin-x': 'vertOriginX', 1182 vertoriginy: 'vertOriginY', 1183 'vert-origin-y': 'vertOriginY', 1184 vhanging: 'vHanging', 1185 'v-hanging': 'vHanging', 1186 videographic: 'vIdeographic', 1187 'v-ideographic': 'vIdeographic', 1188 viewbox: 'viewBox', 1189 viewtarget: 'viewTarget', 1190 visibility: 'visibility', 1191 vmathematical: 'vMathematical', 1192 'v-mathematical': 'vMathematical', 1193 vocab: 'vocab', 1194 widths: 'widths', 1195 wordspacing: 'wordSpacing', 1196 'word-spacing': 'wordSpacing', 1197 writingmode: 'writingMode', 1198 'writing-mode': 'writingMode', 1199 x1: 'x1', 1200 x2: 'x2', 1201 x: 'x', 1202 xchannelselector: 'xChannelSelector', 1203 xheight: 'xHeight', 1204 'x-height': 'xHeight', 1205 xlinkactuate: 'xlinkActuate', 1206 'xlink:actuate': 'xlinkActuate', 1207 xlinkarcrole: 'xlinkArcrole', 1208 'xlink:arcrole': 'xlinkArcrole', 1209 xlinkhref: 'xlinkHref', 1210 'xlink:href': 'xlinkHref', 1211 xlinkrole: 'xlinkRole', 1212 'xlink:role': 'xlinkRole', 1213 xlinkshow: 'xlinkShow', 1214 'xlink:show': 'xlinkShow', 1215 xlinktitle: 'xlinkTitle', 1216 'xlink:title': 'xlinkTitle', 1217 xlinktype: 'xlinkType', 1218 'xlink:type': 'xlinkType', 1219 xmlbase: 'xmlBase', 1220 'xml:base': 'xmlBase', 1221 xmllang: 'xmlLang', 1222 'xml:lang': 'xmlLang', 1223 xmlns: 'xmlns', 1224 'xml:space': 'xmlSpace', 1225 xmlnsxlink: 'xmlnsXlink', 1226 'xmlns:xlink': 'xmlnsXlink', 1227 xmlspace: 'xmlSpace', 1228 y1: 'y1', 1229 y2: 'y2', 1230 y: 'y', 1231 ychannelselector: 'yChannelSelector', 1232 z: 'z', 1233 zoomandpan: 'zoomAndPan' 1234 }; 1235 1236 var validateProperty$1 = function () {}; 1237 1238 { 1239 var warnedProperties$1 = {}; 1240 var EVENT_NAME_REGEX = /^on./; 1241 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 1242 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 1243 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 1244 1245 validateProperty$1 = function (tagName, name, value, eventRegistry) { 1246 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 1247 return true; 1248 } 1249 1250 var lowerCasedName = name.toLowerCase(); 1251 1252 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 1253 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.'); 1254 1255 warnedProperties$1[name] = true; 1256 return true; 1257 } // We can't rely on the event system being injected on the server. 1258 1259 1260 if (eventRegistry != null) { 1261 var registrationNameDependencies = eventRegistry.registrationNameDependencies, 1262 possibleRegistrationNames = eventRegistry.possibleRegistrationNames; 1263 1264 if (registrationNameDependencies.hasOwnProperty(name)) { 1265 return true; 1266 } 1267 1268 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 1269 1270 if (registrationName != null) { 1271 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 1272 1273 warnedProperties$1[name] = true; 1274 return true; 1275 } 1276 1277 if (EVENT_NAME_REGEX.test(name)) { 1278 error('Unknown event handler property `%s`. It will be ignored.', name); 1279 1280 warnedProperties$1[name] = true; 1281 return true; 1282 } 1283 } else if (EVENT_NAME_REGEX.test(name)) { 1284 // If no event plugins have been injected, we are in a server environment. 1285 // So we can't tell if the event name is correct for sure, but we can filter 1286 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 1287 if (INVALID_EVENT_NAME_REGEX.test(name)) { 1288 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 1289 } 1290 1291 warnedProperties$1[name] = true; 1292 return true; 1293 } // Let the ARIA attribute hook validate ARIA attributes 1294 1295 1296 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 1297 return true; 1298 } 1299 1300 if (lowerCasedName === 'innerhtml') { 1301 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 1302 1303 warnedProperties$1[name] = true; 1304 return true; 1305 } 1306 1307 if (lowerCasedName === 'aria') { 1308 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 1309 1310 warnedProperties$1[name] = true; 1311 return true; 1312 } 1313 1314 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 1315 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 1316 1317 warnedProperties$1[name] = true; 1318 return true; 1319 } 1320 1321 if (typeof value === 'number' && isNaN(value)) { 1322 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 1323 1324 warnedProperties$1[name] = true; 1325 return true; 1326 } 1327 1328 var propertyInfo = getPropertyInfo(name); 1329 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config. 1330 1331 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 1332 var standardName = possibleStandardNames[lowerCasedName]; 1333 1334 if (standardName !== name) { 1335 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 1336 1337 warnedProperties$1[name] = true; 1338 return true; 1339 } 1340 } else if (!isReserved && name !== lowerCasedName) { 1341 // Unknown attributes should have lowercase casing since that's how they 1342 // will be cased anyway with server rendering. 1343 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); 1344 1345 warnedProperties$1[name] = true; 1346 return true; 1347 } 1348 1349 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 1350 if (value) { 1351 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); 1352 } else { 1353 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); 1354 } 1355 1356 warnedProperties$1[name] = true; 1357 return true; 1358 } // Now that we've validated casing, do not validate 1359 // data types for reserved props 1360 1361 1362 if (isReserved) { 1363 return true; 1364 } // Warn when a known attribute is a bad type 1365 1366 1367 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 1368 warnedProperties$1[name] = true; 1369 return false; 1370 } // Warn when passing the strings 'false' or 'true' into a boolean prop 1371 1372 1373 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 1374 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); 1375 1376 warnedProperties$1[name] = true; 1377 return true; 1378 } 1379 1380 return true; 1381 }; 1382 } 1383 1384 var warnUnknownProperties = function (type, props, eventRegistry) { 1385 { 1386 var unknownProps = []; 1387 1388 for (var key in props) { 1389 var isValid = validateProperty$1(type, key, props[key], eventRegistry); 1390 1391 if (!isValid) { 1392 unknownProps.push(key); 1393 } 1394 } 1395 1396 var unknownPropString = unknownProps.map(function (prop) { 1397 return '`' + prop + '`'; 1398 }).join(', '); 1399 1400 if (unknownProps.length === 1) { 1401 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); 1402 } else if (unknownProps.length > 1) { 1403 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); 1404 } 1405 } 1406 }; 1407 1408 function validateProperties$2(type, props, eventRegistry) { 1409 if (isCustomComponent(type, props)) { 1410 return; 1411 } 1412 1413 warnUnknownProperties(type, props, eventRegistry); 1414 } 1415 1416 var warnValidStyle = function () {}; 1417 1418 { 1419 // 'msTransform' is correct, but the other prefixes should be capitalized 1420 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 1421 var msPattern = /^-ms-/; 1422 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon 1423 1424 var badStyleValueWithSemicolonPattern = /;\s*$/; 1425 var warnedStyleNames = {}; 1426 var warnedStyleValues = {}; 1427 var warnedForNaNValue = false; 1428 var warnedForInfinityValue = false; 1429 1430 var camelize = function (string) { 1431 return string.replace(hyphenPattern, function (_, character) { 1432 return character.toUpperCase(); 1433 }); 1434 }; 1435 1436 var warnHyphenatedStyleName = function (name) { 1437 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 1438 return; 1439 } 1440 1441 warnedStyleNames[name] = true; 1442 1443 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests 1444 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 1445 // is converted to lowercase `ms`. 1446 camelize(name.replace(msPattern, 'ms-'))); 1447 }; 1448 1449 var warnBadVendoredStyleName = function (name) { 1450 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 1451 return; 1452 } 1453 1454 warnedStyleNames[name] = true; 1455 1456 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 1457 }; 1458 1459 var warnStyleValueWithSemicolon = function (name, value) { 1460 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 1461 return; 1462 } 1463 1464 warnedStyleValues[value] = true; 1465 1466 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 1467 }; 1468 1469 var warnStyleValueIsNaN = function (name, value) { 1470 if (warnedForNaNValue) { 1471 return; 1472 } 1473 1474 warnedForNaNValue = true; 1475 1476 error('`NaN` is an invalid value for the `%s` css style property.', name); 1477 }; 1478 1479 var warnStyleValueIsInfinity = function (name, value) { 1480 if (warnedForInfinityValue) { 1481 return; 1482 } 1483 1484 warnedForInfinityValue = true; 1485 1486 error('`Infinity` is an invalid value for the `%s` css style property.', name); 1487 }; 1488 1489 warnValidStyle = function (name, value) { 1490 if (name.indexOf('-') > -1) { 1491 warnHyphenatedStyleName(name); 1492 } else if (badVendoredStyleNamePattern.test(name)) { 1493 warnBadVendoredStyleName(name); 1494 } else if (badStyleValueWithSemicolonPattern.test(value)) { 1495 warnStyleValueWithSemicolon(name, value); 1496 } 1497 1498 if (typeof value === 'number') { 1499 if (isNaN(value)) { 1500 warnStyleValueIsNaN(name, value); 1501 } else if (!isFinite(value)) { 1502 warnStyleValueIsInfinity(name, value); 1503 } 1504 } 1505 }; 1506 } 1507 1508 var warnValidStyle$1 = warnValidStyle; 1509 1510 // code copied and modified from escape-html 1511 var matchHtmlRegExp = /["'&<>]/; 1512 /** 1513 * Escapes special characters and HTML entities in a given html string. 1514 * 1515 * @param {string} string HTML string to escape for later insertion 1516 * @return {string} 1517 * @public 1518 */ 1519 1520 function escapeHtml(string) { 1521 { 1522 checkHtmlStringCoercion(string); 1523 } 1524 1525 var str = '' + string; 1526 var match = matchHtmlRegExp.exec(str); 1527 1528 if (!match) { 1529 return str; 1530 } 1531 1532 var escape; 1533 var html = ''; 1534 var index; 1535 var lastIndex = 0; 1536 1537 for (index = match.index; index < str.length; index++) { 1538 switch (str.charCodeAt(index)) { 1539 case 34: 1540 // " 1541 escape = '"'; 1542 break; 1543 1544 case 38: 1545 // & 1546 escape = '&'; 1547 break; 1548 1549 case 39: 1550 // ' 1551 escape = '''; // modified from escape-html; used to be ''' 1552 1553 break; 1554 1555 case 60: 1556 // < 1557 escape = '<'; 1558 break; 1559 1560 case 62: 1561 // > 1562 escape = '>'; 1563 break; 1564 1565 default: 1566 continue; 1567 } 1568 1569 if (lastIndex !== index) { 1570 html += str.substring(lastIndex, index); 1571 } 1572 1573 lastIndex = index + 1; 1574 html += escape; 1575 } 1576 1577 return lastIndex !== index ? html + str.substring(lastIndex, index) : html; 1578 } // end code copied and modified from escape-html 1579 1580 /** 1581 * Escapes text to prevent scripting attacks. 1582 * 1583 * @param {*} text Text value to escape. 1584 * @return {string} An escaped string. 1585 */ 1586 1587 1588 function escapeTextForBrowser(text) { 1589 if (typeof text === 'boolean' || typeof text === 'number') { 1590 // this shortcircuit helps perf for types that we know will never have 1591 // special characters, especially given that this function is used often 1592 // for numeric dom ids. 1593 return '' + text; 1594 } 1595 1596 return escapeHtml(text); 1597 } 1598 1599 var uppercasePattern = /([A-Z])/g; 1600 var msPattern$1 = /^ms-/; 1601 /** 1602 * Hyphenates a camelcased CSS property name, for example: 1603 * 1604 * > hyphenateStyleName('backgroundColor') 1605 * < "background-color" 1606 * > hyphenateStyleName('MozTransition') 1607 * < "-moz-transition" 1608 * > hyphenateStyleName('msTransition') 1609 * < "-ms-transition" 1610 * 1611 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 1612 * is converted to `-ms-`. 1613 */ 1614 1615 function hyphenateStyleName(name) { 1616 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern$1, '-ms-'); 1617 } 1618 1619 // and any newline or tab are filtered out as if they're not part of the URL. 1620 // https://url.spec.whatwg.org/#url-parsing 1621 // Tab or newline are defined as \r\n\t: 1622 // https://infra.spec.whatwg.org/#ascii-tab-or-newline 1623 // A C0 control is a code point in the range \u0000 NULL to \u001F 1624 // INFORMATION SEPARATOR ONE, inclusive: 1625 // https://infra.spec.whatwg.org/#c0-control-or-space 1626 1627 /* eslint-disable max-len */ 1628 1629 var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; 1630 var didWarn = false; 1631 1632 function sanitizeURL(url) { 1633 { 1634 if (!didWarn && isJavaScriptProtocol.test(url)) { 1635 didWarn = true; 1636 1637 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)); 1638 } 1639 } 1640 } 1641 1642 var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare 1643 1644 function isArray(a) { 1645 return isArrayImpl(a); 1646 } 1647 1648 var startInlineScript = stringToPrecomputedChunk('<script>'); 1649 var endInlineScript = stringToPrecomputedChunk('</script>'); 1650 var startScriptSrc = stringToPrecomputedChunk('<script src="'); 1651 var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="'); 1652 var endAsyncScript = stringToPrecomputedChunk('" async=""></script>'); 1653 /** 1654 * This escaping function is designed to work with bootstrapScriptContent only. 1655 * because we know we are escaping the entire script. We can avoid for instance 1656 * escaping html comment string sequences that are valid javascript as well because 1657 * if there are no sebsequent <script sequences the html parser will never enter 1658 * script data double escaped state (see: https://www.w3.org/TR/html53/syntax.html#script-data-double-escaped-state) 1659 * 1660 * While untrusted script content should be made safe before using this api it will 1661 * ensure that the script cannot be early terminated or never terminated state 1662 */ 1663 1664 function escapeBootstrapScriptContent(scriptText) { 1665 { 1666 checkHtmlStringCoercion(scriptText); 1667 } 1668 1669 return ('' + scriptText).replace(scriptRegex, scriptReplacer); 1670 } 1671 1672 var scriptRegex = /(<\/|<)(s)(cript)/gi; 1673 1674 var scriptReplacer = function (match, prefix, s, suffix) { 1675 return "" + prefix + (s === 's' ? "\\u0073" : "\\u0053") + suffix; 1676 }; // Allows us to keep track of what we've already written so we can refer back to it. 1677 1678 1679 function createResponseState(identifierPrefix, nonce, bootstrapScriptContent, bootstrapScripts, bootstrapModules) { 1680 var idPrefix = identifierPrefix === undefined ? '' : identifierPrefix; 1681 var inlineScriptWithNonce = nonce === undefined ? startInlineScript : stringToPrecomputedChunk('<script nonce="' + escapeTextForBrowser(nonce) + '">'); 1682 var bootstrapChunks = []; 1683 1684 if (bootstrapScriptContent !== undefined) { 1685 bootstrapChunks.push(inlineScriptWithNonce, stringToChunk(escapeBootstrapScriptContent(bootstrapScriptContent)), endInlineScript); 1686 } 1687 1688 if (bootstrapScripts !== undefined) { 1689 for (var i = 0; i < bootstrapScripts.length; i++) { 1690 bootstrapChunks.push(startScriptSrc, stringToChunk(escapeTextForBrowser(bootstrapScripts[i])), endAsyncScript); 1691 } 1692 } 1693 1694 if (bootstrapModules !== undefined) { 1695 for (var _i = 0; _i < bootstrapModules.length; _i++) { 1696 bootstrapChunks.push(startModuleSrc, stringToChunk(escapeTextForBrowser(bootstrapModules[_i])), endAsyncScript); 1697 } 1698 } 1699 1700 return { 1701 bootstrapChunks: bootstrapChunks, 1702 startInlineScript: inlineScriptWithNonce, 1703 placeholderPrefix: stringToPrecomputedChunk(idPrefix + 'P:'), 1704 segmentPrefix: stringToPrecomputedChunk(idPrefix + 'S:'), 1705 boundaryPrefix: idPrefix + 'B:', 1706 idPrefix: idPrefix, 1707 nextSuspenseID: 0, 1708 sentCompleteSegmentFunction: false, 1709 sentCompleteBoundaryFunction: false, 1710 sentClientRenderFunction: false 1711 }; 1712 } // Constants for the insertion mode we're currently writing in. We don't encode all HTML5 insertion 1713 // modes. We only include the variants as they matter for the sake of our purposes. 1714 // We don't actually provide the namespace therefore we use constants instead of the string. 1715 1716 var ROOT_HTML_MODE = 0; // Used for the root most element tag. 1717 1718 var HTML_MODE = 1; 1719 var SVG_MODE = 2; 1720 var MATHML_MODE = 3; 1721 var HTML_TABLE_MODE = 4; 1722 var HTML_TABLE_BODY_MODE = 5; 1723 var HTML_TABLE_ROW_MODE = 6; 1724 var HTML_COLGROUP_MODE = 7; // We have a greater than HTML_TABLE_MODE check elsewhere. If you add more cases here, make sure it 1725 // still makes sense 1726 1727 function createFormatContext(insertionMode, selectedValue) { 1728 return { 1729 insertionMode: insertionMode, 1730 selectedValue: selectedValue 1731 }; 1732 } 1733 function getChildFormatContext(parentContext, type, props) { 1734 switch (type) { 1735 case 'select': 1736 return createFormatContext(HTML_MODE, props.value != null ? props.value : props.defaultValue); 1737 1738 case 'svg': 1739 return createFormatContext(SVG_MODE, null); 1740 1741 case 'math': 1742 return createFormatContext(MATHML_MODE, null); 1743 1744 case 'foreignObject': 1745 return createFormatContext(HTML_MODE, null); 1746 // Table parents are special in that their children can only be created at all if they're 1747 // wrapped in a table parent. So we need to encode that we're entering this mode. 1748 1749 case 'table': 1750 return createFormatContext(HTML_TABLE_MODE, null); 1751 1752 case 'thead': 1753 case 'tbody': 1754 case 'tfoot': 1755 return createFormatContext(HTML_TABLE_BODY_MODE, null); 1756 1757 case 'colgroup': 1758 return createFormatContext(HTML_COLGROUP_MODE, null); 1759 1760 case 'tr': 1761 return createFormatContext(HTML_TABLE_ROW_MODE, null); 1762 } 1763 1764 if (parentContext.insertionMode >= HTML_TABLE_MODE) { 1765 // Whatever tag this was, it wasn't a table parent or other special parent, so we must have 1766 // entered plain HTML again. 1767 return createFormatContext(HTML_MODE, null); 1768 } 1769 1770 if (parentContext.insertionMode === ROOT_HTML_MODE) { 1771 // We've emitted the root and is now in plain HTML mode. 1772 return createFormatContext(HTML_MODE, null); 1773 } 1774 1775 return parentContext; 1776 } 1777 var UNINITIALIZED_SUSPENSE_BOUNDARY_ID = null; 1778 function assignSuspenseBoundaryID(responseState) { 1779 var generatedID = responseState.nextSuspenseID++; 1780 return stringToPrecomputedChunk(responseState.boundaryPrefix + generatedID.toString(16)); 1781 } 1782 function makeId(responseState, treeId, localId) { 1783 var idPrefix = responseState.idPrefix; 1784 var id = ':' + idPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end 1785 // that represents the position of this useId hook among all the useId 1786 // hooks for this fiber. 1787 1788 if (localId > 0) { 1789 id += 'H' + localId.toString(32); 1790 } 1791 1792 return id + ':'; 1793 } 1794 1795 function encodeHTMLTextNode(text) { 1796 return escapeTextForBrowser(text); 1797 } 1798 1799 var textSeparator = stringToPrecomputedChunk('<!-- -->'); 1800 function pushTextInstance(target, text, responseState, textEmbedded) { 1801 if (text === '') { 1802 // Empty text doesn't have a DOM node representation and the hydration is aware of this. 1803 return textEmbedded; 1804 } 1805 1806 if (textEmbedded) { 1807 target.push(textSeparator); 1808 } 1809 1810 target.push(stringToChunk(encodeHTMLTextNode(text))); 1811 return true; 1812 } // Called when Fizz is done with a Segment. Currently the only purpose is to conditionally 1813 // emit a text separator when we don't know for sure it is safe to omit 1814 1815 function pushSegmentFinale(target, responseState, lastPushedText, textEmbedded) { 1816 if (lastPushedText && textEmbedded) { 1817 target.push(textSeparator); 1818 } 1819 } 1820 var styleNameCache = new Map(); 1821 1822 function processStyleName(styleName) { 1823 var chunk = styleNameCache.get(styleName); 1824 1825 if (chunk !== undefined) { 1826 return chunk; 1827 } 1828 1829 var result = stringToPrecomputedChunk(escapeTextForBrowser(hyphenateStyleName(styleName))); 1830 styleNameCache.set(styleName, result); 1831 return result; 1832 } 1833 1834 var styleAttributeStart = stringToPrecomputedChunk(' style="'); 1835 var styleAssign = stringToPrecomputedChunk(':'); 1836 var styleSeparator = stringToPrecomputedChunk(';'); 1837 1838 function pushStyle(target, responseState, style) { 1839 if (typeof style !== 'object') { 1840 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.'); 1841 } 1842 1843 var isFirst = true; 1844 1845 for (var styleName in style) { 1846 if (!hasOwnProperty.call(style, styleName)) { 1847 continue; 1848 } // If you provide unsafe user data here they can inject arbitrary CSS 1849 // which may be problematic (I couldn't repro this): 1850 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 1851 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 1852 // This is not an XSS hole but instead a potential CSS injection issue 1853 // which has lead to a greater discussion about how we're going to 1854 // trust URLs moving forward. See #2115901 1855 1856 1857 var styleValue = style[styleName]; 1858 1859 if (styleValue == null || typeof styleValue === 'boolean' || styleValue === '') { 1860 // TODO: We used to set empty string as a style with an empty value. Does that ever make sense? 1861 continue; 1862 } 1863 1864 var nameChunk = void 0; 1865 var valueChunk = void 0; 1866 var isCustomProperty = styleName.indexOf('--') === 0; 1867 1868 if (isCustomProperty) { 1869 nameChunk = stringToChunk(escapeTextForBrowser(styleName)); 1870 1871 { 1872 checkCSSPropertyStringCoercion(styleValue, styleName); 1873 } 1874 1875 valueChunk = stringToChunk(escapeTextForBrowser(('' + styleValue).trim())); 1876 } else { 1877 { 1878 warnValidStyle$1(styleName, styleValue); 1879 } 1880 1881 nameChunk = processStyleName(styleName); 1882 1883 if (typeof styleValue === 'number') { 1884 if (styleValue !== 0 && !hasOwnProperty.call(isUnitlessNumber, styleName)) { 1885 valueChunk = stringToChunk(styleValue + 'px'); // Presumes implicit 'px' suffix for unitless numbers 1886 } else { 1887 valueChunk = stringToChunk('' + styleValue); 1888 } 1889 } else { 1890 { 1891 checkCSSPropertyStringCoercion(styleValue, styleName); 1892 } 1893 1894 valueChunk = stringToChunk(escapeTextForBrowser(('' + styleValue).trim())); 1895 } 1896 } 1897 1898 if (isFirst) { 1899 isFirst = false; // If it's first, we don't need any separators prefixed. 1900 1901 target.push(styleAttributeStart, nameChunk, styleAssign, valueChunk); 1902 } else { 1903 target.push(styleSeparator, nameChunk, styleAssign, valueChunk); 1904 } 1905 } 1906 1907 if (!isFirst) { 1908 target.push(attributeEnd); 1909 } 1910 } 1911 1912 var attributeSeparator = stringToPrecomputedChunk(' '); 1913 var attributeAssign = stringToPrecomputedChunk('="'); 1914 var attributeEnd = stringToPrecomputedChunk('"'); 1915 var attributeEmptyString = stringToPrecomputedChunk('=""'); 1916 1917 function pushAttribute(target, responseState, name, value) { 1918 switch (name) { 1919 case 'style': 1920 { 1921 pushStyle(target, responseState, value); 1922 return; 1923 } 1924 1925 case 'defaultValue': 1926 case 'defaultChecked': // These shouldn't be set as attributes on generic HTML elements. 1927 1928 case 'innerHTML': // Must use dangerouslySetInnerHTML instead. 1929 1930 case 'suppressContentEditableWarning': 1931 case 'suppressHydrationWarning': 1932 // Ignored. These are built-in to React on the client. 1933 return; 1934 } 1935 1936 if ( // shouldIgnoreAttribute 1937 // We have already filtered out null/undefined and reserved words. 1938 name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 1939 return; 1940 } 1941 1942 var propertyInfo = getPropertyInfo(name); 1943 1944 if (propertyInfo !== null) { 1945 // shouldRemoveAttribute 1946 switch (typeof value) { 1947 case 'function': // $FlowIssue symbol is perfectly valid here 1948 1949 case 'symbol': 1950 // eslint-disable-line 1951 return; 1952 1953 case 'boolean': 1954 { 1955 if (!propertyInfo.acceptsBooleans) { 1956 return; 1957 } 1958 } 1959 } 1960 1961 var attributeName = propertyInfo.attributeName; 1962 var attributeNameChunk = stringToChunk(attributeName); // TODO: If it's known we can cache the chunk. 1963 1964 switch (propertyInfo.type) { 1965 case BOOLEAN: 1966 if (value) { 1967 target.push(attributeSeparator, attributeNameChunk, attributeEmptyString); 1968 } 1969 1970 return; 1971 1972 case OVERLOADED_BOOLEAN: 1973 if (value === true) { 1974 target.push(attributeSeparator, attributeNameChunk, attributeEmptyString); 1975 } else if (value === false) ; else { 1976 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 1977 } 1978 1979 return; 1980 1981 case NUMERIC: 1982 if (!isNaN(value)) { 1983 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 1984 } 1985 1986 break; 1987 1988 case POSITIVE_NUMERIC: 1989 if (!isNaN(value) && value >= 1) { 1990 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 1991 } 1992 1993 break; 1994 1995 default: 1996 if (propertyInfo.sanitizeURL) { 1997 { 1998 checkAttributeStringCoercion(value, attributeName); 1999 } 2000 2001 value = '' + value; 2002 sanitizeURL(value); 2003 } 2004 2005 target.push(attributeSeparator, attributeNameChunk, attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2006 } 2007 } else if (isAttributeNameSafe(name)) { 2008 // shouldRemoveAttribute 2009 switch (typeof value) { 2010 case 'function': // $FlowIssue symbol is perfectly valid here 2011 2012 case 'symbol': 2013 // eslint-disable-line 2014 return; 2015 2016 case 'boolean': 2017 { 2018 var prefix = name.toLowerCase().slice(0, 5); 2019 2020 if (prefix !== 'data-' && prefix !== 'aria-') { 2021 return; 2022 } 2023 } 2024 } 2025 2026 target.push(attributeSeparator, stringToChunk(name), attributeAssign, stringToChunk(escapeTextForBrowser(value)), attributeEnd); 2027 } 2028 } 2029 2030 var endOfStartTag = stringToPrecomputedChunk('>'); 2031 var endOfStartTagSelfClosing = stringToPrecomputedChunk('/>'); 2032 2033 function pushInnerHTML(target, innerHTML, children) { 2034 if (innerHTML != null) { 2035 if (children != null) { 2036 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'); 2037 } 2038 2039 if (typeof innerHTML !== 'object' || !('__html' in innerHTML)) { 2040 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.'); 2041 } 2042 2043 var html = innerHTML.__html; 2044 2045 if (html !== null && html !== undefined) { 2046 { 2047 checkHtmlStringCoercion(html); 2048 } 2049 2050 target.push(stringToChunk('' + html)); 2051 } 2052 } 2053 } // TODO: Move these to ResponseState so that we warn for every request. 2054 // It would help debugging in stateful servers (e.g. service worker). 2055 2056 2057 var didWarnDefaultInputValue = false; 2058 var didWarnDefaultChecked = false; 2059 var didWarnDefaultSelectValue = false; 2060 var didWarnDefaultTextareaValue = false; 2061 var didWarnInvalidOptionChildren = false; 2062 var didWarnInvalidOptionInnerHTML = false; 2063 var didWarnSelectedSetOnOption = false; 2064 2065 function checkSelectProp(props, propName) { 2066 { 2067 var value = props[propName]; 2068 2069 if (value != null) { 2070 var array = isArray(value); 2071 2072 if (props.multiple && !array) { 2073 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.', propName); 2074 } else if (!props.multiple && array) { 2075 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.', propName); 2076 } 2077 } 2078 } 2079 } 2080 2081 function pushStartSelect(target, props, responseState) { 2082 { 2083 checkControlledValueProps('select', props); 2084 checkSelectProp(props, 'value'); 2085 checkSelectProp(props, 'defaultValue'); 2086 2087 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultSelectValue) { 2088 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'); 2089 2090 didWarnDefaultSelectValue = true; 2091 } 2092 } 2093 2094 target.push(startChunkForTag('select')); 2095 var children = null; 2096 var innerHTML = null; 2097 2098 for (var propKey in props) { 2099 if (hasOwnProperty.call(props, propKey)) { 2100 var propValue = props[propKey]; 2101 2102 if (propValue == null) { 2103 continue; 2104 } 2105 2106 switch (propKey) { 2107 case 'children': 2108 children = propValue; 2109 break; 2110 2111 case 'dangerouslySetInnerHTML': 2112 // TODO: This doesn't really make sense for select since it can't use the controlled 2113 // value in the innerHTML. 2114 innerHTML = propValue; 2115 break; 2116 2117 case 'defaultValue': 2118 case 'value': 2119 // These are set on the Context instead and applied to the nested options. 2120 break; 2121 2122 default: 2123 pushAttribute(target, responseState, propKey, propValue); 2124 break; 2125 } 2126 } 2127 } 2128 2129 target.push(endOfStartTag); 2130 pushInnerHTML(target, innerHTML, children); 2131 return children; 2132 } 2133 2134 function flattenOptionChildren(children) { 2135 var content = ''; // Flatten children and warn if they aren't strings or numbers; 2136 // invalid types are ignored. 2137 2138 React.Children.forEach(children, function (child) { 2139 if (child == null) { 2140 return; 2141 } 2142 2143 content += child; 2144 2145 { 2146 if (!didWarnInvalidOptionChildren && typeof child !== 'string' && typeof child !== 'number') { 2147 didWarnInvalidOptionChildren = true; 2148 2149 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.'); 2150 } 2151 } 2152 }); 2153 return content; 2154 } 2155 2156 var selectedMarkerAttribute = stringToPrecomputedChunk(' selected=""'); 2157 2158 function pushStartOption(target, props, responseState, formatContext) { 2159 var selectedValue = formatContext.selectedValue; 2160 target.push(startChunkForTag('option')); 2161 var children = null; 2162 var value = null; 2163 var selected = null; 2164 var innerHTML = null; 2165 2166 for (var propKey in props) { 2167 if (hasOwnProperty.call(props, propKey)) { 2168 var propValue = props[propKey]; 2169 2170 if (propValue == null) { 2171 continue; 2172 } 2173 2174 switch (propKey) { 2175 case 'children': 2176 children = propValue; 2177 break; 2178 2179 case 'selected': 2180 // ignore 2181 selected = propValue; 2182 2183 { 2184 // TODO: Remove support for `selected` in <option>. 2185 if (!didWarnSelectedSetOnOption) { 2186 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 2187 2188 didWarnSelectedSetOnOption = true; 2189 } 2190 } 2191 2192 break; 2193 2194 case 'dangerouslySetInnerHTML': 2195 innerHTML = propValue; 2196 break; 2197 // eslint-disable-next-line-no-fallthrough 2198 2199 case 'value': 2200 value = propValue; 2201 // We intentionally fallthrough to also set the attribute on the node. 2202 // eslint-disable-next-line-no-fallthrough 2203 2204 default: 2205 pushAttribute(target, responseState, propKey, propValue); 2206 break; 2207 } 2208 } 2209 } 2210 2211 if (selectedValue != null) { 2212 var stringValue; 2213 2214 if (value !== null) { 2215 { 2216 checkAttributeStringCoercion(value, 'value'); 2217 } 2218 2219 stringValue = '' + value; 2220 } else { 2221 { 2222 if (innerHTML !== null) { 2223 if (!didWarnInvalidOptionInnerHTML) { 2224 didWarnInvalidOptionInnerHTML = true; 2225 2226 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.'); 2227 } 2228 } 2229 } 2230 2231 stringValue = flattenOptionChildren(children); 2232 } 2233 2234 if (isArray(selectedValue)) { 2235 // multiple 2236 for (var i = 0; i < selectedValue.length; i++) { 2237 { 2238 checkAttributeStringCoercion(selectedValue[i], 'value'); 2239 } 2240 2241 var v = '' + selectedValue[i]; 2242 2243 if (v === stringValue) { 2244 target.push(selectedMarkerAttribute); 2245 break; 2246 } 2247 } 2248 } else { 2249 { 2250 checkAttributeStringCoercion(selectedValue, 'select.value'); 2251 } 2252 2253 if ('' + selectedValue === stringValue) { 2254 target.push(selectedMarkerAttribute); 2255 } 2256 } 2257 } else if (selected) { 2258 target.push(selectedMarkerAttribute); 2259 } 2260 2261 target.push(endOfStartTag); 2262 pushInnerHTML(target, innerHTML, children); 2263 return children; 2264 } 2265 2266 function pushInput(target, props, responseState) { 2267 { 2268 checkControlledValueProps('input', props); 2269 2270 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnDefaultChecked) { 2271 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); 2272 2273 didWarnDefaultChecked = true; 2274 } 2275 2276 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultInputValue) { 2277 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); 2278 2279 didWarnDefaultInputValue = true; 2280 } 2281 } 2282 2283 target.push(startChunkForTag('input')); 2284 var value = null; 2285 var defaultValue = null; 2286 var checked = null; 2287 var defaultChecked = null; 2288 2289 for (var propKey in props) { 2290 if (hasOwnProperty.call(props, propKey)) { 2291 var propValue = props[propKey]; 2292 2293 if (propValue == null) { 2294 continue; 2295 } 2296 2297 switch (propKey) { 2298 case 'children': 2299 case 'dangerouslySetInnerHTML': 2300 throw new Error('input' + " is a self-closing tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.'); 2301 // eslint-disable-next-line-no-fallthrough 2302 2303 case 'defaultChecked': 2304 defaultChecked = propValue; 2305 break; 2306 2307 case 'defaultValue': 2308 defaultValue = propValue; 2309 break; 2310 2311 case 'checked': 2312 checked = propValue; 2313 break; 2314 2315 case 'value': 2316 value = propValue; 2317 break; 2318 2319 default: 2320 pushAttribute(target, responseState, propKey, propValue); 2321 break; 2322 } 2323 } 2324 } 2325 2326 if (checked !== null) { 2327 pushAttribute(target, responseState, 'checked', checked); 2328 } else if (defaultChecked !== null) { 2329 pushAttribute(target, responseState, 'checked', defaultChecked); 2330 } 2331 2332 if (value !== null) { 2333 pushAttribute(target, responseState, 'value', value); 2334 } else if (defaultValue !== null) { 2335 pushAttribute(target, responseState, 'value', defaultValue); 2336 } 2337 2338 target.push(endOfStartTagSelfClosing); 2339 return null; 2340 } 2341 2342 function pushStartTextArea(target, props, responseState) { 2343 { 2344 checkControlledValueProps('textarea', props); 2345 2346 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnDefaultTextareaValue) { 2347 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'); 2348 2349 didWarnDefaultTextareaValue = true; 2350 } 2351 } 2352 2353 target.push(startChunkForTag('textarea')); 2354 var value = null; 2355 var defaultValue = null; 2356 var children = null; 2357 2358 for (var propKey in props) { 2359 if (hasOwnProperty.call(props, propKey)) { 2360 var propValue = props[propKey]; 2361 2362 if (propValue == null) { 2363 continue; 2364 } 2365 2366 switch (propKey) { 2367 case 'children': 2368 children = propValue; 2369 break; 2370 2371 case 'value': 2372 value = propValue; 2373 break; 2374 2375 case 'defaultValue': 2376 defaultValue = propValue; 2377 break; 2378 2379 case 'dangerouslySetInnerHTML': 2380 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.'); 2381 // eslint-disable-next-line-no-fallthrough 2382 2383 default: 2384 pushAttribute(target, responseState, propKey, propValue); 2385 break; 2386 } 2387 } 2388 } 2389 2390 if (value === null && defaultValue !== null) { 2391 value = defaultValue; 2392 } 2393 2394 target.push(endOfStartTag); // TODO (yungsters): Remove support for children content in <textarea>. 2395 2396 if (children != null) { 2397 { 2398 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 2399 } 2400 2401 if (value != null) { 2402 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.'); 2403 } 2404 2405 if (isArray(children)) { 2406 if (children.length > 1) { 2407 throw new Error('<textarea> can only have at most one child.'); 2408 } // TODO: remove the coercion and the DEV check below because it will 2409 // always be overwritten by the coercion several lines below it. #22309 2410 2411 2412 { 2413 checkHtmlStringCoercion(children[0]); 2414 } 2415 2416 value = '' + children[0]; 2417 } 2418 2419 { 2420 checkHtmlStringCoercion(children); 2421 } 2422 2423 value = '' + children; 2424 } 2425 2426 if (typeof value === 'string' && value[0] === '\n') { 2427 // text/html ignores the first character in these tags if it's a newline 2428 // Prefer to break application/xml over text/html (for now) by adding 2429 // a newline specifically to get eaten by the parser. (Alternately for 2430 // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first 2431 // \r is normalized out by HTMLTextAreaElement#value.) 2432 // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> 2433 // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> 2434 // See: <http://www.w3.org/TR/html5/syntax.html#newlines> 2435 // See: Parsing of "textarea" "listing" and "pre" elements 2436 // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> 2437 target.push(leadingNewline); 2438 } // ToString and push directly instead of recurse over children. 2439 // We don't really support complex children in the value anyway. 2440 // This also currently avoids a trailing comment node which breaks textarea. 2441 2442 2443 if (value !== null) { 2444 { 2445 checkAttributeStringCoercion(value, 'value'); 2446 } 2447 2448 target.push(stringToChunk(encodeHTMLTextNode('' + value))); 2449 } 2450 2451 return null; 2452 } 2453 2454 function pushSelfClosing(target, props, tag, responseState) { 2455 target.push(startChunkForTag(tag)); 2456 2457 for (var propKey in props) { 2458 if (hasOwnProperty.call(props, propKey)) { 2459 var propValue = props[propKey]; 2460 2461 if (propValue == null) { 2462 continue; 2463 } 2464 2465 switch (propKey) { 2466 case 'children': 2467 case 'dangerouslySetInnerHTML': 2468 throw new Error(tag + " is a self-closing tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.'); 2469 // eslint-disable-next-line-no-fallthrough 2470 2471 default: 2472 pushAttribute(target, responseState, propKey, propValue); 2473 break; 2474 } 2475 } 2476 } 2477 2478 target.push(endOfStartTagSelfClosing); 2479 return null; 2480 } 2481 2482 function pushStartMenuItem(target, props, responseState) { 2483 target.push(startChunkForTag('menuitem')); 2484 2485 for (var propKey in props) { 2486 if (hasOwnProperty.call(props, propKey)) { 2487 var propValue = props[propKey]; 2488 2489 if (propValue == null) { 2490 continue; 2491 } 2492 2493 switch (propKey) { 2494 case 'children': 2495 case 'dangerouslySetInnerHTML': 2496 throw new Error('menuitems cannot have `children` nor `dangerouslySetInnerHTML`.'); 2497 // eslint-disable-next-line-no-fallthrough 2498 2499 default: 2500 pushAttribute(target, responseState, propKey, propValue); 2501 break; 2502 } 2503 } 2504 } 2505 2506 target.push(endOfStartTag); 2507 return null; 2508 } 2509 2510 function pushStartTitle(target, props, responseState) { 2511 target.push(startChunkForTag('title')); 2512 var children = null; 2513 2514 for (var propKey in props) { 2515 if (hasOwnProperty.call(props, propKey)) { 2516 var propValue = props[propKey]; 2517 2518 if (propValue == null) { 2519 continue; 2520 } 2521 2522 switch (propKey) { 2523 case 'children': 2524 children = propValue; 2525 break; 2526 2527 case 'dangerouslySetInnerHTML': 2528 throw new Error('`dangerouslySetInnerHTML` does not make sense on <title>.'); 2529 // eslint-disable-next-line-no-fallthrough 2530 2531 default: 2532 pushAttribute(target, responseState, propKey, propValue); 2533 break; 2534 } 2535 } 2536 } 2537 2538 target.push(endOfStartTag); 2539 2540 { 2541 var child = Array.isArray(children) && children.length < 2 ? children[0] || null : children; 2542 2543 if (Array.isArray(children) && children.length > 1) { 2544 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'); 2545 } else if (child != null && child.$$typeof != null) { 2546 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'); 2547 } else if (child != null && typeof child !== 'string' && typeof child !== 'number') { 2548 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'); 2549 } 2550 } 2551 2552 return children; 2553 } 2554 2555 function pushStartGenericElement(target, props, tag, responseState) { 2556 target.push(startChunkForTag(tag)); 2557 var children = null; 2558 var innerHTML = null; 2559 2560 for (var propKey in props) { 2561 if (hasOwnProperty.call(props, propKey)) { 2562 var propValue = props[propKey]; 2563 2564 if (propValue == null) { 2565 continue; 2566 } 2567 2568 switch (propKey) { 2569 case 'children': 2570 children = propValue; 2571 break; 2572 2573 case 'dangerouslySetInnerHTML': 2574 innerHTML = propValue; 2575 break; 2576 2577 default: 2578 pushAttribute(target, responseState, propKey, propValue); 2579 break; 2580 } 2581 } 2582 } 2583 2584 target.push(endOfStartTag); 2585 pushInnerHTML(target, innerHTML, children); 2586 2587 if (typeof children === 'string') { 2588 // Special case children as a string to avoid the unnecessary comment. 2589 // TODO: Remove this special case after the general optimization is in place. 2590 target.push(stringToChunk(encodeHTMLTextNode(children))); 2591 return null; 2592 } 2593 2594 return children; 2595 } 2596 2597 function pushStartCustomElement(target, props, tag, responseState) { 2598 target.push(startChunkForTag(tag)); 2599 var children = null; 2600 var innerHTML = null; 2601 2602 for (var propKey in props) { 2603 if (hasOwnProperty.call(props, propKey)) { 2604 var propValue = props[propKey]; 2605 2606 if (propValue == null) { 2607 continue; 2608 } 2609 2610 switch (propKey) { 2611 case 'children': 2612 children = propValue; 2613 break; 2614 2615 case 'dangerouslySetInnerHTML': 2616 innerHTML = propValue; 2617 break; 2618 2619 case 'style': 2620 pushStyle(target, responseState, propValue); 2621 break; 2622 2623 case 'suppressContentEditableWarning': 2624 case 'suppressHydrationWarning': 2625 // Ignored. These are built-in to React on the client. 2626 break; 2627 2628 default: 2629 if (isAttributeNameSafe(propKey) && typeof propValue !== 'function' && typeof propValue !== 'symbol') { 2630 target.push(attributeSeparator, stringToChunk(propKey), attributeAssign, stringToChunk(escapeTextForBrowser(propValue)), attributeEnd); 2631 } 2632 2633 break; 2634 } 2635 } 2636 } 2637 2638 target.push(endOfStartTag); 2639 pushInnerHTML(target, innerHTML, children); 2640 return children; 2641 } 2642 2643 var leadingNewline = stringToPrecomputedChunk('\n'); 2644 2645 function pushStartPreformattedElement(target, props, tag, responseState) { 2646 target.push(startChunkForTag(tag)); 2647 var children = null; 2648 var innerHTML = null; 2649 2650 for (var propKey in props) { 2651 if (hasOwnProperty.call(props, propKey)) { 2652 var propValue = props[propKey]; 2653 2654 if (propValue == null) { 2655 continue; 2656 } 2657 2658 switch (propKey) { 2659 case 'children': 2660 children = propValue; 2661 break; 2662 2663 case 'dangerouslySetInnerHTML': 2664 innerHTML = propValue; 2665 break; 2666 2667 default: 2668 pushAttribute(target, responseState, propKey, propValue); 2669 break; 2670 } 2671 } 2672 } 2673 2674 target.push(endOfStartTag); // text/html ignores the first character in these tags if it's a newline 2675 // Prefer to break application/xml over text/html (for now) by adding 2676 // a newline specifically to get eaten by the parser. (Alternately for 2677 // textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first 2678 // \r is normalized out by HTMLTextAreaElement#value.) 2679 // See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> 2680 // See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> 2681 // See: <http://www.w3.org/TR/html5/syntax.html#newlines> 2682 // See: Parsing of "textarea" "listing" and "pre" elements 2683 // from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> 2684 // TODO: This doesn't deal with the case where the child is an array 2685 // or component that returns a string. 2686 2687 if (innerHTML != null) { 2688 if (children != null) { 2689 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'); 2690 } 2691 2692 if (typeof innerHTML !== 'object' || !('__html' in innerHTML)) { 2693 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.'); 2694 } 2695 2696 var html = innerHTML.__html; 2697 2698 if (html !== null && html !== undefined) { 2699 if (typeof html === 'string' && html.length > 0 && html[0] === '\n') { 2700 target.push(leadingNewline, stringToChunk(html)); 2701 } else { 2702 { 2703 checkHtmlStringCoercion(html); 2704 } 2705 2706 target.push(stringToChunk('' + html)); 2707 } 2708 } 2709 } 2710 2711 if (typeof children === 'string' && children[0] === '\n') { 2712 target.push(leadingNewline); 2713 } 2714 2715 return children; 2716 } // We accept any tag to be rendered but since this gets injected into arbitrary 2717 // HTML, we want to make sure that it's a safe tag. 2718 // http://www.w3.org/TR/REC-xml/#NT-Name 2719 2720 2721 var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset 2722 2723 var validatedTagCache = new Map(); 2724 2725 function startChunkForTag(tag) { 2726 var tagStartChunk = validatedTagCache.get(tag); 2727 2728 if (tagStartChunk === undefined) { 2729 if (!VALID_TAG_REGEX.test(tag)) { 2730 throw new Error("Invalid tag: " + tag); 2731 } 2732 2733 tagStartChunk = stringToPrecomputedChunk('<' + tag); 2734 validatedTagCache.set(tag, tagStartChunk); 2735 } 2736 2737 return tagStartChunk; 2738 } 2739 2740 var DOCTYPE = stringToPrecomputedChunk('<!DOCTYPE html>'); 2741 function pushStartInstance(target, type, props, responseState, formatContext) { 2742 { 2743 validateProperties(type, props); 2744 validateProperties$1(type, props); 2745 validateProperties$2(type, props, null); 2746 2747 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) { 2748 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.'); 2749 } 2750 2751 if (formatContext.insertionMode !== SVG_MODE && formatContext.insertionMode !== MATHML_MODE) { 2752 if (type.indexOf('-') === -1 && typeof props.is !== 'string' && type.toLowerCase() !== type) { 2753 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type); 2754 } 2755 } 2756 } 2757 2758 switch (type) { 2759 // Special tags 2760 case 'select': 2761 return pushStartSelect(target, props, responseState); 2762 2763 case 'option': 2764 return pushStartOption(target, props, responseState, formatContext); 2765 2766 case 'textarea': 2767 return pushStartTextArea(target, props, responseState); 2768 2769 case 'input': 2770 return pushInput(target, props, responseState); 2771 2772 case 'menuitem': 2773 return pushStartMenuItem(target, props, responseState); 2774 2775 case 'title': 2776 return pushStartTitle(target, props, responseState); 2777 // Newline eating tags 2778 2779 case 'listing': 2780 case 'pre': 2781 { 2782 return pushStartPreformattedElement(target, props, type, responseState); 2783 } 2784 // Omitted close tags 2785 2786 case 'area': 2787 case 'base': 2788 case 'br': 2789 case 'col': 2790 case 'embed': 2791 case 'hr': 2792 case 'img': 2793 case 'keygen': 2794 case 'link': 2795 case 'meta': 2796 case 'param': 2797 case 'source': 2798 case 'track': 2799 case 'wbr': 2800 { 2801 return pushSelfClosing(target, props, type, responseState); 2802 } 2803 // These are reserved SVG and MathML elements, that are never custom elements. 2804 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 2805 2806 case 'annotation-xml': 2807 case 'color-profile': 2808 case 'font-face': 2809 case 'font-face-src': 2810 case 'font-face-uri': 2811 case 'font-face-format': 2812 case 'font-face-name': 2813 case 'missing-glyph': 2814 { 2815 return pushStartGenericElement(target, props, type, responseState); 2816 } 2817 2818 case 'html': 2819 { 2820 if (formatContext.insertionMode === ROOT_HTML_MODE) { 2821 // If we're rendering the html tag and we're at the root (i.e. not in foreignObject) 2822 // then we also emit the DOCTYPE as part of the root content as a convenience for 2823 // rendering the whole document. 2824 target.push(DOCTYPE); 2825 } 2826 2827 return pushStartGenericElement(target, props, type, responseState); 2828 } 2829 2830 default: 2831 { 2832 if (type.indexOf('-') === -1 && typeof props.is !== 'string') { 2833 // Generic element 2834 return pushStartGenericElement(target, props, type, responseState); 2835 } else { 2836 // Custom element 2837 return pushStartCustomElement(target, props, type, responseState); 2838 } 2839 } 2840 } 2841 } 2842 var endTag1 = stringToPrecomputedChunk('</'); 2843 var endTag2 = stringToPrecomputedChunk('>'); 2844 function pushEndInstance(target, type, props) { 2845 switch (type) { 2846 // Omitted close tags 2847 // TODO: Instead of repeating this switch we could try to pass a flag from above. 2848 // That would require returning a tuple. Which might be ok if it gets inlined. 2849 case 'area': 2850 case 'base': 2851 case 'br': 2852 case 'col': 2853 case 'embed': 2854 case 'hr': 2855 case 'img': 2856 case 'input': 2857 case 'keygen': 2858 case 'link': 2859 case 'meta': 2860 case 'param': 2861 case 'source': 2862 case 'track': 2863 case 'wbr': 2864 { 2865 // No close tag needed. 2866 break; 2867 } 2868 2869 default: 2870 { 2871 target.push(endTag1, stringToChunk(type), endTag2); 2872 } 2873 } 2874 } 2875 function writeCompletedRoot(destination, responseState) { 2876 var bootstrapChunks = responseState.bootstrapChunks; 2877 var i = 0; 2878 2879 for (; i < bootstrapChunks.length - 1; i++) { 2880 writeChunk(destination, bootstrapChunks[i]); 2881 } 2882 2883 if (i < bootstrapChunks.length) { 2884 return writeChunkAndReturn(destination, bootstrapChunks[i]); 2885 } 2886 2887 return true; 2888 } // Structural Nodes 2889 // A placeholder is a node inside a hidden partial tree that can be filled in later, but before 2890 // display. It's never visible to users. We use the template tag because it can be used in every 2891 // type of parent. <script> tags also work in every other tag except <colgroup>. 2892 2893 var placeholder1 = stringToPrecomputedChunk('<template id="'); 2894 var placeholder2 = stringToPrecomputedChunk('"></template>'); 2895 function writePlaceholder(destination, responseState, id) { 2896 writeChunk(destination, placeholder1); 2897 writeChunk(destination, responseState.placeholderPrefix); 2898 var formattedID = stringToChunk(id.toString(16)); 2899 writeChunk(destination, formattedID); 2900 return writeChunkAndReturn(destination, placeholder2); 2901 } // Suspense boundaries are encoded as comments. 2902 2903 var startCompletedSuspenseBoundary = stringToPrecomputedChunk('<!--$-->'); 2904 var startPendingSuspenseBoundary1 = stringToPrecomputedChunk('<!--$?--><template id="'); 2905 var startPendingSuspenseBoundary2 = stringToPrecomputedChunk('"></template>'); 2906 var startClientRenderedSuspenseBoundary = stringToPrecomputedChunk('<!--$!-->'); 2907 var endSuspenseBoundary = stringToPrecomputedChunk('<!--/$-->'); 2908 var clientRenderedSuspenseBoundaryError1 = stringToPrecomputedChunk('<template'); 2909 var clientRenderedSuspenseBoundaryErrorAttrInterstitial = stringToPrecomputedChunk('"'); 2910 var clientRenderedSuspenseBoundaryError1A = stringToPrecomputedChunk(' data-dgst="'); 2911 var clientRenderedSuspenseBoundaryError1B = stringToPrecomputedChunk(' data-msg="'); 2912 var clientRenderedSuspenseBoundaryError1C = stringToPrecomputedChunk(' data-stck="'); 2913 var clientRenderedSuspenseBoundaryError2 = stringToPrecomputedChunk('></template>'); 2914 function writeStartCompletedSuspenseBoundary(destination, responseState) { 2915 return writeChunkAndReturn(destination, startCompletedSuspenseBoundary); 2916 } 2917 function writeStartPendingSuspenseBoundary(destination, responseState, id) { 2918 writeChunk(destination, startPendingSuspenseBoundary1); 2919 2920 if (id === null) { 2921 throw new Error('An ID must have been assigned before we can complete the boundary.'); 2922 } 2923 2924 writeChunk(destination, id); 2925 return writeChunkAndReturn(destination, startPendingSuspenseBoundary2); 2926 } 2927 function writeStartClientRenderedSuspenseBoundary(destination, responseState, errorDigest, errorMesssage, errorComponentStack) { 2928 var result; 2929 result = writeChunkAndReturn(destination, startClientRenderedSuspenseBoundary); 2930 writeChunk(destination, clientRenderedSuspenseBoundaryError1); 2931 2932 if (errorDigest) { 2933 writeChunk(destination, clientRenderedSuspenseBoundaryError1A); 2934 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorDigest))); 2935 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 2936 } 2937 2938 { 2939 if (errorMesssage) { 2940 writeChunk(destination, clientRenderedSuspenseBoundaryError1B); 2941 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorMesssage))); 2942 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 2943 } 2944 2945 if (errorComponentStack) { 2946 writeChunk(destination, clientRenderedSuspenseBoundaryError1C); 2947 writeChunk(destination, stringToChunk(escapeTextForBrowser(errorComponentStack))); 2948 writeChunk(destination, clientRenderedSuspenseBoundaryErrorAttrInterstitial); 2949 } 2950 } 2951 2952 result = writeChunkAndReturn(destination, clientRenderedSuspenseBoundaryError2); 2953 return result; 2954 } 2955 function writeEndCompletedSuspenseBoundary(destination, responseState) { 2956 return writeChunkAndReturn(destination, endSuspenseBoundary); 2957 } 2958 function writeEndPendingSuspenseBoundary(destination, responseState) { 2959 return writeChunkAndReturn(destination, endSuspenseBoundary); 2960 } 2961 function writeEndClientRenderedSuspenseBoundary(destination, responseState) { 2962 return writeChunkAndReturn(destination, endSuspenseBoundary); 2963 } 2964 var startSegmentHTML = stringToPrecomputedChunk('<div hidden id="'); 2965 var startSegmentHTML2 = stringToPrecomputedChunk('">'); 2966 var endSegmentHTML = stringToPrecomputedChunk('</div>'); 2967 var startSegmentSVG = stringToPrecomputedChunk('<svg aria-hidden="true" style="display:none" id="'); 2968 var startSegmentSVG2 = stringToPrecomputedChunk('">'); 2969 var endSegmentSVG = stringToPrecomputedChunk('</svg>'); 2970 var startSegmentMathML = stringToPrecomputedChunk('<math aria-hidden="true" style="display:none" id="'); 2971 var startSegmentMathML2 = stringToPrecomputedChunk('">'); 2972 var endSegmentMathML = stringToPrecomputedChunk('</math>'); 2973 var startSegmentTable = stringToPrecomputedChunk('<table hidden id="'); 2974 var startSegmentTable2 = stringToPrecomputedChunk('">'); 2975 var endSegmentTable = stringToPrecomputedChunk('</table>'); 2976 var startSegmentTableBody = stringToPrecomputedChunk('<table hidden><tbody id="'); 2977 var startSegmentTableBody2 = stringToPrecomputedChunk('">'); 2978 var endSegmentTableBody = stringToPrecomputedChunk('</tbody></table>'); 2979 var startSegmentTableRow = stringToPrecomputedChunk('<table hidden><tr id="'); 2980 var startSegmentTableRow2 = stringToPrecomputedChunk('">'); 2981 var endSegmentTableRow = stringToPrecomputedChunk('</tr></table>'); 2982 var startSegmentColGroup = stringToPrecomputedChunk('<table hidden><colgroup id="'); 2983 var startSegmentColGroup2 = stringToPrecomputedChunk('">'); 2984 var endSegmentColGroup = stringToPrecomputedChunk('</colgroup></table>'); 2985 function writeStartSegment(destination, responseState, formatContext, id) { 2986 switch (formatContext.insertionMode) { 2987 case ROOT_HTML_MODE: 2988 case HTML_MODE: 2989 { 2990 writeChunk(destination, startSegmentHTML); 2991 writeChunk(destination, responseState.segmentPrefix); 2992 writeChunk(destination, stringToChunk(id.toString(16))); 2993 return writeChunkAndReturn(destination, startSegmentHTML2); 2994 } 2995 2996 case SVG_MODE: 2997 { 2998 writeChunk(destination, startSegmentSVG); 2999 writeChunk(destination, responseState.segmentPrefix); 3000 writeChunk(destination, stringToChunk(id.toString(16))); 3001 return writeChunkAndReturn(destination, startSegmentSVG2); 3002 } 3003 3004 case MATHML_MODE: 3005 { 3006 writeChunk(destination, startSegmentMathML); 3007 writeChunk(destination, responseState.segmentPrefix); 3008 writeChunk(destination, stringToChunk(id.toString(16))); 3009 return writeChunkAndReturn(destination, startSegmentMathML2); 3010 } 3011 3012 case HTML_TABLE_MODE: 3013 { 3014 writeChunk(destination, startSegmentTable); 3015 writeChunk(destination, responseState.segmentPrefix); 3016 writeChunk(destination, stringToChunk(id.toString(16))); 3017 return writeChunkAndReturn(destination, startSegmentTable2); 3018 } 3019 // TODO: For the rest of these, there will be extra wrapper nodes that never 3020 // get deleted from the document. We need to delete the table too as part 3021 // of the injected scripts. They are invisible though so it's not too terrible 3022 // and it's kind of an edge case to suspend in a table. Totally supported though. 3023 3024 case HTML_TABLE_BODY_MODE: 3025 { 3026 writeChunk(destination, startSegmentTableBody); 3027 writeChunk(destination, responseState.segmentPrefix); 3028 writeChunk(destination, stringToChunk(id.toString(16))); 3029 return writeChunkAndReturn(destination, startSegmentTableBody2); 3030 } 3031 3032 case HTML_TABLE_ROW_MODE: 3033 { 3034 writeChunk(destination, startSegmentTableRow); 3035 writeChunk(destination, responseState.segmentPrefix); 3036 writeChunk(destination, stringToChunk(id.toString(16))); 3037 return writeChunkAndReturn(destination, startSegmentTableRow2); 3038 } 3039 3040 case HTML_COLGROUP_MODE: 3041 { 3042 writeChunk(destination, startSegmentColGroup); 3043 writeChunk(destination, responseState.segmentPrefix); 3044 writeChunk(destination, stringToChunk(id.toString(16))); 3045 return writeChunkAndReturn(destination, startSegmentColGroup2); 3046 } 3047 3048 default: 3049 { 3050 throw new Error('Unknown insertion mode. This is a bug in React.'); 3051 } 3052 } 3053 } 3054 function writeEndSegment(destination, formatContext) { 3055 switch (formatContext.insertionMode) { 3056 case ROOT_HTML_MODE: 3057 case HTML_MODE: 3058 { 3059 return writeChunkAndReturn(destination, endSegmentHTML); 3060 } 3061 3062 case SVG_MODE: 3063 { 3064 return writeChunkAndReturn(destination, endSegmentSVG); 3065 } 3066 3067 case MATHML_MODE: 3068 { 3069 return writeChunkAndReturn(destination, endSegmentMathML); 3070 } 3071 3072 case HTML_TABLE_MODE: 3073 { 3074 return writeChunkAndReturn(destination, endSegmentTable); 3075 } 3076 3077 case HTML_TABLE_BODY_MODE: 3078 { 3079 return writeChunkAndReturn(destination, endSegmentTableBody); 3080 } 3081 3082 case HTML_TABLE_ROW_MODE: 3083 { 3084 return writeChunkAndReturn(destination, endSegmentTableRow); 3085 } 3086 3087 case HTML_COLGROUP_MODE: 3088 { 3089 return writeChunkAndReturn(destination, endSegmentColGroup); 3090 } 3091 3092 default: 3093 { 3094 throw new Error('Unknown insertion mode. This is a bug in React.'); 3095 } 3096 } 3097 } // Instruction Set 3098 // The following code is the source scripts that we then minify and inline below, 3099 // with renamed function names that we hope don't collide: 3100 // const COMMENT_NODE = 8; 3101 // const SUSPENSE_START_DATA = '$'; 3102 // const SUSPENSE_END_DATA = '/$'; 3103 // const SUSPENSE_PENDING_START_DATA = '$?'; 3104 // const SUSPENSE_FALLBACK_START_DATA = '$!'; 3105 // 3106 // function clientRenderBoundary(suspenseBoundaryID, errorDigest, errorMsg, errorComponentStack) { 3107 // // Find the fallback's first element. 3108 // const suspenseIdNode = document.getElementById(suspenseBoundaryID); 3109 // if (!suspenseIdNode) { 3110 // // The user must have already navigated away from this tree. 3111 // // E.g. because the parent was hydrated. 3112 // return; 3113 // } 3114 // // Find the boundary around the fallback. This is always the previous node. 3115 // const suspenseNode = suspenseIdNode.previousSibling; 3116 // // Tag it to be client rendered. 3117 // suspenseNode.data = SUSPENSE_FALLBACK_START_DATA; 3118 // // assign error metadata to first sibling 3119 // let dataset = suspenseIdNode.dataset; 3120 // if (errorDigest) dataset.dgst = errorDigest; 3121 // if (errorMsg) dataset.msg = errorMsg; 3122 // if (errorComponentStack) dataset.stck = errorComponentStack; 3123 // // Tell React to retry it if the parent already hydrated. 3124 // if (suspenseNode._reactRetry) { 3125 // suspenseNode._reactRetry(); 3126 // } 3127 // } 3128 // 3129 // function completeBoundary(suspenseBoundaryID, contentID) { 3130 // // Find the fallback's first element. 3131 // const suspenseIdNode = document.getElementById(suspenseBoundaryID); 3132 // const contentNode = document.getElementById(contentID); 3133 // // We'll detach the content node so that regardless of what happens next we don't leave in the tree. 3134 // // This might also help by not causing recalcing each time we move a child from here to the target. 3135 // contentNode.parentNode.removeChild(contentNode); 3136 // if (!suspenseIdNode) { 3137 // // The user must have already navigated away from this tree. 3138 // // E.g. because the parent was hydrated. That's fine there's nothing to do 3139 // // but we have to make sure that we already deleted the container node. 3140 // return; 3141 // } 3142 // // Find the boundary around the fallback. This is always the previous node. 3143 // const suspenseNode = suspenseIdNode.previousSibling; 3144 // 3145 // // Clear all the existing children. This is complicated because 3146 // // there can be embedded Suspense boundaries in the fallback. 3147 // // This is similar to clearSuspenseBoundary in ReactDOMHostConfig. 3148 // // TODO: We could avoid this if we never emitted suspense boundaries in fallback trees. 3149 // // They never hydrate anyway. However, currently we support incrementally loading the fallback. 3150 // const parentInstance = suspenseNode.parentNode; 3151 // let node = suspenseNode.nextSibling; 3152 // let depth = 0; 3153 // do { 3154 // if (node && node.nodeType === COMMENT_NODE) { 3155 // const data = node.data; 3156 // if (data === SUSPENSE_END_DATA) { 3157 // if (depth === 0) { 3158 // break; 3159 // } else { 3160 // depth--; 3161 // } 3162 // } else if ( 3163 // data === SUSPENSE_START_DATA || 3164 // data === SUSPENSE_PENDING_START_DATA || 3165 // data === SUSPENSE_FALLBACK_START_DATA 3166 // ) { 3167 // depth++; 3168 // } 3169 // } 3170 // 3171 // const nextNode = node.nextSibling; 3172 // parentInstance.removeChild(node); 3173 // node = nextNode; 3174 // } while (node); 3175 // 3176 // const endOfBoundary = node; 3177 // 3178 // // Insert all the children from the contentNode between the start and end of suspense boundary. 3179 // while (contentNode.firstChild) { 3180 // parentInstance.insertBefore(contentNode.firstChild, endOfBoundary); 3181 // } 3182 // suspenseNode.data = SUSPENSE_START_DATA; 3183 // if (suspenseNode._reactRetry) { 3184 // suspenseNode._reactRetry(); 3185 // } 3186 // } 3187 // 3188 // function completeSegment(containerID, placeholderID) { 3189 // const segmentContainer = document.getElementById(containerID); 3190 // const placeholderNode = document.getElementById(placeholderID); 3191 // // We always expect both nodes to exist here because, while we might 3192 // // have navigated away from the main tree, we still expect the detached 3193 // // tree to exist. 3194 // segmentContainer.parentNode.removeChild(segmentContainer); 3195 // while (segmentContainer.firstChild) { 3196 // placeholderNode.parentNode.insertBefore( 3197 // segmentContainer.firstChild, 3198 // placeholderNode, 3199 // ); 3200 // } 3201 // placeholderNode.parentNode.removeChild(placeholderNode); 3202 // } 3203 3204 var completeSegmentFunction = 'function $RS(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)}'; 3205 var completeBoundaryFunction = 'function $RC(a,b){a=document.getElementById(a);b=document.getElementById(b);b.parentNode.removeChild(b);if(a){a=a.previousSibling;var f=a.parentNode,c=a.nextSibling,e=0;do{if(c&&8===c.nodeType){var d=c.data;if("/$"===d)if(0===e)break;else e--;else"$"!==d&&"$?"!==d&&"$!"!==d||e++}d=c.nextSibling;f.removeChild(c);c=d}while(c);for(;b.firstChild;)f.insertBefore(b.firstChild,c);a.data="$";a._reactRetry&&a._reactRetry()}}'; 3206 var clientRenderFunction = 'function $RX(b,c,d,e){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),b._reactRetry&&b._reactRetry())}'; 3207 var completeSegmentScript1Full = stringToPrecomputedChunk(completeSegmentFunction + ';$RS("'); 3208 var completeSegmentScript1Partial = stringToPrecomputedChunk('$RS("'); 3209 var completeSegmentScript2 = stringToPrecomputedChunk('","'); 3210 var completeSegmentScript3 = stringToPrecomputedChunk('")</script>'); 3211 function writeCompletedSegmentInstruction(destination, responseState, contentSegmentID) { 3212 writeChunk(destination, responseState.startInlineScript); 3213 3214 if (!responseState.sentCompleteSegmentFunction) { 3215 // The first time we write this, we'll need to include the full implementation. 3216 responseState.sentCompleteSegmentFunction = true; 3217 writeChunk(destination, completeSegmentScript1Full); 3218 } else { 3219 // Future calls can just reuse the same function. 3220 writeChunk(destination, completeSegmentScript1Partial); 3221 } 3222 3223 writeChunk(destination, responseState.segmentPrefix); 3224 var formattedID = stringToChunk(contentSegmentID.toString(16)); 3225 writeChunk(destination, formattedID); 3226 writeChunk(destination, completeSegmentScript2); 3227 writeChunk(destination, responseState.placeholderPrefix); 3228 writeChunk(destination, formattedID); 3229 return writeChunkAndReturn(destination, completeSegmentScript3); 3230 } 3231 var completeBoundaryScript1Full = stringToPrecomputedChunk(completeBoundaryFunction + ';$RC("'); 3232 var completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'); 3233 var completeBoundaryScript2 = stringToPrecomputedChunk('","'); 3234 var completeBoundaryScript3 = stringToPrecomputedChunk('")</script>'); 3235 function writeCompletedBoundaryInstruction(destination, responseState, boundaryID, contentSegmentID) { 3236 writeChunk(destination, responseState.startInlineScript); 3237 3238 if (!responseState.sentCompleteBoundaryFunction) { 3239 // The first time we write this, we'll need to include the full implementation. 3240 responseState.sentCompleteBoundaryFunction = true; 3241 writeChunk(destination, completeBoundaryScript1Full); 3242 } else { 3243 // Future calls can just reuse the same function. 3244 writeChunk(destination, completeBoundaryScript1Partial); 3245 } 3246 3247 if (boundaryID === null) { 3248 throw new Error('An ID must have been assigned before we can complete the boundary.'); 3249 } 3250 3251 var formattedContentID = stringToChunk(contentSegmentID.toString(16)); 3252 writeChunk(destination, boundaryID); 3253 writeChunk(destination, completeBoundaryScript2); 3254 writeChunk(destination, responseState.segmentPrefix); 3255 writeChunk(destination, formattedContentID); 3256 return writeChunkAndReturn(destination, completeBoundaryScript3); 3257 } 3258 var clientRenderScript1Full = stringToPrecomputedChunk(clientRenderFunction + ';$RX("'); 3259 var clientRenderScript1Partial = stringToPrecomputedChunk('$RX("'); 3260 var clientRenderScript1A = stringToPrecomputedChunk('"'); 3261 var clientRenderScript2 = stringToPrecomputedChunk(')</script>'); 3262 var clientRenderErrorScriptArgInterstitial = stringToPrecomputedChunk(','); 3263 function writeClientRenderBoundaryInstruction(destination, responseState, boundaryID, errorDigest, errorMessage, errorComponentStack) { 3264 writeChunk(destination, responseState.startInlineScript); 3265 3266 if (!responseState.sentClientRenderFunction) { 3267 // The first time we write this, we'll need to include the full implementation. 3268 responseState.sentClientRenderFunction = true; 3269 writeChunk(destination, clientRenderScript1Full); 3270 } else { 3271 // Future calls can just reuse the same function. 3272 writeChunk(destination, clientRenderScript1Partial); 3273 } 3274 3275 if (boundaryID === null) { 3276 throw new Error('An ID must have been assigned before we can complete the boundary.'); 3277 } 3278 3279 writeChunk(destination, boundaryID); 3280 writeChunk(destination, clientRenderScript1A); 3281 3282 if (errorDigest || errorMessage || errorComponentStack) { 3283 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3284 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorDigest || ''))); 3285 } 3286 3287 if (errorMessage || errorComponentStack) { 3288 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3289 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorMessage || ''))); 3290 } 3291 3292 if (errorComponentStack) { 3293 writeChunk(destination, clientRenderErrorScriptArgInterstitial); 3294 writeChunk(destination, stringToChunk(escapeJSStringsForInstructionScripts(errorComponentStack))); 3295 } 3296 3297 return writeChunkAndReturn(destination, clientRenderScript2); 3298 } 3299 var regexForJSStringsInScripts = /[<\u2028\u2029]/g; 3300 3301 function escapeJSStringsForInstructionScripts(input) { 3302 var escaped = JSON.stringify(input); 3303 return escaped.replace(regexForJSStringsInScripts, function (match) { 3304 switch (match) { 3305 // santizing breaking out of strings and script tags 3306 case '<': 3307 return "\\u003c"; 3308 3309 case "\u2028": 3310 return "\\u2028"; 3311 3312 case "\u2029": 3313 return "\\u2029"; 3314 3315 default: 3316 { 3317 // eslint-disable-next-line react-internal/prod-error-codes 3318 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'); 3319 } 3320 } 3321 }); 3322 } 3323 3324 function createResponseState$1(generateStaticMarkup, identifierPrefix) { 3325 var responseState = createResponseState(identifierPrefix, undefined); 3326 return { 3327 // Keep this in sync with ReactDOMServerFormatConfig 3328 bootstrapChunks: responseState.bootstrapChunks, 3329 startInlineScript: responseState.startInlineScript, 3330 placeholderPrefix: responseState.placeholderPrefix, 3331 segmentPrefix: responseState.segmentPrefix, 3332 boundaryPrefix: responseState.boundaryPrefix, 3333 idPrefix: responseState.idPrefix, 3334 nextSuspenseID: responseState.nextSuspenseID, 3335 sentCompleteSegmentFunction: responseState.sentCompleteSegmentFunction, 3336 sentCompleteBoundaryFunction: responseState.sentCompleteBoundaryFunction, 3337 sentClientRenderFunction: responseState.sentClientRenderFunction, 3338 // This is an extra field for the legacy renderer 3339 generateStaticMarkup: generateStaticMarkup 3340 }; 3341 } 3342 function createRootFormatContext() { 3343 return { 3344 insertionMode: HTML_MODE, 3345 // We skip the root mode because we don't want to emit the DOCTYPE in legacy mode. 3346 selectedValue: null 3347 }; 3348 } 3349 function pushTextInstance$1(target, text, responseState, textEmbedded) { 3350 if (responseState.generateStaticMarkup) { 3351 target.push(stringToChunk(escapeTextForBrowser(text))); 3352 return false; 3353 } else { 3354 return pushTextInstance(target, text, responseState, textEmbedded); 3355 } 3356 } 3357 function pushSegmentFinale$1(target, responseState, lastPushedText, textEmbedded) { 3358 if (responseState.generateStaticMarkup) { 3359 return; 3360 } else { 3361 return pushSegmentFinale(target, responseState, lastPushedText, textEmbedded); 3362 } 3363 } 3364 function writeStartCompletedSuspenseBoundary$1(destination, responseState) { 3365 if (responseState.generateStaticMarkup) { 3366 // A completed boundary is done and doesn't need a representation in the HTML 3367 // if we're not going to be hydrating it. 3368 return true; 3369 } 3370 3371 return writeStartCompletedSuspenseBoundary(destination); 3372 } 3373 function writeStartClientRenderedSuspenseBoundary$1(destination, responseState, // flushing these error arguments are not currently supported in this legacy streaming format. 3374 errorDigest, errorMessage, errorComponentStack) { 3375 if (responseState.generateStaticMarkup) { 3376 // A client rendered boundary is done and doesn't need a representation in the HTML 3377 // since we'll never hydrate it. This is arguably an error in static generation. 3378 return true; 3379 } 3380 3381 return writeStartClientRenderedSuspenseBoundary(destination, responseState, errorDigest, errorMessage, errorComponentStack); 3382 } 3383 function writeEndCompletedSuspenseBoundary$1(destination, responseState) { 3384 if (responseState.generateStaticMarkup) { 3385 return true; 3386 } 3387 3388 return writeEndCompletedSuspenseBoundary(destination); 3389 } 3390 function writeEndClientRenderedSuspenseBoundary$1(destination, responseState) { 3391 if (responseState.generateStaticMarkup) { 3392 return true; 3393 } 3394 3395 return writeEndClientRenderedSuspenseBoundary(destination); 3396 } 3397 3398 var 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. 3404 var REACT_ELEMENT_TYPE = Symbol.for('react.element'); 3405 var REACT_PORTAL_TYPE = Symbol.for('react.portal'); 3406 var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); 3407 var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode'); 3408 var REACT_PROFILER_TYPE = Symbol.for('react.profiler'); 3409 var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); 3410 var REACT_CONTEXT_TYPE = Symbol.for('react.context'); 3411 var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); 3412 var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense'); 3413 var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list'); 3414 var REACT_MEMO_TYPE = Symbol.for('react.memo'); 3415 var REACT_LAZY_TYPE = Symbol.for('react.lazy'); 3416 var REACT_SCOPE_TYPE = Symbol.for('react.scope'); 3417 var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode'); 3418 var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden'); 3419 var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value'); 3420 var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; 3421 var FAUX_ITERATOR_SYMBOL = '@@iterator'; 3422 function 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 3436 function 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 3448 function getContextName(type) { 3449 return type.displayName || 'Context'; 3450 } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. 3451 3452 3453 function 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. 3540 var disabledDepth = 0; 3541 var prevLog; 3542 var prevInfo; 3543 var prevWarn; 3544 var prevError; 3545 var prevGroup; 3546 var prevGroupCollapsed; 3547 var prevGroupEnd; 3548 3549 function disabledLog() {} 3550 3551 disabledLog.__reactDisabledLog = true; 3552 function 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 } 3586 function 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 3630 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 3631 var prefix; 3632 function 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 } 3648 var reentry = false; 3649 var componentFrameCache; 3650 3651 { 3652 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; 3653 componentFrameCache = new PossiblyWeakMap(); 3654 } 3655 3656 function 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 3816 function describeClassComponentFrame(ctor, source, ownerFn) { 3817 { 3818 return describeNativeComponentFrame(ctor, true); 3819 } 3820 } 3821 function describeFunctionComponentFrame(fn, source, ownerFn) { 3822 { 3823 return describeNativeComponentFrame(fn, false); 3824 } 3825 } 3826 3827 function shouldConstruct(Component) { 3828 var prototype = Component.prototype; 3829 return !!(prototype && prototype.isReactComponent); 3830 } 3831 3832 function 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 3882 var loggedTypeFailures = {}; 3883 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 3884 3885 function 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 3897 function 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 3946 var warnedAboutMissingGetChildContext; 3947 3948 { 3949 warnedAboutMissingGetChildContext = {}; 3950 } 3951 3952 var emptyContextObject = {}; 3953 3954 { 3955 Object.freeze(emptyContextObject); 3956 } 3957 3958 function 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 } 3980 function 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 4015 var 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 4024 var 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 4028 var currentActiveSnapshot = null; 4029 4030 function popNode(prev) { 4031 { 4032 prev.context._currentValue2 = prev.parentValue; 4033 } 4034 } 4035 4036 function pushNode(next) { 4037 { 4038 next.context._currentValue2 = next.value; 4039 } 4040 } 4041 4042 function 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 4065 function popAllPrevious(prev) { 4066 popNode(prev); 4067 var parentPrev = prev.parent; 4068 4069 if (parentPrev !== null) { 4070 popAllPrevious(parentPrev); 4071 } 4072 } 4073 4074 function pushAllNext(next) { 4075 var parentNext = next.parent; 4076 4077 if (parentNext !== null) { 4078 pushAllNext(parentNext); 4079 } 4080 4081 pushNode(next); 4082 } 4083 4084 function 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 4101 function 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 4123 function 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 } 4152 function pushProvider(context, nextValue) { 4153 var prevValue; 4154 4155 { 4156 prevValue = context._currentValue2; 4157 context._currentValue2 = nextValue; 4158 4159 { 4160 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) { 4161 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 4162 } 4163 4164 context._currentRenderer2 = 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 } 4179 function 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._currentValue2 = prevSnapshot.context._defaultValue; 4197 } else { 4198 prevSnapshot.context._currentValue2 = _value; 4199 } 4200 4201 { 4202 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) { 4203 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 4204 } 4205 4206 context._currentRenderer2 = rendererSigil; 4207 } 4208 } 4209 4210 return currentActiveSnapshot = prevSnapshot.parent; 4211 } 4212 function getActiveContext() { 4213 return currentActiveSnapshot; 4214 } 4215 function readContext(context) { 4216 var value = context._currentValue2; 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 */ 4229 function get(key) { 4230 return key._reactInternals; 4231 } 4232 function set(key, value) { 4233 key._reactInternals = value; 4234 } 4235 4236 var didWarnAboutNoopUpdateForComponent = {}; 4237 var didWarnAboutDeprecatedWillMount = {}; 4238 var didWarnAboutUninitializedState; 4239 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; 4240 var didWarnAboutLegacyLifecyclesAndDerivedState; 4241 var didWarnAboutUndefinedDerivedState; 4242 var warnOnUndefinedDerivedState; 4243 var warnOnInvalidCallback; 4244 var didWarnAboutDirectlyAssigningPropsToState; 4245 var didWarnAboutContextTypeAndContextTypes; 4246 var 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 4285 function 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 4301 var 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 4346 function 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 4358 function 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 4451 function 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 4556 function 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 4589 function 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 4624 function 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. 4727 var emptyTreeContext = { 4728 id: 1, 4729 overflow: '' 4730 }; 4731 function 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 } 4737 function 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 4794 function getBitLength(number) { 4795 return 32 - clz32(number); 4796 } 4797 4798 function 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 4803 var 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 4807 var log = Math.log; 4808 var LN2 = Math.LN2; 4809 4810 function 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 */ 4824 function 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 4829 var objectIs = typeof Object.is === 'function' ? Object.is : is; 4830 4831 var currentlyRenderingComponent = null; 4832 var currentlyRenderingTask = null; 4833 var firstWorkInProgressHook = null; 4834 var workInProgressHook = null; // Whether the work-in-progress hook is a re-rendered hook 4835 4836 var isReRender = false; // Whether an update was scheduled during the currently executing render pass. 4837 4838 var didScheduleRenderPhaseUpdate = false; // Counts the number of useId hooks in this component 4839 4840 var localIdCounter = 0; // Lazily created map of render-phase updates 4841 4842 var renderPhaseUpdates = null; // Counter to prevent infinite loops. 4843 4844 var numberOfReRenders = 0; 4845 var RE_RENDER_LIMIT = 25; 4846 var isInHookUserCodeInDev = false; // In DEV, this is the name of the currently executing primitive hook 4847 4848 var currentHookNameInDev; 4849 4850 function 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 4864 function 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 4892 function 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 4904 function 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 4930 function 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 } 4947 function 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 } 4966 function 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 4974 function 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 4988 function 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 4998 function useContext(context) { 4999 { 5000 currentHookNameInDev = 'useContext'; 5001 } 5002 5003 resolveCurrentlyRenderingComponent(); 5004 return readContext(context); 5005 } 5006 5007 function basicStateReducer(state, action) { 5008 // $FlowFixMe: Flow doesn't like mixed types 5009 return typeof action === 'function' ? action(state) : action; 5010 } 5011 5012 function 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 } 5020 function 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 5101 function 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 5134 function 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 5155 function 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 5163 function 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 5199 function 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 5207 function useMutableSource(source, getSnapshot, subscribe) { 5208 resolveCurrentlyRenderingComponent(); 5209 return getSnapshot(source._source); 5210 } 5211 5212 function 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 5220 function useDeferredValue(value) { 5221 resolveCurrentlyRenderingComponent(); 5222 return value; 5223 } 5224 5225 function unsupportedStartTransition() { 5226 throw new Error('startTransition cannot be called during server rendering.'); 5227 } 5228 5229 function useTransition() { 5230 resolveCurrentlyRenderingComponent(); 5231 return [false, unsupportedStartTransition]; 5232 } 5233 5234 function 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 5247 function noop() {} 5248 5249 var 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 5273 var currentResponseState = null; 5274 function setCurrentResponseState(responseState) { 5275 currentResponseState = responseState; 5276 } 5277 5278 function 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 5307 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; 5308 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 5309 var PENDING = 0; 5310 var COMPLETED = 1; 5311 var FLUSHED = 2; 5312 var ABORTED = 3; 5313 var ERRORED = 4; 5314 var OPEN = 0; 5315 var CLOSING = 1; 5316 var 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 5332 var DEFAULT_PROGRESSIVE_CHUNK_SIZE = 12800; 5333 5334 function defaultErrorHandler(error) { 5335 console['error'](error); // Don't transform to our wrapper 5336 5337 return null; 5338 } 5339 5340 function noop$1() {} 5341 5342 function 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 5376 function 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 5387 function 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 5401 function 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 5431 function 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 5448 var currentTaskInDEV = null; 5449 5450 function getCurrentStackInDEV() { 5451 { 5452 if (currentTaskInDEV === null || currentTaskInDEV.componentStack === null) { 5453 return ''; 5454 } 5455 5456 return getStackByComponentStackNode(currentTaskInDEV.componentStack); 5457 } 5458 } 5459 5460 function pushBuiltInComponentStackInDEV(task, type) { 5461 { 5462 task.componentStack = { 5463 tag: 0, 5464 parent: task.componentStack, 5465 type: type 5466 }; 5467 } 5468 } 5469 5470 function pushFunctionComponentStackInDEV(task, type) { 5471 { 5472 task.componentStack = { 5473 tag: 1, 5474 parent: task.componentStack, 5475 type: type 5476 }; 5477 } 5478 } 5479 5480 function pushClassComponentStackInDEV(task, type) { 5481 { 5482 task.componentStack = { 5483 tag: 2, 5484 parent: task.componentStack, 5485 type: type 5486 }; 5487 } 5488 } 5489 5490 function 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 5501 var lastBoundaryErrorComponentStackDev = null; 5502 5503 function 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 5523 function 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 5536 function 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 5554 function 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$1(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 5633 function 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 5651 function shouldConstruct$1(Component) { 5652 return Component.prototype && Component.prototype.isReactComponent; 5653 } 5654 5655 function 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 5662 function 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 5691 function 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 5700 var didWarnAboutBadClass = {}; 5701 var didWarnAboutModulePatternComponent = {}; 5702 var didWarnAboutContextTypeOnFunctionComponent = {}; 5703 var didWarnAboutGetDerivedStateOnFunctionComponent = {}; 5704 var didWarnAboutReassigningProps = false; 5705 var didWarnAboutGenerators = false; 5706 var didWarnAboutMaps = false; 5707 var hasWarnedAboutUsingContextAsConsumer = false; // This would typically be a function component but we still support module pattern 5708 // components for some reason. 5709 5710 function 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 5792 function 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 5822 function 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 5840 function 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 5865 function 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 5871 function 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 5909 function 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 5930 function 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 5940 function 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 6046 function 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 6070 function 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 6091 function 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$1(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$1(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 6201 function 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 6218 function 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 6244 function 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 6298 function 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 6335 function 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 6346 function 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 6414 function 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 6431 function 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 6506 function 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$1(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 6552 function 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 6608 function 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 6660 function 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$1(destination, request.responseState, boundary.errorDigest, boundary.errorMessage, boundary.errorComponentStack); // Flush the fallback. 6675 6676 flushSubtree(request, destination, segment); 6677 return writeEndClientRenderedSuspenseBoundary$1(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$1(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$1(destination, request.responseState); 6720 } 6721 } 6722 6723 function flushClientRenderedBoundary(request, destination, boundary) { 6724 return writeClientRenderBoundaryInstruction(destination, request.responseState, boundary.id, boundary.errorDigest, boundary.errorMessage, boundary.errorComponentStack); 6725 } 6726 6727 function 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 6733 function 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 6746 function 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 6766 function 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 6790 function flushCompletedQueues(request, destination) { 6791 6792 try { 6793 // The structure of this is to go through each queue one by one and write 6794 // until the sink tells us to stop. When we should stop, we still finish writing 6795 // that item fully and then yield. At that point we remove the already completed 6796 // items up until the point we completed them. 6797 // TODO: Emit preloading. 6798 // TODO: It's kind of unfortunate to keep checking this array after we've already 6799 // emitted the root. 6800 var completedRootSegment = request.completedRootSegment; 6801 6802 if (completedRootSegment !== null && request.pendingRootTasks === 0) { 6803 flushSegment(request, destination, completedRootSegment); 6804 request.completedRootSegment = null; 6805 writeCompletedRoot(destination, request.responseState); 6806 } // We emit client rendering instructions for already emitted boundaries first. 6807 // This is so that we can signal to the client to start client rendering them as 6808 // soon as possible. 6809 6810 6811 var clientRenderedBoundaries = request.clientRenderedBoundaries; 6812 var i; 6813 6814 for (i = 0; i < clientRenderedBoundaries.length; i++) { 6815 var boundary = clientRenderedBoundaries[i]; 6816 6817 if (!flushClientRenderedBoundary(request, destination, boundary)) { 6818 request.destination = null; 6819 i++; 6820 clientRenderedBoundaries.splice(0, i); 6821 return; 6822 } 6823 } 6824 6825 clientRenderedBoundaries.splice(0, i); // Next we emit any complete boundaries. It's better to favor boundaries 6826 // that are completely done since we can actually show them, than it is to emit 6827 // any individual segments from a partially complete boundary. 6828 6829 var completedBoundaries = request.completedBoundaries; 6830 6831 for (i = 0; i < completedBoundaries.length; i++) { 6832 var _boundary = completedBoundaries[i]; 6833 6834 if (!flushCompletedBoundary(request, destination, _boundary)) { 6835 request.destination = null; 6836 i++; 6837 completedBoundaries.splice(0, i); 6838 return; 6839 } 6840 } 6841 6842 completedBoundaries.splice(0, i); // Allow anything written so far to flush to the underlying sink before 6843 // we continue with lower priorities. 6844 6845 completeWriting(destination); 6846 beginWriting(destination); // TODO: Here we'll emit data used by hydration. 6847 // Next we emit any segments of any boundaries that are partially complete 6848 // but not deeply complete. 6849 6850 var partialBoundaries = request.partialBoundaries; 6851 6852 for (i = 0; i < partialBoundaries.length; i++) { 6853 var _boundary2 = partialBoundaries[i]; 6854 6855 if (!flushPartialBoundary(request, destination, _boundary2)) { 6856 request.destination = null; 6857 i++; 6858 partialBoundaries.splice(0, i); 6859 return; 6860 } 6861 } 6862 6863 partialBoundaries.splice(0, i); // Next we check the completed boundaries again. This may have had 6864 // boundaries added to it in case they were too larged to be inlined. 6865 // New ones might be added in this loop. 6866 6867 var largeBoundaries = request.completedBoundaries; 6868 6869 for (i = 0; i < largeBoundaries.length; i++) { 6870 var _boundary3 = largeBoundaries[i]; 6871 6872 if (!flushCompletedBoundary(request, destination, _boundary3)) { 6873 request.destination = null; 6874 i++; 6875 largeBoundaries.splice(0, i); 6876 return; 6877 } 6878 } 6879 6880 largeBoundaries.splice(0, i); 6881 } finally { 6882 6883 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 6884 // either they have pending task or they're complete. 6885 ) { 6886 { 6887 if (request.abortableTasks.size !== 0) { 6888 error('There was still abortable task at the root when we closed. This is a bug in React.'); 6889 } 6890 } // We're done. 6891 6892 6893 close(destination); 6894 } 6895 } 6896 } 6897 6898 function startWork(request) { 6899 scheduleWork(function () { 6900 return performWork(request); 6901 }); 6902 } 6903 function startFlowing(request, destination) { 6904 if (request.status === CLOSING) { 6905 request.status = CLOSED; 6906 closeWithError(destination, request.fatalError); 6907 return; 6908 } 6909 6910 if (request.status === CLOSED) { 6911 return; 6912 } 6913 6914 if (request.destination !== null) { 6915 // We're already flowing. 6916 return; 6917 } 6918 6919 request.destination = destination; 6920 6921 try { 6922 flushCompletedQueues(request, destination); 6923 } catch (error) { 6924 logRecoverableError(request, error); 6925 fatalError(request, error); 6926 } 6927 } // This is called to early terminate a request. It puts all pending boundaries in client rendered state. 6928 6929 function abort(request, reason) { 6930 try { 6931 var abortableTasks = request.abortableTasks; 6932 abortableTasks.forEach(function (task) { 6933 return abortTask(task, request, reason); 6934 }); 6935 abortableTasks.clear(); 6936 6937 if (request.destination !== null) { 6938 flushCompletedQueues(request, request.destination); 6939 } 6940 } catch (error) { 6941 logRecoverableError(request, error); 6942 fatalError(request, error); 6943 } 6944 } 6945 6946 function onError() {// Non-fatal errors are ignored. 6947 } 6948 6949 function renderToStringImpl(children, options, generateStaticMarkup, abortReason) { 6950 var didFatal = false; 6951 var fatalError = null; 6952 var result = ''; 6953 var destination = { 6954 push: function (chunk) { 6955 if (chunk !== null) { 6956 result += chunk; 6957 } 6958 6959 return true; 6960 }, 6961 destroy: function (error) { 6962 didFatal = true; 6963 fatalError = error; 6964 } 6965 }; 6966 var readyToStream = false; 6967 6968 function onShellReady() { 6969 readyToStream = true; 6970 } 6971 6972 var request = createRequest(children, createResponseState$1(generateStaticMarkup, options ? options.identifierPrefix : undefined), createRootFormatContext(), Infinity, onError, undefined, onShellReady, undefined, undefined); 6973 startWork(request); // If anything suspended and is still pending, we'll abort it before writing. 6974 // That way we write only client-rendered boundaries from the start. 6975 6976 abort(request, abortReason); 6977 startFlowing(request, destination); 6978 6979 if (didFatal) { 6980 throw fatalError; 6981 } 6982 6983 if (!readyToStream) { 6984 // Note: This error message is the one we use on the client. It doesn't 6985 // really make sense here. But this is the legacy server renderer, anyway. 6986 // We're going to delete it soon. 6987 throw new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To fix, ' + 'updates that suspend should be wrapped with startTransition.'); 6988 } 6989 6990 return result; 6991 } 6992 6993 function renderToString(children, options) { 6994 return renderToStringImpl(children, options, false, 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'); 6995 } 6996 6997 function renderToStaticMarkup(children, options) { 6998 return renderToStringImpl(children, options, true, 'The server used "renderToStaticMarkup" which does not support Suspense. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'); 6999 } 7000 7001 function renderToNodeStream() { 7002 throw new Error('ReactDOMServer.renderToNodeStream(): The streaming API is not available ' + 'in the browser. Use ReactDOMServer.renderToString() instead.'); 7003 } 7004 7005 function renderToStaticNodeStream() { 7006 throw new Error('ReactDOMServer.renderToStaticNodeStream(): The streaming API is not available ' + 'in the browser. Use ReactDOMServer.renderToStaticMarkup() instead.'); 7007 } 7008 7009 exports.renderToNodeStream = renderToNodeStream; 7010 exports.renderToStaticMarkup = renderToStaticMarkup; 7011 exports.renderToStaticNodeStream = renderToStaticNodeStream; 7012 exports.renderToString = renderToString; 7013 exports.version = ReactVersion; 7014 7015})));