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