UNPKG

895 kBJavaScriptView Raw
1/** @license React v17.0.2
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12if (process.env.NODE_ENV !== "production") {
13 (function() {
14'use strict';
15
16var React = require('react');
17var _assign = require('object-assign');
18var Scheduler = require('scheduler');
19var tracing = require('scheduler/tracing');
20
21var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
22
23// by calls to these methods by a Babel plugin.
24//
25// In PROD (or in packages without access to React internals),
26// they are left as they are instead.
27
28function warn(format) {
29 {
30 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
31 args[_key - 1] = arguments[_key];
32 }
33
34 printWarning('warn', format, args);
35 }
36}
37function error(format) {
38 {
39 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
40 args[_key2 - 1] = arguments[_key2];
41 }
42
43 printWarning('error', format, args);
44 }
45}
46
47function printWarning(level, format, args) {
48 // When changing this logic, you might want to also
49 // update consoleWithStackDev.www.js as well.
50 {
51 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
52 var stack = ReactDebugCurrentFrame.getStackAddendum();
53
54 if (stack !== '') {
55 format += '%s';
56 args = args.concat([stack]);
57 }
58
59 var argsWithFormat = args.map(function (item) {
60 return '' + item;
61 }); // Careful: RN currently depends on this prefix
62
63 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
64 // breaks IE9: https://github.com/facebook/react/issues/13610
65 // eslint-disable-next-line react-internal/no-production-logging
66
67 Function.prototype.apply.call(console[level], console, argsWithFormat);
68 }
69}
70
71if (!React) {
72 {
73 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." );
74 }
75}
76
77var FunctionComponent = 0;
78var ClassComponent = 1;
79var IndeterminateComponent = 2; // Before we know whether it is function or class
80
81var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
82
83var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
84
85var HostComponent = 5;
86var HostText = 6;
87var Fragment = 7;
88var Mode = 8;
89var ContextConsumer = 9;
90var ContextProvider = 10;
91var ForwardRef = 11;
92var Profiler = 12;
93var SuspenseComponent = 13;
94var MemoComponent = 14;
95var SimpleMemoComponent = 15;
96var LazyComponent = 16;
97var IncompleteClassComponent = 17;
98var DehydratedFragment = 18;
99var SuspenseListComponent = 19;
100var FundamentalComponent = 20;
101var ScopeComponent = 21;
102var Block = 22;
103var OffscreenComponent = 23;
104var LegacyHiddenComponent = 24;
105
106// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
107
108var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
109
110var enableFundamentalAPI = false; // Experimental Scope support.
111var enableNewReconciler = false; // Errors that are thrown while unmounting (or after in the case of passive effects)
112var warnAboutStringRefs = false;
113
114var allNativeEvents = new Set();
115/**
116 * Mapping from registration name to event name
117 */
118
119
120var registrationNameDependencies = {};
121/**
122 * Mapping from lowercase registration names to the properly cased version,
123 * used to warn in the case of missing event handlers. Available
124 * only in true.
125 * @type {Object}
126 */
127
128var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
129
130function registerTwoPhaseEvent(registrationName, dependencies) {
131 registerDirectEvent(registrationName, dependencies);
132 registerDirectEvent(registrationName + 'Capture', dependencies);
133}
134function registerDirectEvent(registrationName, dependencies) {
135 {
136 if (registrationNameDependencies[registrationName]) {
137 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
138 }
139 }
140
141 registrationNameDependencies[registrationName] = dependencies;
142
143 {
144 var lowerCasedName = registrationName.toLowerCase();
145 possibleRegistrationNames[lowerCasedName] = registrationName;
146
147 if (registrationName === 'onDoubleClick') {
148 possibleRegistrationNames.ondblclick = registrationName;
149 }
150 }
151
152 for (var i = 0; i < dependencies.length; i++) {
153 allNativeEvents.add(dependencies[i]);
154 }
155}
156
157var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
158
159// A reserved attribute.
160// It is handled by React separately and shouldn't be written to the DOM.
161var RESERVED = 0; // A simple string attribute.
162// Attributes that aren't in the filter are presumed to have this type.
163
164var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
165// "enumerated" attributes with "true" and "false" as possible values.
166// When true, it should be set to a "true" string.
167// When false, it should be set to a "false" string.
168
169var BOOLEANISH_STRING = 2; // A real boolean attribute.
170// When true, it should be present (set either to an empty string or its name).
171// When false, it should be omitted.
172
173var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
174// When true, it should be present (set either to an empty string or its name).
175// When false, it should be omitted.
176// For any other value, should be present with that value.
177
178var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
179// When falsy, it should be removed.
180
181var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
182// When falsy, it should be removed.
183
184var POSITIVE_NUMERIC = 6;
185
186/* eslint-disable max-len */
187var 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";
188/* eslint-enable max-len */
189
190var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
191var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
192var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
193var hasOwnProperty = Object.prototype.hasOwnProperty;
194var illegalAttributeNameCache = {};
195var validatedAttributeNameCache = {};
196function isAttributeNameSafe(attributeName) {
197 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
198 return true;
199 }
200
201 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
202 return false;
203 }
204
205 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
206 validatedAttributeNameCache[attributeName] = true;
207 return true;
208 }
209
210 illegalAttributeNameCache[attributeName] = true;
211
212 {
213 error('Invalid attribute name: `%s`', attributeName);
214 }
215
216 return false;
217}
218function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
219 if (propertyInfo !== null) {
220 return propertyInfo.type === RESERVED;
221 }
222
223 if (isCustomComponentTag) {
224 return false;
225 }
226
227 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
228 return true;
229 }
230
231 return false;
232}
233function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
234 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
235 return false;
236 }
237
238 switch (typeof value) {
239 case 'function': // $FlowIssue symbol is perfectly valid here
240
241 case 'symbol':
242 // eslint-disable-line
243 return true;
244
245 case 'boolean':
246 {
247 if (isCustomComponentTag) {
248 return false;
249 }
250
251 if (propertyInfo !== null) {
252 return !propertyInfo.acceptsBooleans;
253 } else {
254 var prefix = name.toLowerCase().slice(0, 5);
255 return prefix !== 'data-' && prefix !== 'aria-';
256 }
257 }
258
259 default:
260 return false;
261 }
262}
263function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
264 if (value === null || typeof value === 'undefined') {
265 return true;
266 }
267
268 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
269 return true;
270 }
271
272 if (isCustomComponentTag) {
273 return false;
274 }
275
276 if (propertyInfo !== null) {
277
278 switch (propertyInfo.type) {
279 case BOOLEAN:
280 return !value;
281
282 case OVERLOADED_BOOLEAN:
283 return value === false;
284
285 case NUMERIC:
286 return isNaN(value);
287
288 case POSITIVE_NUMERIC:
289 return isNaN(value) || value < 1;
290 }
291 }
292
293 return false;
294}
295function getPropertyInfo(name) {
296 return properties.hasOwnProperty(name) ? properties[name] : null;
297}
298
299function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
300 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
301 this.attributeName = attributeName;
302 this.attributeNamespace = attributeNamespace;
303 this.mustUseProperty = mustUseProperty;
304 this.propertyName = name;
305 this.type = type;
306 this.sanitizeURL = sanitizeURL;
307 this.removeEmptyString = removeEmptyString;
308} // When adding attributes to this list, be sure to also add them to
309// the `possibleStandardNames` module to ensure casing and incorrect
310// name warnings.
311
312
313var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
314
315var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
316// elements (not just inputs). Now that ReactDOMInput assigns to the
317// defaultValue property -- do we need this?
318'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
319reservedProps.forEach(function (name) {
320 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
321 name, // attributeName
322 null, // attributeNamespace
323 false, // sanitizeURL
324 false);
325}); // A few React string attributes have a different name.
326// This is a mapping from React prop names to the attribute names.
327
328[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
329 var name = _ref[0],
330 attributeName = _ref[1];
331 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
332 attributeName, // attributeName
333 null, // attributeNamespace
334 false, // sanitizeURL
335 false);
336}); // These are "enumerated" HTML attributes that accept "true" and "false".
337// In React, we let users pass `true` and `false` even though technically
338// these aren't boolean attributes (they are coerced to strings).
339
340['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
341 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
342 name.toLowerCase(), // attributeName
343 null, // attributeNamespace
344 false, // sanitizeURL
345 false);
346}); // These are "enumerated" SVG attributes that accept "true" and "false".
347// In React, we let users pass `true` and `false` even though technically
348// these aren't boolean attributes (they are coerced to strings).
349// Since these are SVG attributes, their attribute names are case-sensitive.
350
351['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
352 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
353 name, // attributeName
354 null, // attributeNamespace
355 false, // sanitizeURL
356 false);
357}); // These are HTML boolean attributes.
358
359['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
360// on the client side because the browsers are inconsistent. Instead we call focus().
361'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
362'itemScope'].forEach(function (name) {
363 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
364 name.toLowerCase(), // attributeName
365 null, // attributeNamespace
366 false, // sanitizeURL
367 false);
368}); // These are the few React props that we set as DOM properties
369// rather than attributes. These are all booleans.
370
371['checked', // Note: `option.selected` is not updated if `select.multiple` is
372// disabled with `removeAttribute`. We have special logic for handling this.
373'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
374// you'll need to set attributeName to name.toLowerCase()
375// instead in the assignment below.
376].forEach(function (name) {
377 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
378 name, // attributeName
379 null, // attributeNamespace
380 false, // sanitizeURL
381 false);
382}); // These are HTML attributes that are "overloaded booleans": they behave like
383// booleans, but can also accept a string value.
384
385['capture', 'download' // NOTE: if you add a camelCased prop to this list,
386// you'll need to set attributeName to name.toLowerCase()
387// instead in the assignment below.
388].forEach(function (name) {
389 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
390 name, // attributeName
391 null, // attributeNamespace
392 false, // sanitizeURL
393 false);
394}); // These are HTML attributes that must be positive numbers.
395
396['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
397// you'll need to set attributeName to name.toLowerCase()
398// instead in the assignment below.
399].forEach(function (name) {
400 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
401 name, // attributeName
402 null, // attributeNamespace
403 false, // sanitizeURL
404 false);
405}); // These are HTML attributes that must be numbers.
406
407['rowSpan', 'start'].forEach(function (name) {
408 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
409 name.toLowerCase(), // attributeName
410 null, // attributeNamespace
411 false, // sanitizeURL
412 false);
413});
414var CAMELIZE = /[\-\:]([a-z])/g;
415
416var capitalize = function (token) {
417 return token[1].toUpperCase();
418}; // This is a list of all SVG attributes that need special casing, namespacing,
419// or boolean value assignment. Regular attributes that just accept strings
420// and have the same names are omitted, just like in the HTML attribute filter.
421// Some of these attributes can be hard to find. This list was created by
422// scraping the MDN documentation.
423
424
425['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,
426// you'll need to set attributeName to name.toLowerCase()
427// instead in the assignment below.
428].forEach(function (attributeName) {
429 var name = attributeName.replace(CAMELIZE, capitalize);
430 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
431 attributeName, null, // attributeNamespace
432 false, // sanitizeURL
433 false);
434}); // String SVG attributes with the xlink namespace.
435
436['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
437// you'll need to set attributeName to name.toLowerCase()
438// instead in the assignment below.
439].forEach(function (attributeName) {
440 var name = attributeName.replace(CAMELIZE, capitalize);
441 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
442 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
443 false);
444}); // String SVG attributes with the xml namespace.
445
446['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
447// you'll need to set attributeName to name.toLowerCase()
448// instead in the assignment below.
449].forEach(function (attributeName) {
450 var name = attributeName.replace(CAMELIZE, capitalize);
451 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
452 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL
453 false);
454}); // These attribute exists both in HTML and SVG.
455// The attribute name is case-sensitive in SVG so we can't just use
456// the React name like we do for attributes that exist only in HTML.
457
458['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
459 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
460 attributeName.toLowerCase(), // attributeName
461 null, // attributeNamespace
462 false, // sanitizeURL
463 false);
464}); // These attributes accept URLs. These must not allow javascript: URLS.
465// These will also need to accept Trusted Types object in the future.
466
467var xlinkHref = 'xlinkHref';
468properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
469'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
470false);
471['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
472 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
473 attributeName.toLowerCase(), // attributeName
474 null, // attributeNamespace
475 true, // sanitizeURL
476 true);
477});
478
479// and any newline or tab are filtered out as if they're not part of the URL.
480// https://url.spec.whatwg.org/#url-parsing
481// Tab or newline are defined as \r\n\t:
482// https://infra.spec.whatwg.org/#ascii-tab-or-newline
483// A C0 control is a code point in the range \u0000 NULL to \u001F
484// INFORMATION SEPARATOR ONE, inclusive:
485// https://infra.spec.whatwg.org/#c0-control-or-space
486
487/* eslint-disable max-len */
488
489var 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;
490var didWarn = false;
491
492function sanitizeURL(url) {
493 {
494 if (!didWarn && isJavaScriptProtocol.test(url)) {
495 didWarn = true;
496
497 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));
498 }
499 }
500}
501
502/**
503 * Get the value for a property on a node. Only used in DEV for SSR validation.
504 * The "expected" argument is used as a hint of what the expected value is.
505 * Some properties have multiple equivalent values.
506 */
507function getValueForProperty(node, name, expected, propertyInfo) {
508 {
509 if (propertyInfo.mustUseProperty) {
510 var propertyName = propertyInfo.propertyName;
511 return node[propertyName];
512 } else {
513 if ( propertyInfo.sanitizeURL) {
514 // If we haven't fully disabled javascript: URLs, and if
515 // the hydration is successful of a javascript: URL, we
516 // still want to warn on the client.
517 sanitizeURL('' + expected);
518 }
519
520 var attributeName = propertyInfo.attributeName;
521 var stringValue = null;
522
523 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
524 if (node.hasAttribute(attributeName)) {
525 var value = node.getAttribute(attributeName);
526
527 if (value === '') {
528 return true;
529 }
530
531 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
532 return value;
533 }
534
535 if (value === '' + expected) {
536 return expected;
537 }
538
539 return value;
540 }
541 } else if (node.hasAttribute(attributeName)) {
542 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
543 // We had an attribute but shouldn't have had one, so read it
544 // for the error message.
545 return node.getAttribute(attributeName);
546 }
547
548 if (propertyInfo.type === BOOLEAN) {
549 // If this was a boolean, it doesn't matter what the value is
550 // the fact that we have it is the same as the expected.
551 return expected;
552 } // Even if this property uses a namespace we use getAttribute
553 // because we assume its namespaced name is the same as our config.
554 // To use getAttributeNS we need the local name which we don't have
555 // in our config atm.
556
557
558 stringValue = node.getAttribute(attributeName);
559 }
560
561 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
562 return stringValue === null ? expected : stringValue;
563 } else if (stringValue === '' + expected) {
564 return expected;
565 } else {
566 return stringValue;
567 }
568 }
569 }
570}
571/**
572 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
573 * The third argument is used as a hint of what the expected value is. Some
574 * attributes have multiple equivalent values.
575 */
576
577function getValueForAttribute(node, name, expected) {
578 {
579 if (!isAttributeNameSafe(name)) {
580 return;
581 } // If the object is an opaque reference ID, it's expected that
582 // the next prop is different than the server value, so just return
583 // expected
584
585
586 if (isOpaqueHydratingObject(expected)) {
587 return expected;
588 }
589
590 if (!node.hasAttribute(name)) {
591 return expected === undefined ? undefined : null;
592 }
593
594 var value = node.getAttribute(name);
595
596 if (value === '' + expected) {
597 return expected;
598 }
599
600 return value;
601 }
602}
603/**
604 * Sets the value for a property on a node.
605 *
606 * @param {DOMElement} node
607 * @param {string} name
608 * @param {*} value
609 */
610
611function setValueForProperty(node, name, value, isCustomComponentTag) {
612 var propertyInfo = getPropertyInfo(name);
613
614 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
615 return;
616 }
617
618 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
619 value = null;
620 } // If the prop isn't in the special list, treat it as a simple attribute.
621
622
623 if (isCustomComponentTag || propertyInfo === null) {
624 if (isAttributeNameSafe(name)) {
625 var _attributeName = name;
626
627 if (value === null) {
628 node.removeAttribute(_attributeName);
629 } else {
630 node.setAttribute(_attributeName, '' + value);
631 }
632 }
633
634 return;
635 }
636
637 var mustUseProperty = propertyInfo.mustUseProperty;
638
639 if (mustUseProperty) {
640 var propertyName = propertyInfo.propertyName;
641
642 if (value === null) {
643 var type = propertyInfo.type;
644 node[propertyName] = type === BOOLEAN ? false : '';
645 } else {
646 // Contrary to `setAttribute`, object properties are properly
647 // `toString`ed by IE8/9.
648 node[propertyName] = value;
649 }
650
651 return;
652 } // The rest are treated as attributes with special cases.
653
654
655 var attributeName = propertyInfo.attributeName,
656 attributeNamespace = propertyInfo.attributeNamespace;
657
658 if (value === null) {
659 node.removeAttribute(attributeName);
660 } else {
661 var _type = propertyInfo.type;
662 var attributeValue;
663
664 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
665 // If attribute type is boolean, we know for sure it won't be an execution sink
666 // and we won't require Trusted Type here.
667 attributeValue = '';
668 } else {
669 // `setAttribute` with objects becomes only `[object]` in IE8/9,
670 // ('' + value) makes it output the correct toString()-value.
671 {
672 attributeValue = '' + value;
673 }
674
675 if (propertyInfo.sanitizeURL) {
676 sanitizeURL(attributeValue.toString());
677 }
678 }
679
680 if (attributeNamespace) {
681 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
682 } else {
683 node.setAttribute(attributeName, attributeValue);
684 }
685 }
686}
687
688// ATTENTION
689// When adding new symbols to this file,
690// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
691// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
692// nor polyfill, then a plain number is used for performance.
693var REACT_ELEMENT_TYPE = 0xeac7;
694var REACT_PORTAL_TYPE = 0xeaca;
695var REACT_FRAGMENT_TYPE = 0xeacb;
696var REACT_STRICT_MODE_TYPE = 0xeacc;
697var REACT_PROFILER_TYPE = 0xead2;
698var REACT_PROVIDER_TYPE = 0xeacd;
699var REACT_CONTEXT_TYPE = 0xeace;
700var REACT_FORWARD_REF_TYPE = 0xead0;
701var REACT_SUSPENSE_TYPE = 0xead1;
702var REACT_SUSPENSE_LIST_TYPE = 0xead8;
703var REACT_MEMO_TYPE = 0xead3;
704var REACT_LAZY_TYPE = 0xead4;
705var REACT_BLOCK_TYPE = 0xead9;
706var REACT_SERVER_BLOCK_TYPE = 0xeada;
707var REACT_FUNDAMENTAL_TYPE = 0xead5;
708var REACT_SCOPE_TYPE = 0xead7;
709var REACT_OPAQUE_ID_TYPE = 0xeae0;
710var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
711var REACT_OFFSCREEN_TYPE = 0xeae2;
712var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
713
714if (typeof Symbol === 'function' && Symbol.for) {
715 var symbolFor = Symbol.for;
716 REACT_ELEMENT_TYPE = symbolFor('react.element');
717 REACT_PORTAL_TYPE = symbolFor('react.portal');
718 REACT_FRAGMENT_TYPE = symbolFor('react.fragment');
719 REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
720 REACT_PROFILER_TYPE = symbolFor('react.profiler');
721 REACT_PROVIDER_TYPE = symbolFor('react.provider');
722 REACT_CONTEXT_TYPE = symbolFor('react.context');
723 REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
724 REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
725 REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
726 REACT_MEMO_TYPE = symbolFor('react.memo');
727 REACT_LAZY_TYPE = symbolFor('react.lazy');
728 REACT_BLOCK_TYPE = symbolFor('react.block');
729 REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
730 REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
731 REACT_SCOPE_TYPE = symbolFor('react.scope');
732 REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
733 REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
734 REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
735 REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
736}
737
738var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
739var FAUX_ITERATOR_SYMBOL = '@@iterator';
740function getIteratorFn(maybeIterable) {
741 if (maybeIterable === null || typeof maybeIterable !== 'object') {
742 return null;
743 }
744
745 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
746
747 if (typeof maybeIterator === 'function') {
748 return maybeIterator;
749 }
750
751 return null;
752}
753
754// Helpers to patch console.logs to avoid logging during side-effect free
755// replaying on render function. This currently only patches the object
756// lazily which won't cover if the log function was extracted eagerly.
757// We could also eagerly patch the method.
758var disabledDepth = 0;
759var prevLog;
760var prevInfo;
761var prevWarn;
762var prevError;
763var prevGroup;
764var prevGroupCollapsed;
765var prevGroupEnd;
766
767function disabledLog() {}
768
769disabledLog.__reactDisabledLog = true;
770function disableLogs() {
771 {
772 if (disabledDepth === 0) {
773 /* eslint-disable react-internal/no-production-logging */
774 prevLog = console.log;
775 prevInfo = console.info;
776 prevWarn = console.warn;
777 prevError = console.error;
778 prevGroup = console.group;
779 prevGroupCollapsed = console.groupCollapsed;
780 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
781
782 var props = {
783 configurable: true,
784 enumerable: true,
785 value: disabledLog,
786 writable: true
787 }; // $FlowFixMe Flow thinks console is immutable.
788
789 Object.defineProperties(console, {
790 info: props,
791 log: props,
792 warn: props,
793 error: props,
794 group: props,
795 groupCollapsed: props,
796 groupEnd: props
797 });
798 /* eslint-enable react-internal/no-production-logging */
799 }
800
801 disabledDepth++;
802 }
803}
804function reenableLogs() {
805 {
806 disabledDepth--;
807
808 if (disabledDepth === 0) {
809 /* eslint-disable react-internal/no-production-logging */
810 var props = {
811 configurable: true,
812 enumerable: true,
813 writable: true
814 }; // $FlowFixMe Flow thinks console is immutable.
815
816 Object.defineProperties(console, {
817 log: _assign({}, props, {
818 value: prevLog
819 }),
820 info: _assign({}, props, {
821 value: prevInfo
822 }),
823 warn: _assign({}, props, {
824 value: prevWarn
825 }),
826 error: _assign({}, props, {
827 value: prevError
828 }),
829 group: _assign({}, props, {
830 value: prevGroup
831 }),
832 groupCollapsed: _assign({}, props, {
833 value: prevGroupCollapsed
834 }),
835 groupEnd: _assign({}, props, {
836 value: prevGroupEnd
837 })
838 });
839 /* eslint-enable react-internal/no-production-logging */
840 }
841
842 if (disabledDepth < 0) {
843 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
844 }
845 }
846}
847
848var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
849var prefix;
850function describeBuiltInComponentFrame(name, source, ownerFn) {
851 {
852 if (prefix === undefined) {
853 // Extract the VM specific prefix used by each line.
854 try {
855 throw Error();
856 } catch (x) {
857 var match = x.stack.trim().match(/\n( *(at )?)/);
858 prefix = match && match[1] || '';
859 }
860 } // We use the prefix to ensure our stacks line up with native stack frames.
861
862
863 return '\n' + prefix + name;
864 }
865}
866var reentry = false;
867var componentFrameCache;
868
869{
870 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
871 componentFrameCache = new PossiblyWeakMap();
872}
873
874function describeNativeComponentFrame(fn, construct) {
875 // If something asked for a stack inside a fake render, it should get ignored.
876 if (!fn || reentry) {
877 return '';
878 }
879
880 {
881 var frame = componentFrameCache.get(fn);
882
883 if (frame !== undefined) {
884 return frame;
885 }
886 }
887
888 var control;
889 reentry = true;
890 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
891
892 Error.prepareStackTrace = undefined;
893 var previousDispatcher;
894
895 {
896 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
897 // for warnings.
898
899 ReactCurrentDispatcher.current = null;
900 disableLogs();
901 }
902
903 try {
904 // This should throw.
905 if (construct) {
906 // Something should be setting the props in the constructor.
907 var Fake = function () {
908 throw Error();
909 }; // $FlowFixMe
910
911
912 Object.defineProperty(Fake.prototype, 'props', {
913 set: function () {
914 // We use a throwing setter instead of frozen or non-writable props
915 // because that won't throw in a non-strict mode function.
916 throw Error();
917 }
918 });
919
920 if (typeof Reflect === 'object' && Reflect.construct) {
921 // We construct a different control for this case to include any extra
922 // frames added by the construct call.
923 try {
924 Reflect.construct(Fake, []);
925 } catch (x) {
926 control = x;
927 }
928
929 Reflect.construct(fn, [], Fake);
930 } else {
931 try {
932 Fake.call();
933 } catch (x) {
934 control = x;
935 }
936
937 fn.call(Fake.prototype);
938 }
939 } else {
940 try {
941 throw Error();
942 } catch (x) {
943 control = x;
944 }
945
946 fn();
947 }
948 } catch (sample) {
949 // This is inlined manually because closure doesn't do it for us.
950 if (sample && control && typeof sample.stack === 'string') {
951 // This extracts the first frame from the sample that isn't also in the control.
952 // Skipping one frame that we assume is the frame that calls the two.
953 var sampleLines = sample.stack.split('\n');
954 var controlLines = control.stack.split('\n');
955 var s = sampleLines.length - 1;
956 var c = controlLines.length - 1;
957
958 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
959 // We expect at least one stack frame to be shared.
960 // Typically this will be the root most one. However, stack frames may be
961 // cut off due to maximum stack limits. In this case, one maybe cut off
962 // earlier than the other. We assume that the sample is longer or the same
963 // and there for cut off earlier. So we should find the root most frame in
964 // the sample somewhere in the control.
965 c--;
966 }
967
968 for (; s >= 1 && c >= 0; s--, c--) {
969 // Next we find the first one that isn't the same which should be the
970 // frame that called our sample function and the control.
971 if (sampleLines[s] !== controlLines[c]) {
972 // In V8, the first line is describing the message but other VMs don't.
973 // If we're about to return the first line, and the control is also on the same
974 // line, that's a pretty good indicator that our sample threw at same line as
975 // the control. I.e. before we entered the sample frame. So we ignore this result.
976 // This can happen if you passed a class to function component, or non-function.
977 if (s !== 1 || c !== 1) {
978 do {
979 s--;
980 c--; // We may still have similar intermediate frames from the construct call.
981 // The next one that isn't the same should be our match though.
982
983 if (c < 0 || sampleLines[s] !== controlLines[c]) {
984 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
985 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at ');
986
987 {
988 if (typeof fn === 'function') {
989 componentFrameCache.set(fn, _frame);
990 }
991 } // Return the line we found.
992
993
994 return _frame;
995 }
996 } while (s >= 1 && c >= 0);
997 }
998
999 break;
1000 }
1001 }
1002 }
1003 } finally {
1004 reentry = false;
1005
1006 {
1007 ReactCurrentDispatcher.current = previousDispatcher;
1008 reenableLogs();
1009 }
1010
1011 Error.prepareStackTrace = previousPrepareStackTrace;
1012 } // Fallback to just using the name if we couldn't make it throw.
1013
1014
1015 var name = fn ? fn.displayName || fn.name : '';
1016 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
1017
1018 {
1019 if (typeof fn === 'function') {
1020 componentFrameCache.set(fn, syntheticFrame);
1021 }
1022 }
1023
1024 return syntheticFrame;
1025}
1026
1027function describeClassComponentFrame(ctor, source, ownerFn) {
1028 {
1029 return describeNativeComponentFrame(ctor, true);
1030 }
1031}
1032function describeFunctionComponentFrame(fn, source, ownerFn) {
1033 {
1034 return describeNativeComponentFrame(fn, false);
1035 }
1036}
1037
1038function shouldConstruct(Component) {
1039 var prototype = Component.prototype;
1040 return !!(prototype && prototype.isReactComponent);
1041}
1042
1043function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
1044
1045 if (type == null) {
1046 return '';
1047 }
1048
1049 if (typeof type === 'function') {
1050 {
1051 return describeNativeComponentFrame(type, shouldConstruct(type));
1052 }
1053 }
1054
1055 if (typeof type === 'string') {
1056 return describeBuiltInComponentFrame(type);
1057 }
1058
1059 switch (type) {
1060 case REACT_SUSPENSE_TYPE:
1061 return describeBuiltInComponentFrame('Suspense');
1062
1063 case REACT_SUSPENSE_LIST_TYPE:
1064 return describeBuiltInComponentFrame('SuspenseList');
1065 }
1066
1067 if (typeof type === 'object') {
1068 switch (type.$$typeof) {
1069 case REACT_FORWARD_REF_TYPE:
1070 return describeFunctionComponentFrame(type.render);
1071
1072 case REACT_MEMO_TYPE:
1073 // Memo may contain any component type so we recursively resolve it.
1074 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
1075
1076 case REACT_BLOCK_TYPE:
1077 return describeFunctionComponentFrame(type._render);
1078
1079 case REACT_LAZY_TYPE:
1080 {
1081 var lazyComponent = type;
1082 var payload = lazyComponent._payload;
1083 var init = lazyComponent._init;
1084
1085 try {
1086 // Lazy may contain any component type so we recursively resolve it.
1087 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
1088 } catch (x) {}
1089 }
1090 }
1091 }
1092
1093 return '';
1094}
1095
1096function describeFiber(fiber) {
1097 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
1098 var source = fiber._debugSource ;
1099
1100 switch (fiber.tag) {
1101 case HostComponent:
1102 return describeBuiltInComponentFrame(fiber.type);
1103
1104 case LazyComponent:
1105 return describeBuiltInComponentFrame('Lazy');
1106
1107 case SuspenseComponent:
1108 return describeBuiltInComponentFrame('Suspense');
1109
1110 case SuspenseListComponent:
1111 return describeBuiltInComponentFrame('SuspenseList');
1112
1113 case FunctionComponent:
1114 case IndeterminateComponent:
1115 case SimpleMemoComponent:
1116 return describeFunctionComponentFrame(fiber.type);
1117
1118 case ForwardRef:
1119 return describeFunctionComponentFrame(fiber.type.render);
1120
1121 case Block:
1122 return describeFunctionComponentFrame(fiber.type._render);
1123
1124 case ClassComponent:
1125 return describeClassComponentFrame(fiber.type);
1126
1127 default:
1128 return '';
1129 }
1130}
1131
1132function getStackByFiberInDevAndProd(workInProgress) {
1133 try {
1134 var info = '';
1135 var node = workInProgress;
1136
1137 do {
1138 info += describeFiber(node);
1139 node = node.return;
1140 } while (node);
1141
1142 return info;
1143 } catch (x) {
1144 return '\nError generating stack: ' + x.message + '\n' + x.stack;
1145 }
1146}
1147
1148function getWrappedName(outerType, innerType, wrapperName) {
1149 var functionName = innerType.displayName || innerType.name || '';
1150 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1151}
1152
1153function getContextName(type) {
1154 return type.displayName || 'Context';
1155}
1156
1157function getComponentName(type) {
1158 if (type == null) {
1159 // Host root, text node or just invalid type.
1160 return null;
1161 }
1162
1163 {
1164 if (typeof type.tag === 'number') {
1165 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
1166 }
1167 }
1168
1169 if (typeof type === 'function') {
1170 return type.displayName || type.name || null;
1171 }
1172
1173 if (typeof type === 'string') {
1174 return type;
1175 }
1176
1177 switch (type) {
1178 case REACT_FRAGMENT_TYPE:
1179 return 'Fragment';
1180
1181 case REACT_PORTAL_TYPE:
1182 return 'Portal';
1183
1184 case REACT_PROFILER_TYPE:
1185 return 'Profiler';
1186
1187 case REACT_STRICT_MODE_TYPE:
1188 return 'StrictMode';
1189
1190 case REACT_SUSPENSE_TYPE:
1191 return 'Suspense';
1192
1193 case REACT_SUSPENSE_LIST_TYPE:
1194 return 'SuspenseList';
1195 }
1196
1197 if (typeof type === 'object') {
1198 switch (type.$$typeof) {
1199 case REACT_CONTEXT_TYPE:
1200 var context = type;
1201 return getContextName(context) + '.Consumer';
1202
1203 case REACT_PROVIDER_TYPE:
1204 var provider = type;
1205 return getContextName(provider._context) + '.Provider';
1206
1207 case REACT_FORWARD_REF_TYPE:
1208 return getWrappedName(type, type.render, 'ForwardRef');
1209
1210 case REACT_MEMO_TYPE:
1211 return getComponentName(type.type);
1212
1213 case REACT_BLOCK_TYPE:
1214 return getComponentName(type._render);
1215
1216 case REACT_LAZY_TYPE:
1217 {
1218 var lazyComponent = type;
1219 var payload = lazyComponent._payload;
1220 var init = lazyComponent._init;
1221
1222 try {
1223 return getComponentName(init(payload));
1224 } catch (x) {
1225 return null;
1226 }
1227 }
1228 }
1229 }
1230
1231 return null;
1232}
1233
1234var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1235var current = null;
1236var isRendering = false;
1237function getCurrentFiberOwnerNameInDevOrNull() {
1238 {
1239 if (current === null) {
1240 return null;
1241 }
1242
1243 var owner = current._debugOwner;
1244
1245 if (owner !== null && typeof owner !== 'undefined') {
1246 return getComponentName(owner.type);
1247 }
1248 }
1249
1250 return null;
1251}
1252
1253function getCurrentFiberStackInDev() {
1254 {
1255 if (current === null) {
1256 return '';
1257 } // Safe because if current fiber exists, we are reconciling,
1258 // and it is guaranteed to be the work-in-progress version.
1259
1260
1261 return getStackByFiberInDevAndProd(current);
1262 }
1263}
1264
1265function resetCurrentFiber() {
1266 {
1267 ReactDebugCurrentFrame.getCurrentStack = null;
1268 current = null;
1269 isRendering = false;
1270 }
1271}
1272function setCurrentFiber(fiber) {
1273 {
1274 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1275 current = fiber;
1276 isRendering = false;
1277 }
1278}
1279function setIsRendering(rendering) {
1280 {
1281 isRendering = rendering;
1282 }
1283}
1284function getIsRendering() {
1285 {
1286 return isRendering;
1287 }
1288}
1289
1290// Flow does not allow string concatenation of most non-string types. To work
1291// around this limitation, we use an opaque type that can only be obtained by
1292// passing the value through getToStringValue first.
1293function toString(value) {
1294 return '' + value;
1295}
1296function getToStringValue(value) {
1297 switch (typeof value) {
1298 case 'boolean':
1299 case 'number':
1300 case 'object':
1301 case 'string':
1302 case 'undefined':
1303 return value;
1304
1305 default:
1306 // function, symbol are assigned as empty strings
1307 return '';
1308 }
1309}
1310
1311var hasReadOnlyValue = {
1312 button: true,
1313 checkbox: true,
1314 image: true,
1315 hidden: true,
1316 radio: true,
1317 reset: true,
1318 submit: true
1319};
1320function checkControlledValueProps(tagName, props) {
1321 {
1322 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
1323 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`.');
1324 }
1325
1326 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
1327 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`.');
1328 }
1329 }
1330}
1331
1332function isCheckable(elem) {
1333 var type = elem.type;
1334 var nodeName = elem.nodeName;
1335 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1336}
1337
1338function getTracker(node) {
1339 return node._valueTracker;
1340}
1341
1342function detachTracker(node) {
1343 node._valueTracker = null;
1344}
1345
1346function getValueFromNode(node) {
1347 var value = '';
1348
1349 if (!node) {
1350 return value;
1351 }
1352
1353 if (isCheckable(node)) {
1354 value = node.checked ? 'true' : 'false';
1355 } else {
1356 value = node.value;
1357 }
1358
1359 return value;
1360}
1361
1362function trackValueOnNode(node) {
1363 var valueField = isCheckable(node) ? 'checked' : 'value';
1364 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1365 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1366 // and don't track value will cause over reporting of changes,
1367 // but it's better then a hard failure
1368 // (needed for certain tests that spyOn input values and Safari)
1369
1370 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1371 return;
1372 }
1373
1374 var get = descriptor.get,
1375 set = descriptor.set;
1376 Object.defineProperty(node, valueField, {
1377 configurable: true,
1378 get: function () {
1379 return get.call(this);
1380 },
1381 set: function (value) {
1382 currentValue = '' + value;
1383 set.call(this, value);
1384 }
1385 }); // We could've passed this the first time
1386 // but it triggers a bug in IE11 and Edge 14/15.
1387 // Calling defineProperty() again should be equivalent.
1388 // https://github.com/facebook/react/issues/11768
1389
1390 Object.defineProperty(node, valueField, {
1391 enumerable: descriptor.enumerable
1392 });
1393 var tracker = {
1394 getValue: function () {
1395 return currentValue;
1396 },
1397 setValue: function (value) {
1398 currentValue = '' + value;
1399 },
1400 stopTracking: function () {
1401 detachTracker(node);
1402 delete node[valueField];
1403 }
1404 };
1405 return tracker;
1406}
1407
1408function track(node) {
1409 if (getTracker(node)) {
1410 return;
1411 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1412
1413
1414 node._valueTracker = trackValueOnNode(node);
1415}
1416function updateValueIfChanged(node) {
1417 if (!node) {
1418 return false;
1419 }
1420
1421 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1422 // that trying again will succeed
1423
1424 if (!tracker) {
1425 return true;
1426 }
1427
1428 var lastValue = tracker.getValue();
1429 var nextValue = getValueFromNode(node);
1430
1431 if (nextValue !== lastValue) {
1432 tracker.setValue(nextValue);
1433 return true;
1434 }
1435
1436 return false;
1437}
1438
1439function getActiveElement(doc) {
1440 doc = doc || (typeof document !== 'undefined' ? document : undefined);
1441
1442 if (typeof doc === 'undefined') {
1443 return null;
1444 }
1445
1446 try {
1447 return doc.activeElement || doc.body;
1448 } catch (e) {
1449 return doc.body;
1450 }
1451}
1452
1453var didWarnValueDefaultValue = false;
1454var didWarnCheckedDefaultChecked = false;
1455var didWarnControlledToUncontrolled = false;
1456var didWarnUncontrolledToControlled = false;
1457
1458function isControlled(props) {
1459 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1460 return usesChecked ? props.checked != null : props.value != null;
1461}
1462/**
1463 * Implements an <input> host component that allows setting these optional
1464 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1465 *
1466 * If `checked` or `value` are not supplied (or null/undefined), user actions
1467 * that affect the checked state or value will trigger updates to the element.
1468 *
1469 * If they are supplied (and not null/undefined), the rendered element will not
1470 * trigger updates to the element. Instead, the props must change in order for
1471 * the rendered element to be updated.
1472 *
1473 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1474 * with an empty value (or `defaultValue`).
1475 *
1476 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1477 */
1478
1479
1480function getHostProps(element, props) {
1481 var node = element;
1482 var checked = props.checked;
1483
1484 var hostProps = _assign({}, props, {
1485 defaultChecked: undefined,
1486 defaultValue: undefined,
1487 value: undefined,
1488 checked: checked != null ? checked : node._wrapperState.initialChecked
1489 });
1490
1491 return hostProps;
1492}
1493function initWrapperState(element, props) {
1494 {
1495 checkControlledValueProps('input', props);
1496
1497 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1498 error('%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1499
1500 didWarnCheckedDefaultChecked = true;
1501 }
1502
1503 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1504 error('%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1505
1506 didWarnValueDefaultValue = true;
1507 }
1508 }
1509
1510 var node = element;
1511 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1512 node._wrapperState = {
1513 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1514 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1515 controlled: isControlled(props)
1516 };
1517}
1518function updateChecked(element, props) {
1519 var node = element;
1520 var checked = props.checked;
1521
1522 if (checked != null) {
1523 setValueForProperty(node, 'checked', checked, false);
1524 }
1525}
1526function updateWrapper(element, props) {
1527 var node = element;
1528
1529 {
1530 var controlled = isControlled(props);
1531
1532 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1533 error('A component is changing an uncontrolled input to be controlled. ' + 'This is likely caused by the value changing from undefined to ' + 'a defined value, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1534
1535 didWarnUncontrolledToControlled = true;
1536 }
1537
1538 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1539 error('A component is changing a controlled input to be uncontrolled. ' + 'This is likely caused by the value changing from a defined to ' + 'undefined, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1540
1541 didWarnControlledToUncontrolled = true;
1542 }
1543 }
1544
1545 updateChecked(element, props);
1546 var value = getToStringValue(props.value);
1547 var type = props.type;
1548
1549 if (value != null) {
1550 if (type === 'number') {
1551 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1552 // eslint-disable-next-line
1553 node.value != value) {
1554 node.value = toString(value);
1555 }
1556 } else if (node.value !== toString(value)) {
1557 node.value = toString(value);
1558 }
1559 } else if (type === 'submit' || type === 'reset') {
1560 // Submit/reset inputs need the attribute removed completely to avoid
1561 // blank-text buttons.
1562 node.removeAttribute('value');
1563 return;
1564 }
1565
1566 {
1567 // When syncing the value attribute, the value comes from a cascade of
1568 // properties:
1569 // 1. The value React property
1570 // 2. The defaultValue React property
1571 // 3. Otherwise there should be no change
1572 if (props.hasOwnProperty('value')) {
1573 setDefaultValue(node, props.type, value);
1574 } else if (props.hasOwnProperty('defaultValue')) {
1575 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1576 }
1577 }
1578
1579 {
1580 // When syncing the checked attribute, it only changes when it needs
1581 // to be removed, such as transitioning from a checkbox into a text input
1582 if (props.checked == null && props.defaultChecked != null) {
1583 node.defaultChecked = !!props.defaultChecked;
1584 }
1585 }
1586}
1587function postMountWrapper(element, props, isHydrating) {
1588 var node = element; // Do not assign value if it is already set. This prevents user text input
1589 // from being lost during SSR hydration.
1590
1591 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1592 var type = props.type;
1593 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1594 // default value provided by the browser. See: #12872
1595
1596 if (isButton && (props.value === undefined || props.value === null)) {
1597 return;
1598 }
1599
1600 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1601 // from being lost during SSR hydration.
1602
1603 if (!isHydrating) {
1604 {
1605 // When syncing the value attribute, the value property should use
1606 // the wrapperState._initialValue property. This uses:
1607 //
1608 // 1. The value React property when present
1609 // 2. The defaultValue React property when present
1610 // 3. An empty string
1611 if (initialValue !== node.value) {
1612 node.value = initialValue;
1613 }
1614 }
1615 }
1616
1617 {
1618 // Otherwise, the value attribute is synchronized to the property,
1619 // so we assign defaultValue to the same thing as the value property
1620 // assignment step above.
1621 node.defaultValue = initialValue;
1622 }
1623 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1624 // this is needed to work around a chrome bug where setting defaultChecked
1625 // will sometimes influence the value of checked (even after detachment).
1626 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1627 // We need to temporarily unset name to avoid disrupting radio button groups.
1628
1629
1630 var name = node.name;
1631
1632 if (name !== '') {
1633 node.name = '';
1634 }
1635
1636 {
1637 // When syncing the checked attribute, both the checked property and
1638 // attribute are assigned at the same time using defaultChecked. This uses:
1639 //
1640 // 1. The checked React property when present
1641 // 2. The defaultChecked React property when present
1642 // 3. Otherwise, false
1643 node.defaultChecked = !node.defaultChecked;
1644 node.defaultChecked = !!node._wrapperState.initialChecked;
1645 }
1646
1647 if (name !== '') {
1648 node.name = name;
1649 }
1650}
1651function restoreControlledState(element, props) {
1652 var node = element;
1653 updateWrapper(node, props);
1654 updateNamedCousins(node, props);
1655}
1656
1657function updateNamedCousins(rootNode, props) {
1658 var name = props.name;
1659
1660 if (props.type === 'radio' && name != null) {
1661 var queryRoot = rootNode;
1662
1663 while (queryRoot.parentNode) {
1664 queryRoot = queryRoot.parentNode;
1665 } // If `rootNode.form` was non-null, then we could try `form.elements`,
1666 // but that sometimes behaves strangely in IE8. We could also try using
1667 // `form.getElementsByName`, but that will only return direct children
1668 // and won't include inputs that use the HTML5 `form=` attribute. Since
1669 // the input might not even be in a form. It might not even be in the
1670 // document. Let's just use the local `querySelectorAll` to ensure we don't
1671 // miss anything.
1672
1673
1674 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
1675
1676 for (var i = 0; i < group.length; i++) {
1677 var otherNode = group[i];
1678
1679 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
1680 continue;
1681 } // This will throw if radio buttons rendered by different copies of React
1682 // and the same name are rendered into the same form (same as #1939).
1683 // That's probably okay; we don't support it just as we don't support
1684 // mixing React radio buttons with non-React ones.
1685
1686
1687 var otherProps = getFiberCurrentPropsFromNode(otherNode);
1688
1689 if (!otherProps) {
1690 {
1691 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." );
1692 }
1693 } // We need update the tracked value on the named cousin since the value
1694 // was changed but the input saw no event or value set
1695
1696
1697 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
1698 // was previously checked to update will cause it to be come re-checked
1699 // as appropriate.
1700
1701 updateWrapper(otherNode, otherProps);
1702 }
1703 }
1704} // In Chrome, assigning defaultValue to certain input types triggers input validation.
1705// For number inputs, the display value loses trailing decimal points. For email inputs,
1706// Chrome raises "The specified value <x> is not a valid email address".
1707//
1708// Here we check to see if the defaultValue has actually changed, avoiding these problems
1709// when the user is inputting text
1710//
1711// https://github.com/facebook/react/issues/7253
1712
1713
1714function setDefaultValue(node, type, value) {
1715 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
1716 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
1717 if (value == null) {
1718 node.defaultValue = toString(node._wrapperState.initialValue);
1719 } else if (node.defaultValue !== toString(value)) {
1720 node.defaultValue = toString(value);
1721 }
1722 }
1723}
1724
1725var didWarnSelectedSetOnOption = false;
1726var didWarnInvalidChild = false;
1727
1728function flattenChildren(children) {
1729 var content = ''; // Flatten children. We'll warn if they are invalid
1730 // during validateProps() which runs for hydration too.
1731 // Note that this would throw on non-element objects.
1732 // Elements are stringified (which is normally irrelevant
1733 // but matters for <fbt>).
1734
1735 React.Children.forEach(children, function (child) {
1736 if (child == null) {
1737 return;
1738 }
1739
1740 content += child; // Note: we don't warn about invalid children here.
1741 // Instead, this is done separately below so that
1742 // it happens during the hydration code path too.
1743 });
1744 return content;
1745}
1746/**
1747 * Implements an <option> host component that warns when `selected` is set.
1748 */
1749
1750
1751function validateProps(element, props) {
1752 {
1753 // This mirrors the code path above, but runs for hydration too.
1754 // Warn about invalid children here so that client and hydration are consistent.
1755 // TODO: this seems like it could cause a DEV-only throw for hydration
1756 // if children contains a non-element object. We should try to avoid that.
1757 if (typeof props.children === 'object' && props.children !== null) {
1758 React.Children.forEach(props.children, function (child) {
1759 if (child == null) {
1760 return;
1761 }
1762
1763 if (typeof child === 'string' || typeof child === 'number') {
1764 return;
1765 }
1766
1767 if (typeof child.type !== 'string') {
1768 return;
1769 }
1770
1771 if (!didWarnInvalidChild) {
1772 didWarnInvalidChild = true;
1773
1774 error('Only strings and numbers are supported as <option> children.');
1775 }
1776 });
1777 } // TODO: Remove support for `selected` in <option>.
1778
1779
1780 if (props.selected != null && !didWarnSelectedSetOnOption) {
1781 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
1782
1783 didWarnSelectedSetOnOption = true;
1784 }
1785 }
1786}
1787function postMountWrapper$1(element, props) {
1788 // value="" should make a value attribute (#6219)
1789 if (props.value != null) {
1790 element.setAttribute('value', toString(getToStringValue(props.value)));
1791 }
1792}
1793function getHostProps$1(element, props) {
1794 var hostProps = _assign({
1795 children: undefined
1796 }, props);
1797
1798 var content = flattenChildren(props.children);
1799
1800 if (content) {
1801 hostProps.children = content;
1802 }
1803
1804 return hostProps;
1805}
1806
1807var didWarnValueDefaultValue$1;
1808
1809{
1810 didWarnValueDefaultValue$1 = false;
1811}
1812
1813function getDeclarationErrorAddendum() {
1814 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
1815
1816 if (ownerName) {
1817 return '\n\nCheck the render method of `' + ownerName + '`.';
1818 }
1819
1820 return '';
1821}
1822
1823var valuePropNames = ['value', 'defaultValue'];
1824/**
1825 * Validation function for `value` and `defaultValue`.
1826 */
1827
1828function checkSelectPropTypes(props) {
1829 {
1830 checkControlledValueProps('select', props);
1831
1832 for (var i = 0; i < valuePropNames.length; i++) {
1833 var propName = valuePropNames[i];
1834
1835 if (props[propName] == null) {
1836 continue;
1837 }
1838
1839 var isArray = Array.isArray(props[propName]);
1840
1841 if (props.multiple && !isArray) {
1842 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
1843 } else if (!props.multiple && isArray) {
1844 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
1845 }
1846 }
1847 }
1848}
1849
1850function updateOptions(node, multiple, propValue, setDefaultSelected) {
1851 var options = node.options;
1852
1853 if (multiple) {
1854 var selectedValues = propValue;
1855 var selectedValue = {};
1856
1857 for (var i = 0; i < selectedValues.length; i++) {
1858 // Prefix to avoid chaos with special keys.
1859 selectedValue['$' + selectedValues[i]] = true;
1860 }
1861
1862 for (var _i = 0; _i < options.length; _i++) {
1863 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
1864
1865 if (options[_i].selected !== selected) {
1866 options[_i].selected = selected;
1867 }
1868
1869 if (selected && setDefaultSelected) {
1870 options[_i].defaultSelected = true;
1871 }
1872 }
1873 } else {
1874 // Do not set `select.value` as exact behavior isn't consistent across all
1875 // browsers for all cases.
1876 var _selectedValue = toString(getToStringValue(propValue));
1877
1878 var defaultSelected = null;
1879
1880 for (var _i2 = 0; _i2 < options.length; _i2++) {
1881 if (options[_i2].value === _selectedValue) {
1882 options[_i2].selected = true;
1883
1884 if (setDefaultSelected) {
1885 options[_i2].defaultSelected = true;
1886 }
1887
1888 return;
1889 }
1890
1891 if (defaultSelected === null && !options[_i2].disabled) {
1892 defaultSelected = options[_i2];
1893 }
1894 }
1895
1896 if (defaultSelected !== null) {
1897 defaultSelected.selected = true;
1898 }
1899 }
1900}
1901/**
1902 * Implements a <select> host component that allows optionally setting the
1903 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
1904 * stringable. If `multiple` is true, the prop must be an array of stringables.
1905 *
1906 * If `value` is not supplied (or null/undefined), user actions that change the
1907 * selected option will trigger updates to the rendered options.
1908 *
1909 * If it is supplied (and not null/undefined), the rendered options will not
1910 * update in response to user actions. Instead, the `value` prop must change in
1911 * order for the rendered options to update.
1912 *
1913 * If `defaultValue` is provided, any options with the supplied values will be
1914 * selected.
1915 */
1916
1917
1918function getHostProps$2(element, props) {
1919 return _assign({}, props, {
1920 value: undefined
1921 });
1922}
1923function initWrapperState$1(element, props) {
1924 var node = element;
1925
1926 {
1927 checkSelectPropTypes(props);
1928 }
1929
1930 node._wrapperState = {
1931 wasMultiple: !!props.multiple
1932 };
1933
1934 {
1935 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
1936 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');
1937
1938 didWarnValueDefaultValue$1 = true;
1939 }
1940 }
1941}
1942function postMountWrapper$2(element, props) {
1943 var node = element;
1944 node.multiple = !!props.multiple;
1945 var value = props.value;
1946
1947 if (value != null) {
1948 updateOptions(node, !!props.multiple, value, false);
1949 } else if (props.defaultValue != null) {
1950 updateOptions(node, !!props.multiple, props.defaultValue, true);
1951 }
1952}
1953function postUpdateWrapper(element, props) {
1954 var node = element;
1955 var wasMultiple = node._wrapperState.wasMultiple;
1956 node._wrapperState.wasMultiple = !!props.multiple;
1957 var value = props.value;
1958
1959 if (value != null) {
1960 updateOptions(node, !!props.multiple, value, false);
1961 } else if (wasMultiple !== !!props.multiple) {
1962 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
1963 if (props.defaultValue != null) {
1964 updateOptions(node, !!props.multiple, props.defaultValue, true);
1965 } else {
1966 // Revert the select back to its default unselected state.
1967 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
1968 }
1969 }
1970}
1971function restoreControlledState$1(element, props) {
1972 var node = element;
1973 var value = props.value;
1974
1975 if (value != null) {
1976 updateOptions(node, !!props.multiple, value, false);
1977 }
1978}
1979
1980var didWarnValDefaultVal = false;
1981
1982/**
1983 * Implements a <textarea> host component that allows setting `value`, and
1984 * `defaultValue`. This differs from the traditional DOM API because value is
1985 * usually set as PCDATA children.
1986 *
1987 * If `value` is not supplied (or null/undefined), user actions that affect the
1988 * value will trigger updates to the element.
1989 *
1990 * If `value` is supplied (and not null/undefined), the rendered element will
1991 * not trigger updates to the element. Instead, the `value` prop must change in
1992 * order for the rendered element to be updated.
1993 *
1994 * The rendered element will be initialized with an empty value, the prop
1995 * `defaultValue` if specified, or the children content (deprecated).
1996 */
1997function getHostProps$3(element, props) {
1998 var node = element;
1999
2000 if (!(props.dangerouslySetInnerHTML == null)) {
2001 {
2002 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." );
2003 }
2004 } // Always set children to the same thing. In IE9, the selection range will
2005 // get reset if `textContent` is mutated. We could add a check in setTextContent
2006 // to only set the value if/when the value differs from the node value (which would
2007 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2008 // solution. The value can be a boolean or object so that's why it's forced
2009 // to be a string.
2010
2011
2012 var hostProps = _assign({}, props, {
2013 value: undefined,
2014 defaultValue: undefined,
2015 children: toString(node._wrapperState.initialValue)
2016 });
2017
2018 return hostProps;
2019}
2020function initWrapperState$2(element, props) {
2021 var node = element;
2022
2023 {
2024 checkControlledValueProps('textarea', props);
2025
2026 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2027 error('%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
2028
2029 didWarnValDefaultVal = true;
2030 }
2031 }
2032
2033 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2034
2035 if (initialValue == null) {
2036 var children = props.children,
2037 defaultValue = props.defaultValue;
2038
2039 if (children != null) {
2040 {
2041 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2042 }
2043
2044 {
2045 if (!(defaultValue == null)) {
2046 {
2047 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." );
2048 }
2049 }
2050
2051 if (Array.isArray(children)) {
2052 if (!(children.length <= 1)) {
2053 {
2054 throw Error( "<textarea> can only have at most one child." );
2055 }
2056 }
2057
2058 children = children[0];
2059 }
2060
2061 defaultValue = children;
2062 }
2063 }
2064
2065 if (defaultValue == null) {
2066 defaultValue = '';
2067 }
2068
2069 initialValue = defaultValue;
2070 }
2071
2072 node._wrapperState = {
2073 initialValue: getToStringValue(initialValue)
2074 };
2075}
2076function updateWrapper$1(element, props) {
2077 var node = element;
2078 var value = getToStringValue(props.value);
2079 var defaultValue = getToStringValue(props.defaultValue);
2080
2081 if (value != null) {
2082 // Cast `value` to a string to ensure the value is set correctly. While
2083 // browsers typically do this as necessary, jsdom doesn't.
2084 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2085
2086 if (newValue !== node.value) {
2087 node.value = newValue;
2088 }
2089
2090 if (props.defaultValue == null && node.defaultValue !== newValue) {
2091 node.defaultValue = newValue;
2092 }
2093 }
2094
2095 if (defaultValue != null) {
2096 node.defaultValue = toString(defaultValue);
2097 }
2098}
2099function postMountWrapper$3(element, props) {
2100 var node = element; // This is in postMount because we need access to the DOM node, which is not
2101 // available until after the component has mounted.
2102
2103 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2104 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2105 // will populate textContent as well.
2106 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2107
2108 if (textContent === node._wrapperState.initialValue) {
2109 if (textContent !== '' && textContent !== null) {
2110 node.value = textContent;
2111 }
2112 }
2113}
2114function restoreControlledState$2(element, props) {
2115 // DOM component is still mounted; update
2116 updateWrapper$1(element, props);
2117}
2118
2119var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2120var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2121var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2122var Namespaces = {
2123 html: HTML_NAMESPACE,
2124 mathml: MATH_NAMESPACE,
2125 svg: SVG_NAMESPACE
2126}; // Assumes there is no parent namespace.
2127
2128function getIntrinsicNamespace(type) {
2129 switch (type) {
2130 case 'svg':
2131 return SVG_NAMESPACE;
2132
2133 case 'math':
2134 return MATH_NAMESPACE;
2135
2136 default:
2137 return HTML_NAMESPACE;
2138 }
2139}
2140function getChildNamespace(parentNamespace, type) {
2141 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2142 // No (or default) parent namespace: potential entry point.
2143 return getIntrinsicNamespace(type);
2144 }
2145
2146 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2147 // We're leaving SVG.
2148 return HTML_NAMESPACE;
2149 } // By default, pass namespace below.
2150
2151
2152 return parentNamespace;
2153}
2154
2155/* globals MSApp */
2156
2157/**
2158 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2159 */
2160var createMicrosoftUnsafeLocalFunction = function (func) {
2161 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2162 return function (arg0, arg1, arg2, arg3) {
2163 MSApp.execUnsafeLocalFunction(function () {
2164 return func(arg0, arg1, arg2, arg3);
2165 });
2166 };
2167 } else {
2168 return func;
2169 }
2170};
2171
2172var reusableSVGContainer;
2173/**
2174 * Set the innerHTML property of a node
2175 *
2176 * @param {DOMElement} node
2177 * @param {string} html
2178 * @internal
2179 */
2180
2181var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2182 if (node.namespaceURI === Namespaces.svg) {
2183
2184 if (!('innerHTML' in node)) {
2185 // IE does not have innerHTML for SVG nodes, so instead we inject the
2186 // new markup in a temp node and then move the child nodes across into
2187 // the target node
2188 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2189 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2190 var svgNode = reusableSVGContainer.firstChild;
2191
2192 while (node.firstChild) {
2193 node.removeChild(node.firstChild);
2194 }
2195
2196 while (svgNode.firstChild) {
2197 node.appendChild(svgNode.firstChild);
2198 }
2199
2200 return;
2201 }
2202 }
2203
2204 node.innerHTML = html;
2205});
2206
2207/**
2208 * HTML nodeType values that represent the type of the node
2209 */
2210var ELEMENT_NODE = 1;
2211var TEXT_NODE = 3;
2212var COMMENT_NODE = 8;
2213var DOCUMENT_NODE = 9;
2214var DOCUMENT_FRAGMENT_NODE = 11;
2215
2216/**
2217 * Set the textContent property of a node. For text updates, it's faster
2218 * to set the `nodeValue` of the Text node directly instead of using
2219 * `.textContent` which will remove the existing node and create a new one.
2220 *
2221 * @param {DOMElement} node
2222 * @param {string} text
2223 * @internal
2224 */
2225
2226var setTextContent = function (node, text) {
2227 if (text) {
2228 var firstChild = node.firstChild;
2229
2230 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2231 firstChild.nodeValue = text;
2232 return;
2233 }
2234 }
2235
2236 node.textContent = text;
2237};
2238
2239// List derived from Gecko source code:
2240// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
2241var shorthandToLonghand = {
2242 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
2243 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
2244 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
2245 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2246 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
2247 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
2248 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
2249 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
2250 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
2251 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
2252 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
2253 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
2254 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
2255 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
2256 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
2257 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2258 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
2259 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
2260 columns: ['columnCount', 'columnWidth'],
2261 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
2262 flexFlow: ['flexDirection', 'flexWrap'],
2263 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
2264 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
2265 gap: ['columnGap', 'rowGap'],
2266 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2267 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
2268 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
2269 gridColumnGap: ['columnGap'],
2270 gridGap: ['columnGap', 'rowGap'],
2271 gridRow: ['gridRowEnd', 'gridRowStart'],
2272 gridRowGap: ['rowGap'],
2273 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2274 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
2275 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
2276 marker: ['markerEnd', 'markerMid', 'markerStart'],
2277 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
2278 maskPosition: ['maskPositionX', 'maskPositionY'],
2279 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
2280 overflow: ['overflowX', 'overflowY'],
2281 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
2282 placeContent: ['alignContent', 'justifyContent'],
2283 placeItems: ['alignItems', 'justifyItems'],
2284 placeSelf: ['alignSelf', 'justifySelf'],
2285 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
2286 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
2287 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
2288 wordWrap: ['overflowWrap']
2289};
2290
2291/**
2292 * CSS properties which accept numbers but are not in units of "px".
2293 */
2294var isUnitlessNumber = {
2295 animationIterationCount: true,
2296 borderImageOutset: true,
2297 borderImageSlice: true,
2298 borderImageWidth: true,
2299 boxFlex: true,
2300 boxFlexGroup: true,
2301 boxOrdinalGroup: true,
2302 columnCount: true,
2303 columns: true,
2304 flex: true,
2305 flexGrow: true,
2306 flexPositive: true,
2307 flexShrink: true,
2308 flexNegative: true,
2309 flexOrder: true,
2310 gridArea: true,
2311 gridRow: true,
2312 gridRowEnd: true,
2313 gridRowSpan: true,
2314 gridRowStart: true,
2315 gridColumn: true,
2316 gridColumnEnd: true,
2317 gridColumnSpan: true,
2318 gridColumnStart: true,
2319 fontWeight: true,
2320 lineClamp: true,
2321 lineHeight: true,
2322 opacity: true,
2323 order: true,
2324 orphans: true,
2325 tabSize: true,
2326 widows: true,
2327 zIndex: true,
2328 zoom: true,
2329 // SVG-related properties
2330 fillOpacity: true,
2331 floodOpacity: true,
2332 stopOpacity: true,
2333 strokeDasharray: true,
2334 strokeDashoffset: true,
2335 strokeMiterlimit: true,
2336 strokeOpacity: true,
2337 strokeWidth: true
2338};
2339/**
2340 * @param {string} prefix vendor-specific prefix, eg: Webkit
2341 * @param {string} key style name, eg: transitionDuration
2342 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
2343 * WebkitTransitionDuration
2344 */
2345
2346function prefixKey(prefix, key) {
2347 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
2348}
2349/**
2350 * Support style names that may come passed in prefixed by adding permutations
2351 * of vendor prefixes.
2352 */
2353
2354
2355var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
2356// infinite loop, because it iterates over the newly added props too.
2357
2358Object.keys(isUnitlessNumber).forEach(function (prop) {
2359 prefixes.forEach(function (prefix) {
2360 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
2361 });
2362});
2363
2364/**
2365 * Convert a value into the proper css writable value. The style name `name`
2366 * should be logical (no hyphens), as specified
2367 * in `CSSProperty.isUnitlessNumber`.
2368 *
2369 * @param {string} name CSS property name such as `topMargin`.
2370 * @param {*} value CSS property value such as `10px`.
2371 * @return {string} Normalized style value with dimensions applied.
2372 */
2373
2374function dangerousStyleValue(name, value, isCustomProperty) {
2375 // Note that we've removed escapeTextForBrowser() calls here since the
2376 // whole string will be escaped when the attribute is injected into
2377 // the markup. If you provide unsafe user data here they can inject
2378 // arbitrary CSS which may be problematic (I couldn't repro this):
2379 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
2380 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
2381 // This is not an XSS hole but instead a potential CSS injection issue
2382 // which has lead to a greater discussion about how we're going to
2383 // trust URLs moving forward. See #2115901
2384 var isEmpty = value == null || typeof value === 'boolean' || value === '';
2385
2386 if (isEmpty) {
2387 return '';
2388 }
2389
2390 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
2391 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
2392 }
2393
2394 return ('' + value).trim();
2395}
2396
2397var uppercasePattern = /([A-Z])/g;
2398var msPattern = /^ms-/;
2399/**
2400 * Hyphenates a camelcased CSS property name, for example:
2401 *
2402 * > hyphenateStyleName('backgroundColor')
2403 * < "background-color"
2404 * > hyphenateStyleName('MozTransition')
2405 * < "-moz-transition"
2406 * > hyphenateStyleName('msTransition')
2407 * < "-ms-transition"
2408 *
2409 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
2410 * is converted to `-ms-`.
2411 */
2412
2413function hyphenateStyleName(name) {
2414 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
2415}
2416
2417var warnValidStyle = function () {};
2418
2419{
2420 // 'msTransform' is correct, but the other prefixes should be capitalized
2421 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
2422 var msPattern$1 = /^-ms-/;
2423 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
2424
2425 var badStyleValueWithSemicolonPattern = /;\s*$/;
2426 var warnedStyleNames = {};
2427 var warnedStyleValues = {};
2428 var warnedForNaNValue = false;
2429 var warnedForInfinityValue = false;
2430
2431 var camelize = function (string) {
2432 return string.replace(hyphenPattern, function (_, character) {
2433 return character.toUpperCase();
2434 });
2435 };
2436
2437 var warnHyphenatedStyleName = function (name) {
2438 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2439 return;
2440 }
2441
2442 warnedStyleNames[name] = true;
2443
2444 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
2445 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
2446 // is converted to lowercase `ms`.
2447 camelize(name.replace(msPattern$1, 'ms-')));
2448 };
2449
2450 var warnBadVendoredStyleName = function (name) {
2451 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2452 return;
2453 }
2454
2455 warnedStyleNames[name] = true;
2456
2457 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
2458 };
2459
2460 var warnStyleValueWithSemicolon = function (name, value) {
2461 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
2462 return;
2463 }
2464
2465 warnedStyleValues[value] = true;
2466
2467 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
2468 };
2469
2470 var warnStyleValueIsNaN = function (name, value) {
2471 if (warnedForNaNValue) {
2472 return;
2473 }
2474
2475 warnedForNaNValue = true;
2476
2477 error('`NaN` is an invalid value for the `%s` css style property.', name);
2478 };
2479
2480 var warnStyleValueIsInfinity = function (name, value) {
2481 if (warnedForInfinityValue) {
2482 return;
2483 }
2484
2485 warnedForInfinityValue = true;
2486
2487 error('`Infinity` is an invalid value for the `%s` css style property.', name);
2488 };
2489
2490 warnValidStyle = function (name, value) {
2491 if (name.indexOf('-') > -1) {
2492 warnHyphenatedStyleName(name);
2493 } else if (badVendoredStyleNamePattern.test(name)) {
2494 warnBadVendoredStyleName(name);
2495 } else if (badStyleValueWithSemicolonPattern.test(value)) {
2496 warnStyleValueWithSemicolon(name, value);
2497 }
2498
2499 if (typeof value === 'number') {
2500 if (isNaN(value)) {
2501 warnStyleValueIsNaN(name, value);
2502 } else if (!isFinite(value)) {
2503 warnStyleValueIsInfinity(name, value);
2504 }
2505 }
2506 };
2507}
2508
2509var warnValidStyle$1 = warnValidStyle;
2510
2511/**
2512 * Operations for dealing with CSS properties.
2513 */
2514
2515/**
2516 * This creates a string that is expected to be equivalent to the style
2517 * attribute generated by server-side rendering. It by-passes warnings and
2518 * security checks so it's not safe to use this value for anything other than
2519 * comparison. It is only used in DEV for SSR validation.
2520 */
2521
2522function createDangerousStringForStyles(styles) {
2523 {
2524 var serialized = '';
2525 var delimiter = '';
2526
2527 for (var styleName in styles) {
2528 if (!styles.hasOwnProperty(styleName)) {
2529 continue;
2530 }
2531
2532 var styleValue = styles[styleName];
2533
2534 if (styleValue != null) {
2535 var isCustomProperty = styleName.indexOf('--') === 0;
2536 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
2537 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
2538 delimiter = ';';
2539 }
2540 }
2541
2542 return serialized || null;
2543 }
2544}
2545/**
2546 * Sets the value for multiple styles on a node. If a value is specified as
2547 * '' (empty string), the corresponding style property will be unset.
2548 *
2549 * @param {DOMElement} node
2550 * @param {object} styles
2551 */
2552
2553function setValueForStyles(node, styles) {
2554 var style = node.style;
2555
2556 for (var styleName in styles) {
2557 if (!styles.hasOwnProperty(styleName)) {
2558 continue;
2559 }
2560
2561 var isCustomProperty = styleName.indexOf('--') === 0;
2562
2563 {
2564 if (!isCustomProperty) {
2565 warnValidStyle$1(styleName, styles[styleName]);
2566 }
2567 }
2568
2569 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
2570
2571 if (styleName === 'float') {
2572 styleName = 'cssFloat';
2573 }
2574
2575 if (isCustomProperty) {
2576 style.setProperty(styleName, styleValue);
2577 } else {
2578 style[styleName] = styleValue;
2579 }
2580 }
2581}
2582
2583function isValueEmpty(value) {
2584 return value == null || typeof value === 'boolean' || value === '';
2585}
2586/**
2587 * Given {color: 'red', overflow: 'hidden'} returns {
2588 * color: 'color',
2589 * overflowX: 'overflow',
2590 * overflowY: 'overflow',
2591 * }. This can be read as "the overflowY property was set by the overflow
2592 * shorthand". That is, the values are the property that each was derived from.
2593 */
2594
2595
2596function expandShorthandMap(styles) {
2597 var expanded = {};
2598
2599 for (var key in styles) {
2600 var longhands = shorthandToLonghand[key] || [key];
2601
2602 for (var i = 0; i < longhands.length; i++) {
2603 expanded[longhands[i]] = key;
2604 }
2605 }
2606
2607 return expanded;
2608}
2609/**
2610 * When mixing shorthand and longhand property names, we warn during updates if
2611 * we expect an incorrect result to occur. In particular, we warn for:
2612 *
2613 * Updating a shorthand property (longhand gets overwritten):
2614 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
2615 * becomes .style.font = 'baz'
2616 * Removing a shorthand property (longhand gets lost too):
2617 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
2618 * becomes .style.font = ''
2619 * Removing a longhand property (should revert to shorthand; doesn't):
2620 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
2621 * becomes .style.fontVariant = ''
2622 */
2623
2624
2625function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
2626 {
2627 if (!nextStyles) {
2628 return;
2629 }
2630
2631 var expandedUpdates = expandShorthandMap(styleUpdates);
2632 var expandedStyles = expandShorthandMap(nextStyles);
2633 var warnedAbout = {};
2634
2635 for (var key in expandedUpdates) {
2636 var originalKey = expandedUpdates[key];
2637 var correctOriginalKey = expandedStyles[key];
2638
2639 if (correctOriginalKey && originalKey !== correctOriginalKey) {
2640 var warningKey = originalKey + ',' + correctOriginalKey;
2641
2642 if (warnedAbout[warningKey]) {
2643 continue;
2644 }
2645
2646 warnedAbout[warningKey] = true;
2647
2648 error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
2649 }
2650 }
2651 }
2652}
2653
2654// For HTML, certain tags should omit their close tag. We keep a list for
2655// those special-case tags.
2656var omittedCloseTags = {
2657 area: true,
2658 base: true,
2659 br: true,
2660 col: true,
2661 embed: true,
2662 hr: true,
2663 img: true,
2664 input: true,
2665 keygen: true,
2666 link: true,
2667 meta: true,
2668 param: true,
2669 source: true,
2670 track: true,
2671 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
2672
2673};
2674
2675// `omittedCloseTags` except that `menuitem` should still have its closing tag.
2676
2677var voidElementTags = _assign({
2678 menuitem: true
2679}, omittedCloseTags);
2680
2681var HTML = '__html';
2682
2683function assertValidProps(tag, props) {
2684 if (!props) {
2685 return;
2686 } // Note the use of `==` which checks for null or undefined.
2687
2688
2689 if (voidElementTags[tag]) {
2690 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
2691 {
2692 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." );
2693 }
2694 }
2695 }
2696
2697 if (props.dangerouslySetInnerHTML != null) {
2698 if (!(props.children == null)) {
2699 {
2700 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." );
2701 }
2702 }
2703
2704 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {
2705 {
2706 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://reactjs.org/link/dangerously-set-inner-html for more information." );
2707 }
2708 }
2709 }
2710
2711 {
2712 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
2713 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.');
2714 }
2715 }
2716
2717 if (!(props.style == null || typeof props.style === 'object')) {
2718 {
2719 throw Error( "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." );
2720 }
2721 }
2722}
2723
2724function isCustomComponent(tagName, props) {
2725 if (tagName.indexOf('-') === -1) {
2726 return typeof props.is === 'string';
2727 }
2728
2729 switch (tagName) {
2730 // These are reserved SVG and MathML elements.
2731 // We don't mind this list too much because we expect it to never grow.
2732 // The alternative is to track the namespace in a few places which is convoluted.
2733 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
2734 case 'annotation-xml':
2735 case 'color-profile':
2736 case 'font-face':
2737 case 'font-face-src':
2738 case 'font-face-uri':
2739 case 'font-face-format':
2740 case 'font-face-name':
2741 case 'missing-glyph':
2742 return false;
2743
2744 default:
2745 return true;
2746 }
2747}
2748
2749// When adding attributes to the HTML or SVG allowed attribute list, be sure to
2750// also add them to this module to ensure casing and incorrect name
2751// warnings.
2752var possibleStandardNames = {
2753 // HTML
2754 accept: 'accept',
2755 acceptcharset: 'acceptCharset',
2756 'accept-charset': 'acceptCharset',
2757 accesskey: 'accessKey',
2758 action: 'action',
2759 allowfullscreen: 'allowFullScreen',
2760 alt: 'alt',
2761 as: 'as',
2762 async: 'async',
2763 autocapitalize: 'autoCapitalize',
2764 autocomplete: 'autoComplete',
2765 autocorrect: 'autoCorrect',
2766 autofocus: 'autoFocus',
2767 autoplay: 'autoPlay',
2768 autosave: 'autoSave',
2769 capture: 'capture',
2770 cellpadding: 'cellPadding',
2771 cellspacing: 'cellSpacing',
2772 challenge: 'challenge',
2773 charset: 'charSet',
2774 checked: 'checked',
2775 children: 'children',
2776 cite: 'cite',
2777 class: 'className',
2778 classid: 'classID',
2779 classname: 'className',
2780 cols: 'cols',
2781 colspan: 'colSpan',
2782 content: 'content',
2783 contenteditable: 'contentEditable',
2784 contextmenu: 'contextMenu',
2785 controls: 'controls',
2786 controlslist: 'controlsList',
2787 coords: 'coords',
2788 crossorigin: 'crossOrigin',
2789 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
2790 data: 'data',
2791 datetime: 'dateTime',
2792 default: 'default',
2793 defaultchecked: 'defaultChecked',
2794 defaultvalue: 'defaultValue',
2795 defer: 'defer',
2796 dir: 'dir',
2797 disabled: 'disabled',
2798 disablepictureinpicture: 'disablePictureInPicture',
2799 disableremoteplayback: 'disableRemotePlayback',
2800 download: 'download',
2801 draggable: 'draggable',
2802 enctype: 'encType',
2803 enterkeyhint: 'enterKeyHint',
2804 for: 'htmlFor',
2805 form: 'form',
2806 formmethod: 'formMethod',
2807 formaction: 'formAction',
2808 formenctype: 'formEncType',
2809 formnovalidate: 'formNoValidate',
2810 formtarget: 'formTarget',
2811 frameborder: 'frameBorder',
2812 headers: 'headers',
2813 height: 'height',
2814 hidden: 'hidden',
2815 high: 'high',
2816 href: 'href',
2817 hreflang: 'hrefLang',
2818 htmlfor: 'htmlFor',
2819 httpequiv: 'httpEquiv',
2820 'http-equiv': 'httpEquiv',
2821 icon: 'icon',
2822 id: 'id',
2823 innerhtml: 'innerHTML',
2824 inputmode: 'inputMode',
2825 integrity: 'integrity',
2826 is: 'is',
2827 itemid: 'itemID',
2828 itemprop: 'itemProp',
2829 itemref: 'itemRef',
2830 itemscope: 'itemScope',
2831 itemtype: 'itemType',
2832 keyparams: 'keyParams',
2833 keytype: 'keyType',
2834 kind: 'kind',
2835 label: 'label',
2836 lang: 'lang',
2837 list: 'list',
2838 loop: 'loop',
2839 low: 'low',
2840 manifest: 'manifest',
2841 marginwidth: 'marginWidth',
2842 marginheight: 'marginHeight',
2843 max: 'max',
2844 maxlength: 'maxLength',
2845 media: 'media',
2846 mediagroup: 'mediaGroup',
2847 method: 'method',
2848 min: 'min',
2849 minlength: 'minLength',
2850 multiple: 'multiple',
2851 muted: 'muted',
2852 name: 'name',
2853 nomodule: 'noModule',
2854 nonce: 'nonce',
2855 novalidate: 'noValidate',
2856 open: 'open',
2857 optimum: 'optimum',
2858 pattern: 'pattern',
2859 placeholder: 'placeholder',
2860 playsinline: 'playsInline',
2861 poster: 'poster',
2862 preload: 'preload',
2863 profile: 'profile',
2864 radiogroup: 'radioGroup',
2865 readonly: 'readOnly',
2866 referrerpolicy: 'referrerPolicy',
2867 rel: 'rel',
2868 required: 'required',
2869 reversed: 'reversed',
2870 role: 'role',
2871 rows: 'rows',
2872 rowspan: 'rowSpan',
2873 sandbox: 'sandbox',
2874 scope: 'scope',
2875 scoped: 'scoped',
2876 scrolling: 'scrolling',
2877 seamless: 'seamless',
2878 selected: 'selected',
2879 shape: 'shape',
2880 size: 'size',
2881 sizes: 'sizes',
2882 span: 'span',
2883 spellcheck: 'spellCheck',
2884 src: 'src',
2885 srcdoc: 'srcDoc',
2886 srclang: 'srcLang',
2887 srcset: 'srcSet',
2888 start: 'start',
2889 step: 'step',
2890 style: 'style',
2891 summary: 'summary',
2892 tabindex: 'tabIndex',
2893 target: 'target',
2894 title: 'title',
2895 type: 'type',
2896 usemap: 'useMap',
2897 value: 'value',
2898 width: 'width',
2899 wmode: 'wmode',
2900 wrap: 'wrap',
2901 // SVG
2902 about: 'about',
2903 accentheight: 'accentHeight',
2904 'accent-height': 'accentHeight',
2905 accumulate: 'accumulate',
2906 additive: 'additive',
2907 alignmentbaseline: 'alignmentBaseline',
2908 'alignment-baseline': 'alignmentBaseline',
2909 allowreorder: 'allowReorder',
2910 alphabetic: 'alphabetic',
2911 amplitude: 'amplitude',
2912 arabicform: 'arabicForm',
2913 'arabic-form': 'arabicForm',
2914 ascent: 'ascent',
2915 attributename: 'attributeName',
2916 attributetype: 'attributeType',
2917 autoreverse: 'autoReverse',
2918 azimuth: 'azimuth',
2919 basefrequency: 'baseFrequency',
2920 baselineshift: 'baselineShift',
2921 'baseline-shift': 'baselineShift',
2922 baseprofile: 'baseProfile',
2923 bbox: 'bbox',
2924 begin: 'begin',
2925 bias: 'bias',
2926 by: 'by',
2927 calcmode: 'calcMode',
2928 capheight: 'capHeight',
2929 'cap-height': 'capHeight',
2930 clip: 'clip',
2931 clippath: 'clipPath',
2932 'clip-path': 'clipPath',
2933 clippathunits: 'clipPathUnits',
2934 cliprule: 'clipRule',
2935 'clip-rule': 'clipRule',
2936 color: 'color',
2937 colorinterpolation: 'colorInterpolation',
2938 'color-interpolation': 'colorInterpolation',
2939 colorinterpolationfilters: 'colorInterpolationFilters',
2940 'color-interpolation-filters': 'colorInterpolationFilters',
2941 colorprofile: 'colorProfile',
2942 'color-profile': 'colorProfile',
2943 colorrendering: 'colorRendering',
2944 'color-rendering': 'colorRendering',
2945 contentscripttype: 'contentScriptType',
2946 contentstyletype: 'contentStyleType',
2947 cursor: 'cursor',
2948 cx: 'cx',
2949 cy: 'cy',
2950 d: 'd',
2951 datatype: 'datatype',
2952 decelerate: 'decelerate',
2953 descent: 'descent',
2954 diffuseconstant: 'diffuseConstant',
2955 direction: 'direction',
2956 display: 'display',
2957 divisor: 'divisor',
2958 dominantbaseline: 'dominantBaseline',
2959 'dominant-baseline': 'dominantBaseline',
2960 dur: 'dur',
2961 dx: 'dx',
2962 dy: 'dy',
2963 edgemode: 'edgeMode',
2964 elevation: 'elevation',
2965 enablebackground: 'enableBackground',
2966 'enable-background': 'enableBackground',
2967 end: 'end',
2968 exponent: 'exponent',
2969 externalresourcesrequired: 'externalResourcesRequired',
2970 fill: 'fill',
2971 fillopacity: 'fillOpacity',
2972 'fill-opacity': 'fillOpacity',
2973 fillrule: 'fillRule',
2974 'fill-rule': 'fillRule',
2975 filter: 'filter',
2976 filterres: 'filterRes',
2977 filterunits: 'filterUnits',
2978 floodopacity: 'floodOpacity',
2979 'flood-opacity': 'floodOpacity',
2980 floodcolor: 'floodColor',
2981 'flood-color': 'floodColor',
2982 focusable: 'focusable',
2983 fontfamily: 'fontFamily',
2984 'font-family': 'fontFamily',
2985 fontsize: 'fontSize',
2986 'font-size': 'fontSize',
2987 fontsizeadjust: 'fontSizeAdjust',
2988 'font-size-adjust': 'fontSizeAdjust',
2989 fontstretch: 'fontStretch',
2990 'font-stretch': 'fontStretch',
2991 fontstyle: 'fontStyle',
2992 'font-style': 'fontStyle',
2993 fontvariant: 'fontVariant',
2994 'font-variant': 'fontVariant',
2995 fontweight: 'fontWeight',
2996 'font-weight': 'fontWeight',
2997 format: 'format',
2998 from: 'from',
2999 fx: 'fx',
3000 fy: 'fy',
3001 g1: 'g1',
3002 g2: 'g2',
3003 glyphname: 'glyphName',
3004 'glyph-name': 'glyphName',
3005 glyphorientationhorizontal: 'glyphOrientationHorizontal',
3006 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
3007 glyphorientationvertical: 'glyphOrientationVertical',
3008 'glyph-orientation-vertical': 'glyphOrientationVertical',
3009 glyphref: 'glyphRef',
3010 gradienttransform: 'gradientTransform',
3011 gradientunits: 'gradientUnits',
3012 hanging: 'hanging',
3013 horizadvx: 'horizAdvX',
3014 'horiz-adv-x': 'horizAdvX',
3015 horizoriginx: 'horizOriginX',
3016 'horiz-origin-x': 'horizOriginX',
3017 ideographic: 'ideographic',
3018 imagerendering: 'imageRendering',
3019 'image-rendering': 'imageRendering',
3020 in2: 'in2',
3021 in: 'in',
3022 inlist: 'inlist',
3023 intercept: 'intercept',
3024 k1: 'k1',
3025 k2: 'k2',
3026 k3: 'k3',
3027 k4: 'k4',
3028 k: 'k',
3029 kernelmatrix: 'kernelMatrix',
3030 kernelunitlength: 'kernelUnitLength',
3031 kerning: 'kerning',
3032 keypoints: 'keyPoints',
3033 keysplines: 'keySplines',
3034 keytimes: 'keyTimes',
3035 lengthadjust: 'lengthAdjust',
3036 letterspacing: 'letterSpacing',
3037 'letter-spacing': 'letterSpacing',
3038 lightingcolor: 'lightingColor',
3039 'lighting-color': 'lightingColor',
3040 limitingconeangle: 'limitingConeAngle',
3041 local: 'local',
3042 markerend: 'markerEnd',
3043 'marker-end': 'markerEnd',
3044 markerheight: 'markerHeight',
3045 markermid: 'markerMid',
3046 'marker-mid': 'markerMid',
3047 markerstart: 'markerStart',
3048 'marker-start': 'markerStart',
3049 markerunits: 'markerUnits',
3050 markerwidth: 'markerWidth',
3051 mask: 'mask',
3052 maskcontentunits: 'maskContentUnits',
3053 maskunits: 'maskUnits',
3054 mathematical: 'mathematical',
3055 mode: 'mode',
3056 numoctaves: 'numOctaves',
3057 offset: 'offset',
3058 opacity: 'opacity',
3059 operator: 'operator',
3060 order: 'order',
3061 orient: 'orient',
3062 orientation: 'orientation',
3063 origin: 'origin',
3064 overflow: 'overflow',
3065 overlineposition: 'overlinePosition',
3066 'overline-position': 'overlinePosition',
3067 overlinethickness: 'overlineThickness',
3068 'overline-thickness': 'overlineThickness',
3069 paintorder: 'paintOrder',
3070 'paint-order': 'paintOrder',
3071 panose1: 'panose1',
3072 'panose-1': 'panose1',
3073 pathlength: 'pathLength',
3074 patterncontentunits: 'patternContentUnits',
3075 patterntransform: 'patternTransform',
3076 patternunits: 'patternUnits',
3077 pointerevents: 'pointerEvents',
3078 'pointer-events': 'pointerEvents',
3079 points: 'points',
3080 pointsatx: 'pointsAtX',
3081 pointsaty: 'pointsAtY',
3082 pointsatz: 'pointsAtZ',
3083 prefix: 'prefix',
3084 preservealpha: 'preserveAlpha',
3085 preserveaspectratio: 'preserveAspectRatio',
3086 primitiveunits: 'primitiveUnits',
3087 property: 'property',
3088 r: 'r',
3089 radius: 'radius',
3090 refx: 'refX',
3091 refy: 'refY',
3092 renderingintent: 'renderingIntent',
3093 'rendering-intent': 'renderingIntent',
3094 repeatcount: 'repeatCount',
3095 repeatdur: 'repeatDur',
3096 requiredextensions: 'requiredExtensions',
3097 requiredfeatures: 'requiredFeatures',
3098 resource: 'resource',
3099 restart: 'restart',
3100 result: 'result',
3101 results: 'results',
3102 rotate: 'rotate',
3103 rx: 'rx',
3104 ry: 'ry',
3105 scale: 'scale',
3106 security: 'security',
3107 seed: 'seed',
3108 shaperendering: 'shapeRendering',
3109 'shape-rendering': 'shapeRendering',
3110 slope: 'slope',
3111 spacing: 'spacing',
3112 specularconstant: 'specularConstant',
3113 specularexponent: 'specularExponent',
3114 speed: 'speed',
3115 spreadmethod: 'spreadMethod',
3116 startoffset: 'startOffset',
3117 stddeviation: 'stdDeviation',
3118 stemh: 'stemh',
3119 stemv: 'stemv',
3120 stitchtiles: 'stitchTiles',
3121 stopcolor: 'stopColor',
3122 'stop-color': 'stopColor',
3123 stopopacity: 'stopOpacity',
3124 'stop-opacity': 'stopOpacity',
3125 strikethroughposition: 'strikethroughPosition',
3126 'strikethrough-position': 'strikethroughPosition',
3127 strikethroughthickness: 'strikethroughThickness',
3128 'strikethrough-thickness': 'strikethroughThickness',
3129 string: 'string',
3130 stroke: 'stroke',
3131 strokedasharray: 'strokeDasharray',
3132 'stroke-dasharray': 'strokeDasharray',
3133 strokedashoffset: 'strokeDashoffset',
3134 'stroke-dashoffset': 'strokeDashoffset',
3135 strokelinecap: 'strokeLinecap',
3136 'stroke-linecap': 'strokeLinecap',
3137 strokelinejoin: 'strokeLinejoin',
3138 'stroke-linejoin': 'strokeLinejoin',
3139 strokemiterlimit: 'strokeMiterlimit',
3140 'stroke-miterlimit': 'strokeMiterlimit',
3141 strokewidth: 'strokeWidth',
3142 'stroke-width': 'strokeWidth',
3143 strokeopacity: 'strokeOpacity',
3144 'stroke-opacity': 'strokeOpacity',
3145 suppresscontenteditablewarning: 'suppressContentEditableWarning',
3146 suppresshydrationwarning: 'suppressHydrationWarning',
3147 surfacescale: 'surfaceScale',
3148 systemlanguage: 'systemLanguage',
3149 tablevalues: 'tableValues',
3150 targetx: 'targetX',
3151 targety: 'targetY',
3152 textanchor: 'textAnchor',
3153 'text-anchor': 'textAnchor',
3154 textdecoration: 'textDecoration',
3155 'text-decoration': 'textDecoration',
3156 textlength: 'textLength',
3157 textrendering: 'textRendering',
3158 'text-rendering': 'textRendering',
3159 to: 'to',
3160 transform: 'transform',
3161 typeof: 'typeof',
3162 u1: 'u1',
3163 u2: 'u2',
3164 underlineposition: 'underlinePosition',
3165 'underline-position': 'underlinePosition',
3166 underlinethickness: 'underlineThickness',
3167 'underline-thickness': 'underlineThickness',
3168 unicode: 'unicode',
3169 unicodebidi: 'unicodeBidi',
3170 'unicode-bidi': 'unicodeBidi',
3171 unicoderange: 'unicodeRange',
3172 'unicode-range': 'unicodeRange',
3173 unitsperem: 'unitsPerEm',
3174 'units-per-em': 'unitsPerEm',
3175 unselectable: 'unselectable',
3176 valphabetic: 'vAlphabetic',
3177 'v-alphabetic': 'vAlphabetic',
3178 values: 'values',
3179 vectoreffect: 'vectorEffect',
3180 'vector-effect': 'vectorEffect',
3181 version: 'version',
3182 vertadvy: 'vertAdvY',
3183 'vert-adv-y': 'vertAdvY',
3184 vertoriginx: 'vertOriginX',
3185 'vert-origin-x': 'vertOriginX',
3186 vertoriginy: 'vertOriginY',
3187 'vert-origin-y': 'vertOriginY',
3188 vhanging: 'vHanging',
3189 'v-hanging': 'vHanging',
3190 videographic: 'vIdeographic',
3191 'v-ideographic': 'vIdeographic',
3192 viewbox: 'viewBox',
3193 viewtarget: 'viewTarget',
3194 visibility: 'visibility',
3195 vmathematical: 'vMathematical',
3196 'v-mathematical': 'vMathematical',
3197 vocab: 'vocab',
3198 widths: 'widths',
3199 wordspacing: 'wordSpacing',
3200 'word-spacing': 'wordSpacing',
3201 writingmode: 'writingMode',
3202 'writing-mode': 'writingMode',
3203 x1: 'x1',
3204 x2: 'x2',
3205 x: 'x',
3206 xchannelselector: 'xChannelSelector',
3207 xheight: 'xHeight',
3208 'x-height': 'xHeight',
3209 xlinkactuate: 'xlinkActuate',
3210 'xlink:actuate': 'xlinkActuate',
3211 xlinkarcrole: 'xlinkArcrole',
3212 'xlink:arcrole': 'xlinkArcrole',
3213 xlinkhref: 'xlinkHref',
3214 'xlink:href': 'xlinkHref',
3215 xlinkrole: 'xlinkRole',
3216 'xlink:role': 'xlinkRole',
3217 xlinkshow: 'xlinkShow',
3218 'xlink:show': 'xlinkShow',
3219 xlinktitle: 'xlinkTitle',
3220 'xlink:title': 'xlinkTitle',
3221 xlinktype: 'xlinkType',
3222 'xlink:type': 'xlinkType',
3223 xmlbase: 'xmlBase',
3224 'xml:base': 'xmlBase',
3225 xmllang: 'xmlLang',
3226 'xml:lang': 'xmlLang',
3227 xmlns: 'xmlns',
3228 'xml:space': 'xmlSpace',
3229 xmlnsxlink: 'xmlnsXlink',
3230 'xmlns:xlink': 'xmlnsXlink',
3231 xmlspace: 'xmlSpace',
3232 y1: 'y1',
3233 y2: 'y2',
3234 y: 'y',
3235 ychannelselector: 'yChannelSelector',
3236 z: 'z',
3237 zoomandpan: 'zoomAndPan'
3238};
3239
3240var ariaProperties = {
3241 'aria-current': 0,
3242 // state
3243 'aria-details': 0,
3244 'aria-disabled': 0,
3245 // state
3246 'aria-hidden': 0,
3247 // state
3248 'aria-invalid': 0,
3249 // state
3250 'aria-keyshortcuts': 0,
3251 'aria-label': 0,
3252 'aria-roledescription': 0,
3253 // Widget Attributes
3254 'aria-autocomplete': 0,
3255 'aria-checked': 0,
3256 'aria-expanded': 0,
3257 'aria-haspopup': 0,
3258 'aria-level': 0,
3259 'aria-modal': 0,
3260 'aria-multiline': 0,
3261 'aria-multiselectable': 0,
3262 'aria-orientation': 0,
3263 'aria-placeholder': 0,
3264 'aria-pressed': 0,
3265 'aria-readonly': 0,
3266 'aria-required': 0,
3267 'aria-selected': 0,
3268 'aria-sort': 0,
3269 'aria-valuemax': 0,
3270 'aria-valuemin': 0,
3271 'aria-valuenow': 0,
3272 'aria-valuetext': 0,
3273 // Live Region Attributes
3274 'aria-atomic': 0,
3275 'aria-busy': 0,
3276 'aria-live': 0,
3277 'aria-relevant': 0,
3278 // Drag-and-Drop Attributes
3279 'aria-dropeffect': 0,
3280 'aria-grabbed': 0,
3281 // Relationship Attributes
3282 'aria-activedescendant': 0,
3283 'aria-colcount': 0,
3284 'aria-colindex': 0,
3285 'aria-colspan': 0,
3286 'aria-controls': 0,
3287 'aria-describedby': 0,
3288 'aria-errormessage': 0,
3289 'aria-flowto': 0,
3290 'aria-labelledby': 0,
3291 'aria-owns': 0,
3292 'aria-posinset': 0,
3293 'aria-rowcount': 0,
3294 'aria-rowindex': 0,
3295 'aria-rowspan': 0,
3296 'aria-setsize': 0
3297};
3298
3299var warnedProperties = {};
3300var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3301var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3302var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
3303
3304function validateProperty(tagName, name) {
3305 {
3306 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
3307 return true;
3308 }
3309
3310 if (rARIACamel.test(name)) {
3311 var ariaName = 'aria-' + name.slice(4).toLowerCase();
3312 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3313 // DOM properties, then it is an invalid aria-* attribute.
3314
3315 if (correctName == null) {
3316 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
3317
3318 warnedProperties[name] = true;
3319 return true;
3320 } // aria-* attributes should be lowercase; suggest the lowercase version.
3321
3322
3323 if (name !== correctName) {
3324 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
3325
3326 warnedProperties[name] = true;
3327 return true;
3328 }
3329 }
3330
3331 if (rARIA.test(name)) {
3332 var lowerCasedName = name.toLowerCase();
3333 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3334 // DOM properties, then it is an invalid aria-* attribute.
3335
3336 if (standardName == null) {
3337 warnedProperties[name] = true;
3338 return false;
3339 } // aria-* attributes should be lowercase; suggest the lowercase version.
3340
3341
3342 if (name !== standardName) {
3343 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
3344
3345 warnedProperties[name] = true;
3346 return true;
3347 }
3348 }
3349 }
3350
3351 return true;
3352}
3353
3354function warnInvalidARIAProps(type, props) {
3355 {
3356 var invalidProps = [];
3357
3358 for (var key in props) {
3359 var isValid = validateProperty(type, key);
3360
3361 if (!isValid) {
3362 invalidProps.push(key);
3363 }
3364 }
3365
3366 var unknownPropString = invalidProps.map(function (prop) {
3367 return '`' + prop + '`';
3368 }).join(', ');
3369
3370 if (invalidProps.length === 1) {
3371 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3372 } else if (invalidProps.length > 1) {
3373 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3374 }
3375 }
3376}
3377
3378function validateProperties(type, props) {
3379 if (isCustomComponent(type, props)) {
3380 return;
3381 }
3382
3383 warnInvalidARIAProps(type, props);
3384}
3385
3386var didWarnValueNull = false;
3387function validateProperties$1(type, props) {
3388 {
3389 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
3390 return;
3391 }
3392
3393 if (props != null && props.value === null && !didWarnValueNull) {
3394 didWarnValueNull = true;
3395
3396 if (type === 'select' && props.multiple) {
3397 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);
3398 } else {
3399 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
3400 }
3401 }
3402 }
3403}
3404
3405var validateProperty$1 = function () {};
3406
3407{
3408 var warnedProperties$1 = {};
3409 var _hasOwnProperty = Object.prototype.hasOwnProperty;
3410 var EVENT_NAME_REGEX = /^on./;
3411 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
3412 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3413 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3414
3415 validateProperty$1 = function (tagName, name, value, eventRegistry) {
3416 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
3417 return true;
3418 }
3419
3420 var lowerCasedName = name.toLowerCase();
3421
3422 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
3423 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.');
3424
3425 warnedProperties$1[name] = true;
3426 return true;
3427 } // We can't rely on the event system being injected on the server.
3428
3429
3430 if (eventRegistry != null) {
3431 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
3432 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
3433
3434 if (registrationNameDependencies.hasOwnProperty(name)) {
3435 return true;
3436 }
3437
3438 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
3439
3440 if (registrationName != null) {
3441 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
3442
3443 warnedProperties$1[name] = true;
3444 return true;
3445 }
3446
3447 if (EVENT_NAME_REGEX.test(name)) {
3448 error('Unknown event handler property `%s`. It will be ignored.', name);
3449
3450 warnedProperties$1[name] = true;
3451 return true;
3452 }
3453 } else if (EVENT_NAME_REGEX.test(name)) {
3454 // If no event plugins have been injected, we are in a server environment.
3455 // So we can't tell if the event name is correct for sure, but we can filter
3456 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
3457 if (INVALID_EVENT_NAME_REGEX.test(name)) {
3458 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
3459 }
3460
3461 warnedProperties$1[name] = true;
3462 return true;
3463 } // Let the ARIA attribute hook validate ARIA attributes
3464
3465
3466 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
3467 return true;
3468 }
3469
3470 if (lowerCasedName === 'innerhtml') {
3471 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
3472
3473 warnedProperties$1[name] = true;
3474 return true;
3475 }
3476
3477 if (lowerCasedName === 'aria') {
3478 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
3479
3480 warnedProperties$1[name] = true;
3481 return true;
3482 }
3483
3484 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
3485 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
3486
3487 warnedProperties$1[name] = true;
3488 return true;
3489 }
3490
3491 if (typeof value === 'number' && isNaN(value)) {
3492 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
3493
3494 warnedProperties$1[name] = true;
3495 return true;
3496 }
3497
3498 var propertyInfo = getPropertyInfo(name);
3499 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
3500
3501 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
3502 var standardName = possibleStandardNames[lowerCasedName];
3503
3504 if (standardName !== name) {
3505 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
3506
3507 warnedProperties$1[name] = true;
3508 return true;
3509 }
3510 } else if (!isReserved && name !== lowerCasedName) {
3511 // Unknown attributes should have lowercase casing since that's how they
3512 // will be cased anyway with server rendering.
3513 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);
3514
3515 warnedProperties$1[name] = true;
3516 return true;
3517 }
3518
3519 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3520 if (value) {
3521 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);
3522 } else {
3523 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);
3524 }
3525
3526 warnedProperties$1[name] = true;
3527 return true;
3528 } // Now that we've validated casing, do not validate
3529 // data types for reserved props
3530
3531
3532 if (isReserved) {
3533 return true;
3534 } // Warn when a known attribute is a bad type
3535
3536
3537 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3538 warnedProperties$1[name] = true;
3539 return false;
3540 } // Warn when passing the strings 'false' or 'true' into a boolean prop
3541
3542
3543 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
3544 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);
3545
3546 warnedProperties$1[name] = true;
3547 return true;
3548 }
3549
3550 return true;
3551 };
3552}
3553
3554var warnUnknownProperties = function (type, props, eventRegistry) {
3555 {
3556 var unknownProps = [];
3557
3558 for (var key in props) {
3559 var isValid = validateProperty$1(type, key, props[key], eventRegistry);
3560
3561 if (!isValid) {
3562 unknownProps.push(key);
3563 }
3564 }
3565
3566 var unknownPropString = unknownProps.map(function (prop) {
3567 return '`' + prop + '`';
3568 }).join(', ');
3569
3570 if (unknownProps.length === 1) {
3571 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);
3572 } else if (unknownProps.length > 1) {
3573 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);
3574 }
3575 }
3576};
3577
3578function validateProperties$2(type, props, eventRegistry) {
3579 if (isCustomComponent(type, props)) {
3580 return;
3581 }
3582
3583 warnUnknownProperties(type, props, eventRegistry);
3584}
3585
3586var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
3587var IS_NON_DELEGATED = 1 << 1;
3588var IS_CAPTURE_PHASE = 1 << 2;
3589var IS_REPLAYED = 1 << 4;
3590// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
3591// we call willDeferLaterForLegacyFBSupport, thus not bailing out
3592// will result in endless cycles like an infinite loop.
3593// We also don't want to defer during event replaying.
3594
3595var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
3596
3597/**
3598 * Gets the target node from a native browser event by accounting for
3599 * inconsistencies in browser DOM APIs.
3600 *
3601 * @param {object} nativeEvent Native browser event.
3602 * @return {DOMEventTarget} Target node.
3603 */
3604
3605function getEventTarget(nativeEvent) {
3606 // Fallback to nativeEvent.srcElement for IE9
3607 // https://github.com/facebook/react/issues/12506
3608 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3609
3610 if (target.correspondingUseElement) {
3611 target = target.correspondingUseElement;
3612 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3613 // @see http://www.quirksmode.org/js/events_properties.html
3614
3615
3616 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3617}
3618
3619var restoreImpl = null;
3620var restoreTarget = null;
3621var restoreQueue = null;
3622
3623function restoreStateOfTarget(target) {
3624 // We perform this translation at the end of the event loop so that we
3625 // always receive the correct fiber here
3626 var internalInstance = getInstanceFromNode(target);
3627
3628 if (!internalInstance) {
3629 // Unmounted
3630 return;
3631 }
3632
3633 if (!(typeof restoreImpl === 'function')) {
3634 {
3635 throw Error( "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." );
3636 }
3637 }
3638
3639 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
3640
3641 if (stateNode) {
3642 var _props = getFiberCurrentPropsFromNode(stateNode);
3643
3644 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
3645 }
3646}
3647
3648function setRestoreImplementation(impl) {
3649 restoreImpl = impl;
3650}
3651function enqueueStateRestore(target) {
3652 if (restoreTarget) {
3653 if (restoreQueue) {
3654 restoreQueue.push(target);
3655 } else {
3656 restoreQueue = [target];
3657 }
3658 } else {
3659 restoreTarget = target;
3660 }
3661}
3662function needsStateRestore() {
3663 return restoreTarget !== null || restoreQueue !== null;
3664}
3665function restoreStateIfNeeded() {
3666 if (!restoreTarget) {
3667 return;
3668 }
3669
3670 var target = restoreTarget;
3671 var queuedTargets = restoreQueue;
3672 restoreTarget = null;
3673 restoreQueue = null;
3674 restoreStateOfTarget(target);
3675
3676 if (queuedTargets) {
3677 for (var i = 0; i < queuedTargets.length; i++) {
3678 restoreStateOfTarget(queuedTargets[i]);
3679 }
3680 }
3681}
3682
3683// the renderer. Such as when we're dispatching events or if third party
3684// libraries need to call batchedUpdates. Eventually, this API will go away when
3685// everything is batched by default. We'll then have a similar API to opt-out of
3686// scheduled work and instead do synchronous work.
3687// Defaults
3688
3689var batchedUpdatesImpl = function (fn, bookkeeping) {
3690 return fn(bookkeeping);
3691};
3692
3693var discreteUpdatesImpl = function (fn, a, b, c, d) {
3694 return fn(a, b, c, d);
3695};
3696
3697var flushDiscreteUpdatesImpl = function () {};
3698
3699var batchedEventUpdatesImpl = batchedUpdatesImpl;
3700var isInsideEventHandler = false;
3701var isBatchingEventUpdates = false;
3702
3703function finishEventHandler() {
3704 // Here we wait until all updates have propagated, which is important
3705 // when using controlled components within layers:
3706 // https://github.com/facebook/react/issues/1698
3707 // Then we restore state of any controlled component.
3708 var controlledComponentsHavePendingUpdates = needsStateRestore();
3709
3710 if (controlledComponentsHavePendingUpdates) {
3711 // If a controlled event was fired, we may need to restore the state of
3712 // the DOM node back to the controlled value. This is necessary when React
3713 // bails out of the update without touching the DOM.
3714 flushDiscreteUpdatesImpl();
3715 restoreStateIfNeeded();
3716 }
3717}
3718
3719function batchedUpdates(fn, bookkeeping) {
3720 if (isInsideEventHandler) {
3721 // If we are currently inside another batch, we need to wait until it
3722 // fully completes before restoring state.
3723 return fn(bookkeeping);
3724 }
3725
3726 isInsideEventHandler = true;
3727
3728 try {
3729 return batchedUpdatesImpl(fn, bookkeeping);
3730 } finally {
3731 isInsideEventHandler = false;
3732 finishEventHandler();
3733 }
3734}
3735function batchedEventUpdates(fn, a, b) {
3736 if (isBatchingEventUpdates) {
3737 // If we are currently inside another batch, we need to wait until it
3738 // fully completes before restoring state.
3739 return fn(a, b);
3740 }
3741
3742 isBatchingEventUpdates = true;
3743
3744 try {
3745 return batchedEventUpdatesImpl(fn, a, b);
3746 } finally {
3747 isBatchingEventUpdates = false;
3748 finishEventHandler();
3749 }
3750}
3751function discreteUpdates(fn, a, b, c, d) {
3752 var prevIsInsideEventHandler = isInsideEventHandler;
3753 isInsideEventHandler = true;
3754
3755 try {
3756 return discreteUpdatesImpl(fn, a, b, c, d);
3757 } finally {
3758 isInsideEventHandler = prevIsInsideEventHandler;
3759
3760 if (!isInsideEventHandler) {
3761 finishEventHandler();
3762 }
3763 }
3764}
3765function flushDiscreteUpdatesIfNeeded(timeStamp) {
3766 {
3767 if (!isInsideEventHandler) {
3768 flushDiscreteUpdatesImpl();
3769 }
3770 }
3771}
3772function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
3773 batchedUpdatesImpl = _batchedUpdatesImpl;
3774 discreteUpdatesImpl = _discreteUpdatesImpl;
3775 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
3776 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
3777}
3778
3779function isInteractive(tag) {
3780 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
3781}
3782
3783function shouldPreventMouseEvent(name, type, props) {
3784 switch (name) {
3785 case 'onClick':
3786 case 'onClickCapture':
3787 case 'onDoubleClick':
3788 case 'onDoubleClickCapture':
3789 case 'onMouseDown':
3790 case 'onMouseDownCapture':
3791 case 'onMouseMove':
3792 case 'onMouseMoveCapture':
3793 case 'onMouseUp':
3794 case 'onMouseUpCapture':
3795 case 'onMouseEnter':
3796 return !!(props.disabled && isInteractive(type));
3797
3798 default:
3799 return false;
3800 }
3801}
3802/**
3803 * @param {object} inst The instance, which is the source of events.
3804 * @param {string} registrationName Name of listener (e.g. `onClick`).
3805 * @return {?function} The stored callback.
3806 */
3807
3808
3809function getListener(inst, registrationName) {
3810 var stateNode = inst.stateNode;
3811
3812 if (stateNode === null) {
3813 // Work in progress (ex: onload events in incremental mode).
3814 return null;
3815 }
3816
3817 var props = getFiberCurrentPropsFromNode(stateNode);
3818
3819 if (props === null) {
3820 // Work in progress.
3821 return null;
3822 }
3823
3824 var listener = props[registrationName];
3825
3826 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
3827 return null;
3828 }
3829
3830 if (!(!listener || typeof listener === 'function')) {
3831 {
3832 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
3833 }
3834 }
3835
3836 return listener;
3837}
3838
3839var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
3840// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
3841
3842if (canUseDOM) {
3843 try {
3844 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
3845
3846 Object.defineProperty(options, 'passive', {
3847 get: function () {
3848 passiveBrowserEventsSupported = true;
3849 }
3850 });
3851 window.addEventListener('test', options, options);
3852 window.removeEventListener('test', options, options);
3853 } catch (e) {
3854 passiveBrowserEventsSupported = false;
3855 }
3856}
3857
3858function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
3859 var funcArgs = Array.prototype.slice.call(arguments, 3);
3860
3861 try {
3862 func.apply(context, funcArgs);
3863 } catch (error) {
3864 this.onError(error);
3865 }
3866}
3867
3868var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
3869
3870{
3871 // In DEV mode, we swap out invokeGuardedCallback for a special version
3872 // that plays more nicely with the browser's DevTools. The idea is to preserve
3873 // "Pause on exceptions" behavior. Because React wraps all user-provided
3874 // functions in invokeGuardedCallback, and the production version of
3875 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
3876 // like caught exceptions, and the DevTools won't pause unless the developer
3877 // takes the extra step of enabling pause on caught exceptions. This is
3878 // unintuitive, though, because even though React has caught the error, from
3879 // the developer's perspective, the error is uncaught.
3880 //
3881 // To preserve the expected "Pause on exceptions" behavior, we don't use a
3882 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
3883 // DOM node, and call the user-provided callback from inside an event handler
3884 // for that fake event. If the callback throws, the error is "captured" using
3885 // a global event handler. But because the error happens in a different
3886 // event loop context, it does not interrupt the normal program flow.
3887 // Effectively, this gives us try-catch behavior without actually using
3888 // try-catch. Neat!
3889 // Check that the browser supports the APIs we need to implement our special
3890 // DEV version of invokeGuardedCallback
3891 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
3892 var fakeNode = document.createElement('react');
3893
3894 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
3895 // If document doesn't exist we know for sure we will crash in this method
3896 // when we call document.createEvent(). However this can cause confusing
3897 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
3898 // So we preemptively throw with a better message instead.
3899 if (!(typeof document !== 'undefined')) {
3900 {
3901 throw Error( "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." );
3902 }
3903 }
3904
3905 var evt = document.createEvent('Event');
3906 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
3907 // set this to true at the beginning, then set it to false right after
3908 // calling the function. If the function errors, `didError` will never be
3909 // set to false. This strategy works even if the browser is flaky and
3910 // fails to call our global error handler, because it doesn't rely on
3911 // the error event at all.
3912
3913 var didError = true; // Keeps track of the value of window.event so that we can reset it
3914 // during the callback to let user code access window.event in the
3915 // browsers that support it.
3916
3917 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
3918 // dispatching: https://github.com/facebook/react/issues/13688
3919
3920 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
3921
3922 function restoreAfterDispatch() {
3923 // We immediately remove the callback from event listeners so that
3924 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
3925 // nested call would trigger the fake event handlers of any call higher
3926 // in the stack.
3927 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
3928 // window.event assignment in both IE <= 10 as they throw an error
3929 // "Member not found" in strict mode, and in Firefox which does not
3930 // support window.event.
3931
3932 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
3933 window.event = windowEvent;
3934 }
3935 } // Create an event handler for our fake event. We will synchronously
3936 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
3937 // call the user-provided callback.
3938
3939
3940 var funcArgs = Array.prototype.slice.call(arguments, 3);
3941
3942 function callCallback() {
3943 didCall = true;
3944 restoreAfterDispatch();
3945 func.apply(context, funcArgs);
3946 didError = false;
3947 } // Create a global error event handler. We use this to capture the value
3948 // that was thrown. It's possible that this error handler will fire more
3949 // than once; for example, if non-React code also calls `dispatchEvent`
3950 // and a handler for that event throws. We should be resilient to most of
3951 // those cases. Even if our error event handler fires more than once, the
3952 // last error event is always used. If the callback actually does error,
3953 // we know that the last error event is the correct one, because it's not
3954 // possible for anything else to have happened in between our callback
3955 // erroring and the code that follows the `dispatchEvent` call below. If
3956 // the callback doesn't error, but the error event was fired, we know to
3957 // ignore it because `didError` will be false, as described above.
3958
3959
3960 var error; // Use this to track whether the error event is ever called.
3961
3962 var didSetError = false;
3963 var isCrossOriginError = false;
3964
3965 function handleWindowError(event) {
3966 error = event.error;
3967 didSetError = true;
3968
3969 if (error === null && event.colno === 0 && event.lineno === 0) {
3970 isCrossOriginError = true;
3971 }
3972
3973 if (event.defaultPrevented) {
3974 // Some other error handler has prevented default.
3975 // Browsers silence the error report if this happens.
3976 // We'll remember this to later decide whether to log it or not.
3977 if (error != null && typeof error === 'object') {
3978 try {
3979 error._suppressLogging = true;
3980 } catch (inner) {// Ignore.
3981 }
3982 }
3983 }
3984 } // Create a fake event type.
3985
3986
3987 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
3988
3989 window.addEventListener('error', handleWindowError);
3990 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
3991 // errors, it will trigger our global error handler.
3992
3993 evt.initEvent(evtType, false, false);
3994 fakeNode.dispatchEvent(evt);
3995
3996 if (windowEventDescriptor) {
3997 Object.defineProperty(window, 'event', windowEventDescriptor);
3998 }
3999
4000 if (didCall && didError) {
4001 if (!didSetError) {
4002 // The callback errored, but the error event never fired.
4003 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
4004 } else if (isCrossOriginError) {
4005 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://reactjs.org/link/crossorigin-error for more information.');
4006 }
4007
4008 this.onError(error);
4009 } // Remove our event listeners
4010
4011
4012 window.removeEventListener('error', handleWindowError);
4013
4014 if (!didCall) {
4015 // Something went really wrong, and our event was not dispatched.
4016 // https://github.com/facebook/react/issues/16734
4017 // https://github.com/facebook/react/issues/16585
4018 // Fall back to the production implementation.
4019 restoreAfterDispatch();
4020 return invokeGuardedCallbackProd.apply(this, arguments);
4021 }
4022 };
4023 }
4024}
4025
4026var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
4027
4028var hasError = false;
4029var caughtError = null; // Used by event system to capture/rethrow the first error.
4030
4031var hasRethrowError = false;
4032var rethrowError = null;
4033var reporter = {
4034 onError: function (error) {
4035 hasError = true;
4036 caughtError = error;
4037 }
4038};
4039/**
4040 * Call a function while guarding against errors that happens within it.
4041 * Returns an error if it throws, otherwise null.
4042 *
4043 * In production, this is implemented using a try-catch. The reason we don't
4044 * use a try-catch directly is so that we can swap out a different
4045 * implementation in DEV mode.
4046 *
4047 * @param {String} name of the guard to use for logging or debugging
4048 * @param {Function} func The function to invoke
4049 * @param {*} context The context to use when calling the function
4050 * @param {...*} args Arguments for function
4051 */
4052
4053function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
4054 hasError = false;
4055 caughtError = null;
4056 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
4057}
4058/**
4059 * Same as invokeGuardedCallback, but instead of returning an error, it stores
4060 * it in a global so it can be rethrown by `rethrowCaughtError` later.
4061 * TODO: See if caughtError and rethrowError can be unified.
4062 *
4063 * @param {String} name of the guard to use for logging or debugging
4064 * @param {Function} func The function to invoke
4065 * @param {*} context The context to use when calling the function
4066 * @param {...*} args Arguments for function
4067 */
4068
4069function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
4070 invokeGuardedCallback.apply(this, arguments);
4071
4072 if (hasError) {
4073 var error = clearCaughtError();
4074
4075 if (!hasRethrowError) {
4076 hasRethrowError = true;
4077 rethrowError = error;
4078 }
4079 }
4080}
4081/**
4082 * During execution of guarded functions we will capture the first error which
4083 * we will rethrow to be handled by the top level error handler.
4084 */
4085
4086function rethrowCaughtError() {
4087 if (hasRethrowError) {
4088 var error = rethrowError;
4089 hasRethrowError = false;
4090 rethrowError = null;
4091 throw error;
4092 }
4093}
4094function hasCaughtError() {
4095 return hasError;
4096}
4097function clearCaughtError() {
4098 if (hasError) {
4099 var error = caughtError;
4100 hasError = false;
4101 caughtError = null;
4102 return error;
4103 } else {
4104 {
4105 {
4106 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
4107 }
4108 }
4109 }
4110}
4111
4112/**
4113 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4114 * instance (key) and the internal representation (value). This allows public
4115 * methods to accept the user facing instance as an argument and map them back
4116 * to internal methods.
4117 *
4118 * Note that this module is currently shared and assumed to be stateless.
4119 * If this becomes an actual Map, that will break.
4120 */
4121function get(key) {
4122 return key._reactInternals;
4123}
4124function has(key) {
4125 return key._reactInternals !== undefined;
4126}
4127function set(key, value) {
4128 key._reactInternals = value;
4129}
4130
4131// Don't change these two values. They're used by React Dev Tools.
4132var NoFlags =
4133/* */
41340;
4135var PerformedWork =
4136/* */
41371; // You can change the rest (and add more).
4138
4139var Placement =
4140/* */
41412;
4142var Update =
4143/* */
41444;
4145var PlacementAndUpdate =
4146/* */
41476;
4148var Deletion =
4149/* */
41508;
4151var ContentReset =
4152/* */
415316;
4154var Callback =
4155/* */
415632;
4157var DidCapture =
4158/* */
415964;
4160var Ref =
4161/* */
4162128;
4163var Snapshot =
4164/* */
4165256;
4166var Passive =
4167/* */
4168512; // TODO (effects) Remove this bit once the new reconciler is synced to the old.
4169
4170var PassiveUnmountPendingDev =
4171/* */
41728192;
4173var Hydrating =
4174/* */
41751024;
4176var HydratingAndUpdate =
4177/* */
41781028; // Passive & Update & Callback & Ref & Snapshot
4179
4180var LifecycleEffectMask =
4181/* */
4182932; // Union of all host effects
4183
4184var HostEffectMask =
4185/* */
41862047; // These are not really side effects, but we still reuse this field.
4187
4188var Incomplete =
4189/* */
41902048;
4191var ShouldCapture =
4192/* */
41934096;
4194var ForceUpdateForLegacySuspense =
4195/* */
419616384; // Static tags describe aspects of a fiber that are not specific to a render,
4197
4198var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4199function getNearestMountedFiber(fiber) {
4200 var node = fiber;
4201 var nearestMounted = fiber;
4202
4203 if (!fiber.alternate) {
4204 // If there is no alternate, this might be a new tree that isn't inserted
4205 // yet. If it is, then it will have a pending insertion effect on it.
4206 var nextNode = node;
4207
4208 do {
4209 node = nextNode;
4210
4211 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
4212 // This is an insertion or in-progress hydration. The nearest possible
4213 // mounted fiber is the parent but we need to continue to figure out
4214 // if that one is still mounted.
4215 nearestMounted = node.return;
4216 }
4217
4218 nextNode = node.return;
4219 } while (nextNode);
4220 } else {
4221 while (node.return) {
4222 node = node.return;
4223 }
4224 }
4225
4226 if (node.tag === HostRoot) {
4227 // TODO: Check if this was a nested HostRoot when used with
4228 // renderContainerIntoSubtree.
4229 return nearestMounted;
4230 } // If we didn't hit the root, that means that we're in an disconnected tree
4231 // that has been unmounted.
4232
4233
4234 return null;
4235}
4236function getSuspenseInstanceFromFiber(fiber) {
4237 if (fiber.tag === SuspenseComponent) {
4238 var suspenseState = fiber.memoizedState;
4239
4240 if (suspenseState === null) {
4241 var current = fiber.alternate;
4242
4243 if (current !== null) {
4244 suspenseState = current.memoizedState;
4245 }
4246 }
4247
4248 if (suspenseState !== null) {
4249 return suspenseState.dehydrated;
4250 }
4251 }
4252
4253 return null;
4254}
4255function getContainerFromFiber(fiber) {
4256 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
4257}
4258function isFiberMounted(fiber) {
4259 return getNearestMountedFiber(fiber) === fiber;
4260}
4261function isMounted(component) {
4262 {
4263 var owner = ReactCurrentOwner.current;
4264
4265 if (owner !== null && owner.tag === ClassComponent) {
4266 var ownerFiber = owner;
4267 var instance = ownerFiber.stateNode;
4268
4269 if (!instance._warnedAboutRefsInRender) {
4270 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');
4271 }
4272
4273 instance._warnedAboutRefsInRender = true;
4274 }
4275 }
4276
4277 var fiber = get(component);
4278
4279 if (!fiber) {
4280 return false;
4281 }
4282
4283 return getNearestMountedFiber(fiber) === fiber;
4284}
4285
4286function assertIsMounted(fiber) {
4287 if (!(getNearestMountedFiber(fiber) === fiber)) {
4288 {
4289 throw Error( "Unable to find node on an unmounted component." );
4290 }
4291 }
4292}
4293
4294function findCurrentFiberUsingSlowPath(fiber) {
4295 var alternate = fiber.alternate;
4296
4297 if (!alternate) {
4298 // If there is no alternate, then we only need to check if it is mounted.
4299 var nearestMounted = getNearestMountedFiber(fiber);
4300
4301 if (!(nearestMounted !== null)) {
4302 {
4303 throw Error( "Unable to find node on an unmounted component." );
4304 }
4305 }
4306
4307 if (nearestMounted !== fiber) {
4308 return null;
4309 }
4310
4311 return fiber;
4312 } // If we have two possible branches, we'll walk backwards up to the root
4313 // to see what path the root points to. On the way we may hit one of the
4314 // special cases and we'll deal with them.
4315
4316
4317 var a = fiber;
4318 var b = alternate;
4319
4320 while (true) {
4321 var parentA = a.return;
4322
4323 if (parentA === null) {
4324 // We're at the root.
4325 break;
4326 }
4327
4328 var parentB = parentA.alternate;
4329
4330 if (parentB === null) {
4331 // There is no alternate. This is an unusual case. Currently, it only
4332 // happens when a Suspense component is hidden. An extra fragment fiber
4333 // is inserted in between the Suspense fiber and its children. Skip
4334 // over this extra fragment fiber and proceed to the next parent.
4335 var nextParent = parentA.return;
4336
4337 if (nextParent !== null) {
4338 a = b = nextParent;
4339 continue;
4340 } // If there's no parent, we're at the root.
4341
4342
4343 break;
4344 } // If both copies of the parent fiber point to the same child, we can
4345 // assume that the child is current. This happens when we bailout on low
4346 // priority: the bailed out fiber's child reuses the current child.
4347
4348
4349 if (parentA.child === parentB.child) {
4350 var child = parentA.child;
4351
4352 while (child) {
4353 if (child === a) {
4354 // We've determined that A is the current branch.
4355 assertIsMounted(parentA);
4356 return fiber;
4357 }
4358
4359 if (child === b) {
4360 // We've determined that B is the current branch.
4361 assertIsMounted(parentA);
4362 return alternate;
4363 }
4364
4365 child = child.sibling;
4366 } // We should never have an alternate for any mounting node. So the only
4367 // way this could possibly happen is if this was unmounted, if at all.
4368
4369
4370 {
4371 {
4372 throw Error( "Unable to find node on an unmounted component." );
4373 }
4374 }
4375 }
4376
4377 if (a.return !== b.return) {
4378 // The return pointer of A and the return pointer of B point to different
4379 // fibers. We assume that return pointers never criss-cross, so A must
4380 // belong to the child set of A.return, and B must belong to the child
4381 // set of B.return.
4382 a = parentA;
4383 b = parentB;
4384 } else {
4385 // The return pointers point to the same fiber. We'll have to use the
4386 // default, slow path: scan the child sets of each parent alternate to see
4387 // which child belongs to which set.
4388 //
4389 // Search parent A's child set
4390 var didFindChild = false;
4391 var _child = parentA.child;
4392
4393 while (_child) {
4394 if (_child === a) {
4395 didFindChild = true;
4396 a = parentA;
4397 b = parentB;
4398 break;
4399 }
4400
4401 if (_child === b) {
4402 didFindChild = true;
4403 b = parentA;
4404 a = parentB;
4405 break;
4406 }
4407
4408 _child = _child.sibling;
4409 }
4410
4411 if (!didFindChild) {
4412 // Search parent B's child set
4413 _child = parentB.child;
4414
4415 while (_child) {
4416 if (_child === a) {
4417 didFindChild = true;
4418 a = parentB;
4419 b = parentA;
4420 break;
4421 }
4422
4423 if (_child === b) {
4424 didFindChild = true;
4425 b = parentB;
4426 a = parentA;
4427 break;
4428 }
4429
4430 _child = _child.sibling;
4431 }
4432
4433 if (!didFindChild) {
4434 {
4435 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
4436 }
4437 }
4438 }
4439 }
4440
4441 if (!(a.alternate === b)) {
4442 {
4443 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
4444 }
4445 }
4446 } // If the root is not a host container, we're in a disconnected tree. I.e.
4447 // unmounted.
4448
4449
4450 if (!(a.tag === HostRoot)) {
4451 {
4452 throw Error( "Unable to find node on an unmounted component." );
4453 }
4454 }
4455
4456 if (a.stateNode.current === a) {
4457 // We've determined that A is the current branch.
4458 return fiber;
4459 } // Otherwise B has to be current branch.
4460
4461
4462 return alternate;
4463}
4464function findCurrentHostFiber(parent) {
4465 var currentParent = findCurrentFiberUsingSlowPath(parent);
4466
4467 if (!currentParent) {
4468 return null;
4469 } // Next we'll drill down this component to find the first HostComponent/Text.
4470
4471
4472 var node = currentParent;
4473
4474 while (true) {
4475 if (node.tag === HostComponent || node.tag === HostText) {
4476 return node;
4477 } else if (node.child) {
4478 node.child.return = node;
4479 node = node.child;
4480 continue;
4481 }
4482
4483 if (node === currentParent) {
4484 return null;
4485 }
4486
4487 while (!node.sibling) {
4488 if (!node.return || node.return === currentParent) {
4489 return null;
4490 }
4491
4492 node = node.return;
4493 }
4494
4495 node.sibling.return = node.return;
4496 node = node.sibling;
4497 } // Flow needs the return null here, but ESLint complains about it.
4498 // eslint-disable-next-line no-unreachable
4499
4500
4501 return null;
4502}
4503function findCurrentHostFiberWithNoPortals(parent) {
4504 var currentParent = findCurrentFiberUsingSlowPath(parent);
4505
4506 if (!currentParent) {
4507 return null;
4508 } // Next we'll drill down this component to find the first HostComponent/Text.
4509
4510
4511 var node = currentParent;
4512
4513 while (true) {
4514 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {
4515 return node;
4516 } else if (node.child && node.tag !== HostPortal) {
4517 node.child.return = node;
4518 node = node.child;
4519 continue;
4520 }
4521
4522 if (node === currentParent) {
4523 return null;
4524 }
4525
4526 while (!node.sibling) {
4527 if (!node.return || node.return === currentParent) {
4528 return null;
4529 }
4530
4531 node = node.return;
4532 }
4533
4534 node.sibling.return = node.return;
4535 node = node.sibling;
4536 } // Flow needs the return null here, but ESLint complains about it.
4537 // eslint-disable-next-line no-unreachable
4538
4539
4540 return null;
4541}
4542function doesFiberContain(parentFiber, childFiber) {
4543 var node = childFiber;
4544 var parentFiberAlternate = parentFiber.alternate;
4545
4546 while (node !== null) {
4547 if (node === parentFiber || node === parentFiberAlternate) {
4548 return true;
4549 }
4550
4551 node = node.return;
4552 }
4553
4554 return false;
4555}
4556
4557var attemptUserBlockingHydration;
4558function setAttemptUserBlockingHydration(fn) {
4559 attemptUserBlockingHydration = fn;
4560}
4561var attemptContinuousHydration;
4562function setAttemptContinuousHydration(fn) {
4563 attemptContinuousHydration = fn;
4564}
4565var attemptHydrationAtCurrentPriority;
4566function setAttemptHydrationAtCurrentPriority(fn) {
4567 attemptHydrationAtCurrentPriority = fn;
4568}
4569var attemptHydrationAtPriority;
4570function setAttemptHydrationAtPriority(fn) {
4571 attemptHydrationAtPriority = fn;
4572} // TODO: Upgrade this definition once we're on a newer version of Flow that
4573var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
4574
4575var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
4576// if the last target was dehydrated.
4577
4578var queuedFocus = null;
4579var queuedDrag = null;
4580var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
4581
4582var queuedPointers = new Map();
4583var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
4584
4585var queuedExplicitHydrationTargets = [];
4586function hasQueuedDiscreteEvents() {
4587 return queuedDiscreteEvents.length > 0;
4588}
4589var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase
4590'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit'];
4591function isReplayableDiscreteEvent(eventType) {
4592 return discreteReplayableEvents.indexOf(eventType) > -1;
4593}
4594
4595function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4596 return {
4597 blockedOn: blockedOn,
4598 domEventName: domEventName,
4599 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
4600 nativeEvent: nativeEvent,
4601 targetContainers: [targetContainer]
4602 };
4603}
4604
4605function queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4606 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
4607 queuedDiscreteEvents.push(queuedEvent);
4608} // Resets the replaying for this type of continuous event to no event.
4609
4610function clearIfContinuousEvent(domEventName, nativeEvent) {
4611 switch (domEventName) {
4612 case 'focusin':
4613 case 'focusout':
4614 queuedFocus = null;
4615 break;
4616
4617 case 'dragenter':
4618 case 'dragleave':
4619 queuedDrag = null;
4620 break;
4621
4622 case 'mouseover':
4623 case 'mouseout':
4624 queuedMouse = null;
4625 break;
4626
4627 case 'pointerover':
4628 case 'pointerout':
4629 {
4630 var pointerId = nativeEvent.pointerId;
4631 queuedPointers.delete(pointerId);
4632 break;
4633 }
4634
4635 case 'gotpointercapture':
4636 case 'lostpointercapture':
4637 {
4638 var _pointerId = nativeEvent.pointerId;
4639 queuedPointerCaptures.delete(_pointerId);
4640 break;
4641 }
4642 }
4643}
4644
4645function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4646 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
4647 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
4648
4649 if (blockedOn !== null) {
4650 var _fiber2 = getInstanceFromNode(blockedOn);
4651
4652 if (_fiber2 !== null) {
4653 // Attempt to increase the priority of this target.
4654 attemptContinuousHydration(_fiber2);
4655 }
4656 }
4657
4658 return queuedEvent;
4659 } // If we have already queued this exact event, then it's because
4660 // the different event systems have different DOM event listeners.
4661 // We can accumulate the flags, and the targetContainers, and
4662 // store a single event to be replayed.
4663
4664
4665 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
4666 var targetContainers = existingQueuedEvent.targetContainers;
4667
4668 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
4669 targetContainers.push(targetContainer);
4670 }
4671
4672 return existingQueuedEvent;
4673}
4674
4675function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
4676 // These set relatedTarget to null because the replayed event will be treated as if we
4677 // moved from outside the window (no target) onto the target once it hydrates.
4678 // Instead of mutating we could clone the event.
4679 switch (domEventName) {
4680 case 'focusin':
4681 {
4682 var focusEvent = nativeEvent;
4683 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
4684 return true;
4685 }
4686
4687 case 'dragenter':
4688 {
4689 var dragEvent = nativeEvent;
4690 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
4691 return true;
4692 }
4693
4694 case 'mouseover':
4695 {
4696 var mouseEvent = nativeEvent;
4697 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
4698 return true;
4699 }
4700
4701 case 'pointerover':
4702 {
4703 var pointerEvent = nativeEvent;
4704 var pointerId = pointerEvent.pointerId;
4705 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
4706 return true;
4707 }
4708
4709 case 'gotpointercapture':
4710 {
4711 var _pointerEvent = nativeEvent;
4712 var _pointerId2 = _pointerEvent.pointerId;
4713 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
4714 return true;
4715 }
4716 }
4717
4718 return false;
4719} // Check if this target is unblocked. Returns true if it's unblocked.
4720
4721function attemptExplicitHydrationTarget(queuedTarget) {
4722 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
4723 // Try to unify them. It's a bit tricky since it would require two return
4724 // values.
4725 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
4726
4727 if (targetInst !== null) {
4728 var nearestMounted = getNearestMountedFiber(targetInst);
4729
4730 if (nearestMounted !== null) {
4731 var tag = nearestMounted.tag;
4732
4733 if (tag === SuspenseComponent) {
4734 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4735
4736 if (instance !== null) {
4737 // We're blocked on hydrating this boundary.
4738 // Increase its priority.
4739 queuedTarget.blockedOn = instance;
4740 attemptHydrationAtPriority(queuedTarget.lanePriority, function () {
4741 Scheduler.unstable_runWithPriority(queuedTarget.priority, function () {
4742 attemptHydrationAtCurrentPriority(nearestMounted);
4743 });
4744 });
4745 return;
4746 }
4747 } else if (tag === HostRoot) {
4748 var root = nearestMounted.stateNode;
4749
4750 if (root.hydrate) {
4751 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
4752 // a root other than sync.
4753
4754 return;
4755 }
4756 }
4757 }
4758 }
4759
4760 queuedTarget.blockedOn = null;
4761}
4762
4763function attemptReplayContinuousQueuedEvent(queuedEvent) {
4764 if (queuedEvent.blockedOn !== null) {
4765 return false;
4766 }
4767
4768 var targetContainers = queuedEvent.targetContainers;
4769
4770 while (targetContainers.length > 0) {
4771 var targetContainer = targetContainers[0];
4772 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
4773
4774 if (nextBlockedOn !== null) {
4775 // We're still blocked. Try again later.
4776 var _fiber3 = getInstanceFromNode(nextBlockedOn);
4777
4778 if (_fiber3 !== null) {
4779 attemptContinuousHydration(_fiber3);
4780 }
4781
4782 queuedEvent.blockedOn = nextBlockedOn;
4783 return false;
4784 } // This target container was successfully dispatched. Try the next.
4785
4786
4787 targetContainers.shift();
4788 }
4789
4790 return true;
4791}
4792
4793function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
4794 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
4795 map.delete(key);
4796 }
4797}
4798
4799function replayUnblockedEvents() {
4800 hasScheduledReplayAttempt = false; // First replay discrete events.
4801
4802 while (queuedDiscreteEvents.length > 0) {
4803 var nextDiscreteEvent = queuedDiscreteEvents[0];
4804
4805 if (nextDiscreteEvent.blockedOn !== null) {
4806 // We're still blocked.
4807 // Increase the priority of this boundary to unblock
4808 // the next discrete event.
4809 var _fiber4 = getInstanceFromNode(nextDiscreteEvent.blockedOn);
4810
4811 if (_fiber4 !== null) {
4812 attemptUserBlockingHydration(_fiber4);
4813 }
4814
4815 break;
4816 }
4817
4818 var targetContainers = nextDiscreteEvent.targetContainers;
4819
4820 while (targetContainers.length > 0) {
4821 var targetContainer = targetContainers[0];
4822 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.domEventName, nextDiscreteEvent.eventSystemFlags, targetContainer, nextDiscreteEvent.nativeEvent);
4823
4824 if (nextBlockedOn !== null) {
4825 // We're still blocked. Try again later.
4826 nextDiscreteEvent.blockedOn = nextBlockedOn;
4827 break;
4828 } // This target container was successfully dispatched. Try the next.
4829
4830
4831 targetContainers.shift();
4832 }
4833
4834 if (nextDiscreteEvent.blockedOn === null) {
4835 // We've successfully replayed the first event. Let's try the next one.
4836 queuedDiscreteEvents.shift();
4837 }
4838 } // Next replay any continuous events.
4839
4840
4841 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
4842 queuedFocus = null;
4843 }
4844
4845 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
4846 queuedDrag = null;
4847 }
4848
4849 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
4850 queuedMouse = null;
4851 }
4852
4853 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
4854 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
4855}
4856
4857function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
4858 if (queuedEvent.blockedOn === unblocked) {
4859 queuedEvent.blockedOn = null;
4860
4861 if (!hasScheduledReplayAttempt) {
4862 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
4863 // now unblocked. This first might not actually be unblocked yet.
4864 // We could check it early to avoid scheduling an unnecessary callback.
4865
4866 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
4867 }
4868 }
4869}
4870
4871function retryIfBlockedOn(unblocked) {
4872 // Mark anything that was blocked on this as no longer blocked
4873 // and eligible for a replay.
4874 if (queuedDiscreteEvents.length > 0) {
4875 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
4876 // worth it because we expect very few discrete events to queue up and once
4877 // we are actually fully unblocked it will be fast to replay them.
4878
4879 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
4880 var queuedEvent = queuedDiscreteEvents[i];
4881
4882 if (queuedEvent.blockedOn === unblocked) {
4883 queuedEvent.blockedOn = null;
4884 }
4885 }
4886 }
4887
4888 if (queuedFocus !== null) {
4889 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
4890 }
4891
4892 if (queuedDrag !== null) {
4893 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
4894 }
4895
4896 if (queuedMouse !== null) {
4897 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
4898 }
4899
4900 var unblock = function (queuedEvent) {
4901 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
4902 };
4903
4904 queuedPointers.forEach(unblock);
4905 queuedPointerCaptures.forEach(unblock);
4906
4907 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4908 var queuedTarget = queuedExplicitHydrationTargets[_i];
4909
4910 if (queuedTarget.blockedOn === unblocked) {
4911 queuedTarget.blockedOn = null;
4912 }
4913 }
4914
4915 while (queuedExplicitHydrationTargets.length > 0) {
4916 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4917
4918 if (nextExplicitTarget.blockedOn !== null) {
4919 // We're still blocked.
4920 break;
4921 } else {
4922 attemptExplicitHydrationTarget(nextExplicitTarget);
4923
4924 if (nextExplicitTarget.blockedOn === null) {
4925 // We're unblocked.
4926 queuedExplicitHydrationTargets.shift();
4927 }
4928 }
4929 }
4930}
4931
4932var DiscreteEvent = 0;
4933var UserBlockingEvent = 1;
4934var ContinuousEvent = 2;
4935
4936/**
4937 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4938 *
4939 * @param {string} styleProp
4940 * @param {string} eventName
4941 * @returns {object}
4942 */
4943
4944function makePrefixMap(styleProp, eventName) {
4945 var prefixes = {};
4946 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4947 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4948 prefixes['Moz' + styleProp] = 'moz' + eventName;
4949 return prefixes;
4950}
4951/**
4952 * A list of event names to a configurable list of vendor prefixes.
4953 */
4954
4955
4956var vendorPrefixes = {
4957 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4958 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4959 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4960 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4961};
4962/**
4963 * Event names that have already been detected and prefixed (if applicable).
4964 */
4965
4966var prefixedEventNames = {};
4967/**
4968 * Element to check for prefixes on.
4969 */
4970
4971var style = {};
4972/**
4973 * Bootstrap if a DOM exists.
4974 */
4975
4976if (canUseDOM) {
4977 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
4978 // the un-prefixed "animation" and "transition" properties are defined on the
4979 // style object but the events that fire will still be prefixed, so we need
4980 // to check if the un-prefixed events are usable, and if not remove them from the map.
4981
4982 if (!('AnimationEvent' in window)) {
4983 delete vendorPrefixes.animationend.animation;
4984 delete vendorPrefixes.animationiteration.animation;
4985 delete vendorPrefixes.animationstart.animation;
4986 } // Same as above
4987
4988
4989 if (!('TransitionEvent' in window)) {
4990 delete vendorPrefixes.transitionend.transition;
4991 }
4992}
4993/**
4994 * Attempts to determine the correct vendor prefixed event name.
4995 *
4996 * @param {string} eventName
4997 * @returns {string}
4998 */
4999
5000
5001function getVendorPrefixedEventName(eventName) {
5002 if (prefixedEventNames[eventName]) {
5003 return prefixedEventNames[eventName];
5004 } else if (!vendorPrefixes[eventName]) {
5005 return eventName;
5006 }
5007
5008 var prefixMap = vendorPrefixes[eventName];
5009
5010 for (var styleProp in prefixMap) {
5011 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
5012 return prefixedEventNames[eventName] = prefixMap[styleProp];
5013 }
5014 }
5015
5016 return eventName;
5017}
5018
5019var ANIMATION_END = getVendorPrefixedEventName('animationend');
5020var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
5021var ANIMATION_START = getVendorPrefixedEventName('animationstart');
5022var TRANSITION_END = getVendorPrefixedEventName('transitionend');
5023
5024var topLevelEventsToReactNames = new Map();
5025var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use
5026// the code required to apply the same logic for event prioritization and that of the
5027// SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code
5028// duplication (for which there would be quite a bit). For the events that are not needed
5029// for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an
5030// array of top level events.
5031// Lastly, we ignore prettier so we can keep the formatting sane.
5032// prettier-ignore
5033
5034var discreteEventPairsForSimpleEventPlugin = ['cancel', 'cancel', 'click', 'click', 'close', 'close', 'contextmenu', 'contextMenu', 'copy', 'copy', 'cut', 'cut', 'auxclick', 'auxClick', 'dblclick', 'doubleClick', // Careful!
5035'dragend', 'dragEnd', 'dragstart', 'dragStart', 'drop', 'drop', 'focusin', 'focus', // Careful!
5036'focusout', 'blur', // Careful!
5037'input', 'input', 'invalid', 'invalid', 'keydown', 'keyDown', 'keypress', 'keyPress', 'keyup', 'keyUp', 'mousedown', 'mouseDown', 'mouseup', 'mouseUp', 'paste', 'paste', 'pause', 'pause', 'play', 'play', 'pointercancel', 'pointerCancel', 'pointerdown', 'pointerDown', 'pointerup', 'pointerUp', 'ratechange', 'rateChange', 'reset', 'reset', 'seeked', 'seeked', 'submit', 'submit', 'touchcancel', 'touchCancel', 'touchend', 'touchEnd', 'touchstart', 'touchStart', 'volumechange', 'volumeChange'];
5038var otherDiscreteEvents = ['change', 'selectionchange', 'textInput', 'compositionstart', 'compositionend', 'compositionupdate'];
5039
5040
5041var userBlockingPairsForSimpleEventPlugin = ['drag', 'drag', 'dragenter', 'dragEnter', 'dragexit', 'dragExit', 'dragleave', 'dragLeave', 'dragover', 'dragOver', 'mousemove', 'mouseMove', 'mouseout', 'mouseOut', 'mouseover', 'mouseOver', 'pointermove', 'pointerMove', 'pointerout', 'pointerOut', 'pointerover', 'pointerOver', 'scroll', 'scroll', 'toggle', 'toggle', 'touchmove', 'touchMove', 'wheel', 'wheel']; // prettier-ignore
5042
5043var continuousPairsForSimpleEventPlugin = ['abort', 'abort', ANIMATION_END, 'animationEnd', ANIMATION_ITERATION, 'animationIteration', ANIMATION_START, 'animationStart', 'canplay', 'canPlay', 'canplaythrough', 'canPlayThrough', 'durationchange', 'durationChange', 'emptied', 'emptied', 'encrypted', 'encrypted', 'ended', 'ended', 'error', 'error', 'gotpointercapture', 'gotPointerCapture', 'load', 'load', 'loadeddata', 'loadedData', 'loadedmetadata', 'loadedMetadata', 'loadstart', 'loadStart', 'lostpointercapture', 'lostPointerCapture', 'playing', 'playing', 'progress', 'progress', 'seeking', 'seeking', 'stalled', 'stalled', 'suspend', 'suspend', 'timeupdate', 'timeUpdate', TRANSITION_END, 'transitionEnd', 'waiting', 'waiting'];
5044/**
5045 * Turns
5046 * ['abort', ...]
5047 *
5048 * into
5049 *
5050 * topLevelEventsToReactNames = new Map([
5051 * ['abort', 'onAbort'],
5052 * ]);
5053 *
5054 * and registers them.
5055 */
5056
5057function registerSimplePluginEventsAndSetTheirPriorities(eventTypes, priority) {
5058 // As the event types are in pairs of two, we need to iterate
5059 // through in twos. The events are in pairs of two to save code
5060 // and improve init perf of processing this array, as it will
5061 // result in far fewer object allocations and property accesses
5062 // if we only use three arrays to process all the categories of
5063 // instead of tuples.
5064 for (var i = 0; i < eventTypes.length; i += 2) {
5065 var topEvent = eventTypes[i];
5066 var event = eventTypes[i + 1];
5067 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5068 var reactName = 'on' + capitalizedEvent;
5069 eventPriorities.set(topEvent, priority);
5070 topLevelEventsToReactNames.set(topEvent, reactName);
5071 registerTwoPhaseEvent(reactName, [topEvent]);
5072 }
5073}
5074
5075function setEventPriorities(eventTypes, priority) {
5076 for (var i = 0; i < eventTypes.length; i++) {
5077 eventPriorities.set(eventTypes[i], priority);
5078 }
5079}
5080
5081function getEventPriorityForPluginSystem(domEventName) {
5082 var priority = eventPriorities.get(domEventName); // Default to a ContinuousEvent. Note: we might
5083 // want to warn if we can't detect the priority
5084 // for the event.
5085
5086 return priority === undefined ? ContinuousEvent : priority;
5087}
5088function registerSimpleEvents() {
5089 registerSimplePluginEventsAndSetTheirPriorities(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);
5090 registerSimplePluginEventsAndSetTheirPriorities(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);
5091 registerSimplePluginEventsAndSetTheirPriorities(continuousPairsForSimpleEventPlugin, ContinuousEvent);
5092 setEventPriorities(otherDiscreteEvents, DiscreteEvent);
5093}
5094
5095var Scheduler_now = Scheduler.unstable_now;
5096
5097{
5098 // Provide explicit error message when production+profiling bundle of e.g.
5099 // react-dom is used with production (non-profiling) bundle of
5100 // scheduler/tracing
5101 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
5102 {
5103 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" );
5104 }
5105 }
5106}
5107// ascending numbers so we can compare them like numbers. They start at 90 to
5108// avoid clashing with Scheduler's priorities.
5109
5110var ImmediatePriority = 99;
5111var UserBlockingPriority = 98;
5112var NormalPriority = 97;
5113var LowPriority = 96;
5114var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
5115
5116var NoPriority = 90;
5117var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
5118
5119var SyncLanePriority = 15;
5120var SyncBatchedLanePriority = 14;
5121var InputDiscreteHydrationLanePriority = 13;
5122var InputDiscreteLanePriority = 12;
5123var InputContinuousHydrationLanePriority = 11;
5124var InputContinuousLanePriority = 10;
5125var DefaultHydrationLanePriority = 9;
5126var DefaultLanePriority = 8;
5127var TransitionHydrationPriority = 7;
5128var TransitionPriority = 6;
5129var RetryLanePriority = 5;
5130var SelectiveHydrationLanePriority = 4;
5131var IdleHydrationLanePriority = 3;
5132var IdleLanePriority = 2;
5133var OffscreenLanePriority = 1;
5134var NoLanePriority = 0;
5135var TotalLanes = 31;
5136var NoLanes =
5137/* */
51380;
5139var NoLane =
5140/* */
51410;
5142var SyncLane =
5143/* */
51441;
5145var SyncBatchedLane =
5146/* */
51472;
5148var InputDiscreteHydrationLane =
5149/* */
51504;
5151var InputDiscreteLanes =
5152/* */
515324;
5154var InputContinuousHydrationLane =
5155/* */
515632;
5157var InputContinuousLanes =
5158/* */
5159192;
5160var DefaultHydrationLane =
5161/* */
5162256;
5163var DefaultLanes =
5164/* */
51653584;
5166var TransitionHydrationLane =
5167/* */
51684096;
5169var TransitionLanes =
5170/* */
51714186112;
5172var RetryLanes =
5173/* */
517462914560;
5175var SomeRetryLane =
5176/* */
517733554432;
5178var SelectiveHydrationLane =
5179/* */
518067108864;
5181var NonIdleLanes =
5182/* */
5183134217727;
5184var IdleHydrationLane =
5185/* */
5186134217728;
5187var IdleLanes =
5188/* */
5189805306368;
5190var OffscreenLane =
5191/* */
51921073741824;
5193var NoTimestamp = -1;
5194function setCurrentUpdateLanePriority(newLanePriority) {
5195} // "Registers" used to "return" multiple values
5196// Used by getHighestPriorityLanes and getNextLanes:
5197
5198var return_highestLanePriority = DefaultLanePriority;
5199
5200function getHighestPriorityLanes(lanes) {
5201 if ((SyncLane & lanes) !== NoLanes) {
5202 return_highestLanePriority = SyncLanePriority;
5203 return SyncLane;
5204 }
5205
5206 if ((SyncBatchedLane & lanes) !== NoLanes) {
5207 return_highestLanePriority = SyncBatchedLanePriority;
5208 return SyncBatchedLane;
5209 }
5210
5211 if ((InputDiscreteHydrationLane & lanes) !== NoLanes) {
5212 return_highestLanePriority = InputDiscreteHydrationLanePriority;
5213 return InputDiscreteHydrationLane;
5214 }
5215
5216 var inputDiscreteLanes = InputDiscreteLanes & lanes;
5217
5218 if (inputDiscreteLanes !== NoLanes) {
5219 return_highestLanePriority = InputDiscreteLanePriority;
5220 return inputDiscreteLanes;
5221 }
5222
5223 if ((lanes & InputContinuousHydrationLane) !== NoLanes) {
5224 return_highestLanePriority = InputContinuousHydrationLanePriority;
5225 return InputContinuousHydrationLane;
5226 }
5227
5228 var inputContinuousLanes = InputContinuousLanes & lanes;
5229
5230 if (inputContinuousLanes !== NoLanes) {
5231 return_highestLanePriority = InputContinuousLanePriority;
5232 return inputContinuousLanes;
5233 }
5234
5235 if ((lanes & DefaultHydrationLane) !== NoLanes) {
5236 return_highestLanePriority = DefaultHydrationLanePriority;
5237 return DefaultHydrationLane;
5238 }
5239
5240 var defaultLanes = DefaultLanes & lanes;
5241
5242 if (defaultLanes !== NoLanes) {
5243 return_highestLanePriority = DefaultLanePriority;
5244 return defaultLanes;
5245 }
5246
5247 if ((lanes & TransitionHydrationLane) !== NoLanes) {
5248 return_highestLanePriority = TransitionHydrationPriority;
5249 return TransitionHydrationLane;
5250 }
5251
5252 var transitionLanes = TransitionLanes & lanes;
5253
5254 if (transitionLanes !== NoLanes) {
5255 return_highestLanePriority = TransitionPriority;
5256 return transitionLanes;
5257 }
5258
5259 var retryLanes = RetryLanes & lanes;
5260
5261 if (retryLanes !== NoLanes) {
5262 return_highestLanePriority = RetryLanePriority;
5263 return retryLanes;
5264 }
5265
5266 if (lanes & SelectiveHydrationLane) {
5267 return_highestLanePriority = SelectiveHydrationLanePriority;
5268 return SelectiveHydrationLane;
5269 }
5270
5271 if ((lanes & IdleHydrationLane) !== NoLanes) {
5272 return_highestLanePriority = IdleHydrationLanePriority;
5273 return IdleHydrationLane;
5274 }
5275
5276 var idleLanes = IdleLanes & lanes;
5277
5278 if (idleLanes !== NoLanes) {
5279 return_highestLanePriority = IdleLanePriority;
5280 return idleLanes;
5281 }
5282
5283 if ((OffscreenLane & lanes) !== NoLanes) {
5284 return_highestLanePriority = OffscreenLanePriority;
5285 return OffscreenLane;
5286 }
5287
5288 {
5289 error('Should have found matching lanes. This is a bug in React.');
5290 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
5291
5292
5293 return_highestLanePriority = DefaultLanePriority;
5294 return lanes;
5295}
5296
5297function schedulerPriorityToLanePriority(schedulerPriorityLevel) {
5298 switch (schedulerPriorityLevel) {
5299 case ImmediatePriority:
5300 return SyncLanePriority;
5301
5302 case UserBlockingPriority:
5303 return InputContinuousLanePriority;
5304
5305 case NormalPriority:
5306 case LowPriority:
5307 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
5308 return DefaultLanePriority;
5309
5310 case IdlePriority:
5311 return IdleLanePriority;
5312
5313 default:
5314 return NoLanePriority;
5315 }
5316}
5317function lanePriorityToSchedulerPriority(lanePriority) {
5318 switch (lanePriority) {
5319 case SyncLanePriority:
5320 case SyncBatchedLanePriority:
5321 return ImmediatePriority;
5322
5323 case InputDiscreteHydrationLanePriority:
5324 case InputDiscreteLanePriority:
5325 case InputContinuousHydrationLanePriority:
5326 case InputContinuousLanePriority:
5327 return UserBlockingPriority;
5328
5329 case DefaultHydrationLanePriority:
5330 case DefaultLanePriority:
5331 case TransitionHydrationPriority:
5332 case TransitionPriority:
5333 case SelectiveHydrationLanePriority:
5334 case RetryLanePriority:
5335 return NormalPriority;
5336
5337 case IdleHydrationLanePriority:
5338 case IdleLanePriority:
5339 case OffscreenLanePriority:
5340 return IdlePriority;
5341
5342 case NoLanePriority:
5343 return NoPriority;
5344
5345 default:
5346 {
5347 {
5348 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." );
5349 }
5350 }
5351
5352 }
5353}
5354function getNextLanes(root, wipLanes) {
5355 // Early bailout if there's no pending work left.
5356 var pendingLanes = root.pendingLanes;
5357
5358 if (pendingLanes === NoLanes) {
5359 return_highestLanePriority = NoLanePriority;
5360 return NoLanes;
5361 }
5362
5363 var nextLanes = NoLanes;
5364 var nextLanePriority = NoLanePriority;
5365 var expiredLanes = root.expiredLanes;
5366 var suspendedLanes = root.suspendedLanes;
5367 var pingedLanes = root.pingedLanes; // Check if any work has expired.
5368
5369 if (expiredLanes !== NoLanes) {
5370 nextLanes = expiredLanes;
5371 nextLanePriority = return_highestLanePriority = SyncLanePriority;
5372 } else {
5373 // Do not work on any idle work until all the non-idle work has finished,
5374 // even if the work is suspended.
5375 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
5376
5377 if (nonIdlePendingLanes !== NoLanes) {
5378 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
5379
5380 if (nonIdleUnblockedLanes !== NoLanes) {
5381 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
5382 nextLanePriority = return_highestLanePriority;
5383 } else {
5384 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
5385
5386 if (nonIdlePingedLanes !== NoLanes) {
5387 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
5388 nextLanePriority = return_highestLanePriority;
5389 }
5390 }
5391 } else {
5392 // The only remaining work is Idle.
5393 var unblockedLanes = pendingLanes & ~suspendedLanes;
5394
5395 if (unblockedLanes !== NoLanes) {
5396 nextLanes = getHighestPriorityLanes(unblockedLanes);
5397 nextLanePriority = return_highestLanePriority;
5398 } else {
5399 if (pingedLanes !== NoLanes) {
5400 nextLanes = getHighestPriorityLanes(pingedLanes);
5401 nextLanePriority = return_highestLanePriority;
5402 }
5403 }
5404 }
5405 }
5406
5407 if (nextLanes === NoLanes) {
5408 // This should only be reachable if we're suspended
5409 // TODO: Consider warning in this path if a fallback timer is not scheduled.
5410 return NoLanes;
5411 } // If there are higher priority lanes, we'll include them even if they
5412 // are suspended.
5413
5414
5415 nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt
5416 // it and we'll lose our progress. We should only do this if the new lanes are
5417 // higher priority.
5418
5419 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
5420 // bother waiting until the root is complete.
5421 (wipLanes & suspendedLanes) === NoLanes) {
5422 getHighestPriorityLanes(wipLanes);
5423 var wipLanePriority = return_highestLanePriority;
5424
5425 if (nextLanePriority <= wipLanePriority) {
5426 return wipLanes;
5427 } else {
5428 return_highestLanePriority = nextLanePriority;
5429 }
5430 } // Check for entangled lanes and add them to the batch.
5431 //
5432 // A lane is said to be entangled with another when it's not allowed to render
5433 // in a batch that does not also include the other lane. Typically we do this
5434 // when multiple updates have the same source, and we only want to respond to
5435 // the most recent event from that source.
5436 //
5437 // Note that we apply entanglements *after* checking for partial work above.
5438 // This means that if a lane is entangled during an interleaved event while
5439 // it's already rendering, we won't interrupt it. This is intentional, since
5440 // entanglement is usually "best effort": we'll try our best to render the
5441 // lanes in the same batch, but it's not worth throwing out partially
5442 // completed work in order to do it.
5443 //
5444 // For those exceptions where entanglement is semantically important, like
5445 // useMutableSource, we should ensure that there is no partial work at the
5446 // time we apply the entanglement.
5447
5448
5449 var entangledLanes = root.entangledLanes;
5450
5451 if (entangledLanes !== NoLanes) {
5452 var entanglements = root.entanglements;
5453 var lanes = nextLanes & entangledLanes;
5454
5455 while (lanes > 0) {
5456 var index = pickArbitraryLaneIndex(lanes);
5457 var lane = 1 << index;
5458 nextLanes |= entanglements[index];
5459 lanes &= ~lane;
5460 }
5461 }
5462
5463 return nextLanes;
5464}
5465function getMostRecentEventTime(root, lanes) {
5466 var eventTimes = root.eventTimes;
5467 var mostRecentEventTime = NoTimestamp;
5468
5469 while (lanes > 0) {
5470 var index = pickArbitraryLaneIndex(lanes);
5471 var lane = 1 << index;
5472 var eventTime = eventTimes[index];
5473
5474 if (eventTime > mostRecentEventTime) {
5475 mostRecentEventTime = eventTime;
5476 }
5477
5478 lanes &= ~lane;
5479 }
5480
5481 return mostRecentEventTime;
5482}
5483
5484function computeExpirationTime(lane, currentTime) {
5485 // TODO: Expiration heuristic is constant per lane, so could use a map.
5486 getHighestPriorityLanes(lane);
5487 var priority = return_highestLanePriority;
5488
5489 if (priority >= InputContinuousLanePriority) {
5490 // User interactions should expire slightly more quickly.
5491 //
5492 // NOTE: This is set to the corresponding constant as in Scheduler.js. When
5493 // we made it larger, a product metric in www regressed, suggesting there's
5494 // a user interaction that's being starved by a series of synchronous
5495 // updates. If that theory is correct, the proper solution is to fix the
5496 // starvation. However, this scenario supports the idea that expiration
5497 // times are an important safeguard when starvation does happen.
5498 //
5499 // Also note that, in the case of user input specifically, this will soon no
5500 // longer be an issue because we plan to make user input synchronous by
5501 // default (until you enter `startTransition`, of course.)
5502 //
5503 // If weren't planning to make these updates synchronous soon anyway, I
5504 // would probably make this number a configurable parameter.
5505 return currentTime + 250;
5506 } else if (priority >= TransitionPriority) {
5507 return currentTime + 5000;
5508 } else {
5509 // Anything idle priority or lower should never expire.
5510 return NoTimestamp;
5511 }
5512}
5513
5514function markStarvedLanesAsExpired(root, currentTime) {
5515 // TODO: This gets called every time we yield. We can optimize by storing
5516 // the earliest expiration time on the root. Then use that to quickly bail out
5517 // of this function.
5518 var pendingLanes = root.pendingLanes;
5519 var suspendedLanes = root.suspendedLanes;
5520 var pingedLanes = root.pingedLanes;
5521 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
5522 // expiration time. If so, we'll assume the update is being starved and mark
5523 // it as expired to force it to finish.
5524
5525 var lanes = pendingLanes;
5526
5527 while (lanes > 0) {
5528 var index = pickArbitraryLaneIndex(lanes);
5529 var lane = 1 << index;
5530 var expirationTime = expirationTimes[index];
5531
5532 if (expirationTime === NoTimestamp) {
5533 // Found a pending lane with no expiration time. If it's not suspended, or
5534 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
5535 // using the current time.
5536 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
5537 // Assumes timestamps are monotonically increasing.
5538 expirationTimes[index] = computeExpirationTime(lane, currentTime);
5539 }
5540 } else if (expirationTime <= currentTime) {
5541 // This lane expired
5542 root.expiredLanes |= lane;
5543 }
5544
5545 lanes &= ~lane;
5546 }
5547} // This returns the highest priority pending lanes regardless of whether they
5548function getLanesToRetrySynchronouslyOnError(root) {
5549 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
5550
5551 if (everythingButOffscreen !== NoLanes) {
5552 return everythingButOffscreen;
5553 }
5554
5555 if (everythingButOffscreen & OffscreenLane) {
5556 return OffscreenLane;
5557 }
5558
5559 return NoLanes;
5560}
5561function returnNextLanesPriority() {
5562 return return_highestLanePriority;
5563}
5564function includesNonIdleWork(lanes) {
5565 return (lanes & NonIdleLanes) !== NoLanes;
5566}
5567function includesOnlyRetries(lanes) {
5568 return (lanes & RetryLanes) === lanes;
5569}
5570function includesOnlyTransitions(lanes) {
5571 return (lanes & TransitionLanes) === lanes;
5572} // To ensure consistency across multiple updates in the same event, this should
5573// be a pure function, so that it always returns the same lane for given inputs.
5574
5575function findUpdateLane(lanePriority, wipLanes) {
5576 switch (lanePriority) {
5577 case NoLanePriority:
5578 break;
5579
5580 case SyncLanePriority:
5581 return SyncLane;
5582
5583 case SyncBatchedLanePriority:
5584 return SyncBatchedLane;
5585
5586 case InputDiscreteLanePriority:
5587 {
5588 var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes);
5589
5590 if (_lane === NoLane) {
5591 // Shift to the next priority level
5592 return findUpdateLane(InputContinuousLanePriority, wipLanes);
5593 }
5594
5595 return _lane;
5596 }
5597
5598 case InputContinuousLanePriority:
5599 {
5600 var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes);
5601
5602 if (_lane2 === NoLane) {
5603 // Shift to the next priority level
5604 return findUpdateLane(DefaultLanePriority, wipLanes);
5605 }
5606
5607 return _lane2;
5608 }
5609
5610 case DefaultLanePriority:
5611 {
5612 var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes);
5613
5614 if (_lane3 === NoLane) {
5615 // If all the default lanes are already being worked on, look for a
5616 // lane in the transition range.
5617 _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes);
5618
5619 if (_lane3 === NoLane) {
5620 // All the transition lanes are taken, too. This should be very
5621 // rare, but as a last resort, pick a default lane. This will have
5622 // the effect of interrupting the current work-in-progress render.
5623 _lane3 = pickArbitraryLane(DefaultLanes);
5624 }
5625 }
5626
5627 return _lane3;
5628 }
5629
5630 case TransitionPriority: // Should be handled by findTransitionLane instead
5631
5632 case RetryLanePriority:
5633 // Should be handled by findRetryLane instead
5634 break;
5635
5636 case IdleLanePriority:
5637 var lane = pickArbitraryLane(IdleLanes & ~wipLanes);
5638
5639 if (lane === NoLane) {
5640 lane = pickArbitraryLane(IdleLanes);
5641 }
5642
5643 return lane;
5644 }
5645
5646 {
5647 {
5648 throw Error( "Invalid update priority: " + lanePriority + ". This is a bug in React." );
5649 }
5650 }
5651} // To ensure consistency across multiple updates in the same event, this should
5652// be pure function, so that it always returns the same lane for given inputs.
5653
5654function findTransitionLane(wipLanes, pendingLanes) {
5655 // First look for lanes that are completely unclaimed, i.e. have no
5656 // pending work.
5657 var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes);
5658
5659 if (lane === NoLane) {
5660 // If all lanes have pending work, look for a lane that isn't currently
5661 // being worked on.
5662 lane = pickArbitraryLane(TransitionLanes & ~wipLanes);
5663
5664 if (lane === NoLane) {
5665 // If everything is being worked on, pick any lane. This has the
5666 // effect of interrupting the current work-in-progress.
5667 lane = pickArbitraryLane(TransitionLanes);
5668 }
5669 }
5670
5671 return lane;
5672} // To ensure consistency across multiple updates in the same event, this should
5673// be pure function, so that it always returns the same lane for given inputs.
5674
5675function findRetryLane(wipLanes) {
5676 // This is a fork of `findUpdateLane` designed specifically for Suspense
5677 // "retries" — a special update that attempts to flip a Suspense boundary
5678 // from its placeholder state to its primary/resolved state.
5679 var lane = pickArbitraryLane(RetryLanes & ~wipLanes);
5680
5681 if (lane === NoLane) {
5682 lane = pickArbitraryLane(RetryLanes);
5683 }
5684
5685 return lane;
5686}
5687
5688function getHighestPriorityLane(lanes) {
5689 return lanes & -lanes;
5690}
5691
5692function getLowestPriorityLane(lanes) {
5693 // This finds the most significant non-zero bit.
5694 var index = 31 - clz32(lanes);
5695 return index < 0 ? NoLanes : 1 << index;
5696}
5697
5698function getEqualOrHigherPriorityLanes(lanes) {
5699 return (getLowestPriorityLane(lanes) << 1) - 1;
5700}
5701
5702function pickArbitraryLane(lanes) {
5703 // This wrapper function gets inlined. Only exists so to communicate that it
5704 // doesn't matter which bit is selected; you can pick any bit without
5705 // affecting the algorithms where its used. Here I'm using
5706 // getHighestPriorityLane because it requires the fewest operations.
5707 return getHighestPriorityLane(lanes);
5708}
5709
5710function pickArbitraryLaneIndex(lanes) {
5711 return 31 - clz32(lanes);
5712}
5713
5714function laneToIndex(lane) {
5715 return pickArbitraryLaneIndex(lane);
5716}
5717
5718function includesSomeLane(a, b) {
5719 return (a & b) !== NoLanes;
5720}
5721function isSubsetOfLanes(set, subset) {
5722 return (set & subset) === subset;
5723}
5724function mergeLanes(a, b) {
5725 return a | b;
5726}
5727function removeLanes(set, subset) {
5728 return set & ~subset;
5729} // Seems redundant, but it changes the type from a single lane (used for
5730// updates) to a group of lanes (used for flushing work).
5731
5732function laneToLanes(lane) {
5733 return lane;
5734}
5735function higherPriorityLane(a, b) {
5736 // This works because the bit ranges decrease in priority as you go left.
5737 return a !== NoLane && a < b ? a : b;
5738}
5739function createLaneMap(initial) {
5740 // Intentionally pushing one by one.
5741 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5742 var laneMap = [];
5743
5744 for (var i = 0; i < TotalLanes; i++) {
5745 laneMap.push(initial);
5746 }
5747
5748 return laneMap;
5749}
5750function markRootUpdated(root, updateLane, eventTime) {
5751 root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But
5752 // it's not practical to try every single possible combination. We need a
5753 // heuristic to decide which lanes to attempt to render, and in which batches.
5754 // For now, we use the same heuristic as in the old ExpirationTimes model:
5755 // retry any lane at equal or lower priority, but don't try updates at higher
5756 // priority without also including the lower priority updates. This works well
5757 // when considering updates across different priority levels, but isn't
5758 // sufficient for updates within the same priority, since we want to treat
5759 // those updates as parallel.
5760 // Unsuspend any update at equal or lower priority.
5761
5762 var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111
5763
5764 root.suspendedLanes &= higherPriorityLanes;
5765 root.pingedLanes &= higherPriorityLanes;
5766 var eventTimes = root.eventTimes;
5767 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
5768 // recent event, and we assume time is monotonically increasing.
5769
5770 eventTimes[index] = eventTime;
5771}
5772function markRootSuspended(root, suspendedLanes) {
5773 root.suspendedLanes |= suspendedLanes;
5774 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
5775
5776 var expirationTimes = root.expirationTimes;
5777 var lanes = suspendedLanes;
5778
5779 while (lanes > 0) {
5780 var index = pickArbitraryLaneIndex(lanes);
5781 var lane = 1 << index;
5782 expirationTimes[index] = NoTimestamp;
5783 lanes &= ~lane;
5784 }
5785}
5786function markRootPinged(root, pingedLanes, eventTime) {
5787 root.pingedLanes |= root.suspendedLanes & pingedLanes;
5788}
5789function markDiscreteUpdatesExpired(root) {
5790 root.expiredLanes |= InputDiscreteLanes & root.pendingLanes;
5791}
5792function hasDiscreteLanes(lanes) {
5793 return (lanes & InputDiscreteLanes) !== NoLanes;
5794}
5795function markRootMutableRead(root, updateLane) {
5796 root.mutableReadLanes |= updateLane & root.pendingLanes;
5797}
5798function markRootFinished(root, remainingLanes) {
5799 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
5800 root.pendingLanes = remainingLanes; // Let's try everything again
5801
5802 root.suspendedLanes = 0;
5803 root.pingedLanes = 0;
5804 root.expiredLanes &= remainingLanes;
5805 root.mutableReadLanes &= remainingLanes;
5806 root.entangledLanes &= remainingLanes;
5807 var entanglements = root.entanglements;
5808 var eventTimes = root.eventTimes;
5809 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
5810
5811 var lanes = noLongerPendingLanes;
5812
5813 while (lanes > 0) {
5814 var index = pickArbitraryLaneIndex(lanes);
5815 var lane = 1 << index;
5816 entanglements[index] = NoLanes;
5817 eventTimes[index] = NoTimestamp;
5818 expirationTimes[index] = NoTimestamp;
5819 lanes &= ~lane;
5820 }
5821}
5822function markRootEntangled(root, entangledLanes) {
5823 root.entangledLanes |= entangledLanes;
5824 var entanglements = root.entanglements;
5825 var lanes = entangledLanes;
5826
5827 while (lanes > 0) {
5828 var index = pickArbitraryLaneIndex(lanes);
5829 var lane = 1 << index;
5830 entanglements[index] |= entangledLanes;
5831 lanes &= ~lane;
5832 }
5833}
5834var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer.
5835// Based on:
5836// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
5837
5838var log = Math.log;
5839var LN2 = Math.LN2;
5840
5841function clz32Fallback(lanes) {
5842 if (lanes === 0) {
5843 return 32;
5844 }
5845
5846 return 31 - (log(lanes) / LN2 | 0) | 0;
5847}
5848
5849// Intentionally not named imports because Rollup would use dynamic dispatch for
5850var UserBlockingPriority$1 = Scheduler.unstable_UserBlockingPriority,
5851 runWithPriority = Scheduler.unstable_runWithPriority; // TODO: can we stop exporting these?
5852
5853var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra.
5854// We'd like to remove this but it's not clear if this is safe.
5855
5856function setEnabled(enabled) {
5857 _enabled = !!enabled;
5858}
5859function isEnabled() {
5860 return _enabled;
5861}
5862function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
5863 var eventPriority = getEventPriorityForPluginSystem(domEventName);
5864 var listenerWrapper;
5865
5866 switch (eventPriority) {
5867 case DiscreteEvent:
5868 listenerWrapper = dispatchDiscreteEvent;
5869 break;
5870
5871 case UserBlockingEvent:
5872 listenerWrapper = dispatchUserBlockingUpdate;
5873 break;
5874
5875 case ContinuousEvent:
5876 default:
5877 listenerWrapper = dispatchEvent;
5878 break;
5879 }
5880
5881 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
5882}
5883
5884function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
5885 {
5886 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
5887 }
5888
5889 discreteUpdates(dispatchEvent, domEventName, eventSystemFlags, container, nativeEvent);
5890}
5891
5892function dispatchUserBlockingUpdate(domEventName, eventSystemFlags, container, nativeEvent) {
5893 {
5894 runWithPriority(UserBlockingPriority$1, dispatchEvent.bind(null, domEventName, eventSystemFlags, container, nativeEvent));
5895 }
5896}
5897
5898function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
5899 if (!_enabled) {
5900 return;
5901 }
5902
5903 var allowReplay = true;
5904
5905 {
5906 // TODO: replaying capture phase events is currently broken
5907 // because we used to do it during top-level native bubble handlers
5908 // but now we use different bubble and capture handlers.
5909 // In eager mode, we attach capture listeners early, so we need
5910 // to filter them out until we fix the logic to handle them correctly.
5911 // This could've been outside the flag but I put it inside to reduce risk.
5912 allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0;
5913 }
5914
5915 if (allowReplay && hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(domEventName)) {
5916 // If we already have a queue of discrete events, and this is another discrete
5917 // event, then we can't dispatch it regardless of its target, since they
5918 // need to dispatch in order.
5919 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
5920 domEventName, eventSystemFlags, targetContainer, nativeEvent);
5921 return;
5922 }
5923
5924 var blockedOn = attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
5925
5926 if (blockedOn === null) {
5927 // We successfully dispatched this event.
5928 if (allowReplay) {
5929 clearIfContinuousEvent(domEventName, nativeEvent);
5930 }
5931
5932 return;
5933 }
5934
5935 if (allowReplay) {
5936 if (isReplayableDiscreteEvent(domEventName)) {
5937 // This this to be replayed later once the target is available.
5938 queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
5939 return;
5940 }
5941
5942 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
5943 return;
5944 } // We need to clear only if we didn't queue because
5945 // queueing is accummulative.
5946
5947
5948 clearIfContinuousEvent(domEventName, nativeEvent);
5949 } // This is not replayable so we'll invoke it but without a target,
5950 // in case the event system needs to trace it.
5951
5952
5953 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
5954} // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
5955
5956function attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
5957 // TODO: Warn if _enabled is false.
5958 var nativeEventTarget = getEventTarget(nativeEvent);
5959 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
5960
5961 if (targetInst !== null) {
5962 var nearestMounted = getNearestMountedFiber(targetInst);
5963
5964 if (nearestMounted === null) {
5965 // This tree has been unmounted already. Dispatch without a target.
5966 targetInst = null;
5967 } else {
5968 var tag = nearestMounted.tag;
5969
5970 if (tag === SuspenseComponent) {
5971 var instance = getSuspenseInstanceFromFiber(nearestMounted);
5972
5973 if (instance !== null) {
5974 // Queue the event to be replayed later. Abort dispatching since we
5975 // don't want this event dispatched twice through the event system.
5976 // TODO: If this is the first discrete event in the queue. Schedule an increased
5977 // priority for this boundary.
5978 return instance;
5979 } // This shouldn't happen, something went wrong but to avoid blocking
5980 // the whole system, dispatch the event without a target.
5981 // TODO: Warn.
5982
5983
5984 targetInst = null;
5985 } else if (tag === HostRoot) {
5986 var root = nearestMounted.stateNode;
5987
5988 if (root.hydrate) {
5989 // If this happens during a replay something went wrong and it might block
5990 // the whole system.
5991 return getContainerFromFiber(nearestMounted);
5992 }
5993
5994 targetInst = null;
5995 } else if (nearestMounted !== targetInst) {
5996 // If we get an event (ex: img onload) before committing that
5997 // component's mount, ignore it for now (that is, treat it as if it was an
5998 // event on a non-React tree). We might also consider queueing events and
5999 // dispatching them after the mount.
6000 targetInst = null;
6001 }
6002 }
6003 }
6004
6005 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer); // We're not blocked on anything.
6006
6007 return null;
6008}
6009
6010function addEventBubbleListener(target, eventType, listener) {
6011 target.addEventListener(eventType, listener, false);
6012 return listener;
6013}
6014function addEventCaptureListener(target, eventType, listener) {
6015 target.addEventListener(eventType, listener, true);
6016 return listener;
6017}
6018function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6019 target.addEventListener(eventType, listener, {
6020 capture: true,
6021 passive: passive
6022 });
6023 return listener;
6024}
6025function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6026 target.addEventListener(eventType, listener, {
6027 passive: passive
6028 });
6029 return listener;
6030}
6031
6032/**
6033 * These variables store information about text content of a target node,
6034 * allowing comparison of content before and after a given event.
6035 *
6036 * Identify the node where selection currently begins, then observe
6037 * both its text content and its current position in the DOM. Since the
6038 * browser may natively replace the target node during composition, we can
6039 * use its position to find its replacement.
6040 *
6041 *
6042 */
6043var root = null;
6044var startText = null;
6045var fallbackText = null;
6046function initialize(nativeEventTarget) {
6047 root = nativeEventTarget;
6048 startText = getText();
6049 return true;
6050}
6051function reset() {
6052 root = null;
6053 startText = null;
6054 fallbackText = null;
6055}
6056function getData() {
6057 if (fallbackText) {
6058 return fallbackText;
6059 }
6060
6061 var start;
6062 var startValue = startText;
6063 var startLength = startValue.length;
6064 var end;
6065 var endValue = getText();
6066 var endLength = endValue.length;
6067
6068 for (start = 0; start < startLength; start++) {
6069 if (startValue[start] !== endValue[start]) {
6070 break;
6071 }
6072 }
6073
6074 var minEnd = startLength - start;
6075
6076 for (end = 1; end <= minEnd; end++) {
6077 if (startValue[startLength - end] !== endValue[endLength - end]) {
6078 break;
6079 }
6080 }
6081
6082 var sliceTail = end > 1 ? 1 - end : undefined;
6083 fallbackText = endValue.slice(start, sliceTail);
6084 return fallbackText;
6085}
6086function getText() {
6087 if ('value' in root) {
6088 return root.value;
6089 }
6090
6091 return root.textContent;
6092}
6093
6094/**
6095 * `charCode` represents the actual "character code" and is safe to use with
6096 * `String.fromCharCode`. As such, only keys that correspond to printable
6097 * characters produce a valid `charCode`, the only exception to this is Enter.
6098 * The Tab-key is considered non-printable and does not have a `charCode`,
6099 * presumably because it does not produce a tab-character in browsers.
6100 *
6101 * @param {object} nativeEvent Native browser event.
6102 * @return {number} Normalized `charCode` property.
6103 */
6104function getEventCharCode(nativeEvent) {
6105 var charCode;
6106 var keyCode = nativeEvent.keyCode;
6107
6108 if ('charCode' in nativeEvent) {
6109 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6110
6111 if (charCode === 0 && keyCode === 13) {
6112 charCode = 13;
6113 }
6114 } else {
6115 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6116 charCode = keyCode;
6117 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6118 // report Enter as charCode 10 when ctrl is pressed.
6119
6120
6121 if (charCode === 10) {
6122 charCode = 13;
6123 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6124 // Must not discard the (non-)printable Enter-key.
6125
6126
6127 if (charCode >= 32 || charCode === 13) {
6128 return charCode;
6129 }
6130
6131 return 0;
6132}
6133
6134function functionThatReturnsTrue() {
6135 return true;
6136}
6137
6138function functionThatReturnsFalse() {
6139 return false;
6140} // This is intentionally a factory so that we have different returned constructors.
6141// If we had a single constructor, it would be megamorphic and engines would deopt.
6142
6143
6144function createSyntheticEvent(Interface) {
6145 /**
6146 * Synthetic events are dispatched by event plugins, typically in response to a
6147 * top-level event delegation handler.
6148 *
6149 * These systems should generally use pooling to reduce the frequency of garbage
6150 * collection. The system should check `isPersistent` to determine whether the
6151 * event should be released into the pool after being dispatched. Users that
6152 * need a persisted event should invoke `persist`.
6153 *
6154 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6155 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6156 * DOM interface; custom application-specific events can also subclass this.
6157 */
6158 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6159 this._reactName = reactName;
6160 this._targetInst = targetInst;
6161 this.type = reactEventType;
6162 this.nativeEvent = nativeEvent;
6163 this.target = nativeEventTarget;
6164 this.currentTarget = null;
6165
6166 for (var _propName in Interface) {
6167 if (!Interface.hasOwnProperty(_propName)) {
6168 continue;
6169 }
6170
6171 var normalize = Interface[_propName];
6172
6173 if (normalize) {
6174 this[_propName] = normalize(nativeEvent);
6175 } else {
6176 this[_propName] = nativeEvent[_propName];
6177 }
6178 }
6179
6180 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6181
6182 if (defaultPrevented) {
6183 this.isDefaultPrevented = functionThatReturnsTrue;
6184 } else {
6185 this.isDefaultPrevented = functionThatReturnsFalse;
6186 }
6187
6188 this.isPropagationStopped = functionThatReturnsFalse;
6189 return this;
6190 }
6191
6192 _assign(SyntheticBaseEvent.prototype, {
6193 preventDefault: function () {
6194 this.defaultPrevented = true;
6195 var event = this.nativeEvent;
6196
6197 if (!event) {
6198 return;
6199 }
6200
6201 if (event.preventDefault) {
6202 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6203 } else if (typeof event.returnValue !== 'unknown') {
6204 event.returnValue = false;
6205 }
6206
6207 this.isDefaultPrevented = functionThatReturnsTrue;
6208 },
6209 stopPropagation: function () {
6210 var event = this.nativeEvent;
6211
6212 if (!event) {
6213 return;
6214 }
6215
6216 if (event.stopPropagation) {
6217 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6218 } else if (typeof event.cancelBubble !== 'unknown') {
6219 // The ChangeEventPlugin registers a "propertychange" event for
6220 // IE. This event does not support bubbling or cancelling, and
6221 // any references to cancelBubble throw "Member not found". A
6222 // typeof check of "unknown" circumvents this issue (and is also
6223 // IE specific).
6224 event.cancelBubble = true;
6225 }
6226
6227 this.isPropagationStopped = functionThatReturnsTrue;
6228 },
6229
6230 /**
6231 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6232 * them back into the pool. This allows a way to hold onto a reference that
6233 * won't be added back into the pool.
6234 */
6235 persist: function () {// Modern event system doesn't use pooling.
6236 },
6237
6238 /**
6239 * Checks if this event should be released back into the pool.
6240 *
6241 * @return {boolean} True if this should not be released, false otherwise.
6242 */
6243 isPersistent: functionThatReturnsTrue
6244 });
6245
6246 return SyntheticBaseEvent;
6247}
6248/**
6249 * @interface Event
6250 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6251 */
6252
6253
6254var EventInterface = {
6255 eventPhase: 0,
6256 bubbles: 0,
6257 cancelable: 0,
6258 timeStamp: function (event) {
6259 return event.timeStamp || Date.now();
6260 },
6261 defaultPrevented: 0,
6262 isTrusted: 0
6263};
6264var SyntheticEvent = createSyntheticEvent(EventInterface);
6265
6266var UIEventInterface = _assign({}, EventInterface, {
6267 view: 0,
6268 detail: 0
6269});
6270
6271var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6272var lastMovementX;
6273var lastMovementY;
6274var lastMouseEvent;
6275
6276function updateMouseMovementPolyfillState(event) {
6277 if (event !== lastMouseEvent) {
6278 if (lastMouseEvent && event.type === 'mousemove') {
6279 lastMovementX = event.screenX - lastMouseEvent.screenX;
6280 lastMovementY = event.screenY - lastMouseEvent.screenY;
6281 } else {
6282 lastMovementX = 0;
6283 lastMovementY = 0;
6284 }
6285
6286 lastMouseEvent = event;
6287 }
6288}
6289/**
6290 * @interface MouseEvent
6291 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6292 */
6293
6294
6295var MouseEventInterface = _assign({}, UIEventInterface, {
6296 screenX: 0,
6297 screenY: 0,
6298 clientX: 0,
6299 clientY: 0,
6300 pageX: 0,
6301 pageY: 0,
6302 ctrlKey: 0,
6303 shiftKey: 0,
6304 altKey: 0,
6305 metaKey: 0,
6306 getModifierState: getEventModifierState,
6307 button: 0,
6308 buttons: 0,
6309 relatedTarget: function (event) {
6310 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6311 return event.relatedTarget;
6312 },
6313 movementX: function (event) {
6314 if ('movementX' in event) {
6315 return event.movementX;
6316 }
6317
6318 updateMouseMovementPolyfillState(event);
6319 return lastMovementX;
6320 },
6321 movementY: function (event) {
6322 if ('movementY' in event) {
6323 return event.movementY;
6324 } // Don't need to call updateMouseMovementPolyfillState() here
6325 // because it's guaranteed to have already run when movementX
6326 // was copied.
6327
6328
6329 return lastMovementY;
6330 }
6331});
6332
6333var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
6334/**
6335 * @interface DragEvent
6336 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6337 */
6338
6339var DragEventInterface = _assign({}, MouseEventInterface, {
6340 dataTransfer: 0
6341});
6342
6343var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
6344/**
6345 * @interface FocusEvent
6346 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6347 */
6348
6349var FocusEventInterface = _assign({}, UIEventInterface, {
6350 relatedTarget: 0
6351});
6352
6353var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
6354/**
6355 * @interface Event
6356 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
6357 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
6358 */
6359
6360var AnimationEventInterface = _assign({}, EventInterface, {
6361 animationName: 0,
6362 elapsedTime: 0,
6363 pseudoElement: 0
6364});
6365
6366var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
6367/**
6368 * @interface Event
6369 * @see http://www.w3.org/TR/clipboard-apis/
6370 */
6371
6372var ClipboardEventInterface = _assign({}, EventInterface, {
6373 clipboardData: function (event) {
6374 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
6375 }
6376});
6377
6378var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
6379/**
6380 * @interface Event
6381 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
6382 */
6383
6384var CompositionEventInterface = _assign({}, EventInterface, {
6385 data: 0
6386});
6387
6388var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
6389/**
6390 * @interface Event
6391 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
6392 * /#events-inputevents
6393 */
6394// Happens to share the same list for now.
6395
6396var SyntheticInputEvent = SyntheticCompositionEvent;
6397/**
6398 * Normalization of deprecated HTML5 `key` values
6399 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6400 */
6401
6402var normalizeKey = {
6403 Esc: 'Escape',
6404 Spacebar: ' ',
6405 Left: 'ArrowLeft',
6406 Up: 'ArrowUp',
6407 Right: 'ArrowRight',
6408 Down: 'ArrowDown',
6409 Del: 'Delete',
6410 Win: 'OS',
6411 Menu: 'ContextMenu',
6412 Apps: 'ContextMenu',
6413 Scroll: 'ScrollLock',
6414 MozPrintableKey: 'Unidentified'
6415};
6416/**
6417 * Translation from legacy `keyCode` to HTML5 `key`
6418 * Only special keys supported, all others depend on keyboard layout or browser
6419 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
6420 */
6421
6422var translateToKey = {
6423 '8': 'Backspace',
6424 '9': 'Tab',
6425 '12': 'Clear',
6426 '13': 'Enter',
6427 '16': 'Shift',
6428 '17': 'Control',
6429 '18': 'Alt',
6430 '19': 'Pause',
6431 '20': 'CapsLock',
6432 '27': 'Escape',
6433 '32': ' ',
6434 '33': 'PageUp',
6435 '34': 'PageDown',
6436 '35': 'End',
6437 '36': 'Home',
6438 '37': 'ArrowLeft',
6439 '38': 'ArrowUp',
6440 '39': 'ArrowRight',
6441 '40': 'ArrowDown',
6442 '45': 'Insert',
6443 '46': 'Delete',
6444 '112': 'F1',
6445 '113': 'F2',
6446 '114': 'F3',
6447 '115': 'F4',
6448 '116': 'F5',
6449 '117': 'F6',
6450 '118': 'F7',
6451 '119': 'F8',
6452 '120': 'F9',
6453 '121': 'F10',
6454 '122': 'F11',
6455 '123': 'F12',
6456 '144': 'NumLock',
6457 '145': 'ScrollLock',
6458 '224': 'Meta'
6459};
6460/**
6461 * @param {object} nativeEvent Native browser event.
6462 * @return {string} Normalized `key` property.
6463 */
6464
6465function getEventKey(nativeEvent) {
6466 if (nativeEvent.key) {
6467 // Normalize inconsistent values reported by browsers due to
6468 // implementations of a working draft specification.
6469 // FireFox implements `key` but returns `MozPrintableKey` for all
6470 // printable characters (normalized to `Unidentified`), ignore it.
6471 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
6472
6473 if (key !== 'Unidentified') {
6474 return key;
6475 }
6476 } // Browser does not implement `key`, polyfill as much of it as we can.
6477
6478
6479 if (nativeEvent.type === 'keypress') {
6480 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
6481 // thus be captured by `keypress`, no other non-printable key should.
6482
6483 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
6484 }
6485
6486 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
6487 // While user keyboard layout determines the actual meaning of each
6488 // `keyCode` value, almost all function keys have a universal value.
6489 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
6490 }
6491
6492 return '';
6493}
6494/**
6495 * Translation from modifier key to the associated property in the event.
6496 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
6497 */
6498
6499
6500var modifierKeyToProp = {
6501 Alt: 'altKey',
6502 Control: 'ctrlKey',
6503 Meta: 'metaKey',
6504 Shift: 'shiftKey'
6505}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
6506// getModifierState. If getModifierState is not supported, we map it to a set of
6507// modifier keys exposed by the event. In this case, Lock-keys are not supported.
6508
6509function modifierStateGetter(keyArg) {
6510 var syntheticEvent = this;
6511 var nativeEvent = syntheticEvent.nativeEvent;
6512
6513 if (nativeEvent.getModifierState) {
6514 return nativeEvent.getModifierState(keyArg);
6515 }
6516
6517 var keyProp = modifierKeyToProp[keyArg];
6518 return keyProp ? !!nativeEvent[keyProp] : false;
6519}
6520
6521function getEventModifierState(nativeEvent) {
6522 return modifierStateGetter;
6523}
6524/**
6525 * @interface KeyboardEvent
6526 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6527 */
6528
6529
6530var KeyboardEventInterface = _assign({}, UIEventInterface, {
6531 key: getEventKey,
6532 code: 0,
6533 location: 0,
6534 ctrlKey: 0,
6535 shiftKey: 0,
6536 altKey: 0,
6537 metaKey: 0,
6538 repeat: 0,
6539 locale: 0,
6540 getModifierState: getEventModifierState,
6541 // Legacy Interface
6542 charCode: function (event) {
6543 // `charCode` is the result of a KeyPress event and represents the value of
6544 // the actual printable character.
6545 // KeyPress is deprecated, but its replacement is not yet final and not
6546 // implemented in any major browser. Only KeyPress has charCode.
6547 if (event.type === 'keypress') {
6548 return getEventCharCode(event);
6549 }
6550
6551 return 0;
6552 },
6553 keyCode: function (event) {
6554 // `keyCode` is the result of a KeyDown/Up event and represents the value of
6555 // physical keyboard key.
6556 // The actual meaning of the value depends on the users' keyboard layout
6557 // which cannot be detected. Assuming that it is a US keyboard layout
6558 // provides a surprisingly accurate mapping for US and European users.
6559 // Due to this, it is left to the user to implement at this time.
6560 if (event.type === 'keydown' || event.type === 'keyup') {
6561 return event.keyCode;
6562 }
6563
6564 return 0;
6565 },
6566 which: function (event) {
6567 // `which` is an alias for either `keyCode` or `charCode` depending on the
6568 // type of the event.
6569 if (event.type === 'keypress') {
6570 return getEventCharCode(event);
6571 }
6572
6573 if (event.type === 'keydown' || event.type === 'keyup') {
6574 return event.keyCode;
6575 }
6576
6577 return 0;
6578 }
6579});
6580
6581var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
6582/**
6583 * @interface PointerEvent
6584 * @see http://www.w3.org/TR/pointerevents/
6585 */
6586
6587var PointerEventInterface = _assign({}, MouseEventInterface, {
6588 pointerId: 0,
6589 width: 0,
6590 height: 0,
6591 pressure: 0,
6592 tangentialPressure: 0,
6593 tiltX: 0,
6594 tiltY: 0,
6595 twist: 0,
6596 pointerType: 0,
6597 isPrimary: 0
6598});
6599
6600var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
6601/**
6602 * @interface TouchEvent
6603 * @see http://www.w3.org/TR/touch-events/
6604 */
6605
6606var TouchEventInterface = _assign({}, UIEventInterface, {
6607 touches: 0,
6608 targetTouches: 0,
6609 changedTouches: 0,
6610 altKey: 0,
6611 metaKey: 0,
6612 ctrlKey: 0,
6613 shiftKey: 0,
6614 getModifierState: getEventModifierState
6615});
6616
6617var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
6618/**
6619 * @interface Event
6620 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
6621 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
6622 */
6623
6624var TransitionEventInterface = _assign({}, EventInterface, {
6625 propertyName: 0,
6626 elapsedTime: 0,
6627 pseudoElement: 0
6628});
6629
6630var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
6631/**
6632 * @interface WheelEvent
6633 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6634 */
6635
6636var WheelEventInterface = _assign({}, MouseEventInterface, {
6637 deltaX: function (event) {
6638 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
6639 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
6640 },
6641 deltaY: function (event) {
6642 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
6643 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
6644 'wheelDelta' in event ? -event.wheelDelta : 0;
6645 },
6646 deltaZ: 0,
6647 // Browsers without "deltaMode" is reporting in raw wheel delta where one
6648 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
6649 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
6650 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
6651 deltaMode: 0
6652});
6653
6654var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
6655
6656var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
6657
6658var START_KEYCODE = 229;
6659var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
6660var documentMode = null;
6661
6662if (canUseDOM && 'documentMode' in document) {
6663 documentMode = document.documentMode;
6664} // Webkit offers a very useful `textInput` event that can be used to
6665// directly represent `beforeInput`. The IE `textinput` event is not as
6666// useful, so we don't use it.
6667
6668
6669var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
6670// by the native compositionend event may be incorrect. Japanese ideographic
6671// spaces, for instance (\u3000) are not recorded correctly.
6672
6673var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
6674var SPACEBAR_CODE = 32;
6675var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
6676
6677function registerEvents() {
6678 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
6679 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6680 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6681 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
6682} // Track whether we've ever handled a keypress on the space key.
6683
6684
6685var hasSpaceKeypress = false;
6686/**
6687 * Return whether a native keypress event is assumed to be a command.
6688 * This is required because Firefox fires `keypress` events for key commands
6689 * (cut, copy, select-all, etc.) even though no character is inserted.
6690 */
6691
6692function isKeypressCommand(nativeEvent) {
6693 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
6694 !(nativeEvent.ctrlKey && nativeEvent.altKey);
6695}
6696/**
6697 * Translate native top level events into event types.
6698 */
6699
6700
6701function getCompositionEventType(domEventName) {
6702 switch (domEventName) {
6703 case 'compositionstart':
6704 return 'onCompositionStart';
6705
6706 case 'compositionend':
6707 return 'onCompositionEnd';
6708
6709 case 'compositionupdate':
6710 return 'onCompositionUpdate';
6711 }
6712}
6713/**
6714 * Does our fallback best-guess model think this event signifies that
6715 * composition has begun?
6716 */
6717
6718
6719function isFallbackCompositionStart(domEventName, nativeEvent) {
6720 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
6721}
6722/**
6723 * Does our fallback mode think that this event is the end of composition?
6724 */
6725
6726
6727function isFallbackCompositionEnd(domEventName, nativeEvent) {
6728 switch (domEventName) {
6729 case 'keyup':
6730 // Command keys insert or clear IME input.
6731 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
6732
6733 case 'keydown':
6734 // Expect IME keyCode on each keydown. If we get any other
6735 // code we must have exited earlier.
6736 return nativeEvent.keyCode !== START_KEYCODE;
6737
6738 case 'keypress':
6739 case 'mousedown':
6740 case 'focusout':
6741 // Events are not possible without cancelling IME.
6742 return true;
6743
6744 default:
6745 return false;
6746 }
6747}
6748/**
6749 * Google Input Tools provides composition data via a CustomEvent,
6750 * with the `data` property populated in the `detail` object. If this
6751 * is available on the event object, use it. If not, this is a plain
6752 * composition event and we have nothing special to extract.
6753 *
6754 * @param {object} nativeEvent
6755 * @return {?string}
6756 */
6757
6758
6759function getDataFromCustomEvent(nativeEvent) {
6760 var detail = nativeEvent.detail;
6761
6762 if (typeof detail === 'object' && 'data' in detail) {
6763 return detail.data;
6764 }
6765
6766 return null;
6767}
6768/**
6769 * Check if a composition event was triggered by Korean IME.
6770 * Our fallback mode does not work well with IE's Korean IME,
6771 * so just use native composition events when Korean IME is used.
6772 * Although CompositionEvent.locale property is deprecated,
6773 * it is available in IE, where our fallback mode is enabled.
6774 *
6775 * @param {object} nativeEvent
6776 * @return {boolean}
6777 */
6778
6779
6780function isUsingKoreanIME(nativeEvent) {
6781 return nativeEvent.locale === 'ko';
6782} // Track the current IME composition status, if any.
6783
6784
6785var isComposing = false;
6786/**
6787 * @return {?object} A SyntheticCompositionEvent.
6788 */
6789
6790function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
6791 var eventType;
6792 var fallbackData;
6793
6794 if (canUseCompositionEvent) {
6795 eventType = getCompositionEventType(domEventName);
6796 } else if (!isComposing) {
6797 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
6798 eventType = 'onCompositionStart';
6799 }
6800 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
6801 eventType = 'onCompositionEnd';
6802 }
6803
6804 if (!eventType) {
6805 return null;
6806 }
6807
6808 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
6809 // The current composition is stored statically and must not be
6810 // overwritten while composition continues.
6811 if (!isComposing && eventType === 'onCompositionStart') {
6812 isComposing = initialize(nativeEventTarget);
6813 } else if (eventType === 'onCompositionEnd') {
6814 if (isComposing) {
6815 fallbackData = getData();
6816 }
6817 }
6818 }
6819
6820 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
6821
6822 if (listeners.length > 0) {
6823 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
6824 dispatchQueue.push({
6825 event: event,
6826 listeners: listeners
6827 });
6828
6829 if (fallbackData) {
6830 // Inject data generated from fallback path into the synthetic event.
6831 // This matches the property of native CompositionEventInterface.
6832 event.data = fallbackData;
6833 } else {
6834 var customData = getDataFromCustomEvent(nativeEvent);
6835
6836 if (customData !== null) {
6837 event.data = customData;
6838 }
6839 }
6840 }
6841}
6842
6843function getNativeBeforeInputChars(domEventName, nativeEvent) {
6844 switch (domEventName) {
6845 case 'compositionend':
6846 return getDataFromCustomEvent(nativeEvent);
6847
6848 case 'keypress':
6849 /**
6850 * If native `textInput` events are available, our goal is to make
6851 * use of them. However, there is a special case: the spacebar key.
6852 * In Webkit, preventing default on a spacebar `textInput` event
6853 * cancels character insertion, but it *also* causes the browser
6854 * to fall back to its default spacebar behavior of scrolling the
6855 * page.
6856 *
6857 * Tracking at:
6858 * https://code.google.com/p/chromium/issues/detail?id=355103
6859 *
6860 * To avoid this issue, use the keypress event as if no `textInput`
6861 * event is available.
6862 */
6863 var which = nativeEvent.which;
6864
6865 if (which !== SPACEBAR_CODE) {
6866 return null;
6867 }
6868
6869 hasSpaceKeypress = true;
6870 return SPACEBAR_CHAR;
6871
6872 case 'textInput':
6873 // Record the characters to be added to the DOM.
6874 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
6875 // it at the keypress level and bail immediately. Android Chrome
6876 // doesn't give us keycodes, so we need to ignore it.
6877
6878 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
6879 return null;
6880 }
6881
6882 return chars;
6883
6884 default:
6885 // For other native event types, do nothing.
6886 return null;
6887 }
6888}
6889/**
6890 * For browsers that do not provide the `textInput` event, extract the
6891 * appropriate string to use for SyntheticInputEvent.
6892 */
6893
6894
6895function getFallbackBeforeInputChars(domEventName, nativeEvent) {
6896 // If we are currently composing (IME) and using a fallback to do so,
6897 // try to extract the composed characters from the fallback object.
6898 // If composition event is available, we extract a string only at
6899 // compositionevent, otherwise extract it at fallback events.
6900 if (isComposing) {
6901 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
6902 var chars = getData();
6903 reset();
6904 isComposing = false;
6905 return chars;
6906 }
6907
6908 return null;
6909 }
6910
6911 switch (domEventName) {
6912 case 'paste':
6913 // If a paste event occurs after a keypress, throw out the input
6914 // chars. Paste events should not lead to BeforeInput events.
6915 return null;
6916
6917 case 'keypress':
6918 /**
6919 * As of v27, Firefox may fire keypress events even when no character
6920 * will be inserted. A few possibilities:
6921 *
6922 * - `which` is `0`. Arrow keys, Esc key, etc.
6923 *
6924 * - `which` is the pressed key code, but no char is available.
6925 * Ex: 'AltGr + d` in Polish. There is no modified character for
6926 * this key combination and no character is inserted into the
6927 * document, but FF fires the keypress for char code `100` anyway.
6928 * No `input` event will occur.
6929 *
6930 * - `which` is the pressed key code, but a command combination is
6931 * being used. Ex: `Cmd+C`. No character is inserted, and no
6932 * `input` event will occur.
6933 */
6934 if (!isKeypressCommand(nativeEvent)) {
6935 // IE fires the `keypress` event when a user types an emoji via
6936 // Touch keyboard of Windows. In such a case, the `char` property
6937 // holds an emoji character like `\uD83D\uDE0A`. Because its length
6938 // is 2, the property `which` does not represent an emoji correctly.
6939 // In such a case, we directly return the `char` property instead of
6940 // using `which`.
6941 if (nativeEvent.char && nativeEvent.char.length > 1) {
6942 return nativeEvent.char;
6943 } else if (nativeEvent.which) {
6944 return String.fromCharCode(nativeEvent.which);
6945 }
6946 }
6947
6948 return null;
6949
6950 case 'compositionend':
6951 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
6952
6953 default:
6954 return null;
6955 }
6956}
6957/**
6958 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
6959 * `textInput` or fallback behavior.
6960 *
6961 * @return {?object} A SyntheticInputEvent.
6962 */
6963
6964
6965function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
6966 var chars;
6967
6968 if (canUseTextInputEvent) {
6969 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
6970 } else {
6971 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
6972 } // If no characters are being inserted, no BeforeInput event should
6973 // be fired.
6974
6975
6976 if (!chars) {
6977 return null;
6978 }
6979
6980 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
6981
6982 if (listeners.length > 0) {
6983 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
6984 dispatchQueue.push({
6985 event: event,
6986 listeners: listeners
6987 });
6988 event.data = chars;
6989 }
6990}
6991/**
6992 * Create an `onBeforeInput` event to match
6993 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
6994 *
6995 * This event plugin is based on the native `textInput` event
6996 * available in Chrome, Safari, Opera, and IE. This event fires after
6997 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
6998 *
6999 * `beforeInput` is spec'd but not implemented in any browsers, and
7000 * the `input` event does not provide any useful information about what has
7001 * actually been added, contrary to the spec. Thus, `textInput` is the best
7002 * available event to identify the characters that have actually been inserted
7003 * into the target node.
7004 *
7005 * This plugin is also responsible for emitting `composition` events, thus
7006 * allowing us to share composition fallback code for both `beforeInput` and
7007 * `composition` event types.
7008 */
7009
7010
7011function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7012 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7013 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7014}
7015
7016/**
7017 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7018 */
7019var supportedInputTypes = {
7020 color: true,
7021 date: true,
7022 datetime: true,
7023 'datetime-local': true,
7024 email: true,
7025 month: true,
7026 number: true,
7027 password: true,
7028 range: true,
7029 search: true,
7030 tel: true,
7031 text: true,
7032 time: true,
7033 url: true,
7034 week: true
7035};
7036
7037function isTextInputElement(elem) {
7038 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7039
7040 if (nodeName === 'input') {
7041 return !!supportedInputTypes[elem.type];
7042 }
7043
7044 if (nodeName === 'textarea') {
7045 return true;
7046 }
7047
7048 return false;
7049}
7050
7051/**
7052 * Checks if an event is supported in the current execution environment.
7053 *
7054 * NOTE: This will not work correctly for non-generic events such as `change`,
7055 * `reset`, `load`, `error`, and `select`.
7056 *
7057 * Borrows from Modernizr.
7058 *
7059 * @param {string} eventNameSuffix Event name, e.g. "click".
7060 * @return {boolean} True if the event is supported.
7061 * @internal
7062 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7063 */
7064
7065function isEventSupported(eventNameSuffix) {
7066 if (!canUseDOM) {
7067 return false;
7068 }
7069
7070 var eventName = 'on' + eventNameSuffix;
7071 var isSupported = (eventName in document);
7072
7073 if (!isSupported) {
7074 var element = document.createElement('div');
7075 element.setAttribute(eventName, 'return;');
7076 isSupported = typeof element[eventName] === 'function';
7077 }
7078
7079 return isSupported;
7080}
7081
7082function registerEvents$1() {
7083 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7084}
7085
7086function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7087 // Flag this event loop as needing state restore.
7088 enqueueStateRestore(target);
7089 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7090
7091 if (listeners.length > 0) {
7092 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7093 dispatchQueue.push({
7094 event: event,
7095 listeners: listeners
7096 });
7097 }
7098}
7099/**
7100 * For IE shims
7101 */
7102
7103
7104var activeElement = null;
7105var activeElementInst = null;
7106/**
7107 * SECTION: handle `change` event
7108 */
7109
7110function shouldUseChangeEvent(elem) {
7111 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7112 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7113}
7114
7115function manualDispatchChangeEvent(nativeEvent) {
7116 var dispatchQueue = [];
7117 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7118 // other events and have it go through ReactBrowserEventEmitter. Since it
7119 // doesn't, we manually listen for the events and so we have to enqueue and
7120 // process the abstract event manually.
7121 //
7122 // Batching is necessary here in order to ensure that all event handlers run
7123 // before the next rerender (including event handlers attached to ancestor
7124 // elements instead of directly on the input). Without this, controlled
7125 // components don't work properly in conjunction with event bubbling because
7126 // the component is rerendered and the value reverted before all the event
7127 // handlers can run. See https://github.com/facebook/react/issues/708.
7128
7129 batchedUpdates(runEventInBatch, dispatchQueue);
7130}
7131
7132function runEventInBatch(dispatchQueue) {
7133 processDispatchQueue(dispatchQueue, 0);
7134}
7135
7136function getInstIfValueChanged(targetInst) {
7137 var targetNode = getNodeFromInstance(targetInst);
7138
7139 if (updateValueIfChanged(targetNode)) {
7140 return targetInst;
7141 }
7142}
7143
7144function getTargetInstForChangeEvent(domEventName, targetInst) {
7145 if (domEventName === 'change') {
7146 return targetInst;
7147 }
7148}
7149/**
7150 * SECTION: handle `input` event
7151 */
7152
7153
7154var isInputEventSupported = false;
7155
7156if (canUseDOM) {
7157 // IE9 claims to support the input event but fails to trigger it when
7158 // deleting text, so we ignore its input events.
7159 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7160}
7161/**
7162 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7163 * and override the value property so that we can distinguish user events from
7164 * value changes in JS.
7165 */
7166
7167
7168function startWatchingForValueChange(target, targetInst) {
7169 activeElement = target;
7170 activeElementInst = targetInst;
7171 activeElement.attachEvent('onpropertychange', handlePropertyChange);
7172}
7173/**
7174 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7175 * if any exists.
7176 */
7177
7178
7179function stopWatchingForValueChange() {
7180 if (!activeElement) {
7181 return;
7182 }
7183
7184 activeElement.detachEvent('onpropertychange', handlePropertyChange);
7185 activeElement = null;
7186 activeElementInst = null;
7187}
7188/**
7189 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7190 * the value of the active element has changed.
7191 */
7192
7193
7194function handlePropertyChange(nativeEvent) {
7195 if (nativeEvent.propertyName !== 'value') {
7196 return;
7197 }
7198
7199 if (getInstIfValueChanged(activeElementInst)) {
7200 manualDispatchChangeEvent(nativeEvent);
7201 }
7202}
7203
7204function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7205 if (domEventName === 'focusin') {
7206 // In IE9, propertychange fires for most input events but is buggy and
7207 // doesn't fire when text is deleted, but conveniently, selectionchange
7208 // appears to fire in all of the remaining cases so we catch those and
7209 // forward the event if the value has changed
7210 // In either case, we don't want to call the event handler if the value
7211 // is changed from JS so we redefine a setter for `.value` that updates
7212 // our activeElementValue variable, allowing us to ignore those changes
7213 //
7214 // stopWatching() should be a noop here but we call it just in case we
7215 // missed a blur event somehow.
7216 stopWatchingForValueChange();
7217 startWatchingForValueChange(target, targetInst);
7218 } else if (domEventName === 'focusout') {
7219 stopWatchingForValueChange();
7220 }
7221} // For IE8 and IE9.
7222
7223
7224function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7225 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7226 // On the selectionchange event, the target is just document which isn't
7227 // helpful for us so just check activeElement instead.
7228 //
7229 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7230 // propertychange on the first input event after setting `value` from a
7231 // script and fires only keydown, keypress, keyup. Catching keyup usually
7232 // gets it and catching keydown lets us fire an event for the first
7233 // keystroke if user does a key repeat (it'll be a little delayed: right
7234 // before the second keystroke). Other input methods (e.g., paste) seem to
7235 // fire selectionchange normally.
7236 return getInstIfValueChanged(activeElementInst);
7237 }
7238}
7239/**
7240 * SECTION: handle `click` event
7241 */
7242
7243
7244function shouldUseClickEvent(elem) {
7245 // Use the `click` event to detect changes to checkbox and radio inputs.
7246 // This approach works across all browsers, whereas `change` does not fire
7247 // until `blur` in IE8.
7248 var nodeName = elem.nodeName;
7249 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7250}
7251
7252function getTargetInstForClickEvent(domEventName, targetInst) {
7253 if (domEventName === 'click') {
7254 return getInstIfValueChanged(targetInst);
7255 }
7256}
7257
7258function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7259 if (domEventName === 'input' || domEventName === 'change') {
7260 return getInstIfValueChanged(targetInst);
7261 }
7262}
7263
7264function handleControlledInputBlur(node) {
7265 var state = node._wrapperState;
7266
7267 if (!state || !state.controlled || node.type !== 'number') {
7268 return;
7269 }
7270
7271 {
7272 // If controlled, assign the value attribute to the current value on blur
7273 setDefaultValue(node, 'number', node.value);
7274 }
7275}
7276/**
7277 * This plugin creates an `onChange` event that normalizes change events
7278 * across form elements. This event fires at a time when it's possible to
7279 * change the element's value without seeing a flicker.
7280 *
7281 * Supported elements are:
7282 * - input (see `isTextInputElement`)
7283 * - textarea
7284 * - select
7285 */
7286
7287
7288function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7289 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7290 var getTargetInstFunc, handleEventFunc;
7291
7292 if (shouldUseChangeEvent(targetNode)) {
7293 getTargetInstFunc = getTargetInstForChangeEvent;
7294 } else if (isTextInputElement(targetNode)) {
7295 if (isInputEventSupported) {
7296 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7297 } else {
7298 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7299 handleEventFunc = handleEventsForInputEventPolyfill;
7300 }
7301 } else if (shouldUseClickEvent(targetNode)) {
7302 getTargetInstFunc = getTargetInstForClickEvent;
7303 }
7304
7305 if (getTargetInstFunc) {
7306 var inst = getTargetInstFunc(domEventName, targetInst);
7307
7308 if (inst) {
7309 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7310 return;
7311 }
7312 }
7313
7314 if (handleEventFunc) {
7315 handleEventFunc(domEventName, targetNode, targetInst);
7316 } // When blurring, set the value attribute for number inputs
7317
7318
7319 if (domEventName === 'focusout') {
7320 handleControlledInputBlur(targetNode);
7321 }
7322}
7323
7324function registerEvents$2() {
7325 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
7326 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
7327 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
7328 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
7329}
7330/**
7331 * For almost every interaction we care about, there will be both a top-level
7332 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
7333 * we do not extract duplicate events. However, moving the mouse into the
7334 * browser from outside will not fire a `mouseout` event. In this case, we use
7335 * the `mouseover` top-level event.
7336 */
7337
7338
7339function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7340 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
7341 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
7342
7343 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0) {
7344 // If this is an over event with a target, we might have already dispatched
7345 // the event in the out event of the other target. If this is replayed,
7346 // then it's because we couldn't dispatch against this target previously
7347 // so we have to do it now instead.
7348 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
7349
7350 if (related) {
7351 // If the related node is managed by React, we can assume that we have
7352 // already dispatched the corresponding events during its mouseout.
7353 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
7354 return;
7355 }
7356 }
7357 }
7358
7359 if (!isOutEvent && !isOverEvent) {
7360 // Must not be a mouse or pointer in or out - ignoring.
7361 return;
7362 }
7363
7364 var win; // TODO: why is this nullable in the types but we read from it?
7365
7366 if (nativeEventTarget.window === nativeEventTarget) {
7367 // `nativeEventTarget` is probably a window object.
7368 win = nativeEventTarget;
7369 } else {
7370 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
7371 var doc = nativeEventTarget.ownerDocument;
7372
7373 if (doc) {
7374 win = doc.defaultView || doc.parentWindow;
7375 } else {
7376 win = window;
7377 }
7378 }
7379
7380 var from;
7381 var to;
7382
7383 if (isOutEvent) {
7384 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
7385
7386 from = targetInst;
7387 to = _related ? getClosestInstanceFromNode(_related) : null;
7388
7389 if (to !== null) {
7390 var nearestMounted = getNearestMountedFiber(to);
7391
7392 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
7393 to = null;
7394 }
7395 }
7396 } else {
7397 // Moving to a node from outside the window.
7398 from = null;
7399 to = targetInst;
7400 }
7401
7402 if (from === to) {
7403 // Nothing pertains to our managed components.
7404 return;
7405 }
7406
7407 var SyntheticEventCtor = SyntheticMouseEvent;
7408 var leaveEventType = 'onMouseLeave';
7409 var enterEventType = 'onMouseEnter';
7410 var eventTypePrefix = 'mouse';
7411
7412 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
7413 SyntheticEventCtor = SyntheticPointerEvent;
7414 leaveEventType = 'onPointerLeave';
7415 enterEventType = 'onPointerEnter';
7416 eventTypePrefix = 'pointer';
7417 }
7418
7419 var fromNode = from == null ? win : getNodeFromInstance(from);
7420 var toNode = to == null ? win : getNodeFromInstance(to);
7421 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
7422 leave.target = fromNode;
7423 leave.relatedTarget = toNode;
7424 var enter = null; // We should only process this nativeEvent if we are processing
7425 // the first ancestor. Next time, we will ignore the event.
7426
7427 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
7428
7429 if (nativeTargetInst === targetInst) {
7430 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
7431 enterEvent.target = toNode;
7432 enterEvent.relatedTarget = fromNode;
7433 enter = enterEvent;
7434 }
7435
7436 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
7437}
7438
7439/**
7440 * inlined Object.is polyfill to avoid requiring consumers ship their own
7441 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
7442 */
7443function is(x, y) {
7444 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
7445 ;
7446}
7447
7448var objectIs = typeof Object.is === 'function' ? Object.is : is;
7449
7450var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7451/**
7452 * Performs equality by iterating through keys on an object and returning false
7453 * when any key has values which are not strictly equal between the arguments.
7454 * Returns true when the values of all keys are strictly equal.
7455 */
7456
7457function shallowEqual(objA, objB) {
7458 if (objectIs(objA, objB)) {
7459 return true;
7460 }
7461
7462 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
7463 return false;
7464 }
7465
7466 var keysA = Object.keys(objA);
7467 var keysB = Object.keys(objB);
7468
7469 if (keysA.length !== keysB.length) {
7470 return false;
7471 } // Test for A's keys different from B.
7472
7473
7474 for (var i = 0; i < keysA.length; i++) {
7475 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
7476 return false;
7477 }
7478 }
7479
7480 return true;
7481}
7482
7483/**
7484 * Given any node return the first leaf node without children.
7485 *
7486 * @param {DOMElement|DOMTextNode} node
7487 * @return {DOMElement|DOMTextNode}
7488 */
7489
7490function getLeafNode(node) {
7491 while (node && node.firstChild) {
7492 node = node.firstChild;
7493 }
7494
7495 return node;
7496}
7497/**
7498 * Get the next sibling within a container. This will walk up the
7499 * DOM if a node's siblings have been exhausted.
7500 *
7501 * @param {DOMElement|DOMTextNode} node
7502 * @return {?DOMElement|DOMTextNode}
7503 */
7504
7505
7506function getSiblingNode(node) {
7507 while (node) {
7508 if (node.nextSibling) {
7509 return node.nextSibling;
7510 }
7511
7512 node = node.parentNode;
7513 }
7514}
7515/**
7516 * Get object describing the nodes which contain characters at offset.
7517 *
7518 * @param {DOMElement|DOMTextNode} root
7519 * @param {number} offset
7520 * @return {?object}
7521 */
7522
7523
7524function getNodeForCharacterOffset(root, offset) {
7525 var node = getLeafNode(root);
7526 var nodeStart = 0;
7527 var nodeEnd = 0;
7528
7529 while (node) {
7530 if (node.nodeType === TEXT_NODE) {
7531 nodeEnd = nodeStart + node.textContent.length;
7532
7533 if (nodeStart <= offset && nodeEnd >= offset) {
7534 return {
7535 node: node,
7536 offset: offset - nodeStart
7537 };
7538 }
7539
7540 nodeStart = nodeEnd;
7541 }
7542
7543 node = getLeafNode(getSiblingNode(node));
7544 }
7545}
7546
7547/**
7548 * @param {DOMElement} outerNode
7549 * @return {?object}
7550 */
7551
7552function getOffsets(outerNode) {
7553 var ownerDocument = outerNode.ownerDocument;
7554 var win = ownerDocument && ownerDocument.defaultView || window;
7555 var selection = win.getSelection && win.getSelection();
7556
7557 if (!selection || selection.rangeCount === 0) {
7558 return null;
7559 }
7560
7561 var anchorNode = selection.anchorNode,
7562 anchorOffset = selection.anchorOffset,
7563 focusNode = selection.focusNode,
7564 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
7565 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
7566 // expose properties, triggering a "Permission denied error" if any of its
7567 // properties are accessed. The only seemingly possible way to avoid erroring
7568 // is to access a property that typically works for non-anonymous divs and
7569 // catch any error that may otherwise arise. See
7570 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
7571
7572 try {
7573 /* eslint-disable no-unused-expressions */
7574 anchorNode.nodeType;
7575 focusNode.nodeType;
7576 /* eslint-enable no-unused-expressions */
7577 } catch (e) {
7578 return null;
7579 }
7580
7581 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
7582}
7583/**
7584 * Returns {start, end} where `start` is the character/codepoint index of
7585 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
7586 * `end` is the index of (focusNode, focusOffset).
7587 *
7588 * Returns null if you pass in garbage input but we should probably just crash.
7589 *
7590 * Exported only for testing.
7591 */
7592
7593function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
7594 var length = 0;
7595 var start = -1;
7596 var end = -1;
7597 var indexWithinAnchor = 0;
7598 var indexWithinFocus = 0;
7599 var node = outerNode;
7600 var parentNode = null;
7601
7602 outer: while (true) {
7603 var next = null;
7604
7605 while (true) {
7606 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
7607 start = length + anchorOffset;
7608 }
7609
7610 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
7611 end = length + focusOffset;
7612 }
7613
7614 if (node.nodeType === TEXT_NODE) {
7615 length += node.nodeValue.length;
7616 }
7617
7618 if ((next = node.firstChild) === null) {
7619 break;
7620 } // Moving from `node` to its first child `next`.
7621
7622
7623 parentNode = node;
7624 node = next;
7625 }
7626
7627 while (true) {
7628 if (node === outerNode) {
7629 // If `outerNode` has children, this is always the second time visiting
7630 // it. If it has no children, this is still the first loop, and the only
7631 // valid selection is anchorNode and focusNode both equal to this node
7632 // and both offsets 0, in which case we will have handled above.
7633 break outer;
7634 }
7635
7636 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
7637 start = length;
7638 }
7639
7640 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
7641 end = length;
7642 }
7643
7644 if ((next = node.nextSibling) !== null) {
7645 break;
7646 }
7647
7648 node = parentNode;
7649 parentNode = node.parentNode;
7650 } // Moving from `node` to its next sibling `next`.
7651
7652
7653 node = next;
7654 }
7655
7656 if (start === -1 || end === -1) {
7657 // This should never happen. (Would happen if the anchor/focus nodes aren't
7658 // actually inside the passed-in node.)
7659 return null;
7660 }
7661
7662 return {
7663 start: start,
7664 end: end
7665 };
7666}
7667/**
7668 * In modern non-IE browsers, we can support both forward and backward
7669 * selections.
7670 *
7671 * Note: IE10+ supports the Selection object, but it does not support
7672 * the `extend` method, which means that even in modern IE, it's not possible
7673 * to programmatically create a backward selection. Thus, for all IE
7674 * versions, we use the old IE API to create our selections.
7675 *
7676 * @param {DOMElement|DOMTextNode} node
7677 * @param {object} offsets
7678 */
7679
7680function setOffsets(node, offsets) {
7681 var doc = node.ownerDocument || document;
7682 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
7683 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
7684 // fails when pasting 100+ items)
7685
7686 if (!win.getSelection) {
7687 return;
7688 }
7689
7690 var selection = win.getSelection();
7691 var length = node.textContent.length;
7692 var start = Math.min(offsets.start, length);
7693 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
7694 // Flip backward selections, so we can set with a single range.
7695
7696 if (!selection.extend && start > end) {
7697 var temp = end;
7698 end = start;
7699 start = temp;
7700 }
7701
7702 var startMarker = getNodeForCharacterOffset(node, start);
7703 var endMarker = getNodeForCharacterOffset(node, end);
7704
7705 if (startMarker && endMarker) {
7706 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
7707 return;
7708 }
7709
7710 var range = doc.createRange();
7711 range.setStart(startMarker.node, startMarker.offset);
7712 selection.removeAllRanges();
7713
7714 if (start > end) {
7715 selection.addRange(range);
7716 selection.extend(endMarker.node, endMarker.offset);
7717 } else {
7718 range.setEnd(endMarker.node, endMarker.offset);
7719 selection.addRange(range);
7720 }
7721 }
7722}
7723
7724function isTextNode(node) {
7725 return node && node.nodeType === TEXT_NODE;
7726}
7727
7728function containsNode(outerNode, innerNode) {
7729 if (!outerNode || !innerNode) {
7730 return false;
7731 } else if (outerNode === innerNode) {
7732 return true;
7733 } else if (isTextNode(outerNode)) {
7734 return false;
7735 } else if (isTextNode(innerNode)) {
7736 return containsNode(outerNode, innerNode.parentNode);
7737 } else if ('contains' in outerNode) {
7738 return outerNode.contains(innerNode);
7739 } else if (outerNode.compareDocumentPosition) {
7740 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
7741 } else {
7742 return false;
7743 }
7744}
7745
7746function isInDocument(node) {
7747 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
7748}
7749
7750function isSameOriginFrame(iframe) {
7751 try {
7752 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
7753 // to throw, e.g. if it has a cross-origin src attribute.
7754 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
7755 // iframe.contentDocument.defaultView;
7756 // A safety way is to access one of the cross origin properties: Window or Location
7757 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
7758 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
7759 return typeof iframe.contentWindow.location.href === 'string';
7760 } catch (err) {
7761 return false;
7762 }
7763}
7764
7765function getActiveElementDeep() {
7766 var win = window;
7767 var element = getActiveElement();
7768
7769 while (element instanceof win.HTMLIFrameElement) {
7770 if (isSameOriginFrame(element)) {
7771 win = element.contentWindow;
7772 } else {
7773 return element;
7774 }
7775
7776 element = getActiveElement(win.document);
7777 }
7778
7779 return element;
7780}
7781/**
7782 * @ReactInputSelection: React input selection module. Based on Selection.js,
7783 * but modified to be suitable for react and has a couple of bug fixes (doesn't
7784 * assume buttons have range selections allowed).
7785 * Input selection module for React.
7786 */
7787
7788/**
7789 * @hasSelectionCapabilities: we get the element types that support selection
7790 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
7791 * and `selectionEnd` rows.
7792 */
7793
7794
7795function hasSelectionCapabilities(elem) {
7796 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7797 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
7798}
7799function getSelectionInformation() {
7800 var focusedElem = getActiveElementDeep();
7801 return {
7802 focusedElem: focusedElem,
7803 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
7804 };
7805}
7806/**
7807 * @restoreSelection: If any selection information was potentially lost,
7808 * restore it. This is useful when performing operations that could remove dom
7809 * nodes and place them back in, resulting in focus being lost.
7810 */
7811
7812function restoreSelection(priorSelectionInformation) {
7813 var curFocusedElem = getActiveElementDeep();
7814 var priorFocusedElem = priorSelectionInformation.focusedElem;
7815 var priorSelectionRange = priorSelectionInformation.selectionRange;
7816
7817 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
7818 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
7819 setSelection(priorFocusedElem, priorSelectionRange);
7820 } // Focusing a node can change the scroll position, which is undesirable
7821
7822
7823 var ancestors = [];
7824 var ancestor = priorFocusedElem;
7825
7826 while (ancestor = ancestor.parentNode) {
7827 if (ancestor.nodeType === ELEMENT_NODE) {
7828 ancestors.push({
7829 element: ancestor,
7830 left: ancestor.scrollLeft,
7831 top: ancestor.scrollTop
7832 });
7833 }
7834 }
7835
7836 if (typeof priorFocusedElem.focus === 'function') {
7837 priorFocusedElem.focus();
7838 }
7839
7840 for (var i = 0; i < ancestors.length; i++) {
7841 var info = ancestors[i];
7842 info.element.scrollLeft = info.left;
7843 info.element.scrollTop = info.top;
7844 }
7845 }
7846}
7847/**
7848 * @getSelection: Gets the selection bounds of a focused textarea, input or
7849 * contentEditable node.
7850 * -@input: Look up selection bounds of this input
7851 * -@return {start: selectionStart, end: selectionEnd}
7852 */
7853
7854function getSelection(input) {
7855 var selection;
7856
7857 if ('selectionStart' in input) {
7858 // Modern browser with input or textarea.
7859 selection = {
7860 start: input.selectionStart,
7861 end: input.selectionEnd
7862 };
7863 } else {
7864 // Content editable or old IE textarea.
7865 selection = getOffsets(input);
7866 }
7867
7868 return selection || {
7869 start: 0,
7870 end: 0
7871 };
7872}
7873/**
7874 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7875 * the input.
7876 * -@input Set selection bounds of this input or textarea
7877 * -@offsets Object of same form that is returned from get*
7878 */
7879
7880function setSelection(input, offsets) {
7881 var start = offsets.start;
7882 var end = offsets.end;
7883
7884 if (end === undefined) {
7885 end = start;
7886 }
7887
7888 if ('selectionStart' in input) {
7889 input.selectionStart = start;
7890 input.selectionEnd = Math.min(end, input.value.length);
7891 } else {
7892 setOffsets(input, offsets);
7893 }
7894}
7895
7896var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
7897
7898function registerEvents$3() {
7899 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
7900}
7901
7902var activeElement$1 = null;
7903var activeElementInst$1 = null;
7904var lastSelection = null;
7905var mouseDown = false;
7906/**
7907 * Get an object which is a unique representation of the current selection.
7908 *
7909 * The return value will not be consistent across nodes or browsers, but
7910 * two identical selections on the same node will return identical objects.
7911 */
7912
7913function getSelection$1(node) {
7914 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
7915 return {
7916 start: node.selectionStart,
7917 end: node.selectionEnd
7918 };
7919 } else {
7920 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
7921 var selection = win.getSelection();
7922 return {
7923 anchorNode: selection.anchorNode,
7924 anchorOffset: selection.anchorOffset,
7925 focusNode: selection.focusNode,
7926 focusOffset: selection.focusOffset
7927 };
7928 }
7929}
7930/**
7931 * Get document associated with the event target.
7932 */
7933
7934
7935function getEventTargetDocument(eventTarget) {
7936 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
7937}
7938/**
7939 * Poll selection to see whether it's changed.
7940 *
7941 * @param {object} nativeEvent
7942 * @param {object} nativeEventTarget
7943 * @return {?SyntheticEvent}
7944 */
7945
7946
7947function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
7948 // Ensure we have the right element, and that the user is not dragging a
7949 // selection (this matches native `select` event behavior). In HTML5, select
7950 // fires only on input and textarea thus if there's no focused element we
7951 // won't dispatch.
7952 var doc = getEventTargetDocument(nativeEventTarget);
7953
7954 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
7955 return;
7956 } // Only fire when selection has actually changed.
7957
7958
7959 var currentSelection = getSelection$1(activeElement$1);
7960
7961 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
7962 lastSelection = currentSelection;
7963 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
7964
7965 if (listeners.length > 0) {
7966 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
7967 dispatchQueue.push({
7968 event: event,
7969 listeners: listeners
7970 });
7971 event.target = activeElement$1;
7972 }
7973 }
7974}
7975/**
7976 * This plugin creates an `onSelect` event that normalizes select events
7977 * across form elements.
7978 *
7979 * Supported elements are:
7980 * - input (see `isTextInputElement`)
7981 * - textarea
7982 * - contentEditable
7983 *
7984 * This differs from native browser implementations in the following ways:
7985 * - Fires on contentEditable fields as well as inputs.
7986 * - Fires for collapsed selection.
7987 * - Fires after user input.
7988 */
7989
7990
7991function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7992
7993 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7994
7995 switch (domEventName) {
7996 // Track the input node that has focus.
7997 case 'focusin':
7998 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
7999 activeElement$1 = targetNode;
8000 activeElementInst$1 = targetInst;
8001 lastSelection = null;
8002 }
8003
8004 break;
8005
8006 case 'focusout':
8007 activeElement$1 = null;
8008 activeElementInst$1 = null;
8009 lastSelection = null;
8010 break;
8011 // Don't fire the event while the user is dragging. This matches the
8012 // semantics of the native select event.
8013
8014 case 'mousedown':
8015 mouseDown = true;
8016 break;
8017
8018 case 'contextmenu':
8019 case 'mouseup':
8020 case 'dragend':
8021 mouseDown = false;
8022 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8023 break;
8024 // Chrome and IE fire non-standard event when selection is changed (and
8025 // sometimes when it hasn't). IE's event fires out of order with respect
8026 // to key and input events on deletion, so we discard it.
8027 //
8028 // Firefox doesn't support selectionchange, so check selection status
8029 // after each key entry. The selection changes after keydown and before
8030 // keyup, but we check on keydown as well in the case of holding down a
8031 // key, when multiple keydown events are fired but only one keyup is.
8032 // This is also our approach for IE handling, for the reason above.
8033
8034 case 'selectionchange':
8035 if (skipSelectionChangeEvent) {
8036 break;
8037 }
8038
8039 // falls through
8040
8041 case 'keydown':
8042 case 'keyup':
8043 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8044 }
8045}
8046
8047function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8048 var reactName = topLevelEventsToReactNames.get(domEventName);
8049
8050 if (reactName === undefined) {
8051 return;
8052 }
8053
8054 var SyntheticEventCtor = SyntheticEvent;
8055 var reactEventType = domEventName;
8056
8057 switch (domEventName) {
8058 case 'keypress':
8059 // Firefox creates a keypress event for function keys too. This removes
8060 // the unwanted keypress events. Enter is however both printable and
8061 // non-printable. One would expect Tab to be as well (but it isn't).
8062 if (getEventCharCode(nativeEvent) === 0) {
8063 return;
8064 }
8065
8066 /* falls through */
8067
8068 case 'keydown':
8069 case 'keyup':
8070 SyntheticEventCtor = SyntheticKeyboardEvent;
8071 break;
8072
8073 case 'focusin':
8074 reactEventType = 'focus';
8075 SyntheticEventCtor = SyntheticFocusEvent;
8076 break;
8077
8078 case 'focusout':
8079 reactEventType = 'blur';
8080 SyntheticEventCtor = SyntheticFocusEvent;
8081 break;
8082
8083 case 'beforeblur':
8084 case 'afterblur':
8085 SyntheticEventCtor = SyntheticFocusEvent;
8086 break;
8087
8088 case 'click':
8089 // Firefox creates a click event on right mouse clicks. This removes the
8090 // unwanted click events.
8091 if (nativeEvent.button === 2) {
8092 return;
8093 }
8094
8095 /* falls through */
8096
8097 case 'auxclick':
8098 case 'dblclick':
8099 case 'mousedown':
8100 case 'mousemove':
8101 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8102
8103 /* falls through */
8104
8105 case 'mouseout':
8106 case 'mouseover':
8107 case 'contextmenu':
8108 SyntheticEventCtor = SyntheticMouseEvent;
8109 break;
8110
8111 case 'drag':
8112 case 'dragend':
8113 case 'dragenter':
8114 case 'dragexit':
8115 case 'dragleave':
8116 case 'dragover':
8117 case 'dragstart':
8118 case 'drop':
8119 SyntheticEventCtor = SyntheticDragEvent;
8120 break;
8121
8122 case 'touchcancel':
8123 case 'touchend':
8124 case 'touchmove':
8125 case 'touchstart':
8126 SyntheticEventCtor = SyntheticTouchEvent;
8127 break;
8128
8129 case ANIMATION_END:
8130 case ANIMATION_ITERATION:
8131 case ANIMATION_START:
8132 SyntheticEventCtor = SyntheticAnimationEvent;
8133 break;
8134
8135 case TRANSITION_END:
8136 SyntheticEventCtor = SyntheticTransitionEvent;
8137 break;
8138
8139 case 'scroll':
8140 SyntheticEventCtor = SyntheticUIEvent;
8141 break;
8142
8143 case 'wheel':
8144 SyntheticEventCtor = SyntheticWheelEvent;
8145 break;
8146
8147 case 'copy':
8148 case 'cut':
8149 case 'paste':
8150 SyntheticEventCtor = SyntheticClipboardEvent;
8151 break;
8152
8153 case 'gotpointercapture':
8154 case 'lostpointercapture':
8155 case 'pointercancel':
8156 case 'pointerdown':
8157 case 'pointermove':
8158 case 'pointerout':
8159 case 'pointerover':
8160 case 'pointerup':
8161 SyntheticEventCtor = SyntheticPointerEvent;
8162 break;
8163 }
8164
8165 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8166
8167 {
8168 // Some events don't bubble in the browser.
8169 // In the past, React has always bubbled them, but this can be surprising.
8170 // We're going to try aligning closer to the browser behavior by not bubbling
8171 // them in React either. We'll start by not bubbling onScroll, and then expand.
8172 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from
8173 // nonDelegatedEvents list in DOMPluginEventSystem.
8174 // Then we can remove this special list.
8175 // This is a breaking change that can wait until React 18.
8176 domEventName === 'scroll';
8177
8178 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8179
8180 if (_listeners.length > 0) {
8181 // Intentionally create event lazily.
8182 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8183
8184 dispatchQueue.push({
8185 event: _event,
8186 listeners: _listeners
8187 });
8188 }
8189 }
8190}
8191
8192// TODO: remove top-level side effect.
8193registerSimpleEvents();
8194registerEvents$2();
8195registerEvents$1();
8196registerEvents$3();
8197registerEvents();
8198
8199function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8200 // TODO: we should remove the concept of a "SimpleEventPlugin".
8201 // This is the basic functionality of the event system. All
8202 // the other plugins are essentially polyfills. So the plugin
8203 // should probably be inlined somewhere and have its logic
8204 // be core the to event system. This would potentially allow
8205 // us to ship builds of React without the polyfilled plugins below.
8206 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8207 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
8208 // event's native "bubble" phase, which means that we're
8209 // not in the capture phase. That's because we emulate
8210 // the capture phase here still. This is a trade-off,
8211 // because in an ideal world we would not emulate and use
8212 // the phases properly, like we do with the SimpleEvent
8213 // plugin. However, the plugins below either expect
8214 // emulation (EnterLeave) or use state localized to that
8215 // plugin (BeforeInput, Change, Select). The state in
8216 // these modules complicates things, as you'll essentially
8217 // get the case where the capture phase event might change
8218 // state, only for the following bubble event to come in
8219 // later and not trigger anything as the state now
8220 // invalidates the heuristics of the event plugin. We
8221 // could alter all these plugins to work in such ways, but
8222 // that might cause other unknown side-effects that we
8223 // can't forsee right now.
8224
8225 if (shouldProcessPolyfillPlugins) {
8226 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8227 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8228 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8229 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
8230 }
8231} // List of events that need to be individually attached to media elements.
8232
8233
8234var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather
8235// set them on the actual target element itself. This is primarily
8236// because these events do not consistently bubble in the DOM.
8237
8238var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes));
8239
8240function executeDispatch(event, listener, currentTarget) {
8241 var type = event.type || 'unknown-event';
8242 event.currentTarget = currentTarget;
8243 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
8244 event.currentTarget = null;
8245}
8246
8247function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
8248 var previousInstance;
8249
8250 if (inCapturePhase) {
8251 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
8252 var _dispatchListeners$i = dispatchListeners[i],
8253 instance = _dispatchListeners$i.instance,
8254 currentTarget = _dispatchListeners$i.currentTarget,
8255 listener = _dispatchListeners$i.listener;
8256
8257 if (instance !== previousInstance && event.isPropagationStopped()) {
8258 return;
8259 }
8260
8261 executeDispatch(event, listener, currentTarget);
8262 previousInstance = instance;
8263 }
8264 } else {
8265 for (var _i = 0; _i < dispatchListeners.length; _i++) {
8266 var _dispatchListeners$_i = dispatchListeners[_i],
8267 _instance = _dispatchListeners$_i.instance,
8268 _currentTarget = _dispatchListeners$_i.currentTarget,
8269 _listener = _dispatchListeners$_i.listener;
8270
8271 if (_instance !== previousInstance && event.isPropagationStopped()) {
8272 return;
8273 }
8274
8275 executeDispatch(event, _listener, _currentTarget);
8276 previousInstance = _instance;
8277 }
8278 }
8279}
8280
8281function processDispatchQueue(dispatchQueue, eventSystemFlags) {
8282 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8283
8284 for (var i = 0; i < dispatchQueue.length; i++) {
8285 var _dispatchQueue$i = dispatchQueue[i],
8286 event = _dispatchQueue$i.event,
8287 listeners = _dispatchQueue$i.listeners;
8288 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
8289 } // This would be a good time to rethrow if any of the event handlers threw.
8290
8291
8292 rethrowCaughtError();
8293}
8294
8295function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
8296 var nativeEventTarget = getEventTarget(nativeEvent);
8297 var dispatchQueue = [];
8298 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8299 processDispatchQueue(dispatchQueue, eventSystemFlags);
8300}
8301
8302function listenToNonDelegatedEvent(domEventName, targetElement) {
8303 var isCapturePhaseListener = false;
8304 var listenerSet = getEventListenerSet(targetElement);
8305 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
8306
8307 if (!listenerSet.has(listenerSetKey)) {
8308 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
8309 listenerSet.add(listenerSetKey);
8310 }
8311}
8312var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
8313function listenToAllSupportedEvents(rootContainerElement) {
8314 {
8315 if (rootContainerElement[listeningMarker]) {
8316 // Performance optimization: don't iterate through events
8317 // for the same portal container or root node more than once.
8318 // TODO: once we remove the flag, we may be able to also
8319 // remove some of the bookkeeping maps used for laziness.
8320 return;
8321 }
8322
8323 rootContainerElement[listeningMarker] = true;
8324 allNativeEvents.forEach(function (domEventName) {
8325 if (!nonDelegatedEvents.has(domEventName)) {
8326 listenToNativeEvent(domEventName, false, rootContainerElement, null);
8327 }
8328
8329 listenToNativeEvent(domEventName, true, rootContainerElement, null);
8330 });
8331 }
8332}
8333function listenToNativeEvent(domEventName, isCapturePhaseListener, rootContainerElement, targetElement) {
8334 var eventSystemFlags = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
8335 var target = rootContainerElement; // selectionchange needs to be attached to the document
8336 // otherwise it won't capture incoming events that are only
8337 // triggered on the document directly.
8338
8339 if (domEventName === 'selectionchange' && rootContainerElement.nodeType !== DOCUMENT_NODE) {
8340 target = rootContainerElement.ownerDocument;
8341 } // If the event can be delegated (or is capture phase), we can
8342 // register it to the root container. Otherwise, we should
8343 // register the event to the target element and mark it as
8344 // a non-delegated event.
8345
8346
8347 if (targetElement !== null && !isCapturePhaseListener && nonDelegatedEvents.has(domEventName)) {
8348 // For all non-delegated events, apart from scroll, we attach
8349 // their event listeners to the respective elements that their
8350 // events fire on. That means we can skip this step, as event
8351 // listener has already been added previously. However, we
8352 // special case the scroll event because the reality is that any
8353 // element can scroll.
8354 // TODO: ideally, we'd eventually apply the same logic to all
8355 // events from the nonDelegatedEvents list. Then we can remove
8356 // this special case and use the same logic for all events.
8357 if (domEventName !== 'scroll') {
8358 return;
8359 }
8360
8361 eventSystemFlags |= IS_NON_DELEGATED;
8362 target = targetElement;
8363 }
8364
8365 var listenerSet = getEventListenerSet(target);
8366 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener); // If the listener entry is empty or we should upgrade, then
8367 // we need to trap an event listener onto the target.
8368
8369 if (!listenerSet.has(listenerSetKey)) {
8370 if (isCapturePhaseListener) {
8371 eventSystemFlags |= IS_CAPTURE_PHASE;
8372 }
8373
8374 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
8375 listenerSet.add(listenerSetKey);
8376 }
8377}
8378
8379function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
8380 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
8381 // active and not passive.
8382
8383 var isPassiveListener = undefined;
8384
8385 if (passiveBrowserEventsSupported) {
8386 // Browsers introduced an intervention, making these events
8387 // passive by default on document. React doesn't bind them
8388 // to document anymore, but changing this now would undo
8389 // the performance wins from the change. So we emulate
8390 // the existing behavior manually on the roots now.
8391 // https://github.com/facebook/react/issues/19651
8392 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
8393 isPassiveListener = true;
8394 }
8395 }
8396
8397 targetContainer = targetContainer;
8398 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we
8399
8400
8401 if (isCapturePhaseListener) {
8402 if (isPassiveListener !== undefined) {
8403 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
8404 } else {
8405 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
8406 }
8407 } else {
8408 if (isPassiveListener !== undefined) {
8409 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
8410 } else {
8411 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
8412 }
8413 }
8414}
8415
8416function isMatchingRootContainer(grandContainer, targetContainer) {
8417 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
8418}
8419
8420function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
8421 var ancestorInst = targetInst;
8422
8423 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
8424 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
8425
8426 if (targetInst !== null) {
8427 // The below logic attempts to work out if we need to change
8428 // the target fiber to a different ancestor. We had similar logic
8429 // in the legacy event system, except the big difference between
8430 // systems is that the modern event system now has an event listener
8431 // attached to each React Root and React Portal Root. Together,
8432 // the DOM nodes representing these roots are the "rootContainer".
8433 // To figure out which ancestor instance we should use, we traverse
8434 // up the fiber tree from the target instance and attempt to find
8435 // root boundaries that match that of our current "rootContainer".
8436 // If we find that "rootContainer", we find the parent fiber
8437 // sub-tree for that root and make that our ancestor instance.
8438 var node = targetInst;
8439
8440 mainLoop: while (true) {
8441 if (node === null) {
8442 return;
8443 }
8444
8445 var nodeTag = node.tag;
8446
8447 if (nodeTag === HostRoot || nodeTag === HostPortal) {
8448 var container = node.stateNode.containerInfo;
8449
8450 if (isMatchingRootContainer(container, targetContainerNode)) {
8451 break;
8452 }
8453
8454 if (nodeTag === HostPortal) {
8455 // The target is a portal, but it's not the rootContainer we're looking for.
8456 // Normally portals handle their own events all the way down to the root.
8457 // So we should be able to stop now. However, we don't know if this portal
8458 // was part of *our* root.
8459 var grandNode = node.return;
8460
8461 while (grandNode !== null) {
8462 var grandTag = grandNode.tag;
8463
8464 if (grandTag === HostRoot || grandTag === HostPortal) {
8465 var grandContainer = grandNode.stateNode.containerInfo;
8466
8467 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
8468 // This is the rootContainer we're looking for and we found it as
8469 // a parent of the Portal. That means we can ignore it because the
8470 // Portal will bubble through to us.
8471 return;
8472 }
8473 }
8474
8475 grandNode = grandNode.return;
8476 }
8477 } // Now we need to find it's corresponding host fiber in the other
8478 // tree. To do this we can use getClosestInstanceFromNode, but we
8479 // need to validate that the fiber is a host instance, otherwise
8480 // we need to traverse up through the DOM till we find the correct
8481 // node that is from the other tree.
8482
8483
8484 while (container !== null) {
8485 var parentNode = getClosestInstanceFromNode(container);
8486
8487 if (parentNode === null) {
8488 return;
8489 }
8490
8491 var parentTag = parentNode.tag;
8492
8493 if (parentTag === HostComponent || parentTag === HostText) {
8494 node = ancestorInst = parentNode;
8495 continue mainLoop;
8496 }
8497
8498 container = container.parentNode;
8499 }
8500 }
8501
8502 node = node.return;
8503 }
8504 }
8505 }
8506
8507 batchedEventUpdates(function () {
8508 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
8509 });
8510}
8511
8512function createDispatchListener(instance, listener, currentTarget) {
8513 return {
8514 instance: instance,
8515 listener: listener,
8516 currentTarget: currentTarget
8517 };
8518}
8519
8520function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly) {
8521 var captureName = reactName !== null ? reactName + 'Capture' : null;
8522 var reactEventName = inCapturePhase ? captureName : reactName;
8523 var listeners = [];
8524 var instance = targetFiber;
8525 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
8526
8527 while (instance !== null) {
8528 var _instance2 = instance,
8529 stateNode = _instance2.stateNode,
8530 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8531
8532 if (tag === HostComponent && stateNode !== null) {
8533 lastHostComponent = stateNode; // createEventHandle listeners
8534
8535
8536 if (reactEventName !== null) {
8537 var listener = getListener(instance, reactEventName);
8538
8539 if (listener != null) {
8540 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
8541 }
8542 }
8543 } // If we are only accumulating events for the target, then we don't
8544 // continue to propagate through the React fiber tree to find other
8545 // listeners.
8546
8547
8548 if (accumulateTargetOnly) {
8549 break;
8550 }
8551
8552 instance = instance.return;
8553 }
8554
8555 return listeners;
8556} // We should only use this function for:
8557// - BeforeInputEventPlugin
8558// - ChangeEventPlugin
8559// - SelectEventPlugin
8560// This is because we only process these plugins
8561// in the bubble phase, so we need to accumulate two
8562// phase event listeners (via emulation).
8563
8564function accumulateTwoPhaseListeners(targetFiber, reactName) {
8565 var captureName = reactName + 'Capture';
8566 var listeners = [];
8567 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
8568
8569 while (instance !== null) {
8570 var _instance3 = instance,
8571 stateNode = _instance3.stateNode,
8572 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
8573
8574 if (tag === HostComponent && stateNode !== null) {
8575 var currentTarget = stateNode;
8576 var captureListener = getListener(instance, captureName);
8577
8578 if (captureListener != null) {
8579 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8580 }
8581
8582 var bubbleListener = getListener(instance, reactName);
8583
8584 if (bubbleListener != null) {
8585 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8586 }
8587 }
8588
8589 instance = instance.return;
8590 }
8591
8592 return listeners;
8593}
8594
8595function getParent(inst) {
8596 if (inst === null) {
8597 return null;
8598 }
8599
8600 do {
8601 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
8602 // That is depending on if we want nested subtrees (layers) to bubble
8603 // events to their parent. We could also go through parentNode on the
8604 // host node but that wouldn't work for React Native and doesn't let us
8605 // do the portal feature.
8606 } while (inst && inst.tag !== HostComponent);
8607
8608 if (inst) {
8609 return inst;
8610 }
8611
8612 return null;
8613}
8614/**
8615 * Return the lowest common ancestor of A and B, or null if they are in
8616 * different trees.
8617 */
8618
8619
8620function getLowestCommonAncestor(instA, instB) {
8621 var nodeA = instA;
8622 var nodeB = instB;
8623 var depthA = 0;
8624
8625 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
8626 depthA++;
8627 }
8628
8629 var depthB = 0;
8630
8631 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
8632 depthB++;
8633 } // If A is deeper, crawl up.
8634
8635
8636 while (depthA - depthB > 0) {
8637 nodeA = getParent(nodeA);
8638 depthA--;
8639 } // If B is deeper, crawl up.
8640
8641
8642 while (depthB - depthA > 0) {
8643 nodeB = getParent(nodeB);
8644 depthB--;
8645 } // Walk in lockstep until we find a match.
8646
8647
8648 var depth = depthA;
8649
8650 while (depth--) {
8651 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
8652 return nodeA;
8653 }
8654
8655 nodeA = getParent(nodeA);
8656 nodeB = getParent(nodeB);
8657 }
8658
8659 return null;
8660}
8661
8662function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
8663 var registrationName = event._reactName;
8664 var listeners = [];
8665 var instance = target;
8666
8667 while (instance !== null) {
8668 if (instance === common) {
8669 break;
8670 }
8671
8672 var _instance4 = instance,
8673 alternate = _instance4.alternate,
8674 stateNode = _instance4.stateNode,
8675 tag = _instance4.tag;
8676
8677 if (alternate !== null && alternate === common) {
8678 break;
8679 }
8680
8681 if (tag === HostComponent && stateNode !== null) {
8682 var currentTarget = stateNode;
8683
8684 if (inCapturePhase) {
8685 var captureListener = getListener(instance, registrationName);
8686
8687 if (captureListener != null) {
8688 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
8689 }
8690 } else if (!inCapturePhase) {
8691 var bubbleListener = getListener(instance, registrationName);
8692
8693 if (bubbleListener != null) {
8694 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
8695 }
8696 }
8697 }
8698
8699 instance = instance.return;
8700 }
8701
8702 if (listeners.length !== 0) {
8703 dispatchQueue.push({
8704 event: event,
8705 listeners: listeners
8706 });
8707 }
8708} // We should only use this function for:
8709// - EnterLeaveEventPlugin
8710// This is because we only process this plugin
8711// in the bubble phase, so we need to accumulate two
8712// phase event listeners.
8713
8714
8715function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
8716 var common = from && to ? getLowestCommonAncestor(from, to) : null;
8717
8718 if (from !== null) {
8719 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
8720 }
8721
8722 if (to !== null && enterEvent !== null) {
8723 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
8724 }
8725}
8726function getListenerSetKey(domEventName, capture) {
8727 return domEventName + "__" + (capture ? 'capture' : 'bubble');
8728}
8729
8730var didWarnInvalidHydration = false;
8731var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
8732var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
8733var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8734var AUTOFOCUS = 'autoFocus';
8735var CHILDREN = 'children';
8736var STYLE = 'style';
8737var HTML$1 = '__html';
8738var HTML_NAMESPACE$1 = Namespaces.html;
8739var warnedUnknownTags;
8740var suppressHydrationWarning;
8741var validatePropertiesInDevelopment;
8742var warnForTextDifference;
8743var warnForPropDifference;
8744var warnForExtraAttributes;
8745var warnForInvalidEventListener;
8746var canDiffStyleForHydrationWarning;
8747var normalizeMarkupForTextOrAttribute;
8748var normalizeHTML;
8749
8750{
8751 warnedUnknownTags = {
8752 // There are working polyfills for <dialog>. Let people use it.
8753 dialog: true,
8754 // Electron ships a custom <webview> tag to display external web content in
8755 // an isolated frame and process.
8756 // This tag is not present in non Electron environments such as JSDom which
8757 // is often used for testing purposes.
8758 // @see https://electronjs.org/docs/api/webview-tag
8759 webview: true
8760 };
8761
8762 validatePropertiesInDevelopment = function (type, props) {
8763 validateProperties(type, props);
8764 validateProperties$1(type, props);
8765 validateProperties$2(type, props, {
8766 registrationNameDependencies: registrationNameDependencies,
8767 possibleRegistrationNames: possibleRegistrationNames
8768 });
8769 }; // IE 11 parses & normalizes the style attribute as opposed to other
8770 // browsers. It adds spaces and sorts the properties in some
8771 // non-alphabetical order. Handling that would require sorting CSS
8772 // properties in the client & server versions or applying
8773 // `expectedStyle` to a temporary DOM node to read its `style` attribute
8774 // normalized. Since it only affects IE, we're skipping style warnings
8775 // in that browser completely in favor of doing all that work.
8776 // See https://github.com/facebook/react/issues/11807
8777
8778
8779 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
8780 // It also can turn \u0000 into \uFFFD inside attributes.
8781 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
8782 // If we have a mismatch, it might be caused by that.
8783 // We will still patch up in this case but not fire the warning.
8784
8785 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
8786 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
8787
8788 normalizeMarkupForTextOrAttribute = function (markup) {
8789 var markupString = typeof markup === 'string' ? markup : '' + markup;
8790 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
8791 };
8792
8793 warnForTextDifference = function (serverText, clientText) {
8794 if (didWarnInvalidHydration) {
8795 return;
8796 }
8797
8798 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
8799 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
8800
8801 if (normalizedServerText === normalizedClientText) {
8802 return;
8803 }
8804
8805 didWarnInvalidHydration = true;
8806
8807 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
8808 };
8809
8810 warnForPropDifference = function (propName, serverValue, clientValue) {
8811 if (didWarnInvalidHydration) {
8812 return;
8813 }
8814
8815 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
8816 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
8817
8818 if (normalizedServerValue === normalizedClientValue) {
8819 return;
8820 }
8821
8822 didWarnInvalidHydration = true;
8823
8824 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
8825 };
8826
8827 warnForExtraAttributes = function (attributeNames) {
8828 if (didWarnInvalidHydration) {
8829 return;
8830 }
8831
8832 didWarnInvalidHydration = true;
8833 var names = [];
8834 attributeNames.forEach(function (name) {
8835 names.push(name);
8836 });
8837
8838 error('Extra attributes from the server: %s', names);
8839 };
8840
8841 warnForInvalidEventListener = function (registrationName, listener) {
8842 if (listener === false) {
8843 error('Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
8844 } else {
8845 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
8846 }
8847 }; // Parse the HTML and read it back to normalize the HTML string so that it
8848 // can be used for comparison.
8849
8850
8851 normalizeHTML = function (parent, html) {
8852 // We could have created a separate document here to avoid
8853 // re-initializing custom elements if they exist. But this breaks
8854 // how <noscript> is being handled. So we use the same document.
8855 // See the discussion in https://github.com/facebook/react/pull/11157.
8856 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
8857 testElement.innerHTML = html;
8858 return testElement.innerHTML;
8859 };
8860}
8861
8862function getOwnerDocumentFromRootContainer(rootContainerElement) {
8863 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
8864}
8865
8866function noop() {}
8867
8868function trapClickOnNonInteractiveElement(node) {
8869 // Mobile Safari does not fire properly bubble click events on
8870 // non-interactive elements, which means delegated click listeners do not
8871 // fire. The workaround for this bug involves attaching an empty click
8872 // listener on the target node.
8873 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
8874 // Just set it using the onclick property so that we don't have to manage any
8875 // bookkeeping for it. Not sure if we need to clear it when the listener is
8876 // removed.
8877 // TODO: Only do this for the relevant Safaris maybe?
8878 node.onclick = noop;
8879}
8880
8881function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
8882 for (var propKey in nextProps) {
8883 if (!nextProps.hasOwnProperty(propKey)) {
8884 continue;
8885 }
8886
8887 var nextProp = nextProps[propKey];
8888
8889 if (propKey === STYLE) {
8890 {
8891 if (nextProp) {
8892 // Freeze the next style object so that we can assume it won't be
8893 // mutated. We have already warned for this in the past.
8894 Object.freeze(nextProp);
8895 }
8896 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
8897
8898
8899 setValueForStyles(domElement, nextProp);
8900 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8901 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
8902
8903 if (nextHtml != null) {
8904 setInnerHTML(domElement, nextHtml);
8905 }
8906 } else if (propKey === CHILDREN) {
8907 if (typeof nextProp === 'string') {
8908 // Avoid setting initial textContent when the text is empty. In IE11 setting
8909 // textContent on a <textarea> will cause the placeholder to not
8910 // show within the <textarea> until it has been focused and blurred again.
8911 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
8912 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
8913
8914 if (canSetTextContent) {
8915 setTextContent(domElement, nextProp);
8916 }
8917 } else if (typeof nextProp === 'number') {
8918 setTextContent(domElement, '' + nextProp);
8919 }
8920 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
8921 if (nextProp != null) {
8922 if ( typeof nextProp !== 'function') {
8923 warnForInvalidEventListener(propKey, nextProp);
8924 }
8925
8926 if (propKey === 'onScroll') {
8927 listenToNonDelegatedEvent('scroll', domElement);
8928 }
8929 }
8930 } else if (nextProp != null) {
8931 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
8932 }
8933 }
8934}
8935
8936function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
8937 // TODO: Handle wasCustomComponentTag
8938 for (var i = 0; i < updatePayload.length; i += 2) {
8939 var propKey = updatePayload[i];
8940 var propValue = updatePayload[i + 1];
8941
8942 if (propKey === STYLE) {
8943 setValueForStyles(domElement, propValue);
8944 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8945 setInnerHTML(domElement, propValue);
8946 } else if (propKey === CHILDREN) {
8947 setTextContent(domElement, propValue);
8948 } else {
8949 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
8950 }
8951 }
8952}
8953
8954function createElement(type, props, rootContainerElement, parentNamespace) {
8955 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
8956 // tags get no namespace.
8957
8958 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
8959 var domElement;
8960 var namespaceURI = parentNamespace;
8961
8962 if (namespaceURI === HTML_NAMESPACE$1) {
8963 namespaceURI = getIntrinsicNamespace(type);
8964 }
8965
8966 if (namespaceURI === HTML_NAMESPACE$1) {
8967 {
8968 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
8969 // allow <SVG> or <mATH>.
8970
8971 if (!isCustomComponentTag && type !== type.toLowerCase()) {
8972 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
8973 }
8974 }
8975
8976 if (type === 'script') {
8977 // Create the script via .innerHTML so its "parser-inserted" flag is
8978 // set to true and it does not execute
8979 var div = ownerDocument.createElement('div');
8980
8981 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
8982 // This is guaranteed to yield a script element.
8983
8984 var firstChild = div.firstChild;
8985 domElement = div.removeChild(firstChild);
8986 } else if (typeof props.is === 'string') {
8987 // $FlowIssue `createElement` should be updated for Web Components
8988 domElement = ownerDocument.createElement(type, {
8989 is: props.is
8990 });
8991 } else {
8992 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
8993 // See discussion in https://github.com/facebook/react/pull/6896
8994 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
8995 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
8996 // attributes on `select`s needs to be added before `option`s are inserted.
8997 // This prevents:
8998 // - a bug where the `select` does not scroll to the correct option because singular
8999 // `select` elements automatically pick the first item #13222
9000 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
9001 // See https://github.com/facebook/react/issues/13222
9002 // and https://github.com/facebook/react/issues/14239
9003
9004 if (type === 'select') {
9005 var node = domElement;
9006
9007 if (props.multiple) {
9008 node.multiple = true;
9009 } else if (props.size) {
9010 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
9011 // it is possible that no option is selected.
9012 //
9013 // This is only necessary when a select in "single selection mode".
9014 node.size = props.size;
9015 }
9016 }
9017 }
9018 } else {
9019 domElement = ownerDocument.createElementNS(namespaceURI, type);
9020 }
9021
9022 {
9023 if (namespaceURI === HTML_NAMESPACE$1) {
9024 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
9025 warnedUnknownTags[type] = true;
9026
9027 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
9028 }
9029 }
9030 }
9031
9032 return domElement;
9033}
9034function createTextNode(text, rootContainerElement) {
9035 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
9036}
9037function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
9038 var isCustomComponentTag = isCustomComponent(tag, rawProps);
9039
9040 {
9041 validatePropertiesInDevelopment(tag, rawProps);
9042 } // TODO: Make sure that we check isMounted before firing any of these events.
9043
9044
9045 var props;
9046
9047 switch (tag) {
9048 case 'dialog':
9049 listenToNonDelegatedEvent('cancel', domElement);
9050 listenToNonDelegatedEvent('close', domElement);
9051 props = rawProps;
9052 break;
9053
9054 case 'iframe':
9055 case 'object':
9056 case 'embed':
9057 // We listen to this event in case to ensure emulated bubble
9058 // listeners still fire for the load event.
9059 listenToNonDelegatedEvent('load', domElement);
9060 props = rawProps;
9061 break;
9062
9063 case 'video':
9064 case 'audio':
9065 // We listen to these events in case to ensure emulated bubble
9066 // listeners still fire for all the media events.
9067 for (var i = 0; i < mediaEventTypes.length; i++) {
9068 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9069 }
9070
9071 props = rawProps;
9072 break;
9073
9074 case 'source':
9075 // We listen to this event in case to ensure emulated bubble
9076 // listeners still fire for the error event.
9077 listenToNonDelegatedEvent('error', domElement);
9078 props = rawProps;
9079 break;
9080
9081 case 'img':
9082 case 'image':
9083 case 'link':
9084 // We listen to these events in case to ensure emulated bubble
9085 // listeners still fire for error and load events.
9086 listenToNonDelegatedEvent('error', domElement);
9087 listenToNonDelegatedEvent('load', domElement);
9088 props = rawProps;
9089 break;
9090
9091 case 'details':
9092 // We listen to this event in case to ensure emulated bubble
9093 // listeners still fire for the toggle event.
9094 listenToNonDelegatedEvent('toggle', domElement);
9095 props = rawProps;
9096 break;
9097
9098 case 'input':
9099 initWrapperState(domElement, rawProps);
9100 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9101 // listeners still fire for the invalid event.
9102
9103 listenToNonDelegatedEvent('invalid', domElement);
9104
9105 break;
9106
9107 case 'option':
9108 validateProps(domElement, rawProps);
9109 props = getHostProps$1(domElement, rawProps);
9110 break;
9111
9112 case 'select':
9113 initWrapperState$1(domElement, rawProps);
9114 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9115 // listeners still fire for the invalid event.
9116
9117 listenToNonDelegatedEvent('invalid', domElement);
9118
9119 break;
9120
9121 case 'textarea':
9122 initWrapperState$2(domElement, rawProps);
9123 props = getHostProps$3(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9124 // listeners still fire for the invalid event.
9125
9126 listenToNonDelegatedEvent('invalid', domElement);
9127
9128 break;
9129
9130 default:
9131 props = rawProps;
9132 }
9133
9134 assertValidProps(tag, props);
9135 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9136
9137 switch (tag) {
9138 case 'input':
9139 // TODO: Make sure we check if this is still unmounted or do any clean
9140 // up necessary since we never stop tracking anymore.
9141 track(domElement);
9142 postMountWrapper(domElement, rawProps, false);
9143 break;
9144
9145 case 'textarea':
9146 // TODO: Make sure we check if this is still unmounted or do any clean
9147 // up necessary since we never stop tracking anymore.
9148 track(domElement);
9149 postMountWrapper$3(domElement);
9150 break;
9151
9152 case 'option':
9153 postMountWrapper$1(domElement, rawProps);
9154 break;
9155
9156 case 'select':
9157 postMountWrapper$2(domElement, rawProps);
9158 break;
9159
9160 default:
9161 if (typeof props.onClick === 'function') {
9162 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9163 trapClickOnNonInteractiveElement(domElement);
9164 }
9165
9166 break;
9167 }
9168} // Calculate the diff between the two objects.
9169
9170function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9171 {
9172 validatePropertiesInDevelopment(tag, nextRawProps);
9173 }
9174
9175 var updatePayload = null;
9176 var lastProps;
9177 var nextProps;
9178
9179 switch (tag) {
9180 case 'input':
9181 lastProps = getHostProps(domElement, lastRawProps);
9182 nextProps = getHostProps(domElement, nextRawProps);
9183 updatePayload = [];
9184 break;
9185
9186 case 'option':
9187 lastProps = getHostProps$1(domElement, lastRawProps);
9188 nextProps = getHostProps$1(domElement, nextRawProps);
9189 updatePayload = [];
9190 break;
9191
9192 case 'select':
9193 lastProps = getHostProps$2(domElement, lastRawProps);
9194 nextProps = getHostProps$2(domElement, nextRawProps);
9195 updatePayload = [];
9196 break;
9197
9198 case 'textarea':
9199 lastProps = getHostProps$3(domElement, lastRawProps);
9200 nextProps = getHostProps$3(domElement, nextRawProps);
9201 updatePayload = [];
9202 break;
9203
9204 default:
9205 lastProps = lastRawProps;
9206 nextProps = nextRawProps;
9207
9208 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9209 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9210 trapClickOnNonInteractiveElement(domElement);
9211 }
9212
9213 break;
9214 }
9215
9216 assertValidProps(tag, nextProps);
9217 var propKey;
9218 var styleName;
9219 var styleUpdates = null;
9220
9221 for (propKey in lastProps) {
9222 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
9223 continue;
9224 }
9225
9226 if (propKey === STYLE) {
9227 var lastStyle = lastProps[propKey];
9228
9229 for (styleName in lastStyle) {
9230 if (lastStyle.hasOwnProperty(styleName)) {
9231 if (!styleUpdates) {
9232 styleUpdates = {};
9233 }
9234
9235 styleUpdates[styleName] = '';
9236 }
9237 }
9238 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9239 // This is a special case. If any listener updates we need to ensure
9240 // that the "current" fiber pointer gets updated so we need a commit
9241 // to update this element.
9242 if (!updatePayload) {
9243 updatePayload = [];
9244 }
9245 } else {
9246 // For all other deleted properties we add it to the queue. We use
9247 // the allowed property list in the commit phase instead.
9248 (updatePayload = updatePayload || []).push(propKey, null);
9249 }
9250 }
9251
9252 for (propKey in nextProps) {
9253 var nextProp = nextProps[propKey];
9254 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
9255
9256 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
9257 continue;
9258 }
9259
9260 if (propKey === STYLE) {
9261 {
9262 if (nextProp) {
9263 // Freeze the next style object so that we can assume it won't be
9264 // mutated. We have already warned for this in the past.
9265 Object.freeze(nextProp);
9266 }
9267 }
9268
9269 if (lastProp) {
9270 // Unset styles on `lastProp` but not on `nextProp`.
9271 for (styleName in lastProp) {
9272 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
9273 if (!styleUpdates) {
9274 styleUpdates = {};
9275 }
9276
9277 styleUpdates[styleName] = '';
9278 }
9279 } // Update styles that changed since `lastProp`.
9280
9281
9282 for (styleName in nextProp) {
9283 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
9284 if (!styleUpdates) {
9285 styleUpdates = {};
9286 }
9287
9288 styleUpdates[styleName] = nextProp[styleName];
9289 }
9290 }
9291 } else {
9292 // Relies on `updateStylesByID` not mutating `styleUpdates`.
9293 if (!styleUpdates) {
9294 if (!updatePayload) {
9295 updatePayload = [];
9296 }
9297
9298 updatePayload.push(propKey, styleUpdates);
9299 }
9300
9301 styleUpdates = nextProp;
9302 }
9303 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9304 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9305 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
9306
9307 if (nextHtml != null) {
9308 if (lastHtml !== nextHtml) {
9309 (updatePayload = updatePayload || []).push(propKey, nextHtml);
9310 }
9311 }
9312 } else if (propKey === CHILDREN) {
9313 if (typeof nextProp === 'string' || typeof nextProp === 'number') {
9314 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
9315 }
9316 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9317 if (nextProp != null) {
9318 // We eagerly listen to this even though we haven't committed yet.
9319 if ( typeof nextProp !== 'function') {
9320 warnForInvalidEventListener(propKey, nextProp);
9321 }
9322
9323 if (propKey === 'onScroll') {
9324 listenToNonDelegatedEvent('scroll', domElement);
9325 }
9326 }
9327
9328 if (!updatePayload && lastProp !== nextProp) {
9329 // This is a special case. If any listener updates we need to ensure
9330 // that the "current" props pointer gets updated so we need a commit
9331 // to update this element.
9332 updatePayload = [];
9333 }
9334 } else if (typeof nextProp === 'object' && nextProp !== null && nextProp.$$typeof === REACT_OPAQUE_ID_TYPE) {
9335 // If we encounter useOpaqueReference's opaque object, this means we are hydrating.
9336 // In this case, call the opaque object's toString function which generates a new client
9337 // ID so client and server IDs match and throws to rerender.
9338 nextProp.toString();
9339 } else {
9340 // For any other property we always add it to the queue and then we
9341 // filter it out using the allowed property list during the commit.
9342 (updatePayload = updatePayload || []).push(propKey, nextProp);
9343 }
9344 }
9345
9346 if (styleUpdates) {
9347 {
9348 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
9349 }
9350
9351 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
9352 }
9353
9354 return updatePayload;
9355} // Apply the diff.
9356
9357function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
9358 // Update checked *before* name.
9359 // In the middle of an update, it is possible to have multiple checked.
9360 // When a checked radio tries to change name, browser makes another radio's checked false.
9361 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
9362 updateChecked(domElement, nextRawProps);
9363 }
9364
9365 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
9366 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
9367
9368 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
9369 // changed.
9370
9371 switch (tag) {
9372 case 'input':
9373 // Update the wrapper around inputs *after* updating props. This has to
9374 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
9375 // raise warnings and prevent the new value from being assigned.
9376 updateWrapper(domElement, nextRawProps);
9377 break;
9378
9379 case 'textarea':
9380 updateWrapper$1(domElement, nextRawProps);
9381 break;
9382
9383 case 'select':
9384 // <select> value update needs to occur after <option> children
9385 // reconciliation
9386 postUpdateWrapper(domElement, nextRawProps);
9387 break;
9388 }
9389}
9390
9391function getPossibleStandardName(propName) {
9392 {
9393 var lowerCasedName = propName.toLowerCase();
9394
9395 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
9396 return null;
9397 }
9398
9399 return possibleStandardNames[lowerCasedName] || null;
9400 }
9401}
9402
9403function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
9404 var isCustomComponentTag;
9405 var extraAttributeNames;
9406
9407 {
9408 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
9409 isCustomComponentTag = isCustomComponent(tag, rawProps);
9410 validatePropertiesInDevelopment(tag, rawProps);
9411 } // TODO: Make sure that we check isMounted before firing any of these events.
9412
9413
9414 switch (tag) {
9415 case 'dialog':
9416 listenToNonDelegatedEvent('cancel', domElement);
9417 listenToNonDelegatedEvent('close', domElement);
9418 break;
9419
9420 case 'iframe':
9421 case 'object':
9422 case 'embed':
9423 // We listen to this event in case to ensure emulated bubble
9424 // listeners still fire for the load event.
9425 listenToNonDelegatedEvent('load', domElement);
9426 break;
9427
9428 case 'video':
9429 case 'audio':
9430 // We listen to these events in case to ensure emulated bubble
9431 // listeners still fire for all the media events.
9432 for (var i = 0; i < mediaEventTypes.length; i++) {
9433 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9434 }
9435
9436 break;
9437
9438 case 'source':
9439 // We listen to this event in case to ensure emulated bubble
9440 // listeners still fire for the error event.
9441 listenToNonDelegatedEvent('error', domElement);
9442 break;
9443
9444 case 'img':
9445 case 'image':
9446 case 'link':
9447 // We listen to these events in case to ensure emulated bubble
9448 // listeners still fire for error and load events.
9449 listenToNonDelegatedEvent('error', domElement);
9450 listenToNonDelegatedEvent('load', domElement);
9451 break;
9452
9453 case 'details':
9454 // We listen to this event in case to ensure emulated bubble
9455 // listeners still fire for the toggle event.
9456 listenToNonDelegatedEvent('toggle', domElement);
9457 break;
9458
9459 case 'input':
9460 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9461 // listeners still fire for the invalid event.
9462
9463 listenToNonDelegatedEvent('invalid', domElement);
9464
9465 break;
9466
9467 case 'option':
9468 validateProps(domElement, rawProps);
9469 break;
9470
9471 case 'select':
9472 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9473 // listeners still fire for the invalid event.
9474
9475 listenToNonDelegatedEvent('invalid', domElement);
9476
9477 break;
9478
9479 case 'textarea':
9480 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9481 // listeners still fire for the invalid event.
9482
9483 listenToNonDelegatedEvent('invalid', domElement);
9484
9485 break;
9486 }
9487
9488 assertValidProps(tag, rawProps);
9489
9490 {
9491 extraAttributeNames = new Set();
9492 var attributes = domElement.attributes;
9493
9494 for (var _i = 0; _i < attributes.length; _i++) {
9495 var name = attributes[_i].name.toLowerCase();
9496
9497 switch (name) {
9498 // Built-in SSR attribute is allowed
9499 case 'data-reactroot':
9500 break;
9501 // Controlled attributes are not validated
9502 // TODO: Only ignore them on controlled tags.
9503
9504 case 'value':
9505 break;
9506
9507 case 'checked':
9508 break;
9509
9510 case 'selected':
9511 break;
9512
9513 default:
9514 // Intentionally use the original name.
9515 // See discussion in https://github.com/facebook/react/pull/10676.
9516 extraAttributeNames.add(attributes[_i].name);
9517 }
9518 }
9519 }
9520
9521 var updatePayload = null;
9522
9523 for (var propKey in rawProps) {
9524 if (!rawProps.hasOwnProperty(propKey)) {
9525 continue;
9526 }
9527
9528 var nextProp = rawProps[propKey];
9529
9530 if (propKey === CHILDREN) {
9531 // For text content children we compare against textContent. This
9532 // might match additional HTML that is hidden when we read it using
9533 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
9534 // satisfies our requirement. Our requirement is not to produce perfect
9535 // HTML and attributes. Ideally we should preserve structure but it's
9536 // ok not to if the visible content is still enough to indicate what
9537 // even listeners these nodes might be wired up to.
9538 // TODO: Warn if there is more than a single textNode as a child.
9539 // TODO: Should we use domElement.firstChild.nodeValue to compare?
9540 if (typeof nextProp === 'string') {
9541 if (domElement.textContent !== nextProp) {
9542 if ( !suppressHydrationWarning) {
9543 warnForTextDifference(domElement.textContent, nextProp);
9544 }
9545
9546 updatePayload = [CHILDREN, nextProp];
9547 }
9548 } else if (typeof nextProp === 'number') {
9549 if (domElement.textContent !== '' + nextProp) {
9550 if ( !suppressHydrationWarning) {
9551 warnForTextDifference(domElement.textContent, nextProp);
9552 }
9553
9554 updatePayload = [CHILDREN, '' + nextProp];
9555 }
9556 }
9557 } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9558 if (nextProp != null) {
9559 if ( typeof nextProp !== 'function') {
9560 warnForInvalidEventListener(propKey, nextProp);
9561 }
9562
9563 if (propKey === 'onScroll') {
9564 listenToNonDelegatedEvent('scroll', domElement);
9565 }
9566 }
9567 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)
9568 typeof isCustomComponentTag === 'boolean') {
9569 // Validate that the properties correspond to their expected values.
9570 var serverValue = void 0;
9571 var propertyInfo = getPropertyInfo(propKey);
9572
9573 if (suppressHydrationWarning) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
9574 // TODO: Only ignore them on controlled tags.
9575 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9576 var serverHTML = domElement.innerHTML;
9577 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9578
9579 if (nextHtml != null) {
9580 var expectedHTML = normalizeHTML(domElement, nextHtml);
9581
9582 if (expectedHTML !== serverHTML) {
9583 warnForPropDifference(propKey, serverHTML, expectedHTML);
9584 }
9585 }
9586 } else if (propKey === STYLE) {
9587 // $FlowFixMe - Should be inferred as not undefined.
9588 extraAttributeNames.delete(propKey);
9589
9590 if (canDiffStyleForHydrationWarning) {
9591 var expectedStyle = createDangerousStringForStyles(nextProp);
9592 serverValue = domElement.getAttribute('style');
9593
9594 if (expectedStyle !== serverValue) {
9595 warnForPropDifference(propKey, serverValue, expectedStyle);
9596 }
9597 }
9598 } else if (isCustomComponentTag) {
9599 // $FlowFixMe - Should be inferred as not undefined.
9600 extraAttributeNames.delete(propKey.toLowerCase());
9601 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9602
9603 if (nextProp !== serverValue) {
9604 warnForPropDifference(propKey, serverValue, nextProp);
9605 }
9606 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
9607 var isMismatchDueToBadCasing = false;
9608
9609 if (propertyInfo !== null) {
9610 // $FlowFixMe - Should be inferred as not undefined.
9611 extraAttributeNames.delete(propertyInfo.attributeName);
9612 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
9613 } else {
9614 var ownNamespace = parentNamespace;
9615
9616 if (ownNamespace === HTML_NAMESPACE$1) {
9617 ownNamespace = getIntrinsicNamespace(tag);
9618 }
9619
9620 if (ownNamespace === HTML_NAMESPACE$1) {
9621 // $FlowFixMe - Should be inferred as not undefined.
9622 extraAttributeNames.delete(propKey.toLowerCase());
9623 } else {
9624 var standardName = getPossibleStandardName(propKey);
9625
9626 if (standardName !== null && standardName !== propKey) {
9627 // If an SVG prop is supplied with bad casing, it will
9628 // be successfully parsed from HTML, but will produce a mismatch
9629 // (and would be incorrectly rendered on the client).
9630 // However, we already warn about bad casing elsewhere.
9631 // So we'll skip the misleading extra mismatch warning in this case.
9632 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
9633
9634 extraAttributeNames.delete(standardName);
9635 } // $FlowFixMe - Should be inferred as not undefined.
9636
9637
9638 extraAttributeNames.delete(propKey);
9639 }
9640
9641 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9642 }
9643
9644 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
9645 warnForPropDifference(propKey, serverValue, nextProp);
9646 }
9647 }
9648 }
9649 }
9650
9651 {
9652 // $FlowFixMe - Should be inferred as not undefined.
9653 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
9654 // $FlowFixMe - Should be inferred as not undefined.
9655 warnForExtraAttributes(extraAttributeNames);
9656 }
9657 }
9658
9659 switch (tag) {
9660 case 'input':
9661 // TODO: Make sure we check if this is still unmounted or do any clean
9662 // up necessary since we never stop tracking anymore.
9663 track(domElement);
9664 postMountWrapper(domElement, rawProps, true);
9665 break;
9666
9667 case 'textarea':
9668 // TODO: Make sure we check if this is still unmounted or do any clean
9669 // up necessary since we never stop tracking anymore.
9670 track(domElement);
9671 postMountWrapper$3(domElement);
9672 break;
9673
9674 case 'select':
9675 case 'option':
9676 // For input and textarea we current always set the value property at
9677 // post mount to force it to diverge from attributes. However, for
9678 // option and select we don't quite do the same thing and select
9679 // is not resilient to the DOM state changing so we don't do that here.
9680 // TODO: Consider not doing this for input and textarea.
9681 break;
9682
9683 default:
9684 if (typeof rawProps.onClick === 'function') {
9685 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9686 trapClickOnNonInteractiveElement(domElement);
9687 }
9688
9689 break;
9690 }
9691
9692 return updatePayload;
9693}
9694function diffHydratedText(textNode, text) {
9695 var isDifferent = textNode.nodeValue !== text;
9696 return isDifferent;
9697}
9698function warnForUnmatchedText(textNode, text) {
9699 {
9700 warnForTextDifference(textNode.nodeValue, text);
9701 }
9702}
9703function warnForDeletedHydratableElement(parentNode, child) {
9704 {
9705 if (didWarnInvalidHydration) {
9706 return;
9707 }
9708
9709 didWarnInvalidHydration = true;
9710
9711 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
9712 }
9713}
9714function warnForDeletedHydratableText(parentNode, child) {
9715 {
9716 if (didWarnInvalidHydration) {
9717 return;
9718 }
9719
9720 didWarnInvalidHydration = true;
9721
9722 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
9723 }
9724}
9725function warnForInsertedHydratedElement(parentNode, tag, props) {
9726 {
9727 if (didWarnInvalidHydration) {
9728 return;
9729 }
9730
9731 didWarnInvalidHydration = true;
9732
9733 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
9734 }
9735}
9736function warnForInsertedHydratedText(parentNode, text) {
9737 {
9738 if (text === '') {
9739 // We expect to insert empty text nodes since they're not represented in
9740 // the HTML.
9741 // TODO: Remove this special case if we can just avoid inserting empty
9742 // text nodes.
9743 return;
9744 }
9745
9746 if (didWarnInvalidHydration) {
9747 return;
9748 }
9749
9750 didWarnInvalidHydration = true;
9751
9752 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
9753 }
9754}
9755function restoreControlledState$3(domElement, tag, props) {
9756 switch (tag) {
9757 case 'input':
9758 restoreControlledState(domElement, props);
9759 return;
9760
9761 case 'textarea':
9762 restoreControlledState$2(domElement, props);
9763 return;
9764
9765 case 'select':
9766 restoreControlledState$1(domElement, props);
9767 return;
9768 }
9769}
9770
9771var validateDOMNesting = function () {};
9772
9773var updatedAncestorInfo = function () {};
9774
9775{
9776 // This validation code was written based on the HTML5 parsing spec:
9777 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9778 //
9779 // Note: this does not catch all invalid nesting, nor does it try to (as it's
9780 // not clear what practical benefit doing so provides); instead, we warn only
9781 // for cases where the parser will give a parse tree differing from what React
9782 // intended. For example, <b><div></div></b> is invalid but we don't warn
9783 // because it still parses correctly; we do warn for other cases like nested
9784 // <p> tags where the beginning of the second element implicitly closes the
9785 // first, causing a confusing mess.
9786 // https://html.spec.whatwg.org/multipage/syntax.html#special
9787 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9788
9789 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
9790 // TODO: Distinguish by namespace here -- for <title>, including it here
9791 // errs on the side of fewer warnings
9792 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
9793
9794 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
9795
9796 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
9797 var emptyAncestorInfo = {
9798 current: null,
9799 formTag: null,
9800 aTagInScope: null,
9801 buttonTagInScope: null,
9802 nobrTagInScope: null,
9803 pTagInButtonScope: null,
9804 listItemTagAutoclosing: null,
9805 dlItemTagAutoclosing: null
9806 };
9807
9808 updatedAncestorInfo = function (oldInfo, tag) {
9809 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
9810
9811 var info = {
9812 tag: tag
9813 };
9814
9815 if (inScopeTags.indexOf(tag) !== -1) {
9816 ancestorInfo.aTagInScope = null;
9817 ancestorInfo.buttonTagInScope = null;
9818 ancestorInfo.nobrTagInScope = null;
9819 }
9820
9821 if (buttonScopeTags.indexOf(tag) !== -1) {
9822 ancestorInfo.pTagInButtonScope = null;
9823 } // See rules for 'li', 'dd', 'dt' start tags in
9824 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9825
9826
9827 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
9828 ancestorInfo.listItemTagAutoclosing = null;
9829 ancestorInfo.dlItemTagAutoclosing = null;
9830 }
9831
9832 ancestorInfo.current = info;
9833
9834 if (tag === 'form') {
9835 ancestorInfo.formTag = info;
9836 }
9837
9838 if (tag === 'a') {
9839 ancestorInfo.aTagInScope = info;
9840 }
9841
9842 if (tag === 'button') {
9843 ancestorInfo.buttonTagInScope = info;
9844 }
9845
9846 if (tag === 'nobr') {
9847 ancestorInfo.nobrTagInScope = info;
9848 }
9849
9850 if (tag === 'p') {
9851 ancestorInfo.pTagInButtonScope = info;
9852 }
9853
9854 if (tag === 'li') {
9855 ancestorInfo.listItemTagAutoclosing = info;
9856 }
9857
9858 if (tag === 'dd' || tag === 'dt') {
9859 ancestorInfo.dlItemTagAutoclosing = info;
9860 }
9861
9862 return ancestorInfo;
9863 };
9864 /**
9865 * Returns whether
9866 */
9867
9868
9869 var isTagValidWithParent = function (tag, parentTag) {
9870 // First, let's check if we're in an unusual parsing mode...
9871 switch (parentTag) {
9872 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
9873 case 'select':
9874 return tag === 'option' || tag === 'optgroup' || tag === '#text';
9875
9876 case 'optgroup':
9877 return tag === 'option' || tag === '#text';
9878 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
9879 // but
9880
9881 case 'option':
9882 return tag === '#text';
9883 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
9884 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
9885 // No special behavior since these rules fall back to "in body" mode for
9886 // all except special table nodes which cause bad parsing behavior anyway.
9887 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
9888
9889 case 'tr':
9890 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
9891 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
9892
9893 case 'tbody':
9894 case 'thead':
9895 case 'tfoot':
9896 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
9897 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
9898
9899 case 'colgroup':
9900 return tag === 'col' || tag === 'template';
9901 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
9902
9903 case 'table':
9904 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
9905 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
9906
9907 case 'head':
9908 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
9909 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
9910
9911 case 'html':
9912 return tag === 'head' || tag === 'body' || tag === 'frameset';
9913
9914 case 'frameset':
9915 return tag === 'frame';
9916
9917 case '#document':
9918 return tag === 'html';
9919 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
9920 // where the parsing rules cause implicit opens or closes to be added.
9921 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9922
9923
9924 switch (tag) {
9925 case 'h1':
9926 case 'h2':
9927 case 'h3':
9928 case 'h4':
9929 case 'h5':
9930 case 'h6':
9931 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
9932
9933 case 'rp':
9934 case 'rt':
9935 return impliedEndTags.indexOf(parentTag) === -1;
9936
9937 case 'body':
9938 case 'caption':
9939 case 'col':
9940 case 'colgroup':
9941 case 'frameset':
9942 case 'frame':
9943 case 'head':
9944 case 'html':
9945 case 'tbody':
9946 case 'td':
9947 case 'tfoot':
9948 case 'th':
9949 case 'thead':
9950 case 'tr':
9951 // These tags are only valid with a few parents that have special child
9952 // parsing rules -- if we're down here, then none of those matched and
9953 // so we allow it only if we don't know what the parent is, as all other
9954 // cases are invalid.
9955 return parentTag == null;
9956 }
9957
9958 return true;
9959 };
9960 /**
9961 * Returns whether
9962 */
9963
9964
9965 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
9966 switch (tag) {
9967 case 'address':
9968 case 'article':
9969 case 'aside':
9970 case 'blockquote':
9971 case 'center':
9972 case 'details':
9973 case 'dialog':
9974 case 'dir':
9975 case 'div':
9976 case 'dl':
9977 case 'fieldset':
9978 case 'figcaption':
9979 case 'figure':
9980 case 'footer':
9981 case 'header':
9982 case 'hgroup':
9983 case 'main':
9984 case 'menu':
9985 case 'nav':
9986 case 'ol':
9987 case 'p':
9988 case 'section':
9989 case 'summary':
9990 case 'ul':
9991 case 'pre':
9992 case 'listing':
9993 case 'table':
9994 case 'hr':
9995 case 'xmp':
9996 case 'h1':
9997 case 'h2':
9998 case 'h3':
9999 case 'h4':
10000 case 'h5':
10001 case 'h6':
10002 return ancestorInfo.pTagInButtonScope;
10003
10004 case 'form':
10005 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
10006
10007 case 'li':
10008 return ancestorInfo.listItemTagAutoclosing;
10009
10010 case 'dd':
10011 case 'dt':
10012 return ancestorInfo.dlItemTagAutoclosing;
10013
10014 case 'button':
10015 return ancestorInfo.buttonTagInScope;
10016
10017 case 'a':
10018 // Spec says something about storing a list of markers, but it sounds
10019 // equivalent to this check.
10020 return ancestorInfo.aTagInScope;
10021
10022 case 'nobr':
10023 return ancestorInfo.nobrTagInScope;
10024 }
10025
10026 return null;
10027 };
10028
10029 var didWarn$1 = {};
10030
10031 validateDOMNesting = function (childTag, childText, ancestorInfo) {
10032 ancestorInfo = ancestorInfo || emptyAncestorInfo;
10033 var parentInfo = ancestorInfo.current;
10034 var parentTag = parentInfo && parentInfo.tag;
10035
10036 if (childText != null) {
10037 if (childTag != null) {
10038 error('validateDOMNesting: when childText is passed, childTag should be null');
10039 }
10040
10041 childTag = '#text';
10042 }
10043
10044 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
10045 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
10046 var invalidParentOrAncestor = invalidParent || invalidAncestor;
10047
10048 if (!invalidParentOrAncestor) {
10049 return;
10050 }
10051
10052 var ancestorTag = invalidParentOrAncestor.tag;
10053 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag;
10054
10055 if (didWarn$1[warnKey]) {
10056 return;
10057 }
10058
10059 didWarn$1[warnKey] = true;
10060 var tagDisplayName = childTag;
10061 var whitespaceInfo = '';
10062
10063 if (childTag === '#text') {
10064 if (/\S/.test(childText)) {
10065 tagDisplayName = 'Text nodes';
10066 } else {
10067 tagDisplayName = 'Whitespace text nodes';
10068 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
10069 }
10070 } else {
10071 tagDisplayName = '<' + childTag + '>';
10072 }
10073
10074 if (invalidParent) {
10075 var info = '';
10076
10077 if (ancestorTag === 'table' && childTag === 'tr') {
10078 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
10079 }
10080
10081 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
10082 } else {
10083 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
10084 }
10085 };
10086}
10087
10088var SUPPRESS_HYDRATION_WARNING$1;
10089
10090{
10091 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
10092}
10093
10094var SUSPENSE_START_DATA = '$';
10095var SUSPENSE_END_DATA = '/$';
10096var SUSPENSE_PENDING_START_DATA = '$?';
10097var SUSPENSE_FALLBACK_START_DATA = '$!';
10098var STYLE$1 = 'style';
10099var eventsEnabled = null;
10100var selectionInformation = null;
10101
10102function shouldAutoFocusHostComponent(type, props) {
10103 switch (type) {
10104 case 'button':
10105 case 'input':
10106 case 'select':
10107 case 'textarea':
10108 return !!props.autoFocus;
10109 }
10110
10111 return false;
10112}
10113function getRootHostContext(rootContainerInstance) {
10114 var type;
10115 var namespace;
10116 var nodeType = rootContainerInstance.nodeType;
10117
10118 switch (nodeType) {
10119 case DOCUMENT_NODE:
10120 case DOCUMENT_FRAGMENT_NODE:
10121 {
10122 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10123 var root = rootContainerInstance.documentElement;
10124 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10125 break;
10126 }
10127
10128 default:
10129 {
10130 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10131 var ownNamespace = container.namespaceURI || null;
10132 type = container.tagName;
10133 namespace = getChildNamespace(ownNamespace, type);
10134 break;
10135 }
10136 }
10137
10138 {
10139 var validatedTag = type.toLowerCase();
10140 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
10141 return {
10142 namespace: namespace,
10143 ancestorInfo: ancestorInfo
10144 };
10145 }
10146}
10147function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10148 {
10149 var parentHostContextDev = parentHostContext;
10150 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
10151 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10152 return {
10153 namespace: namespace,
10154 ancestorInfo: ancestorInfo
10155 };
10156 }
10157}
10158function getPublicInstance(instance) {
10159 return instance;
10160}
10161function prepareForCommit(containerInfo) {
10162 eventsEnabled = isEnabled();
10163 selectionInformation = getSelectionInformation();
10164 var activeInstance = null;
10165
10166 setEnabled(false);
10167 return activeInstance;
10168}
10169function resetAfterCommit(containerInfo) {
10170 restoreSelection(selectionInformation);
10171 setEnabled(eventsEnabled);
10172 eventsEnabled = null;
10173 selectionInformation = null;
10174}
10175function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10176 var parentNamespace;
10177
10178 {
10179 // TODO: take namespace into account when validating.
10180 var hostContextDev = hostContext;
10181 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10182
10183 if (typeof props.children === 'string' || typeof props.children === 'number') {
10184 var string = '' + props.children;
10185 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10186 validateDOMNesting(null, string, ownAncestorInfo);
10187 }
10188
10189 parentNamespace = hostContextDev.namespace;
10190 }
10191
10192 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10193 precacheFiberNode(internalInstanceHandle, domElement);
10194 updateFiberProps(domElement, props);
10195 return domElement;
10196}
10197function appendInitialChild(parentInstance, child) {
10198 parentInstance.appendChild(child);
10199}
10200function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10201 setInitialProperties(domElement, type, props, rootContainerInstance);
10202 return shouldAutoFocusHostComponent(type, props);
10203}
10204function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10205 {
10206 var hostContextDev = hostContext;
10207
10208 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10209 var string = '' + newProps.children;
10210 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10211 validateDOMNesting(null, string, ownAncestorInfo);
10212 }
10213 }
10214
10215 return diffProperties(domElement, type, oldProps, newProps);
10216}
10217function shouldSetTextContent(type, props) {
10218 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
10219}
10220function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10221 {
10222 var hostContextDev = hostContext;
10223 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10224 }
10225
10226 var textNode = createTextNode(text, rootContainerInstance);
10227 precacheFiberNode(internalInstanceHandle, textNode);
10228 return textNode;
10229}
10230// if a component just imports ReactDOM (e.g. for findDOMNode).
10231// Some environments might not have setTimeout or clearTimeout.
10232
10233var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
10234var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
10235var noTimeout = -1; // -------------------
10236function commitMount(domElement, type, newProps, internalInstanceHandle) {
10237 // Despite the naming that might imply otherwise, this method only
10238 // fires if there is an `Update` effect scheduled during mounting.
10239 // This happens if `finalizeInitialChildren` returns `true` (which it
10240 // does to implement the `autoFocus` attribute on the client). But
10241 // there are also other cases when this might happen (such as patching
10242 // up text content during hydration mismatch). So we'll check this again.
10243 if (shouldAutoFocusHostComponent(type, newProps)) {
10244 domElement.focus();
10245 }
10246}
10247function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
10248 // Update the props handle so that we know which props are the ones with
10249 // with current event handlers.
10250 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
10251
10252 updateProperties(domElement, updatePayload, type, oldProps, newProps);
10253}
10254function resetTextContent(domElement) {
10255 setTextContent(domElement, '');
10256}
10257function commitTextUpdate(textInstance, oldText, newText) {
10258 textInstance.nodeValue = newText;
10259}
10260function appendChild(parentInstance, child) {
10261 parentInstance.appendChild(child);
10262}
10263function appendChildToContainer(container, child) {
10264 var parentNode;
10265
10266 if (container.nodeType === COMMENT_NODE) {
10267 parentNode = container.parentNode;
10268 parentNode.insertBefore(child, container);
10269 } else {
10270 parentNode = container;
10271 parentNode.appendChild(child);
10272 } // This container might be used for a portal.
10273 // If something inside a portal is clicked, that click should bubble
10274 // through the React tree. However, on Mobile Safari the click would
10275 // never bubble through the *DOM* tree unless an ancestor with onclick
10276 // event exists. So we wouldn't see it and dispatch it.
10277 // This is why we ensure that non React root containers have inline onclick
10278 // defined.
10279 // https://github.com/facebook/react/issues/11918
10280
10281
10282 var reactRootContainer = container._reactRootContainer;
10283
10284 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
10285 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10286 trapClickOnNonInteractiveElement(parentNode);
10287 }
10288}
10289function insertBefore(parentInstance, child, beforeChild) {
10290 parentInstance.insertBefore(child, beforeChild);
10291}
10292function insertInContainerBefore(container, child, beforeChild) {
10293 if (container.nodeType === COMMENT_NODE) {
10294 container.parentNode.insertBefore(child, beforeChild);
10295 } else {
10296 container.insertBefore(child, beforeChild);
10297 }
10298}
10299
10300function removeChild(parentInstance, child) {
10301 parentInstance.removeChild(child);
10302}
10303function removeChildFromContainer(container, child) {
10304 if (container.nodeType === COMMENT_NODE) {
10305 container.parentNode.removeChild(child);
10306 } else {
10307 container.removeChild(child);
10308 }
10309}
10310function hideInstance(instance) {
10311 // TODO: Does this work for all element types? What about MathML? Should we
10312 // pass host context to this method?
10313 instance = instance;
10314 var style = instance.style;
10315
10316 if (typeof style.setProperty === 'function') {
10317 style.setProperty('display', 'none', 'important');
10318 } else {
10319 style.display = 'none';
10320 }
10321}
10322function hideTextInstance(textInstance) {
10323 textInstance.nodeValue = '';
10324}
10325function unhideInstance(instance, props) {
10326 instance = instance;
10327 var styleProp = props[STYLE$1];
10328 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
10329 instance.style.display = dangerousStyleValue('display', display);
10330}
10331function unhideTextInstance(textInstance, text) {
10332 textInstance.nodeValue = text;
10333}
10334function clearContainer(container) {
10335 if (container.nodeType === ELEMENT_NODE) {
10336 container.textContent = '';
10337 } else if (container.nodeType === DOCUMENT_NODE) {
10338 var body = container.body;
10339
10340 if (body != null) {
10341 body.textContent = '';
10342 }
10343 }
10344} // -------------------
10345function canHydrateInstance(instance, type, props) {
10346 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
10347 return null;
10348 } // This has now been refined to an element node.
10349
10350
10351 return instance;
10352}
10353function canHydrateTextInstance(instance, text) {
10354 if (text === '' || instance.nodeType !== TEXT_NODE) {
10355 // Empty strings are not parsed by HTML so there won't be a correct match here.
10356 return null;
10357 } // This has now been refined to a text node.
10358
10359
10360 return instance;
10361}
10362function isSuspenseInstancePending(instance) {
10363 return instance.data === SUSPENSE_PENDING_START_DATA;
10364}
10365function isSuspenseInstanceFallback(instance) {
10366 return instance.data === SUSPENSE_FALLBACK_START_DATA;
10367}
10368
10369function getNextHydratable(node) {
10370 // Skip non-hydratable nodes.
10371 for (; node != null; node = node.nextSibling) {
10372 var nodeType = node.nodeType;
10373
10374 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
10375 break;
10376 }
10377 }
10378
10379 return node;
10380}
10381
10382function getNextHydratableSibling(instance) {
10383 return getNextHydratable(instance.nextSibling);
10384}
10385function getFirstHydratableChild(parentInstance) {
10386 return getNextHydratable(parentInstance.firstChild);
10387}
10388function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10389 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
10390 // get attached.
10391
10392 updateFiberProps(instance, props);
10393 var parentNamespace;
10394
10395 {
10396 var hostContextDev = hostContext;
10397 parentNamespace = hostContextDev.namespace;
10398 }
10399
10400 return diffHydratedProperties(instance, type, props, parentNamespace);
10401}
10402function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
10403 precacheFiberNode(internalInstanceHandle, textInstance);
10404 return diffHydratedText(textInstance, text);
10405}
10406function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
10407 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
10408 // There might be nested nodes so we need to keep track of how
10409 // deep we are and only break out when we're back on top.
10410
10411 var depth = 0;
10412
10413 while (node) {
10414 if (node.nodeType === COMMENT_NODE) {
10415 var data = node.data;
10416
10417 if (data === SUSPENSE_END_DATA) {
10418 if (depth === 0) {
10419 return getNextHydratableSibling(node);
10420 } else {
10421 depth--;
10422 }
10423 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
10424 depth++;
10425 }
10426 }
10427
10428 node = node.nextSibling;
10429 } // TODO: Warn, we didn't find the end comment boundary.
10430
10431
10432 return null;
10433} // Returns the SuspenseInstance if this node is a direct child of a
10434// SuspenseInstance. I.e. if its previous sibling is a Comment with
10435// SUSPENSE_x_START_DATA. Otherwise, null.
10436
10437function getParentSuspenseInstance(targetInstance) {
10438 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
10439 // There might be nested nodes so we need to keep track of how
10440 // deep we are and only break out when we're back on top.
10441
10442 var depth = 0;
10443
10444 while (node) {
10445 if (node.nodeType === COMMENT_NODE) {
10446 var data = node.data;
10447
10448 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
10449 if (depth === 0) {
10450 return node;
10451 } else {
10452 depth--;
10453 }
10454 } else if (data === SUSPENSE_END_DATA) {
10455 depth++;
10456 }
10457 }
10458
10459 node = node.previousSibling;
10460 }
10461
10462 return null;
10463}
10464function commitHydratedContainer(container) {
10465 // Retry if any event replaying was blocked on this.
10466 retryIfBlockedOn(container);
10467}
10468function commitHydratedSuspenseInstance(suspenseInstance) {
10469 // Retry if any event replaying was blocked on this.
10470 retryIfBlockedOn(suspenseInstance);
10471}
10472function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
10473 {
10474 warnForUnmatchedText(textInstance, text);
10475 }
10476}
10477function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
10478 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10479 warnForUnmatchedText(textInstance, text);
10480 }
10481}
10482function didNotHydrateContainerInstance(parentContainer, instance) {
10483 {
10484 if (instance.nodeType === ELEMENT_NODE) {
10485 warnForDeletedHydratableElement(parentContainer, instance);
10486 } else if (instance.nodeType === COMMENT_NODE) ; else {
10487 warnForDeletedHydratableText(parentContainer, instance);
10488 }
10489 }
10490}
10491function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
10492 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10493 if (instance.nodeType === ELEMENT_NODE) {
10494 warnForDeletedHydratableElement(parentInstance, instance);
10495 } else if (instance.nodeType === COMMENT_NODE) ; else {
10496 warnForDeletedHydratableText(parentInstance, instance);
10497 }
10498 }
10499}
10500function didNotFindHydratableContainerInstance(parentContainer, type, props) {
10501 {
10502 warnForInsertedHydratedElement(parentContainer, type);
10503 }
10504}
10505function didNotFindHydratableContainerTextInstance(parentContainer, text) {
10506 {
10507 warnForInsertedHydratedText(parentContainer, text);
10508 }
10509}
10510function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
10511 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10512 warnForInsertedHydratedElement(parentInstance, type);
10513 }
10514}
10515function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
10516 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
10517 warnForInsertedHydratedText(parentInstance, text);
10518 }
10519}
10520function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
10521 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
10522}
10523var clientId = 0;
10524function makeClientIdInDEV(warnOnAccessInDEV) {
10525 var id = 'r:' + (clientId++).toString(36);
10526 return {
10527 toString: function () {
10528 warnOnAccessInDEV();
10529 return id;
10530 },
10531 valueOf: function () {
10532 warnOnAccessInDEV();
10533 return id;
10534 }
10535 };
10536}
10537function isOpaqueHydratingObject(value) {
10538 return value !== null && typeof value === 'object' && value.$$typeof === REACT_OPAQUE_ID_TYPE;
10539}
10540function makeOpaqueHydratingObject(attemptToReadValue) {
10541 return {
10542 $$typeof: REACT_OPAQUE_ID_TYPE,
10543 toString: attemptToReadValue,
10544 valueOf: attemptToReadValue
10545 };
10546}
10547function preparePortalMount(portalInstance) {
10548 {
10549 listenToAllSupportedEvents(portalInstance);
10550 }
10551}
10552
10553var randomKey = Math.random().toString(36).slice(2);
10554var internalInstanceKey = '__reactFiber$' + randomKey;
10555var internalPropsKey = '__reactProps$' + randomKey;
10556var internalContainerInstanceKey = '__reactContainer$' + randomKey;
10557var internalEventHandlersKey = '__reactEvents$' + randomKey;
10558function precacheFiberNode(hostInst, node) {
10559 node[internalInstanceKey] = hostInst;
10560}
10561function markContainerAsRoot(hostRoot, node) {
10562 node[internalContainerInstanceKey] = hostRoot;
10563}
10564function unmarkContainerAsRoot(node) {
10565 node[internalContainerInstanceKey] = null;
10566}
10567function isContainerMarkedAsRoot(node) {
10568 return !!node[internalContainerInstanceKey];
10569} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
10570// If the target node is part of a hydrated or not yet rendered subtree, then
10571// this may also return a SuspenseComponent or HostRoot to indicate that.
10572// Conceptually the HostRoot fiber is a child of the Container node. So if you
10573// pass the Container node as the targetNode, you will not actually get the
10574// HostRoot back. To get to the HostRoot, you need to pass a child of it.
10575// The same thing applies to Suspense boundaries.
10576
10577function getClosestInstanceFromNode(targetNode) {
10578 var targetInst = targetNode[internalInstanceKey];
10579
10580 if (targetInst) {
10581 // Don't return HostRoot or SuspenseComponent here.
10582 return targetInst;
10583 } // If the direct event target isn't a React owned DOM node, we need to look
10584 // to see if one of its parents is a React owned DOM node.
10585
10586
10587 var parentNode = targetNode.parentNode;
10588
10589 while (parentNode) {
10590 // We'll check if this is a container root that could include
10591 // React nodes in the future. We need to check this first because
10592 // if we're a child of a dehydrated container, we need to first
10593 // find that inner container before moving on to finding the parent
10594 // instance. Note that we don't check this field on the targetNode
10595 // itself because the fibers are conceptually between the container
10596 // node and the first child. It isn't surrounding the container node.
10597 // If it's not a container, we check if it's an instance.
10598 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
10599
10600 if (targetInst) {
10601 // Since this wasn't the direct target of the event, we might have
10602 // stepped past dehydrated DOM nodes to get here. However they could
10603 // also have been non-React nodes. We need to answer which one.
10604 // If we the instance doesn't have any children, then there can't be
10605 // a nested suspense boundary within it. So we can use this as a fast
10606 // bailout. Most of the time, when people add non-React children to
10607 // the tree, it is using a ref to a child-less DOM node.
10608 // Normally we'd only need to check one of the fibers because if it
10609 // has ever gone from having children to deleting them or vice versa
10610 // it would have deleted the dehydrated boundary nested inside already.
10611 // However, since the HostRoot starts out with an alternate it might
10612 // have one on the alternate so we need to check in case this was a
10613 // root.
10614 var alternate = targetInst.alternate;
10615
10616 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
10617 // Next we need to figure out if the node that skipped past is
10618 // nested within a dehydrated boundary and if so, which one.
10619 var suspenseInstance = getParentSuspenseInstance(targetNode);
10620
10621 while (suspenseInstance !== null) {
10622 // We found a suspense instance. That means that we haven't
10623 // hydrated it yet. Even though we leave the comments in the
10624 // DOM after hydrating, and there are boundaries in the DOM
10625 // that could already be hydrated, we wouldn't have found them
10626 // through this pass since if the target is hydrated it would
10627 // have had an internalInstanceKey on it.
10628 // Let's get the fiber associated with the SuspenseComponent
10629 // as the deepest instance.
10630 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
10631
10632 if (targetSuspenseInst) {
10633 return targetSuspenseInst;
10634 } // If we don't find a Fiber on the comment, it might be because
10635 // we haven't gotten to hydrate it yet. There might still be a
10636 // parent boundary that hasn't above this one so we need to find
10637 // the outer most that is known.
10638
10639
10640 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
10641 // host component also hasn't hydrated yet. We can return it
10642 // below since it will bail out on the isMounted check later.
10643 }
10644 }
10645
10646 return targetInst;
10647 }
10648
10649 targetNode = parentNode;
10650 parentNode = targetNode.parentNode;
10651 }
10652
10653 return null;
10654}
10655/**
10656 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
10657 * instance, or null if the node was not rendered by this React.
10658 */
10659
10660function getInstanceFromNode(node) {
10661 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
10662
10663 if (inst) {
10664 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
10665 return inst;
10666 } else {
10667 return null;
10668 }
10669 }
10670
10671 return null;
10672}
10673/**
10674 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
10675 * DOM node.
10676 */
10677
10678function getNodeFromInstance(inst) {
10679 if (inst.tag === HostComponent || inst.tag === HostText) {
10680 // In Fiber this, is just the state node right now. We assume it will be
10681 // a host component or host text.
10682 return inst.stateNode;
10683 } // Without this first invariant, passing a non-DOM-component triggers the next
10684 // invariant for a missing parent, which is super confusing.
10685
10686
10687 {
10688 {
10689 throw Error( "getNodeFromInstance: Invalid argument." );
10690 }
10691 }
10692}
10693function getFiberCurrentPropsFromNode(node) {
10694 return node[internalPropsKey] || null;
10695}
10696function updateFiberProps(node, props) {
10697 node[internalPropsKey] = props;
10698}
10699function getEventListenerSet(node) {
10700 var elementListenerSet = node[internalEventHandlersKey];
10701
10702 if (elementListenerSet === undefined) {
10703 elementListenerSet = node[internalEventHandlersKey] = new Set();
10704 }
10705
10706 return elementListenerSet;
10707}
10708
10709var loggedTypeFailures = {};
10710var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
10711
10712function setCurrentlyValidatingElement(element) {
10713 {
10714 if (element) {
10715 var owner = element._owner;
10716 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
10717 ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
10718 } else {
10719 ReactDebugCurrentFrame$1.setExtraStackFrame(null);
10720 }
10721 }
10722}
10723
10724function checkPropTypes(typeSpecs, values, location, componentName, element) {
10725 {
10726 // $FlowFixMe This is okay but Flow doesn't know it.
10727 var has = Function.call.bind(Object.prototype.hasOwnProperty);
10728
10729 for (var typeSpecName in typeSpecs) {
10730 if (has(typeSpecs, typeSpecName)) {
10731 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
10732 // fail the render phase where it didn't fail before. So we log it.
10733 // After these have been cleaned up, we'll let them throw.
10734
10735 try {
10736 // This is intentionally an invariant that gets caught. It's the same
10737 // behavior as without this statement except with a better message.
10738 if (typeof typeSpecs[typeSpecName] !== 'function') {
10739 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`.');
10740 err.name = 'Invariant Violation';
10741 throw err;
10742 }
10743
10744 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
10745 } catch (ex) {
10746 error$1 = ex;
10747 }
10748
10749 if (error$1 && !(error$1 instanceof Error)) {
10750 setCurrentlyValidatingElement(element);
10751
10752 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);
10753
10754 setCurrentlyValidatingElement(null);
10755 }
10756
10757 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
10758 // Only monitor this failure once because there tends to be a lot of the
10759 // same error.
10760 loggedTypeFailures[error$1.message] = true;
10761 setCurrentlyValidatingElement(element);
10762
10763 error('Failed %s type: %s', location, error$1.message);
10764
10765 setCurrentlyValidatingElement(null);
10766 }
10767 }
10768 }
10769 }
10770}
10771
10772var valueStack = [];
10773var fiberStack;
10774
10775{
10776 fiberStack = [];
10777}
10778
10779var index = -1;
10780
10781function createCursor(defaultValue) {
10782 return {
10783 current: defaultValue
10784 };
10785}
10786
10787function pop(cursor, fiber) {
10788 if (index < 0) {
10789 {
10790 error('Unexpected pop.');
10791 }
10792
10793 return;
10794 }
10795
10796 {
10797 if (fiber !== fiberStack[index]) {
10798 error('Unexpected Fiber popped.');
10799 }
10800 }
10801
10802 cursor.current = valueStack[index];
10803 valueStack[index] = null;
10804
10805 {
10806 fiberStack[index] = null;
10807 }
10808
10809 index--;
10810}
10811
10812function push(cursor, value, fiber) {
10813 index++;
10814 valueStack[index] = cursor.current;
10815
10816 {
10817 fiberStack[index] = fiber;
10818 }
10819
10820 cursor.current = value;
10821}
10822
10823var warnedAboutMissingGetChildContext;
10824
10825{
10826 warnedAboutMissingGetChildContext = {};
10827}
10828
10829var emptyContextObject = {};
10830
10831{
10832 Object.freeze(emptyContextObject);
10833} // A cursor to the current merged context object on the stack.
10834
10835
10836var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
10837
10838var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
10839// We use this to get access to the parent context after we have already
10840// pushed the next context provider, and now need to merge their contexts.
10841
10842var previousContext = emptyContextObject;
10843
10844function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10845 {
10846 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10847 // If the fiber is a context provider itself, when we read its context
10848 // we may have already pushed its own child context on the stack. A context
10849 // provider should not "see" its own child context. Therefore we read the
10850 // previous (parent) context instead for a context provider.
10851 return previousContext;
10852 }
10853
10854 return contextStackCursor.current;
10855 }
10856}
10857
10858function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10859 {
10860 var instance = workInProgress.stateNode;
10861 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10862 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10863 }
10864}
10865
10866function getMaskedContext(workInProgress, unmaskedContext) {
10867 {
10868 var type = workInProgress.type;
10869 var contextTypes = type.contextTypes;
10870
10871 if (!contextTypes) {
10872 return emptyContextObject;
10873 } // Avoid recreating masked context unless unmasked context has changed.
10874 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10875 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10876
10877
10878 var instance = workInProgress.stateNode;
10879
10880 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10881 return instance.__reactInternalMemoizedMaskedChildContext;
10882 }
10883
10884 var context = {};
10885
10886 for (var key in contextTypes) {
10887 context[key] = unmaskedContext[key];
10888 }
10889
10890 {
10891 var name = getComponentName(type) || 'Unknown';
10892 checkPropTypes(contextTypes, context, 'context', name);
10893 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
10894 // Context is created before the class component is instantiated so check for instance.
10895
10896
10897 if (instance) {
10898 cacheContext(workInProgress, unmaskedContext, context);
10899 }
10900
10901 return context;
10902 }
10903}
10904
10905function hasContextChanged() {
10906 {
10907 return didPerformWorkStackCursor.current;
10908 }
10909}
10910
10911function isContextProvider(type) {
10912 {
10913 var childContextTypes = type.childContextTypes;
10914 return childContextTypes !== null && childContextTypes !== undefined;
10915 }
10916}
10917
10918function popContext(fiber) {
10919 {
10920 pop(didPerformWorkStackCursor, fiber);
10921 pop(contextStackCursor, fiber);
10922 }
10923}
10924
10925function popTopLevelContextObject(fiber) {
10926 {
10927 pop(didPerformWorkStackCursor, fiber);
10928 pop(contextStackCursor, fiber);
10929 }
10930}
10931
10932function pushTopLevelContextObject(fiber, context, didChange) {
10933 {
10934 if (!(contextStackCursor.current === emptyContextObject)) {
10935 {
10936 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
10937 }
10938 }
10939
10940 push(contextStackCursor, context, fiber);
10941 push(didPerformWorkStackCursor, didChange, fiber);
10942 }
10943}
10944
10945function processChildContext(fiber, type, parentContext) {
10946 {
10947 var instance = fiber.stateNode;
10948 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
10949 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
10950
10951 if (typeof instance.getChildContext !== 'function') {
10952 {
10953 var componentName = getComponentName(type) || 'Unknown';
10954
10955 if (!warnedAboutMissingGetChildContext[componentName]) {
10956 warnedAboutMissingGetChildContext[componentName] = true;
10957
10958 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);
10959 }
10960 }
10961
10962 return parentContext;
10963 }
10964
10965 var childContext = instance.getChildContext();
10966
10967 for (var contextKey in childContext) {
10968 if (!(contextKey in childContextTypes)) {
10969 {
10970 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
10971 }
10972 }
10973 }
10974
10975 {
10976 var name = getComponentName(type) || 'Unknown';
10977 checkPropTypes(childContextTypes, childContext, 'child context', name);
10978 }
10979
10980 return _assign({}, parentContext, childContext);
10981 }
10982}
10983
10984function pushContextProvider(workInProgress) {
10985 {
10986 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
10987 // If the instance does not exist yet, we will push null at first,
10988 // and replace it on the stack later when invalidating the context.
10989
10990 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
10991 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
10992
10993 previousContext = contextStackCursor.current;
10994 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
10995 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
10996 return true;
10997 }
10998}
10999
11000function invalidateContextProvider(workInProgress, type, didChange) {
11001 {
11002 var instance = workInProgress.stateNode;
11003
11004 if (!instance) {
11005 {
11006 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
11007 }
11008 }
11009
11010 if (didChange) {
11011 // Merge parent and own context.
11012 // Skip this if we're not updating due to sCU.
11013 // This avoids unnecessarily recomputing memoized values.
11014 var mergedContext = processChildContext(workInProgress, type, previousContext);
11015 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11016 // It is important to unwind the context in the reverse order.
11017
11018 pop(didPerformWorkStackCursor, workInProgress);
11019 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11020
11021 push(contextStackCursor, mergedContext, workInProgress);
11022 push(didPerformWorkStackCursor, didChange, workInProgress);
11023 } else {
11024 pop(didPerformWorkStackCursor, workInProgress);
11025 push(didPerformWorkStackCursor, didChange, workInProgress);
11026 }
11027 }
11028}
11029
11030function findCurrentUnmaskedContext(fiber) {
11031 {
11032 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11033 // makes sense elsewhere
11034 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11035 {
11036 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
11037 }
11038 }
11039
11040 var node = fiber;
11041
11042 do {
11043 switch (node.tag) {
11044 case HostRoot:
11045 return node.stateNode.context;
11046
11047 case ClassComponent:
11048 {
11049 var Component = node.type;
11050
11051 if (isContextProvider(Component)) {
11052 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11053 }
11054
11055 break;
11056 }
11057 }
11058
11059 node = node.return;
11060 } while (node !== null);
11061
11062 {
11063 {
11064 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
11065 }
11066 }
11067 }
11068}
11069
11070var LegacyRoot = 0;
11071var BlockingRoot = 1;
11072var ConcurrentRoot = 2;
11073
11074var rendererID = null;
11075var injectedHook = null;
11076var hasLoggedError = false;
11077var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
11078function injectInternals(internals) {
11079 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
11080 // No DevTools
11081 return false;
11082 }
11083
11084 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
11085
11086 if (hook.isDisabled) {
11087 // This isn't a real property on the hook, but it can be set to opt out
11088 // of DevTools integration and associated warnings and logs.
11089 // https://github.com/facebook/react/issues/3877
11090 return true;
11091 }
11092
11093 if (!hook.supportsFiber) {
11094 {
11095 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools');
11096 } // DevTools exists, even though it doesn't support Fiber.
11097
11098
11099 return true;
11100 }
11101
11102 try {
11103 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
11104
11105 injectedHook = hook;
11106 } catch (err) {
11107 // Catch all errors because it is unsafe to throw during initialization.
11108 {
11109 error('React instrumentation encountered an error: %s.', err);
11110 }
11111 } // DevTools exists
11112
11113
11114 return true;
11115}
11116function onScheduleRoot(root, children) {
11117 {
11118 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
11119 try {
11120 injectedHook.onScheduleFiberRoot(rendererID, root, children);
11121 } catch (err) {
11122 if ( !hasLoggedError) {
11123 hasLoggedError = true;
11124
11125 error('React instrumentation encountered an error: %s', err);
11126 }
11127 }
11128 }
11129 }
11130}
11131function onCommitRoot(root, priorityLevel) {
11132 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
11133 try {
11134 var didError = (root.current.flags & DidCapture) === DidCapture;
11135
11136 if (enableProfilerTimer) {
11137 injectedHook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
11138 } else {
11139 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
11140 }
11141 } catch (err) {
11142 {
11143 if (!hasLoggedError) {
11144 hasLoggedError = true;
11145
11146 error('React instrumentation encountered an error: %s', err);
11147 }
11148 }
11149 }
11150 }
11151}
11152function onCommitUnmount(fiber) {
11153 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
11154 try {
11155 injectedHook.onCommitFiberUnmount(rendererID, fiber);
11156 } catch (err) {
11157 {
11158 if (!hasLoggedError) {
11159 hasLoggedError = true;
11160
11161 error('React instrumentation encountered an error: %s', err);
11162 }
11163 }
11164 }
11165 }
11166}
11167
11168var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority,
11169 Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback,
11170 Scheduler_cancelCallback = Scheduler.unstable_cancelCallback,
11171 Scheduler_shouldYield = Scheduler.unstable_shouldYield,
11172 Scheduler_requestPaint = Scheduler.unstable_requestPaint,
11173 Scheduler_now$1 = Scheduler.unstable_now,
11174 Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,
11175 Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority,
11176 Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,
11177 Scheduler_NormalPriority = Scheduler.unstable_NormalPriority,
11178 Scheduler_LowPriority = Scheduler.unstable_LowPriority,
11179 Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;
11180
11181{
11182 // Provide explicit error message when production+profiling bundle of e.g.
11183 // react-dom is used with production (non-profiling) bundle of
11184 // scheduler/tracing
11185 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
11186 {
11187 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" );
11188 }
11189 }
11190}
11191
11192var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
11193// ascending numbers so we can compare them like numbers. They start at 90 to
11194// avoid clashing with Scheduler's priorities.
11195
11196var ImmediatePriority$1 = 99;
11197var UserBlockingPriority$2 = 98;
11198var NormalPriority$1 = 97;
11199var LowPriority$1 = 96;
11200var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only.
11201
11202var NoPriority$1 = 90;
11203var shouldYield = Scheduler_shouldYield;
11204var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
11205Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11206var syncQueue = null;
11207var immediateQueueCallbackNode = null;
11208var isFlushingSyncQueue = false;
11209var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11210// This will be the case for modern browsers that support `performance.now`. In
11211// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11212// timestamp. In that case, subtract the module initialization time to simulate
11213// the behavior of performance.now and keep our times small enough to fit
11214// within 32 bits.
11215// TODO: Consider lifting this into Scheduler.
11216
11217var now = initialTimeMs$1 < 10000 ? Scheduler_now$1 : function () {
11218 return Scheduler_now$1() - initialTimeMs$1;
11219};
11220function getCurrentPriorityLevel() {
11221 switch (Scheduler_getCurrentPriorityLevel()) {
11222 case Scheduler_ImmediatePriority:
11223 return ImmediatePriority$1;
11224
11225 case Scheduler_UserBlockingPriority:
11226 return UserBlockingPriority$2;
11227
11228 case Scheduler_NormalPriority:
11229 return NormalPriority$1;
11230
11231 case Scheduler_LowPriority:
11232 return LowPriority$1;
11233
11234 case Scheduler_IdlePriority:
11235 return IdlePriority$1;
11236
11237 default:
11238 {
11239 {
11240 throw Error( "Unknown priority level." );
11241 }
11242 }
11243
11244 }
11245}
11246
11247function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11248 switch (reactPriorityLevel) {
11249 case ImmediatePriority$1:
11250 return Scheduler_ImmediatePriority;
11251
11252 case UserBlockingPriority$2:
11253 return Scheduler_UserBlockingPriority;
11254
11255 case NormalPriority$1:
11256 return Scheduler_NormalPriority;
11257
11258 case LowPriority$1:
11259 return Scheduler_LowPriority;
11260
11261 case IdlePriority$1:
11262 return Scheduler_IdlePriority;
11263
11264 default:
11265 {
11266 {
11267 throw Error( "Unknown priority level." );
11268 }
11269 }
11270
11271 }
11272}
11273
11274function runWithPriority$1(reactPriorityLevel, fn) {
11275 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11276 return Scheduler_runWithPriority(priorityLevel, fn);
11277}
11278function scheduleCallback(reactPriorityLevel, callback, options) {
11279 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11280 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11281}
11282function scheduleSyncCallback(callback) {
11283 // Push this callback into an internal queue. We'll flush these either in
11284 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11285 if (syncQueue === null) {
11286 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
11287
11288 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11289 } else {
11290 // Push onto existing queue. Don't need to schedule a callback because
11291 // we already scheduled one when we created the queue.
11292 syncQueue.push(callback);
11293 }
11294
11295 return fakeCallbackNode;
11296}
11297function cancelCallback(callbackNode) {
11298 if (callbackNode !== fakeCallbackNode) {
11299 Scheduler_cancelCallback(callbackNode);
11300 }
11301}
11302function flushSyncCallbackQueue() {
11303 if (immediateQueueCallbackNode !== null) {
11304 var node = immediateQueueCallbackNode;
11305 immediateQueueCallbackNode = null;
11306 Scheduler_cancelCallback(node);
11307 }
11308
11309 flushSyncCallbackQueueImpl();
11310}
11311
11312function flushSyncCallbackQueueImpl() {
11313 if (!isFlushingSyncQueue && syncQueue !== null) {
11314 // Prevent re-entrancy.
11315 isFlushingSyncQueue = true;
11316 var i = 0;
11317
11318 {
11319 try {
11320 var _isSync2 = true;
11321 var _queue = syncQueue;
11322 runWithPriority$1(ImmediatePriority$1, function () {
11323 for (; i < _queue.length; i++) {
11324 var callback = _queue[i];
11325
11326 do {
11327 callback = callback(_isSync2);
11328 } while (callback !== null);
11329 }
11330 });
11331 syncQueue = null;
11332 } catch (error) {
11333 // If something throws, leave the remaining callbacks on the queue.
11334 if (syncQueue !== null) {
11335 syncQueue = syncQueue.slice(i + 1);
11336 } // Resume flushing in the next tick
11337
11338
11339 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11340 throw error;
11341 } finally {
11342 isFlushingSyncQueue = false;
11343 }
11344 }
11345 }
11346}
11347
11348// TODO: this is special because it gets imported during build.
11349var ReactVersion = '17.0.2';
11350
11351var NoMode = 0;
11352var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
11353// tag instead
11354
11355var BlockingMode = 2;
11356var ConcurrentMode = 4;
11357var ProfileMode = 8;
11358var DebugTracingMode = 16;
11359
11360var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
11361var NoTransition = 0;
11362function requestCurrentTransition() {
11363 return ReactCurrentBatchConfig.transition;
11364}
11365
11366var ReactStrictModeWarnings = {
11367 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11368 flushPendingUnsafeLifecycleWarnings: function () {},
11369 recordLegacyContextWarning: function (fiber, instance) {},
11370 flushLegacyContextWarning: function () {},
11371 discardPendingWarnings: function () {}
11372};
11373
11374{
11375 var findStrictRoot = function (fiber) {
11376 var maybeStrictRoot = null;
11377 var node = fiber;
11378
11379 while (node !== null) {
11380 if (node.mode & StrictMode) {
11381 maybeStrictRoot = node;
11382 }
11383
11384 node = node.return;
11385 }
11386
11387 return maybeStrictRoot;
11388 };
11389
11390 var setToSortedString = function (set) {
11391 var array = [];
11392 set.forEach(function (value) {
11393 array.push(value);
11394 });
11395 return array.sort().join(', ');
11396 };
11397
11398 var pendingComponentWillMountWarnings = [];
11399 var pendingUNSAFE_ComponentWillMountWarnings = [];
11400 var pendingComponentWillReceivePropsWarnings = [];
11401 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11402 var pendingComponentWillUpdateWarnings = [];
11403 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
11404
11405 var didWarnAboutUnsafeLifecycles = new Set();
11406
11407 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11408 // Dedup strategy: Warn once per component.
11409 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11410 return;
11411 }
11412
11413 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
11414 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11415 pendingComponentWillMountWarnings.push(fiber);
11416 }
11417
11418 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11419 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11420 }
11421
11422 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11423 pendingComponentWillReceivePropsWarnings.push(fiber);
11424 }
11425
11426 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11427 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11428 }
11429
11430 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11431 pendingComponentWillUpdateWarnings.push(fiber);
11432 }
11433
11434 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11435 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11436 }
11437 };
11438
11439 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11440 // We do an initial pass to gather component names
11441 var componentWillMountUniqueNames = new Set();
11442
11443 if (pendingComponentWillMountWarnings.length > 0) {
11444 pendingComponentWillMountWarnings.forEach(function (fiber) {
11445 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11446 didWarnAboutUnsafeLifecycles.add(fiber.type);
11447 });
11448 pendingComponentWillMountWarnings = [];
11449 }
11450
11451 var UNSAFE_componentWillMountUniqueNames = new Set();
11452
11453 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11454 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11455 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11456 didWarnAboutUnsafeLifecycles.add(fiber.type);
11457 });
11458 pendingUNSAFE_ComponentWillMountWarnings = [];
11459 }
11460
11461 var componentWillReceivePropsUniqueNames = new Set();
11462
11463 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11464 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11465 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11466 didWarnAboutUnsafeLifecycles.add(fiber.type);
11467 });
11468 pendingComponentWillReceivePropsWarnings = [];
11469 }
11470
11471 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11472
11473 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11474 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11475 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11476 didWarnAboutUnsafeLifecycles.add(fiber.type);
11477 });
11478 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11479 }
11480
11481 var componentWillUpdateUniqueNames = new Set();
11482
11483 if (pendingComponentWillUpdateWarnings.length > 0) {
11484 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11485 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11486 didWarnAboutUnsafeLifecycles.add(fiber.type);
11487 });
11488 pendingComponentWillUpdateWarnings = [];
11489 }
11490
11491 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11492
11493 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11494 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11495 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11496 didWarnAboutUnsafeLifecycles.add(fiber.type);
11497 });
11498 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11499 } // Finally, we flush all the warnings
11500 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11501
11502
11503 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11504 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11505
11506 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
11507 }
11508
11509 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11510 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11511
11512 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
11513 }
11514
11515 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11516 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11517
11518 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
11519 }
11520
11521 if (componentWillMountUniqueNames.size > 0) {
11522 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11523
11524 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
11525 }
11526
11527 if (componentWillReceivePropsUniqueNames.size > 0) {
11528 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11529
11530 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
11531 }
11532
11533 if (componentWillUpdateUniqueNames.size > 0) {
11534 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11535
11536 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
11537 }
11538 };
11539
11540 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
11541
11542 var didWarnAboutLegacyContext = new Set();
11543
11544 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11545 var strictRoot = findStrictRoot(fiber);
11546
11547 if (strictRoot === null) {
11548 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11549
11550 return;
11551 } // Dedup strategy: Warn once per component.
11552
11553
11554 if (didWarnAboutLegacyContext.has(fiber.type)) {
11555 return;
11556 }
11557
11558 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11559
11560 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11561 if (warningsForRoot === undefined) {
11562 warningsForRoot = [];
11563 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11564 }
11565
11566 warningsForRoot.push(fiber);
11567 }
11568 };
11569
11570 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11571 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11572 if (fiberArray.length === 0) {
11573 return;
11574 }
11575
11576 var firstFiber = fiberArray[0];
11577 var uniqueNames = new Set();
11578 fiberArray.forEach(function (fiber) {
11579 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11580 didWarnAboutLegacyContext.add(fiber.type);
11581 });
11582 var sortedNames = setToSortedString(uniqueNames);
11583
11584 try {
11585 setCurrentFiber(firstFiber);
11586
11587 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context', sortedNames);
11588 } finally {
11589 resetCurrentFiber();
11590 }
11591 });
11592 };
11593
11594 ReactStrictModeWarnings.discardPendingWarnings = function () {
11595 pendingComponentWillMountWarnings = [];
11596 pendingUNSAFE_ComponentWillMountWarnings = [];
11597 pendingComponentWillReceivePropsWarnings = [];
11598 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11599 pendingComponentWillUpdateWarnings = [];
11600 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11601 pendingLegacyContextWarning = new Map();
11602 };
11603}
11604
11605function resolveDefaultProps(Component, baseProps) {
11606 if (Component && Component.defaultProps) {
11607 // Resolve default props. Taken from ReactElement
11608 var props = _assign({}, baseProps);
11609
11610 var defaultProps = Component.defaultProps;
11611
11612 for (var propName in defaultProps) {
11613 if (props[propName] === undefined) {
11614 props[propName] = defaultProps[propName];
11615 }
11616 }
11617
11618 return props;
11619 }
11620
11621 return baseProps;
11622}
11623
11624// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11625// Math.pow(2, 30) - 1
11626// 0b111111111111111111111111111111
11627var MAX_SIGNED_31_BIT_INT = 1073741823;
11628
11629var valueCursor = createCursor(null);
11630var rendererSigil;
11631
11632{
11633 // Use this to detect multiple renderers using the same context
11634 rendererSigil = {};
11635}
11636
11637var currentlyRenderingFiber = null;
11638var lastContextDependency = null;
11639var lastContextWithAllBitsObserved = null;
11640var isDisallowedContextReadInDEV = false;
11641function resetContextDependencies() {
11642 // This is called right before React yields execution, to ensure `readContext`
11643 // cannot be called outside the render phase.
11644 currentlyRenderingFiber = null;
11645 lastContextDependency = null;
11646 lastContextWithAllBitsObserved = null;
11647
11648 {
11649 isDisallowedContextReadInDEV = false;
11650 }
11651}
11652function enterDisallowedContextReadInDEV() {
11653 {
11654 isDisallowedContextReadInDEV = true;
11655 }
11656}
11657function exitDisallowedContextReadInDEV() {
11658 {
11659 isDisallowedContextReadInDEV = false;
11660 }
11661}
11662function pushProvider(providerFiber, nextValue) {
11663 var context = providerFiber.type._context;
11664
11665 {
11666 push(valueCursor, context._currentValue, providerFiber);
11667 context._currentValue = nextValue;
11668
11669 {
11670 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
11671 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
11672 }
11673
11674 context._currentRenderer = rendererSigil;
11675 }
11676 }
11677}
11678function popProvider(providerFiber) {
11679 var currentValue = valueCursor.current;
11680 pop(valueCursor, providerFiber);
11681 var context = providerFiber.type._context;
11682
11683 {
11684 context._currentValue = currentValue;
11685 }
11686}
11687function calculateChangedBits(context, newValue, oldValue) {
11688 if (objectIs(oldValue, newValue)) {
11689 // No change
11690 return 0;
11691 } else {
11692 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
11693
11694 {
11695 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
11696 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
11697 }
11698 }
11699
11700 return changedBits | 0;
11701 }
11702}
11703function scheduleWorkOnParentPath(parent, renderLanes) {
11704 // Update the child lanes of all the ancestors, including the alternates.
11705 var node = parent;
11706
11707 while (node !== null) {
11708 var alternate = node.alternate;
11709
11710 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
11711 node.childLanes = mergeLanes(node.childLanes, renderLanes);
11712
11713 if (alternate !== null) {
11714 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
11715 }
11716 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
11717 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
11718 } else {
11719 // Neither alternate was updated, which means the rest of the
11720 // ancestor path already has sufficient priority.
11721 break;
11722 }
11723
11724 node = node.return;
11725 }
11726}
11727function propagateContextChange(workInProgress, context, changedBits, renderLanes) {
11728 var fiber = workInProgress.child;
11729
11730 if (fiber !== null) {
11731 // Set the return pointer of the child to the work-in-progress fiber.
11732 fiber.return = workInProgress;
11733 }
11734
11735 while (fiber !== null) {
11736 var nextFiber = void 0; // Visit this fiber.
11737
11738 var list = fiber.dependencies;
11739
11740 if (list !== null) {
11741 nextFiber = fiber.child;
11742 var dependency = list.firstContext;
11743
11744 while (dependency !== null) {
11745 // Check if the context matches.
11746 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
11747 // Match! Schedule an update on this fiber.
11748 if (fiber.tag === ClassComponent) {
11749 // Schedule a force update on the work-in-progress.
11750 var update = createUpdate(NoTimestamp, pickArbitraryLane(renderLanes));
11751 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
11752 // update to the current fiber, too, which means it will persist even if
11753 // this render is thrown away. Since it's a race condition, not sure it's
11754 // worth fixing.
11755
11756 enqueueUpdate(fiber, update);
11757 }
11758
11759 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
11760 var alternate = fiber.alternate;
11761
11762 if (alternate !== null) {
11763 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
11764 }
11765
11766 scheduleWorkOnParentPath(fiber.return, renderLanes); // Mark the updated lanes on the list, too.
11767
11768 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
11769 // dependency list.
11770
11771 break;
11772 }
11773
11774 dependency = dependency.next;
11775 }
11776 } else if (fiber.tag === ContextProvider) {
11777 // Don't scan deeper if this is a matching provider
11778 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
11779 } else {
11780 // Traverse down.
11781 nextFiber = fiber.child;
11782 }
11783
11784 if (nextFiber !== null) {
11785 // Set the return pointer of the child to the work-in-progress fiber.
11786 nextFiber.return = fiber;
11787 } else {
11788 // No child. Traverse to next sibling.
11789 nextFiber = fiber;
11790
11791 while (nextFiber !== null) {
11792 if (nextFiber === workInProgress) {
11793 // We're back to the root of this subtree. Exit.
11794 nextFiber = null;
11795 break;
11796 }
11797
11798 var sibling = nextFiber.sibling;
11799
11800 if (sibling !== null) {
11801 // Set the return pointer of the sibling to the work-in-progress fiber.
11802 sibling.return = nextFiber.return;
11803 nextFiber = sibling;
11804 break;
11805 } // No more siblings. Traverse up.
11806
11807
11808 nextFiber = nextFiber.return;
11809 }
11810 }
11811
11812 fiber = nextFiber;
11813 }
11814}
11815function prepareToReadContext(workInProgress, renderLanes) {
11816 currentlyRenderingFiber = workInProgress;
11817 lastContextDependency = null;
11818 lastContextWithAllBitsObserved = null;
11819 var dependencies = workInProgress.dependencies;
11820
11821 if (dependencies !== null) {
11822 var firstContext = dependencies.firstContext;
11823
11824 if (firstContext !== null) {
11825 if (includesSomeLane(dependencies.lanes, renderLanes)) {
11826 // Context list has a pending update. Mark that this fiber performed work.
11827 markWorkInProgressReceivedUpdate();
11828 } // Reset the work-in-progress list
11829
11830
11831 dependencies.firstContext = null;
11832 }
11833 }
11834}
11835function readContext(context, observedBits) {
11836 {
11837 // This warning would fire if you read context inside a Hook like useMemo.
11838 // Unlike the class check below, it's not enforced in production for perf.
11839 if (isDisallowedContextReadInDEV) {
11840 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().');
11841 }
11842 }
11843
11844 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
11845 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
11846
11847 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
11848 // Observe all updates.
11849 lastContextWithAllBitsObserved = context;
11850 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
11851 } else {
11852 resolvedObservedBits = observedBits;
11853 }
11854
11855 var contextItem = {
11856 context: context,
11857 observedBits: resolvedObservedBits,
11858 next: null
11859 };
11860
11861 if (lastContextDependency === null) {
11862 if (!(currentlyRenderingFiber !== null)) {
11863 {
11864 throw Error( "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." );
11865 }
11866 } // This is the first dependency for this component. Create a new list.
11867
11868
11869 lastContextDependency = contextItem;
11870 currentlyRenderingFiber.dependencies = {
11871 lanes: NoLanes,
11872 firstContext: contextItem,
11873 responders: null
11874 };
11875 } else {
11876 // Append a new context item.
11877 lastContextDependency = lastContextDependency.next = contextItem;
11878 }
11879 }
11880
11881 return context._currentValue ;
11882}
11883
11884var UpdateState = 0;
11885var ReplaceState = 1;
11886var ForceUpdate = 2;
11887var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
11888// It should only be read right after calling `processUpdateQueue`, via
11889// `checkHasForceUpdateAfterProcessing`.
11890
11891var hasForceUpdate = false;
11892var didWarnUpdateInsideUpdate;
11893var currentlyProcessingQueue;
11894
11895{
11896 didWarnUpdateInsideUpdate = false;
11897 currentlyProcessingQueue = null;
11898}
11899
11900function initializeUpdateQueue(fiber) {
11901 var queue = {
11902 baseState: fiber.memoizedState,
11903 firstBaseUpdate: null,
11904 lastBaseUpdate: null,
11905 shared: {
11906 pending: null
11907 },
11908 effects: null
11909 };
11910 fiber.updateQueue = queue;
11911}
11912function cloneUpdateQueue(current, workInProgress) {
11913 // Clone the update queue from current. Unless it's already a clone.
11914 var queue = workInProgress.updateQueue;
11915 var currentQueue = current.updateQueue;
11916
11917 if (queue === currentQueue) {
11918 var clone = {
11919 baseState: currentQueue.baseState,
11920 firstBaseUpdate: currentQueue.firstBaseUpdate,
11921 lastBaseUpdate: currentQueue.lastBaseUpdate,
11922 shared: currentQueue.shared,
11923 effects: currentQueue.effects
11924 };
11925 workInProgress.updateQueue = clone;
11926 }
11927}
11928function createUpdate(eventTime, lane) {
11929 var update = {
11930 eventTime: eventTime,
11931 lane: lane,
11932 tag: UpdateState,
11933 payload: null,
11934 callback: null,
11935 next: null
11936 };
11937 return update;
11938}
11939function enqueueUpdate(fiber, update) {
11940 var updateQueue = fiber.updateQueue;
11941
11942 if (updateQueue === null) {
11943 // Only occurs if the fiber has been unmounted.
11944 return;
11945 }
11946
11947 var sharedQueue = updateQueue.shared;
11948 var pending = sharedQueue.pending;
11949
11950 if (pending === null) {
11951 // This is the first update. Create a circular list.
11952 update.next = update;
11953 } else {
11954 update.next = pending.next;
11955 pending.next = update;
11956 }
11957
11958 sharedQueue.pending = update;
11959
11960 {
11961 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
11962 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
11963
11964 didWarnUpdateInsideUpdate = true;
11965 }
11966 }
11967}
11968function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
11969 // Captured updates are updates that are thrown by a child during the render
11970 // phase. They should be discarded if the render is aborted. Therefore,
11971 // we should only put them on the work-in-progress queue, not the current one.
11972 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
11973
11974 var current = workInProgress.alternate;
11975
11976 if (current !== null) {
11977 var currentQueue = current.updateQueue;
11978
11979 if (queue === currentQueue) {
11980 // The work-in-progress queue is the same as current. This happens when
11981 // we bail out on a parent fiber that then captures an error thrown by
11982 // a child. Since we want to append the update only to the work-in
11983 // -progress queue, we need to clone the updates. We usually clone during
11984 // processUpdateQueue, but that didn't happen in this case because we
11985 // skipped over the parent when we bailed out.
11986 var newFirst = null;
11987 var newLast = null;
11988 var firstBaseUpdate = queue.firstBaseUpdate;
11989
11990 if (firstBaseUpdate !== null) {
11991 // Loop through the updates and clone them.
11992 var update = firstBaseUpdate;
11993
11994 do {
11995 var clone = {
11996 eventTime: update.eventTime,
11997 lane: update.lane,
11998 tag: update.tag,
11999 payload: update.payload,
12000 callback: update.callback,
12001 next: null
12002 };
12003
12004 if (newLast === null) {
12005 newFirst = newLast = clone;
12006 } else {
12007 newLast.next = clone;
12008 newLast = clone;
12009 }
12010
12011 update = update.next;
12012 } while (update !== null); // Append the captured update the end of the cloned list.
12013
12014
12015 if (newLast === null) {
12016 newFirst = newLast = capturedUpdate;
12017 } else {
12018 newLast.next = capturedUpdate;
12019 newLast = capturedUpdate;
12020 }
12021 } else {
12022 // There are no base updates.
12023 newFirst = newLast = capturedUpdate;
12024 }
12025
12026 queue = {
12027 baseState: currentQueue.baseState,
12028 firstBaseUpdate: newFirst,
12029 lastBaseUpdate: newLast,
12030 shared: currentQueue.shared,
12031 effects: currentQueue.effects
12032 };
12033 workInProgress.updateQueue = queue;
12034 return;
12035 }
12036 } // Append the update to the end of the list.
12037
12038
12039 var lastBaseUpdate = queue.lastBaseUpdate;
12040
12041 if (lastBaseUpdate === null) {
12042 queue.firstBaseUpdate = capturedUpdate;
12043 } else {
12044 lastBaseUpdate.next = capturedUpdate;
12045 }
12046
12047 queue.lastBaseUpdate = capturedUpdate;
12048}
12049
12050function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12051 switch (update.tag) {
12052 case ReplaceState:
12053 {
12054 var payload = update.payload;
12055
12056 if (typeof payload === 'function') {
12057 // Updater function
12058 {
12059 enterDisallowedContextReadInDEV();
12060 }
12061
12062 var nextState = payload.call(instance, prevState, nextProps);
12063
12064 {
12065 if ( workInProgress.mode & StrictMode) {
12066 disableLogs();
12067
12068 try {
12069 payload.call(instance, prevState, nextProps);
12070 } finally {
12071 reenableLogs();
12072 }
12073 }
12074
12075 exitDisallowedContextReadInDEV();
12076 }
12077
12078 return nextState;
12079 } // State object
12080
12081
12082 return payload;
12083 }
12084
12085 case CaptureUpdate:
12086 {
12087 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
12088 }
12089 // Intentional fallthrough
12090
12091 case UpdateState:
12092 {
12093 var _payload = update.payload;
12094 var partialState;
12095
12096 if (typeof _payload === 'function') {
12097 // Updater function
12098 {
12099 enterDisallowedContextReadInDEV();
12100 }
12101
12102 partialState = _payload.call(instance, prevState, nextProps);
12103
12104 {
12105 if ( workInProgress.mode & StrictMode) {
12106 disableLogs();
12107
12108 try {
12109 _payload.call(instance, prevState, nextProps);
12110 } finally {
12111 reenableLogs();
12112 }
12113 }
12114
12115 exitDisallowedContextReadInDEV();
12116 }
12117 } else {
12118 // Partial state object
12119 partialState = _payload;
12120 }
12121
12122 if (partialState === null || partialState === undefined) {
12123 // Null and undefined are treated as no-ops.
12124 return prevState;
12125 } // Merge the partial state and the previous state.
12126
12127
12128 return _assign({}, prevState, partialState);
12129 }
12130
12131 case ForceUpdate:
12132 {
12133 hasForceUpdate = true;
12134 return prevState;
12135 }
12136 }
12137
12138 return prevState;
12139}
12140
12141function processUpdateQueue(workInProgress, props, instance, renderLanes) {
12142 // This is always non-null on a ClassComponent or HostRoot
12143 var queue = workInProgress.updateQueue;
12144 hasForceUpdate = false;
12145
12146 {
12147 currentlyProcessingQueue = queue.shared;
12148 }
12149
12150 var firstBaseUpdate = queue.firstBaseUpdate;
12151 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
12152
12153 var pendingQueue = queue.shared.pending;
12154
12155 if (pendingQueue !== null) {
12156 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
12157 // and last so that it's non-circular.
12158
12159 var lastPendingUpdate = pendingQueue;
12160 var firstPendingUpdate = lastPendingUpdate.next;
12161 lastPendingUpdate.next = null; // Append pending updates to base queue
12162
12163 if (lastBaseUpdate === null) {
12164 firstBaseUpdate = firstPendingUpdate;
12165 } else {
12166 lastBaseUpdate.next = firstPendingUpdate;
12167 }
12168
12169 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
12170 // we need to transfer the updates to that queue, too. Because the base
12171 // queue is a singly-linked list with no cycles, we can append to both
12172 // lists and take advantage of structural sharing.
12173 // TODO: Pass `current` as argument
12174
12175 var current = workInProgress.alternate;
12176
12177 if (current !== null) {
12178 // This is always non-null on a ClassComponent or HostRoot
12179 var currentQueue = current.updateQueue;
12180 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
12181
12182 if (currentLastBaseUpdate !== lastBaseUpdate) {
12183 if (currentLastBaseUpdate === null) {
12184 currentQueue.firstBaseUpdate = firstPendingUpdate;
12185 } else {
12186 currentLastBaseUpdate.next = firstPendingUpdate;
12187 }
12188
12189 currentQueue.lastBaseUpdate = lastPendingUpdate;
12190 }
12191 }
12192 } // These values may change as we process the queue.
12193
12194
12195 if (firstBaseUpdate !== null) {
12196 // Iterate through the list of updates to compute the result.
12197 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
12198 // from the original lanes.
12199
12200 var newLanes = NoLanes;
12201 var newBaseState = null;
12202 var newFirstBaseUpdate = null;
12203 var newLastBaseUpdate = null;
12204 var update = firstBaseUpdate;
12205
12206 do {
12207 var updateLane = update.lane;
12208 var updateEventTime = update.eventTime;
12209
12210 if (!isSubsetOfLanes(renderLanes, updateLane)) {
12211 // Priority is insufficient. Skip this update. If this is the first
12212 // skipped update, the previous update/state is the new base
12213 // update/state.
12214 var clone = {
12215 eventTime: updateEventTime,
12216 lane: updateLane,
12217 tag: update.tag,
12218 payload: update.payload,
12219 callback: update.callback,
12220 next: null
12221 };
12222
12223 if (newLastBaseUpdate === null) {
12224 newFirstBaseUpdate = newLastBaseUpdate = clone;
12225 newBaseState = newState;
12226 } else {
12227 newLastBaseUpdate = newLastBaseUpdate.next = clone;
12228 } // Update the remaining priority in the queue.
12229
12230
12231 newLanes = mergeLanes(newLanes, updateLane);
12232 } else {
12233 // This update does have sufficient priority.
12234 if (newLastBaseUpdate !== null) {
12235 var _clone = {
12236 eventTime: updateEventTime,
12237 // This update is going to be committed so we never want uncommit
12238 // it. Using NoLane works because 0 is a subset of all bitmasks, so
12239 // this will never be skipped by the check above.
12240 lane: NoLane,
12241 tag: update.tag,
12242 payload: update.payload,
12243 callback: update.callback,
12244 next: null
12245 };
12246 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
12247 } // Process this update.
12248
12249
12250 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
12251 var callback = update.callback;
12252
12253 if (callback !== null) {
12254 workInProgress.flags |= Callback;
12255 var effects = queue.effects;
12256
12257 if (effects === null) {
12258 queue.effects = [update];
12259 } else {
12260 effects.push(update);
12261 }
12262 }
12263 }
12264
12265 update = update.next;
12266
12267 if (update === null) {
12268 pendingQueue = queue.shared.pending;
12269
12270 if (pendingQueue === null) {
12271 break;
12272 } else {
12273 // An update was scheduled from inside a reducer. Add the new
12274 // pending updates to the end of the list and keep processing.
12275 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
12276 // unravel them when transferring them to the base queue.
12277
12278 var _firstPendingUpdate = _lastPendingUpdate.next;
12279 _lastPendingUpdate.next = null;
12280 update = _firstPendingUpdate;
12281 queue.lastBaseUpdate = _lastPendingUpdate;
12282 queue.shared.pending = null;
12283 }
12284 }
12285 } while (true);
12286
12287 if (newLastBaseUpdate === null) {
12288 newBaseState = newState;
12289 }
12290
12291 queue.baseState = newBaseState;
12292 queue.firstBaseUpdate = newFirstBaseUpdate;
12293 queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue.
12294 // This should be fine because the only two other things that contribute to
12295 // expiration time are props and context. We're already in the middle of the
12296 // begin phase by the time we start processing the queue, so we've already
12297 // dealt with the props. Context in components that specify
12298 // shouldComponentUpdate is tricky; but we'll have to account for
12299 // that regardless.
12300
12301 markSkippedUpdateLanes(newLanes);
12302 workInProgress.lanes = newLanes;
12303 workInProgress.memoizedState = newState;
12304 }
12305
12306 {
12307 currentlyProcessingQueue = null;
12308 }
12309}
12310
12311function callCallback(callback, context) {
12312 if (!(typeof callback === 'function')) {
12313 {
12314 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
12315 }
12316 }
12317
12318 callback.call(context);
12319}
12320
12321function resetHasForceUpdateBeforeProcessing() {
12322 hasForceUpdate = false;
12323}
12324function checkHasForceUpdateAfterProcessing() {
12325 return hasForceUpdate;
12326}
12327function commitUpdateQueue(finishedWork, finishedQueue, instance) {
12328 // Commit the effects
12329 var effects = finishedQueue.effects;
12330 finishedQueue.effects = null;
12331
12332 if (effects !== null) {
12333 for (var i = 0; i < effects.length; i++) {
12334 var effect = effects[i];
12335 var callback = effect.callback;
12336
12337 if (callback !== null) {
12338 effect.callback = null;
12339 callCallback(callback, instance);
12340 }
12341 }
12342 }
12343}
12344
12345var fakeInternalInstance = {};
12346var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
12347// We'll use it to determine whether we need to initialize legacy refs.
12348
12349var emptyRefsObject = new React.Component().refs;
12350var didWarnAboutStateAssignmentForComponent;
12351var didWarnAboutUninitializedState;
12352var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
12353var didWarnAboutLegacyLifecyclesAndDerivedState;
12354var didWarnAboutUndefinedDerivedState;
12355var warnOnUndefinedDerivedState;
12356var warnOnInvalidCallback;
12357var didWarnAboutDirectlyAssigningPropsToState;
12358var didWarnAboutContextTypeAndContextTypes;
12359var didWarnAboutInvalidateContextType;
12360
12361{
12362 didWarnAboutStateAssignmentForComponent = new Set();
12363 didWarnAboutUninitializedState = new Set();
12364 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12365 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12366 didWarnAboutDirectlyAssigningPropsToState = new Set();
12367 didWarnAboutUndefinedDerivedState = new Set();
12368 didWarnAboutContextTypeAndContextTypes = new Set();
12369 didWarnAboutInvalidateContextType = new Set();
12370 var didWarnOnInvalidCallback = new Set();
12371
12372 warnOnInvalidCallback = function (callback, callerName) {
12373 if (callback === null || typeof callback === 'function') {
12374 return;
12375 }
12376
12377 var key = callerName + '_' + callback;
12378
12379 if (!didWarnOnInvalidCallback.has(key)) {
12380 didWarnOnInvalidCallback.add(key);
12381
12382 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12383 }
12384 };
12385
12386 warnOnUndefinedDerivedState = function (type, partialState) {
12387 if (partialState === undefined) {
12388 var componentName = getComponentName(type) || 'Component';
12389
12390 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12391 didWarnAboutUndefinedDerivedState.add(componentName);
12392
12393 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12394 }
12395 }
12396 }; // This is so gross but it's at least non-critical and can be removed if
12397 // it causes problems. This is meant to give a nicer error message for
12398 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12399 // ...)) which otherwise throws a "_processChildContext is not a function"
12400 // exception.
12401
12402
12403 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12404 enumerable: false,
12405 value: function () {
12406 {
12407 {
12408 throw Error( "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." );
12409 }
12410 }
12411 }
12412 });
12413 Object.freeze(fakeInternalInstance);
12414}
12415
12416function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12417 var prevState = workInProgress.memoizedState;
12418
12419 {
12420 if ( workInProgress.mode & StrictMode) {
12421 disableLogs();
12422
12423 try {
12424 // Invoke the function an extra time to help detect side-effects.
12425 getDerivedStateFromProps(nextProps, prevState);
12426 } finally {
12427 reenableLogs();
12428 }
12429 }
12430 }
12431
12432 var partialState = getDerivedStateFromProps(nextProps, prevState);
12433
12434 {
12435 warnOnUndefinedDerivedState(ctor, partialState);
12436 } // Merge the partial state and the previous state.
12437
12438
12439 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12440 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
12441 // base state.
12442
12443 if (workInProgress.lanes === NoLanes) {
12444 // Queue is always non-null for classes
12445 var updateQueue = workInProgress.updateQueue;
12446 updateQueue.baseState = memoizedState;
12447 }
12448}
12449var classComponentUpdater = {
12450 isMounted: isMounted,
12451 enqueueSetState: function (inst, payload, callback) {
12452 var fiber = get(inst);
12453 var eventTime = requestEventTime();
12454 var lane = requestUpdateLane(fiber);
12455 var update = createUpdate(eventTime, lane);
12456 update.payload = payload;
12457
12458 if (callback !== undefined && callback !== null) {
12459 {
12460 warnOnInvalidCallback(callback, 'setState');
12461 }
12462
12463 update.callback = callback;
12464 }
12465
12466 enqueueUpdate(fiber, update);
12467 scheduleUpdateOnFiber(fiber, lane, eventTime);
12468 },
12469 enqueueReplaceState: function (inst, payload, callback) {
12470 var fiber = get(inst);
12471 var eventTime = requestEventTime();
12472 var lane = requestUpdateLane(fiber);
12473 var update = createUpdate(eventTime, lane);
12474 update.tag = ReplaceState;
12475 update.payload = payload;
12476
12477 if (callback !== undefined && callback !== null) {
12478 {
12479 warnOnInvalidCallback(callback, 'replaceState');
12480 }
12481
12482 update.callback = callback;
12483 }
12484
12485 enqueueUpdate(fiber, update);
12486 scheduleUpdateOnFiber(fiber, lane, eventTime);
12487 },
12488 enqueueForceUpdate: function (inst, callback) {
12489 var fiber = get(inst);
12490 var eventTime = requestEventTime();
12491 var lane = requestUpdateLane(fiber);
12492 var update = createUpdate(eventTime, lane);
12493 update.tag = ForceUpdate;
12494
12495 if (callback !== undefined && callback !== null) {
12496 {
12497 warnOnInvalidCallback(callback, 'forceUpdate');
12498 }
12499
12500 update.callback = callback;
12501 }
12502
12503 enqueueUpdate(fiber, update);
12504 scheduleUpdateOnFiber(fiber, lane, eventTime);
12505 }
12506};
12507
12508function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12509 var instance = workInProgress.stateNode;
12510
12511 if (typeof instance.shouldComponentUpdate === 'function') {
12512 {
12513 if ( workInProgress.mode & StrictMode) {
12514 disableLogs();
12515
12516 try {
12517 // Invoke the function an extra time to help detect side-effects.
12518 instance.shouldComponentUpdate(newProps, newState, nextContext);
12519 } finally {
12520 reenableLogs();
12521 }
12522 }
12523 }
12524
12525 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12526
12527 {
12528 if (shouldUpdate === undefined) {
12529 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
12530 }
12531 }
12532
12533 return shouldUpdate;
12534 }
12535
12536 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12537 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12538 }
12539
12540 return true;
12541}
12542
12543function checkClassInstance(workInProgress, ctor, newProps) {
12544 var instance = workInProgress.stateNode;
12545
12546 {
12547 var name = getComponentName(ctor) || 'Component';
12548 var renderPresent = instance.render;
12549
12550 if (!renderPresent) {
12551 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12552 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12553 } else {
12554 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12555 }
12556 }
12557
12558 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
12559 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);
12560 }
12561
12562 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
12563 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);
12564 }
12565
12566 if (instance.propTypes) {
12567 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
12568 }
12569
12570 if (instance.contextType) {
12571 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
12572 }
12573
12574 {
12575 if (instance.contextTypes) {
12576 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
12577 }
12578
12579 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12580 didWarnAboutContextTypeAndContextTypes.add(ctor);
12581
12582 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12583 }
12584 }
12585
12586 if (typeof instance.componentShouldUpdate === 'function') {
12587 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);
12588 }
12589
12590 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12591 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
12592 }
12593
12594 if (typeof instance.componentDidUnmount === 'function') {
12595 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
12596 }
12597
12598 if (typeof instance.componentDidReceiveProps === 'function') {
12599 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);
12600 }
12601
12602 if (typeof instance.componentWillRecieveProps === 'function') {
12603 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
12604 }
12605
12606 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
12607 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
12608 }
12609
12610 var hasMutatedProps = instance.props !== newProps;
12611
12612 if (instance.props !== undefined && hasMutatedProps) {
12613 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
12614 }
12615
12616 if (instance.defaultProps) {
12617 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);
12618 }
12619
12620 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12621 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12622
12623 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12624 }
12625
12626 if (typeof instance.getDerivedStateFromProps === 'function') {
12627 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12628 }
12629
12630 if (typeof instance.getDerivedStateFromError === 'function') {
12631 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12632 }
12633
12634 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
12635 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
12636 }
12637
12638 var _state = instance.state;
12639
12640 if (_state && (typeof _state !== 'object' || isArray(_state))) {
12641 error('%s.state: must be set to an object or null', name);
12642 }
12643
12644 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
12645 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
12646 }
12647 }
12648}
12649
12650function adoptClassInstance(workInProgress, instance) {
12651 instance.updater = classComponentUpdater;
12652 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
12653
12654 set(instance, workInProgress);
12655
12656 {
12657 instance._reactInternalInstance = fakeInternalInstance;
12658 }
12659}
12660
12661function constructClassInstance(workInProgress, ctor, props) {
12662 var isLegacyContextConsumer = false;
12663 var unmaskedContext = emptyContextObject;
12664 var context = emptyContextObject;
12665 var contextType = ctor.contextType;
12666
12667 {
12668 if ('contextType' in ctor) {
12669 var isValid = // Allow null for conditional declaration
12670 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
12671
12672 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
12673 didWarnAboutInvalidateContextType.add(ctor);
12674 var addendum = '';
12675
12676 if (contextType === undefined) {
12677 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.';
12678 } else if (typeof contextType !== 'object') {
12679 addendum = ' However, it is set to a ' + typeof contextType + '.';
12680 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
12681 addendum = ' Did you accidentally pass the Context.Provider instead?';
12682 } else if (contextType._context !== undefined) {
12683 // <Context.Consumer>
12684 addendum = ' Did you accidentally pass the Context.Consumer instead?';
12685 } else {
12686 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
12687 }
12688
12689 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
12690 }
12691 }
12692 }
12693
12694 if (typeof contextType === 'object' && contextType !== null) {
12695 context = readContext(contextType);
12696 } else {
12697 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12698 var contextTypes = ctor.contextTypes;
12699 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
12700 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
12701 } // Instantiate twice to help detect side-effects.
12702
12703
12704 {
12705 if ( workInProgress.mode & StrictMode) {
12706 disableLogs();
12707
12708 try {
12709 new ctor(props, context); // eslint-disable-line no-new
12710 } finally {
12711 reenableLogs();
12712 }
12713 }
12714 }
12715
12716 var instance = new ctor(props, context);
12717 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
12718 adoptClassInstance(workInProgress, instance);
12719
12720 {
12721 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
12722 var componentName = getComponentName(ctor) || 'Component';
12723
12724 if (!didWarnAboutUninitializedState.has(componentName)) {
12725 didWarnAboutUninitializedState.add(componentName);
12726
12727 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);
12728 }
12729 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
12730 // Warn about these lifecycles if they are present.
12731 // Don't warn about react-lifecycles-compat polyfilled methods though.
12732
12733
12734 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
12735 var foundWillMountName = null;
12736 var foundWillReceivePropsName = null;
12737 var foundWillUpdateName = null;
12738
12739 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
12740 foundWillMountName = 'componentWillMount';
12741 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
12742 foundWillMountName = 'UNSAFE_componentWillMount';
12743 }
12744
12745 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12746 foundWillReceivePropsName = 'componentWillReceiveProps';
12747 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12748 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
12749 }
12750
12751 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12752 foundWillUpdateName = 'componentWillUpdate';
12753 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
12754 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
12755 }
12756
12757 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
12758 var _componentName = getComponentName(ctor) || 'Component';
12759
12760 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
12761
12762 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
12763 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
12764
12765 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 : '');
12766 }
12767 }
12768 }
12769 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
12770 // ReactFiberContext usually updates this cache but can't for newly-created instances.
12771
12772
12773 if (isLegacyContextConsumer) {
12774 cacheContext(workInProgress, unmaskedContext, context);
12775 }
12776
12777 return instance;
12778}
12779
12780function callComponentWillMount(workInProgress, instance) {
12781 var oldState = instance.state;
12782
12783 if (typeof instance.componentWillMount === 'function') {
12784 instance.componentWillMount();
12785 }
12786
12787 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12788 instance.UNSAFE_componentWillMount();
12789 }
12790
12791 if (oldState !== instance.state) {
12792 {
12793 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
12794 }
12795
12796 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12797 }
12798}
12799
12800function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
12801 var oldState = instance.state;
12802
12803 if (typeof instance.componentWillReceiveProps === 'function') {
12804 instance.componentWillReceiveProps(newProps, nextContext);
12805 }
12806
12807 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12808 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
12809 }
12810
12811 if (instance.state !== oldState) {
12812 {
12813 var componentName = getComponentName(workInProgress.type) || 'Component';
12814
12815 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
12816 didWarnAboutStateAssignmentForComponent.add(componentName);
12817
12818 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
12819 }
12820 }
12821
12822 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12823 }
12824} // Invokes the mount life-cycles on a previously never rendered instance.
12825
12826
12827function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
12828 {
12829 checkClassInstance(workInProgress, ctor, newProps);
12830 }
12831
12832 var instance = workInProgress.stateNode;
12833 instance.props = newProps;
12834 instance.state = workInProgress.memoizedState;
12835 instance.refs = emptyRefsObject;
12836 initializeUpdateQueue(workInProgress);
12837 var contextType = ctor.contextType;
12838
12839 if (typeof contextType === 'object' && contextType !== null) {
12840 instance.context = readContext(contextType);
12841 } else {
12842 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12843 instance.context = getMaskedContext(workInProgress, unmaskedContext);
12844 }
12845
12846 {
12847 if (instance.state === newProps) {
12848 var componentName = getComponentName(ctor) || 'Component';
12849
12850 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
12851 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
12852
12853 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);
12854 }
12855 }
12856
12857 if (workInProgress.mode & StrictMode) {
12858 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
12859 }
12860
12861 {
12862 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
12863 }
12864 }
12865
12866 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12867 instance.state = workInProgress.memoizedState;
12868 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12869
12870 if (typeof getDerivedStateFromProps === 'function') {
12871 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12872 instance.state = workInProgress.memoizedState;
12873 } // In order to support react-lifecycles-compat polyfilled components,
12874 // Unsafe lifecycles should not be invoked for components using the new APIs.
12875
12876
12877 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12878 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
12879 // process them now.
12880
12881 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12882 instance.state = workInProgress.memoizedState;
12883 }
12884
12885 if (typeof instance.componentDidMount === 'function') {
12886 workInProgress.flags |= Update;
12887 }
12888}
12889
12890function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
12891 var instance = workInProgress.stateNode;
12892 var oldProps = workInProgress.memoizedProps;
12893 instance.props = oldProps;
12894 var oldContext = instance.context;
12895 var contextType = ctor.contextType;
12896 var nextContext = emptyContextObject;
12897
12898 if (typeof contextType === 'object' && contextType !== null) {
12899 nextContext = readContext(contextType);
12900 } else {
12901 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12902 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
12903 }
12904
12905 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12906 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
12907 // ever the previously attempted to render - not the "current". However,
12908 // during componentDidUpdate we pass the "current" props.
12909 // In order to support react-lifecycles-compat polyfilled components,
12910 // Unsafe lifecycles should not be invoked for components using the new APIs.
12911
12912 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
12913 if (oldProps !== newProps || oldContext !== nextContext) {
12914 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
12915 }
12916 }
12917
12918 resetHasForceUpdateBeforeProcessing();
12919 var oldState = workInProgress.memoizedState;
12920 var newState = instance.state = oldState;
12921 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
12922 newState = workInProgress.memoizedState;
12923
12924 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
12925 // If an update was already in progress, we should schedule an Update
12926 // effect even though we're bailing out, so that cWU/cDU are called.
12927 if (typeof instance.componentDidMount === 'function') {
12928 workInProgress.flags |= Update;
12929 }
12930
12931 return false;
12932 }
12933
12934 if (typeof getDerivedStateFromProps === 'function') {
12935 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
12936 newState = workInProgress.memoizedState;
12937 }
12938
12939 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
12940
12941 if (shouldUpdate) {
12942 // In order to support react-lifecycles-compat polyfilled components,
12943 // Unsafe lifecycles should not be invoked for components using the new APIs.
12944 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
12945 if (typeof instance.componentWillMount === 'function') {
12946 instance.componentWillMount();
12947 }
12948
12949 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12950 instance.UNSAFE_componentWillMount();
12951 }
12952 }
12953
12954 if (typeof instance.componentDidMount === 'function') {
12955 workInProgress.flags |= Update;
12956 }
12957 } else {
12958 // If an update was already in progress, we should schedule an Update
12959 // effect even though we're bailing out, so that cWU/cDU are called.
12960 if (typeof instance.componentDidMount === 'function') {
12961 workInProgress.flags |= Update;
12962 } // If shouldComponentUpdate returned false, we should still update the
12963 // memoized state to indicate that this work can be reused.
12964
12965
12966 workInProgress.memoizedProps = newProps;
12967 workInProgress.memoizedState = newState;
12968 } // Update the existing instance's state, props, and context pointers even
12969 // if shouldComponentUpdate returns false.
12970
12971
12972 instance.props = newProps;
12973 instance.state = newState;
12974 instance.context = nextContext;
12975 return shouldUpdate;
12976} // Invokes the update life-cycles and returns false if it shouldn't rerender.
12977
12978
12979function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
12980 var instance = workInProgress.stateNode;
12981 cloneUpdateQueue(current, workInProgress);
12982 var unresolvedOldProps = workInProgress.memoizedProps;
12983 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
12984 instance.props = oldProps;
12985 var unresolvedNewProps = workInProgress.pendingProps;
12986 var oldContext = instance.context;
12987 var contextType = ctor.contextType;
12988 var nextContext = emptyContextObject;
12989
12990 if (typeof contextType === 'object' && contextType !== null) {
12991 nextContext = readContext(contextType);
12992 } else {
12993 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12994 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
12995 }
12996
12997 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
12998 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
12999 // ever the previously attempted to render - not the "current". However,
13000 // during componentDidUpdate we pass the "current" props.
13001 // In order to support react-lifecycles-compat polyfilled components,
13002 // Unsafe lifecycles should not be invoked for components using the new APIs.
13003
13004 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13005 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
13006 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13007 }
13008 }
13009
13010 resetHasForceUpdateBeforeProcessing();
13011 var oldState = workInProgress.memoizedState;
13012 var newState = instance.state = oldState;
13013 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
13014 newState = workInProgress.memoizedState;
13015
13016 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13017 // If an update was already in progress, we should schedule an Update
13018 // effect even though we're bailing out, so that cWU/cDU are called.
13019 if (typeof instance.componentDidUpdate === 'function') {
13020 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13021 workInProgress.flags |= Update;
13022 }
13023 }
13024
13025 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13026 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13027 workInProgress.flags |= Snapshot;
13028 }
13029 }
13030
13031 return false;
13032 }
13033
13034 if (typeof getDerivedStateFromProps === 'function') {
13035 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13036 newState = workInProgress.memoizedState;
13037 }
13038
13039 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13040
13041 if (shouldUpdate) {
13042 // In order to support react-lifecycles-compat polyfilled components,
13043 // Unsafe lifecycles should not be invoked for components using the new APIs.
13044 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13045 if (typeof instance.componentWillUpdate === 'function') {
13046 instance.componentWillUpdate(newProps, newState, nextContext);
13047 }
13048
13049 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13050 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13051 }
13052 }
13053
13054 if (typeof instance.componentDidUpdate === 'function') {
13055 workInProgress.flags |= Update;
13056 }
13057
13058 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13059 workInProgress.flags |= Snapshot;
13060 }
13061 } else {
13062 // If an update was already in progress, we should schedule an Update
13063 // effect even though we're bailing out, so that cWU/cDU are called.
13064 if (typeof instance.componentDidUpdate === 'function') {
13065 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13066 workInProgress.flags |= Update;
13067 }
13068 }
13069
13070 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13071 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13072 workInProgress.flags |= Snapshot;
13073 }
13074 } // If shouldComponentUpdate returned false, we should still update the
13075 // memoized props/state to indicate that this work can be reused.
13076
13077
13078 workInProgress.memoizedProps = newProps;
13079 workInProgress.memoizedState = newState;
13080 } // Update the existing instance's state, props, and context pointers even
13081 // if shouldComponentUpdate returns false.
13082
13083
13084 instance.props = newProps;
13085 instance.state = newState;
13086 instance.context = nextContext;
13087 return shouldUpdate;
13088}
13089
13090var didWarnAboutMaps;
13091var didWarnAboutGenerators;
13092var didWarnAboutStringRefs;
13093var ownerHasKeyUseWarning;
13094var ownerHasFunctionTypeWarning;
13095
13096var warnForMissingKey = function (child, returnFiber) {};
13097
13098{
13099 didWarnAboutMaps = false;
13100 didWarnAboutGenerators = false;
13101 didWarnAboutStringRefs = {};
13102 /**
13103 * Warn if there's no key explicitly set on dynamic arrays of children or
13104 * object keys are not valid. This allows us to keep track of children between
13105 * updates.
13106 */
13107
13108 ownerHasKeyUseWarning = {};
13109 ownerHasFunctionTypeWarning = {};
13110
13111 warnForMissingKey = function (child, returnFiber) {
13112 if (child === null || typeof child !== 'object') {
13113 return;
13114 }
13115
13116 if (!child._store || child._store.validated || child.key != null) {
13117 return;
13118 }
13119
13120 if (!(typeof child._store === 'object')) {
13121 {
13122 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
13123 }
13124 }
13125
13126 child._store.validated = true;
13127 var componentName = getComponentName(returnFiber.type) || 'Component';
13128
13129 if (ownerHasKeyUseWarning[componentName]) {
13130 return;
13131 }
13132
13133 ownerHasKeyUseWarning[componentName] = true;
13134
13135 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
13136 };
13137}
13138
13139var isArray$1 = Array.isArray;
13140
13141function coerceRef(returnFiber, current, element) {
13142 var mixedRef = element.ref;
13143
13144 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13145 {
13146 // TODO: Clean this up once we turn on the string ref warning for
13147 // everyone, because the strict mode case will no longer be relevant
13148 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13149 // because these cannot be automatically converted to an arrow function
13150 // using a codemod. Therefore, we don't have to warn about string refs again.
13151 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
13152 var componentName = getComponentName(returnFiber.type) || 'Component';
13153
13154 if (!didWarnAboutStringRefs[componentName]) {
13155 {
13156 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', mixedRef);
13157 }
13158
13159 didWarnAboutStringRefs[componentName] = true;
13160 }
13161 }
13162 }
13163
13164 if (element._owner) {
13165 var owner = element._owner;
13166 var inst;
13167
13168 if (owner) {
13169 var ownerFiber = owner;
13170
13171 if (!(ownerFiber.tag === ClassComponent)) {
13172 {
13173 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref" );
13174 }
13175 }
13176
13177 inst = ownerFiber.stateNode;
13178 }
13179
13180 if (!inst) {
13181 {
13182 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
13183 }
13184 }
13185
13186 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13187
13188 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13189 return current.ref;
13190 }
13191
13192 var ref = function (value) {
13193 var refs = inst.refs;
13194
13195 if (refs === emptyRefsObject) {
13196 // This is a lazy pooled frozen object, so we need to initialize.
13197 refs = inst.refs = {};
13198 }
13199
13200 if (value === null) {
13201 delete refs[stringRef];
13202 } else {
13203 refs[stringRef] = value;
13204 }
13205 };
13206
13207 ref._stringRef = stringRef;
13208 return ref;
13209 } else {
13210 if (!(typeof mixedRef === 'string')) {
13211 {
13212 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
13213 }
13214 }
13215
13216 if (!element._owner) {
13217 {
13218 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://reactjs.org/link/refs-must-have-owner for more information." );
13219 }
13220 }
13221 }
13222 }
13223
13224 return mixedRef;
13225}
13226
13227function throwOnInvalidObjectType(returnFiber, newChild) {
13228 if (returnFiber.type !== 'textarea') {
13229 {
13230 {
13231 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + "). If you meant to render a collection of children, use an array instead." );
13232 }
13233 }
13234 }
13235}
13236
13237function warnOnFunctionType(returnFiber) {
13238 {
13239 var componentName = getComponentName(returnFiber.type) || 'Component';
13240
13241 if (ownerHasFunctionTypeWarning[componentName]) {
13242 return;
13243 }
13244
13245 ownerHasFunctionTypeWarning[componentName] = true;
13246
13247 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.');
13248 }
13249} // We avoid inlining this to avoid potential deopts from using try/catch.
13250// to be able to optimize each path individually by branching early. This needs
13251// a compiler or we can do it manually. Helpers that don't need this branching
13252// live outside of this function.
13253
13254
13255function ChildReconciler(shouldTrackSideEffects) {
13256 function deleteChild(returnFiber, childToDelete) {
13257 if (!shouldTrackSideEffects) {
13258 // Noop.
13259 return;
13260 } // Deletions are added in reversed order so we add it to the front.
13261 // At this point, the return fiber's effect list is empty except for
13262 // deletions, so we can just append the deletion to the list. The remaining
13263 // effects aren't added until the complete phase. Once we implement
13264 // resuming, this may not be true.
13265
13266
13267 var last = returnFiber.lastEffect;
13268
13269 if (last !== null) {
13270 last.nextEffect = childToDelete;
13271 returnFiber.lastEffect = childToDelete;
13272 } else {
13273 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13274 }
13275
13276 childToDelete.nextEffect = null;
13277 childToDelete.flags = Deletion;
13278 }
13279
13280 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13281 if (!shouldTrackSideEffects) {
13282 // Noop.
13283 return null;
13284 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13285 // assuming that after the first child we've already added everything.
13286
13287
13288 var childToDelete = currentFirstChild;
13289
13290 while (childToDelete !== null) {
13291 deleteChild(returnFiber, childToDelete);
13292 childToDelete = childToDelete.sibling;
13293 }
13294
13295 return null;
13296 }
13297
13298 function mapRemainingChildren(returnFiber, currentFirstChild) {
13299 // Add the remaining children to a temporary map so that we can find them by
13300 // keys quickly. Implicit (null) keys get added to this set with their index
13301 // instead.
13302 var existingChildren = new Map();
13303 var existingChild = currentFirstChild;
13304
13305 while (existingChild !== null) {
13306 if (existingChild.key !== null) {
13307 existingChildren.set(existingChild.key, existingChild);
13308 } else {
13309 existingChildren.set(existingChild.index, existingChild);
13310 }
13311
13312 existingChild = existingChild.sibling;
13313 }
13314
13315 return existingChildren;
13316 }
13317
13318 function useFiber(fiber, pendingProps) {
13319 // We currently set sibling to null and index to 0 here because it is easy
13320 // to forget to do before returning it. E.g. for the single child case.
13321 var clone = createWorkInProgress(fiber, pendingProps);
13322 clone.index = 0;
13323 clone.sibling = null;
13324 return clone;
13325 }
13326
13327 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13328 newFiber.index = newIndex;
13329
13330 if (!shouldTrackSideEffects) {
13331 // Noop.
13332 return lastPlacedIndex;
13333 }
13334
13335 var current = newFiber.alternate;
13336
13337 if (current !== null) {
13338 var oldIndex = current.index;
13339
13340 if (oldIndex < lastPlacedIndex) {
13341 // This is a move.
13342 newFiber.flags = Placement;
13343 return lastPlacedIndex;
13344 } else {
13345 // This item can stay in place.
13346 return oldIndex;
13347 }
13348 } else {
13349 // This is an insertion.
13350 newFiber.flags = Placement;
13351 return lastPlacedIndex;
13352 }
13353 }
13354
13355 function placeSingleChild(newFiber) {
13356 // This is simpler for the single child case. We only need to do a
13357 // placement for inserting new children.
13358 if (shouldTrackSideEffects && newFiber.alternate === null) {
13359 newFiber.flags = Placement;
13360 }
13361
13362 return newFiber;
13363 }
13364
13365 function updateTextNode(returnFiber, current, textContent, lanes) {
13366 if (current === null || current.tag !== HostText) {
13367 // Insert
13368 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
13369 created.return = returnFiber;
13370 return created;
13371 } else {
13372 // Update
13373 var existing = useFiber(current, textContent);
13374 existing.return = returnFiber;
13375 return existing;
13376 }
13377 }
13378
13379 function updateElement(returnFiber, current, element, lanes) {
13380 if (current !== null) {
13381 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
13382 isCompatibleFamilyForHotReloading(current, element) )) {
13383 // Move based on index
13384 var existing = useFiber(current, element.props);
13385 existing.ref = coerceRef(returnFiber, current, element);
13386 existing.return = returnFiber;
13387
13388 {
13389 existing._debugSource = element._source;
13390 existing._debugOwner = element._owner;
13391 }
13392
13393 return existing;
13394 }
13395 } // Insert
13396
13397
13398 var created = createFiberFromElement(element, returnFiber.mode, lanes);
13399 created.ref = coerceRef(returnFiber, current, element);
13400 created.return = returnFiber;
13401 return created;
13402 }
13403
13404 function updatePortal(returnFiber, current, portal, lanes) {
13405 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13406 // Insert
13407 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
13408 created.return = returnFiber;
13409 return created;
13410 } else {
13411 // Update
13412 var existing = useFiber(current, portal.children || []);
13413 existing.return = returnFiber;
13414 return existing;
13415 }
13416 }
13417
13418 function updateFragment(returnFiber, current, fragment, lanes, key) {
13419 if (current === null || current.tag !== Fragment) {
13420 // Insert
13421 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
13422 created.return = returnFiber;
13423 return created;
13424 } else {
13425 // Update
13426 var existing = useFiber(current, fragment);
13427 existing.return = returnFiber;
13428 return existing;
13429 }
13430 }
13431
13432 function createChild(returnFiber, newChild, lanes) {
13433 if (typeof newChild === 'string' || typeof newChild === 'number') {
13434 // Text nodes don't have keys. If the previous node is implicitly keyed
13435 // we can continue to replace it without aborting even if it is not a text
13436 // node.
13437 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
13438 created.return = returnFiber;
13439 return created;
13440 }
13441
13442 if (typeof newChild === 'object' && newChild !== null) {
13443 switch (newChild.$$typeof) {
13444 case REACT_ELEMENT_TYPE:
13445 {
13446 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
13447
13448 _created.ref = coerceRef(returnFiber, null, newChild);
13449 _created.return = returnFiber;
13450 return _created;
13451 }
13452
13453 case REACT_PORTAL_TYPE:
13454 {
13455 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
13456
13457 _created2.return = returnFiber;
13458 return _created2;
13459 }
13460 }
13461
13462 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13463 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
13464
13465 _created3.return = returnFiber;
13466 return _created3;
13467 }
13468
13469 throwOnInvalidObjectType(returnFiber, newChild);
13470 }
13471
13472 {
13473 if (typeof newChild === 'function') {
13474 warnOnFunctionType(returnFiber);
13475 }
13476 }
13477
13478 return null;
13479 }
13480
13481 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
13482 // Update the fiber if the keys match, otherwise return null.
13483 var key = oldFiber !== null ? oldFiber.key : null;
13484
13485 if (typeof newChild === 'string' || typeof newChild === 'number') {
13486 // Text nodes don't have keys. If the previous node is implicitly keyed
13487 // we can continue to replace it without aborting even if it is not a text
13488 // node.
13489 if (key !== null) {
13490 return null;
13491 }
13492
13493 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
13494 }
13495
13496 if (typeof newChild === 'object' && newChild !== null) {
13497 switch (newChild.$$typeof) {
13498 case REACT_ELEMENT_TYPE:
13499 {
13500 if (newChild.key === key) {
13501 if (newChild.type === REACT_FRAGMENT_TYPE) {
13502 return updateFragment(returnFiber, oldFiber, newChild.props.children, lanes, key);
13503 }
13504
13505 return updateElement(returnFiber, oldFiber, newChild, lanes);
13506 } else {
13507 return null;
13508 }
13509 }
13510
13511 case REACT_PORTAL_TYPE:
13512 {
13513 if (newChild.key === key) {
13514 return updatePortal(returnFiber, oldFiber, newChild, lanes);
13515 } else {
13516 return null;
13517 }
13518 }
13519 }
13520
13521 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13522 if (key !== null) {
13523 return null;
13524 }
13525
13526 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
13527 }
13528
13529 throwOnInvalidObjectType(returnFiber, newChild);
13530 }
13531
13532 {
13533 if (typeof newChild === 'function') {
13534 warnOnFunctionType(returnFiber);
13535 }
13536 }
13537
13538 return null;
13539 }
13540
13541 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
13542 if (typeof newChild === 'string' || typeof newChild === 'number') {
13543 // Text nodes don't have keys, so we neither have to check the old nor
13544 // new node for the key. If both are text nodes, they match.
13545 var matchedFiber = existingChildren.get(newIdx) || null;
13546 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
13547 }
13548
13549 if (typeof newChild === 'object' && newChild !== null) {
13550 switch (newChild.$$typeof) {
13551 case REACT_ELEMENT_TYPE:
13552 {
13553 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13554
13555 if (newChild.type === REACT_FRAGMENT_TYPE) {
13556 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, lanes, newChild.key);
13557 }
13558
13559 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
13560 }
13561
13562 case REACT_PORTAL_TYPE:
13563 {
13564 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13565
13566 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
13567 }
13568
13569 }
13570
13571 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13572 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13573
13574 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
13575 }
13576
13577 throwOnInvalidObjectType(returnFiber, newChild);
13578 }
13579
13580 {
13581 if (typeof newChild === 'function') {
13582 warnOnFunctionType(returnFiber);
13583 }
13584 }
13585
13586 return null;
13587 }
13588 /**
13589 * Warns if there is a duplicate or missing key
13590 */
13591
13592
13593 function warnOnInvalidKey(child, knownKeys, returnFiber) {
13594 {
13595 if (typeof child !== 'object' || child === null) {
13596 return knownKeys;
13597 }
13598
13599 switch (child.$$typeof) {
13600 case REACT_ELEMENT_TYPE:
13601 case REACT_PORTAL_TYPE:
13602 warnForMissingKey(child, returnFiber);
13603 var key = child.key;
13604
13605 if (typeof key !== 'string') {
13606 break;
13607 }
13608
13609 if (knownKeys === null) {
13610 knownKeys = new Set();
13611 knownKeys.add(key);
13612 break;
13613 }
13614
13615 if (!knownKeys.has(key)) {
13616 knownKeys.add(key);
13617 break;
13618 }
13619
13620 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
13621
13622 break;
13623 }
13624 }
13625
13626 return knownKeys;
13627 }
13628
13629 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
13630 // This algorithm can't optimize by searching from both ends since we
13631 // don't have backpointers on fibers. I'm trying to see how far we can get
13632 // with that model. If it ends up not being worth the tradeoffs, we can
13633 // add it later.
13634 // Even with a two ended optimization, we'd want to optimize for the case
13635 // where there are few changes and brute force the comparison instead of
13636 // going for the Map. It'd like to explore hitting that path first in
13637 // forward-only mode and only go for the Map once we notice that we need
13638 // lots of look ahead. This doesn't handle reversal as well as two ended
13639 // search but that's unusual. Besides, for the two ended optimization to
13640 // work on Iterables, we'd need to copy the whole set.
13641 // In this first iteration, we'll just live with hitting the bad case
13642 // (adding everything to a Map) in for every insert/move.
13643 // If you change this code, also update reconcileChildrenIterator() which
13644 // uses the same algorithm.
13645 {
13646 // First, validate keys.
13647 var knownKeys = null;
13648
13649 for (var i = 0; i < newChildren.length; i++) {
13650 var child = newChildren[i];
13651 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13652 }
13653 }
13654
13655 var resultingFirstChild = null;
13656 var previousNewFiber = null;
13657 var oldFiber = currentFirstChild;
13658 var lastPlacedIndex = 0;
13659 var newIdx = 0;
13660 var nextOldFiber = null;
13661
13662 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13663 if (oldFiber.index > newIdx) {
13664 nextOldFiber = oldFiber;
13665 oldFiber = null;
13666 } else {
13667 nextOldFiber = oldFiber.sibling;
13668 }
13669
13670 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
13671
13672 if (newFiber === null) {
13673 // TODO: This breaks on empty slots like null children. That's
13674 // unfortunate because it triggers the slow path all the time. We need
13675 // a better way to communicate whether this was a miss or null,
13676 // boolean, undefined, etc.
13677 if (oldFiber === null) {
13678 oldFiber = nextOldFiber;
13679 }
13680
13681 break;
13682 }
13683
13684 if (shouldTrackSideEffects) {
13685 if (oldFiber && newFiber.alternate === null) {
13686 // We matched the slot, but we didn't reuse the existing fiber, so we
13687 // need to delete the existing child.
13688 deleteChild(returnFiber, oldFiber);
13689 }
13690 }
13691
13692 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13693
13694 if (previousNewFiber === null) {
13695 // TODO: Move out of the loop. This only happens for the first run.
13696 resultingFirstChild = newFiber;
13697 } else {
13698 // TODO: Defer siblings if we're not at the right index for this slot.
13699 // I.e. if we had null values before, then we want to defer this
13700 // for each null value. However, we also don't want to call updateSlot
13701 // with the previous one.
13702 previousNewFiber.sibling = newFiber;
13703 }
13704
13705 previousNewFiber = newFiber;
13706 oldFiber = nextOldFiber;
13707 }
13708
13709 if (newIdx === newChildren.length) {
13710 // We've reached the end of the new children. We can delete the rest.
13711 deleteRemainingChildren(returnFiber, oldFiber);
13712 return resultingFirstChild;
13713 }
13714
13715 if (oldFiber === null) {
13716 // If we don't have any more existing children we can choose a fast path
13717 // since the rest will all be insertions.
13718 for (; newIdx < newChildren.length; newIdx++) {
13719 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
13720
13721 if (_newFiber === null) {
13722 continue;
13723 }
13724
13725 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13726
13727 if (previousNewFiber === null) {
13728 // TODO: Move out of the loop. This only happens for the first run.
13729 resultingFirstChild = _newFiber;
13730 } else {
13731 previousNewFiber.sibling = _newFiber;
13732 }
13733
13734 previousNewFiber = _newFiber;
13735 }
13736
13737 return resultingFirstChild;
13738 } // Add all children to a key map for quick lookups.
13739
13740
13741 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13742
13743 for (; newIdx < newChildren.length; newIdx++) {
13744 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
13745
13746 if (_newFiber2 !== null) {
13747 if (shouldTrackSideEffects) {
13748 if (_newFiber2.alternate !== null) {
13749 // The new fiber is a work in progress, but if there exists a
13750 // current, that means that we reused the fiber. We need to delete
13751 // it from the child list so that we don't add it to the deletion
13752 // list.
13753 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13754 }
13755 }
13756
13757 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13758
13759 if (previousNewFiber === null) {
13760 resultingFirstChild = _newFiber2;
13761 } else {
13762 previousNewFiber.sibling = _newFiber2;
13763 }
13764
13765 previousNewFiber = _newFiber2;
13766 }
13767 }
13768
13769 if (shouldTrackSideEffects) {
13770 // Any existing children that weren't consumed above were deleted. We need
13771 // to add them to the deletion list.
13772 existingChildren.forEach(function (child) {
13773 return deleteChild(returnFiber, child);
13774 });
13775 }
13776
13777 return resultingFirstChild;
13778 }
13779
13780 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
13781 // This is the same implementation as reconcileChildrenArray(),
13782 // but using the iterator instead.
13783 var iteratorFn = getIteratorFn(newChildrenIterable);
13784
13785 if (!(typeof iteratorFn === 'function')) {
13786 {
13787 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
13788 }
13789 }
13790
13791 {
13792 // We don't support rendering Generators because it's a mutation.
13793 // See https://github.com/facebook/react/issues/12995
13794 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
13795 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13796 if (!didWarnAboutGenerators) {
13797 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.');
13798 }
13799
13800 didWarnAboutGenerators = true;
13801 } // Warn about using Maps as children
13802
13803
13804 if (newChildrenIterable.entries === iteratorFn) {
13805 if (!didWarnAboutMaps) {
13806 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
13807 }
13808
13809 didWarnAboutMaps = true;
13810 } // First, validate keys.
13811 // We'll get a different iterator later for the main pass.
13812
13813
13814 var _newChildren = iteratorFn.call(newChildrenIterable);
13815
13816 if (_newChildren) {
13817 var knownKeys = null;
13818
13819 var _step = _newChildren.next();
13820
13821 for (; !_step.done; _step = _newChildren.next()) {
13822 var child = _step.value;
13823 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
13824 }
13825 }
13826 }
13827
13828 var newChildren = iteratorFn.call(newChildrenIterable);
13829
13830 if (!(newChildren != null)) {
13831 {
13832 throw Error( "An iterable object provided no iterator." );
13833 }
13834 }
13835
13836 var resultingFirstChild = null;
13837 var previousNewFiber = null;
13838 var oldFiber = currentFirstChild;
13839 var lastPlacedIndex = 0;
13840 var newIdx = 0;
13841 var nextOldFiber = null;
13842 var step = newChildren.next();
13843
13844 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
13845 if (oldFiber.index > newIdx) {
13846 nextOldFiber = oldFiber;
13847 oldFiber = null;
13848 } else {
13849 nextOldFiber = oldFiber.sibling;
13850 }
13851
13852 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
13853
13854 if (newFiber === null) {
13855 // TODO: This breaks on empty slots like null children. That's
13856 // unfortunate because it triggers the slow path all the time. We need
13857 // a better way to communicate whether this was a miss or null,
13858 // boolean, undefined, etc.
13859 if (oldFiber === null) {
13860 oldFiber = nextOldFiber;
13861 }
13862
13863 break;
13864 }
13865
13866 if (shouldTrackSideEffects) {
13867 if (oldFiber && newFiber.alternate === null) {
13868 // We matched the slot, but we didn't reuse the existing fiber, so we
13869 // need to delete the existing child.
13870 deleteChild(returnFiber, oldFiber);
13871 }
13872 }
13873
13874 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13875
13876 if (previousNewFiber === null) {
13877 // TODO: Move out of the loop. This only happens for the first run.
13878 resultingFirstChild = newFiber;
13879 } else {
13880 // TODO: Defer siblings if we're not at the right index for this slot.
13881 // I.e. if we had null values before, then we want to defer this
13882 // for each null value. However, we also don't want to call updateSlot
13883 // with the previous one.
13884 previousNewFiber.sibling = newFiber;
13885 }
13886
13887 previousNewFiber = newFiber;
13888 oldFiber = nextOldFiber;
13889 }
13890
13891 if (step.done) {
13892 // We've reached the end of the new children. We can delete the rest.
13893 deleteRemainingChildren(returnFiber, oldFiber);
13894 return resultingFirstChild;
13895 }
13896
13897 if (oldFiber === null) {
13898 // If we don't have any more existing children we can choose a fast path
13899 // since the rest will all be insertions.
13900 for (; !step.done; newIdx++, step = newChildren.next()) {
13901 var _newFiber3 = createChild(returnFiber, step.value, lanes);
13902
13903 if (_newFiber3 === null) {
13904 continue;
13905 }
13906
13907 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
13908
13909 if (previousNewFiber === null) {
13910 // TODO: Move out of the loop. This only happens for the first run.
13911 resultingFirstChild = _newFiber3;
13912 } else {
13913 previousNewFiber.sibling = _newFiber3;
13914 }
13915
13916 previousNewFiber = _newFiber3;
13917 }
13918
13919 return resultingFirstChild;
13920 } // Add all children to a key map for quick lookups.
13921
13922
13923 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13924
13925 for (; !step.done; newIdx++, step = newChildren.next()) {
13926 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
13927
13928 if (_newFiber4 !== null) {
13929 if (shouldTrackSideEffects) {
13930 if (_newFiber4.alternate !== null) {
13931 // The new fiber is a work in progress, but if there exists a
13932 // current, that means that we reused the fiber. We need to delete
13933 // it from the child list so that we don't add it to the deletion
13934 // list.
13935 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
13936 }
13937 }
13938
13939 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
13940
13941 if (previousNewFiber === null) {
13942 resultingFirstChild = _newFiber4;
13943 } else {
13944 previousNewFiber.sibling = _newFiber4;
13945 }
13946
13947 previousNewFiber = _newFiber4;
13948 }
13949 }
13950
13951 if (shouldTrackSideEffects) {
13952 // Any existing children that weren't consumed above were deleted. We need
13953 // to add them to the deletion list.
13954 existingChildren.forEach(function (child) {
13955 return deleteChild(returnFiber, child);
13956 });
13957 }
13958
13959 return resultingFirstChild;
13960 }
13961
13962 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
13963 // There's no need to check for keys on text nodes since we don't have a
13964 // way to define them.
13965 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
13966 // We already have an existing node so let's just update it and delete
13967 // the rest.
13968 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
13969 var existing = useFiber(currentFirstChild, textContent);
13970 existing.return = returnFiber;
13971 return existing;
13972 } // The existing first child is not a text node so we need to create one
13973 // and delete the existing ones.
13974
13975
13976 deleteRemainingChildren(returnFiber, currentFirstChild);
13977 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
13978 created.return = returnFiber;
13979 return created;
13980 }
13981
13982 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
13983 var key = element.key;
13984 var child = currentFirstChild;
13985
13986 while (child !== null) {
13987 // TODO: If key === null and child.key === null, then this only applies to
13988 // the first item in the list.
13989 if (child.key === key) {
13990 switch (child.tag) {
13991 case Fragment:
13992 {
13993 if (element.type === REACT_FRAGMENT_TYPE) {
13994 deleteRemainingChildren(returnFiber, child.sibling);
13995 var existing = useFiber(child, element.props.children);
13996 existing.return = returnFiber;
13997
13998 {
13999 existing._debugSource = element._source;
14000 existing._debugOwner = element._owner;
14001 }
14002
14003 return existing;
14004 }
14005
14006 break;
14007 }
14008
14009 case Block:
14010
14011 // We intentionally fallthrough here if enableBlocksAPI is not on.
14012 // eslint-disable-next-lined no-fallthrough
14013
14014 default:
14015 {
14016 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
14017 isCompatibleFamilyForHotReloading(child, element) )) {
14018 deleteRemainingChildren(returnFiber, child.sibling);
14019
14020 var _existing3 = useFiber(child, element.props);
14021
14022 _existing3.ref = coerceRef(returnFiber, child, element);
14023 _existing3.return = returnFiber;
14024
14025 {
14026 _existing3._debugSource = element._source;
14027 _existing3._debugOwner = element._owner;
14028 }
14029
14030 return _existing3;
14031 }
14032
14033 break;
14034 }
14035 } // Didn't match.
14036
14037
14038 deleteRemainingChildren(returnFiber, child);
14039 break;
14040 } else {
14041 deleteChild(returnFiber, child);
14042 }
14043
14044 child = child.sibling;
14045 }
14046
14047 if (element.type === REACT_FRAGMENT_TYPE) {
14048 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
14049 created.return = returnFiber;
14050 return created;
14051 } else {
14052 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
14053
14054 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14055 _created4.return = returnFiber;
14056 return _created4;
14057 }
14058 }
14059
14060 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
14061 var key = portal.key;
14062 var child = currentFirstChild;
14063
14064 while (child !== null) {
14065 // TODO: If key === null and child.key === null, then this only applies to
14066 // the first item in the list.
14067 if (child.key === key) {
14068 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14069 deleteRemainingChildren(returnFiber, child.sibling);
14070 var existing = useFiber(child, portal.children || []);
14071 existing.return = returnFiber;
14072 return existing;
14073 } else {
14074 deleteRemainingChildren(returnFiber, child);
14075 break;
14076 }
14077 } else {
14078 deleteChild(returnFiber, child);
14079 }
14080
14081 child = child.sibling;
14082 }
14083
14084 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
14085 created.return = returnFiber;
14086 return created;
14087 } // This API will tag the children with the side-effect of the reconciliation
14088 // itself. They will be added to the side-effect list as we pass through the
14089 // children and the parent.
14090
14091
14092 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
14093 // This function is not recursive.
14094 // If the top level item is an array, we treat it as a set of children,
14095 // not as a fragment. Nested arrays on the other hand will be treated as
14096 // fragment nodes. Recursion happens at the normal flow.
14097 // Handle top level unkeyed fragments as if they were arrays.
14098 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14099 // We treat the ambiguous cases above the same.
14100 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14101
14102 if (isUnkeyedTopLevelFragment) {
14103 newChild = newChild.props.children;
14104 } // Handle object types
14105
14106
14107 var isObject = typeof newChild === 'object' && newChild !== null;
14108
14109 if (isObject) {
14110 switch (newChild.$$typeof) {
14111 case REACT_ELEMENT_TYPE:
14112 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
14113
14114 case REACT_PORTAL_TYPE:
14115 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
14116
14117 }
14118 }
14119
14120 if (typeof newChild === 'string' || typeof newChild === 'number') {
14121 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
14122 }
14123
14124 if (isArray$1(newChild)) {
14125 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
14126 }
14127
14128 if (getIteratorFn(newChild)) {
14129 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
14130 }
14131
14132 if (isObject) {
14133 throwOnInvalidObjectType(returnFiber, newChild);
14134 }
14135
14136 {
14137 if (typeof newChild === 'function') {
14138 warnOnFunctionType(returnFiber);
14139 }
14140 }
14141
14142 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14143 // If the new child is undefined, and the return fiber is a composite
14144 // component, throw an error. If Fiber return types are disabled,
14145 // we already threw above.
14146 switch (returnFiber.tag) {
14147 case ClassComponent:
14148 {
14149 {
14150 var instance = returnFiber.stateNode;
14151
14152 if (instance.render._isMockFunction) {
14153 // We allow auto-mocks to proceed as if they're returning null.
14154 break;
14155 }
14156 }
14157 }
14158 // Intentionally fall through to the next case, which handles both
14159 // functions and classes
14160 // eslint-disable-next-lined no-fallthrough
14161
14162 case Block:
14163 case FunctionComponent:
14164 case ForwardRef:
14165 case SimpleMemoComponent:
14166 {
14167 {
14168 {
14169 throw Error( (getComponentName(returnFiber.type) || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
14170 }
14171 }
14172 }
14173 }
14174 } // Remaining cases are all treated as empty.
14175
14176
14177 return deleteRemainingChildren(returnFiber, currentFirstChild);
14178 }
14179
14180 return reconcileChildFibers;
14181}
14182
14183var reconcileChildFibers = ChildReconciler(true);
14184var mountChildFibers = ChildReconciler(false);
14185function cloneChildFibers(current, workInProgress) {
14186 if (!(current === null || workInProgress.child === current.child)) {
14187 {
14188 throw Error( "Resuming work not yet implemented." );
14189 }
14190 }
14191
14192 if (workInProgress.child === null) {
14193 return;
14194 }
14195
14196 var currentChild = workInProgress.child;
14197 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14198 workInProgress.child = newChild;
14199 newChild.return = workInProgress;
14200
14201 while (currentChild.sibling !== null) {
14202 currentChild = currentChild.sibling;
14203 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14204 newChild.return = workInProgress;
14205 }
14206
14207 newChild.sibling = null;
14208} // Reset a workInProgress child set to prepare it for a second pass.
14209
14210function resetChildFibers(workInProgress, lanes) {
14211 var child = workInProgress.child;
14212
14213 while (child !== null) {
14214 resetWorkInProgress(child, lanes);
14215 child = child.sibling;
14216 }
14217}
14218
14219var NO_CONTEXT = {};
14220var contextStackCursor$1 = createCursor(NO_CONTEXT);
14221var contextFiberStackCursor = createCursor(NO_CONTEXT);
14222var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14223
14224function requiredContext(c) {
14225 if (!(c !== NO_CONTEXT)) {
14226 {
14227 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
14228 }
14229 }
14230
14231 return c;
14232}
14233
14234function getRootHostContainer() {
14235 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14236 return rootInstance;
14237}
14238
14239function pushHostContainer(fiber, nextRootInstance) {
14240 // Push current root instance onto the stack;
14241 // This allows us to reset root when portals are popped.
14242 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
14243 // This enables us to pop only Fibers that provide unique contexts.
14244
14245 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
14246 // However, we can't just call getRootHostContext() and push it because
14247 // we'd have a different number of entries on the stack depending on
14248 // whether getRootHostContext() throws somewhere in renderer code or not.
14249 // So we push an empty value first. This lets us safely unwind on errors.
14250
14251 push(contextStackCursor$1, NO_CONTEXT, fiber);
14252 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
14253
14254 pop(contextStackCursor$1, fiber);
14255 push(contextStackCursor$1, nextRootContext, fiber);
14256}
14257
14258function popHostContainer(fiber) {
14259 pop(contextStackCursor$1, fiber);
14260 pop(contextFiberStackCursor, fiber);
14261 pop(rootInstanceStackCursor, fiber);
14262}
14263
14264function getHostContext() {
14265 var context = requiredContext(contextStackCursor$1.current);
14266 return context;
14267}
14268
14269function pushHostContext(fiber) {
14270 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14271 var context = requiredContext(contextStackCursor$1.current);
14272 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
14273
14274 if (context === nextContext) {
14275 return;
14276 } // Track the context and the Fiber that provided it.
14277 // This enables us to pop only Fibers that provide unique contexts.
14278
14279
14280 push(contextFiberStackCursor, fiber, fiber);
14281 push(contextStackCursor$1, nextContext, fiber);
14282}
14283
14284function popHostContext(fiber) {
14285 // Do not pop unless this Fiber provided the current context.
14286 // pushHostContext() only pushes Fibers that provide unique contexts.
14287 if (contextFiberStackCursor.current !== fiber) {
14288 return;
14289 }
14290
14291 pop(contextStackCursor$1, fiber);
14292 pop(contextFiberStackCursor, fiber);
14293}
14294
14295var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
14296// inherited deeply down the subtree. The upper bits only affect
14297// this immediate suspense boundary and gets reset each new
14298// boundary or suspense list.
14299
14300var SubtreeSuspenseContextMask = 1; // Subtree Flags:
14301// InvisibleParentSuspenseContext indicates that one of our parent Suspense
14302// boundaries is not currently showing visible main content.
14303// Either because it is already showing a fallback or is not mounted at all.
14304// We can use this to determine if it is desirable to trigger a fallback at
14305// the parent. If not, then we might need to trigger undesirable boundaries
14306// and/or suspend the commit to avoid hiding the parent content.
14307
14308var InvisibleParentSuspenseContext = 1; // Shallow Flags:
14309// ForceSuspenseFallback can be used by SuspenseList to force newly added
14310// items into their fallback state during one of the render passes.
14311
14312var ForceSuspenseFallback = 2;
14313var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14314function hasSuspenseContext(parentContext, flag) {
14315 return (parentContext & flag) !== 0;
14316}
14317function setDefaultShallowSuspenseContext(parentContext) {
14318 return parentContext & SubtreeSuspenseContextMask;
14319}
14320function setShallowSuspenseContext(parentContext, shallowContext) {
14321 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14322}
14323function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14324 return parentContext | subtreeContext;
14325}
14326function pushSuspenseContext(fiber, newContext) {
14327 push(suspenseStackCursor, newContext, fiber);
14328}
14329function popSuspenseContext(fiber) {
14330 pop(suspenseStackCursor, fiber);
14331}
14332
14333function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14334 // If it was the primary children that just suspended, capture and render the
14335 // fallback. Otherwise, don't capture and bubble to the next boundary.
14336 var nextState = workInProgress.memoizedState;
14337
14338 if (nextState !== null) {
14339 if (nextState.dehydrated !== null) {
14340 // A dehydrated boundary always captures.
14341 return true;
14342 }
14343
14344 return false;
14345 }
14346
14347 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
14348
14349 if (props.fallback === undefined) {
14350 return false;
14351 } // Regular boundaries always capture.
14352
14353
14354 if (props.unstable_avoidThisFallback !== true) {
14355 return true;
14356 } // If it's a boundary we should avoid, then we prefer to bubble up to the
14357 // parent boundary if it is currently invisible.
14358
14359
14360 if (hasInvisibleParent) {
14361 return false;
14362 } // If the parent is not able to handle it, we must handle it.
14363
14364
14365 return true;
14366}
14367function findFirstSuspended(row) {
14368 var node = row;
14369
14370 while (node !== null) {
14371 if (node.tag === SuspenseComponent) {
14372 var state = node.memoizedState;
14373
14374 if (state !== null) {
14375 var dehydrated = state.dehydrated;
14376
14377 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
14378 return node;
14379 }
14380 }
14381 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
14382 // keep track of whether it suspended or not.
14383 node.memoizedProps.revealOrder !== undefined) {
14384 var didSuspend = (node.flags & DidCapture) !== NoFlags;
14385
14386 if (didSuspend) {
14387 return node;
14388 }
14389 } else if (node.child !== null) {
14390 node.child.return = node;
14391 node = node.child;
14392 continue;
14393 }
14394
14395 if (node === row) {
14396 return null;
14397 }
14398
14399 while (node.sibling === null) {
14400 if (node.return === null || node.return === row) {
14401 return null;
14402 }
14403
14404 node = node.return;
14405 }
14406
14407 node.sibling.return = node.return;
14408 node = node.sibling;
14409 }
14410
14411 return null;
14412}
14413
14414var NoFlags$1 =
14415/* */
144160; // Represents whether effect should fire.
14417
14418var HasEffect =
14419/* */
144201; // Represents the phase in which the effect (not the clean-up) fires.
14421
14422var Layout =
14423/* */
144242;
14425var Passive$1 =
14426/* */
144274;
14428
14429// This may have been an insertion or a hydration.
14430
14431var hydrationParentFiber = null;
14432var nextHydratableInstance = null;
14433var isHydrating = false;
14434
14435function enterHydrationState(fiber) {
14436
14437 var parentInstance = fiber.stateNode.containerInfo;
14438 nextHydratableInstance = getFirstHydratableChild(parentInstance);
14439 hydrationParentFiber = fiber;
14440 isHydrating = true;
14441 return true;
14442}
14443
14444function deleteHydratableInstance(returnFiber, instance) {
14445 {
14446 switch (returnFiber.tag) {
14447 case HostRoot:
14448 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
14449 break;
14450
14451 case HostComponent:
14452 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14453 break;
14454 }
14455 }
14456
14457 var childToDelete = createFiberFromHostInstanceForDeletion();
14458 childToDelete.stateNode = instance;
14459 childToDelete.return = returnFiber;
14460 childToDelete.flags = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
14461 // these children are not part of the reconciliation list of children.
14462 // Even if we abort and rereconcile the children, that will try to hydrate
14463 // again and the nodes are still in the host tree so these will be
14464 // recreated.
14465
14466 if (returnFiber.lastEffect !== null) {
14467 returnFiber.lastEffect.nextEffect = childToDelete;
14468 returnFiber.lastEffect = childToDelete;
14469 } else {
14470 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14471 }
14472}
14473
14474function insertNonHydratedInstance(returnFiber, fiber) {
14475 fiber.flags = fiber.flags & ~Hydrating | Placement;
14476
14477 {
14478 switch (returnFiber.tag) {
14479 case HostRoot:
14480 {
14481 var parentContainer = returnFiber.stateNode.containerInfo;
14482
14483 switch (fiber.tag) {
14484 case HostComponent:
14485 var type = fiber.type;
14486 var props = fiber.pendingProps;
14487 didNotFindHydratableContainerInstance(parentContainer, type);
14488 break;
14489
14490 case HostText:
14491 var text = fiber.pendingProps;
14492 didNotFindHydratableContainerTextInstance(parentContainer, text);
14493 break;
14494 }
14495
14496 break;
14497 }
14498
14499 case HostComponent:
14500 {
14501 var parentType = returnFiber.type;
14502 var parentProps = returnFiber.memoizedProps;
14503 var parentInstance = returnFiber.stateNode;
14504
14505 switch (fiber.tag) {
14506 case HostComponent:
14507 var _type = fiber.type;
14508 var _props = fiber.pendingProps;
14509 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
14510 break;
14511
14512 case HostText:
14513 var _text = fiber.pendingProps;
14514 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14515 break;
14516
14517 case SuspenseComponent:
14518 didNotFindHydratableSuspenseInstance(parentType, parentProps);
14519 break;
14520 }
14521
14522 break;
14523 }
14524
14525 default:
14526 return;
14527 }
14528 }
14529}
14530
14531function tryHydrate(fiber, nextInstance) {
14532 switch (fiber.tag) {
14533 case HostComponent:
14534 {
14535 var type = fiber.type;
14536 var props = fiber.pendingProps;
14537 var instance = canHydrateInstance(nextInstance, type);
14538
14539 if (instance !== null) {
14540 fiber.stateNode = instance;
14541 return true;
14542 }
14543
14544 return false;
14545 }
14546
14547 case HostText:
14548 {
14549 var text = fiber.pendingProps;
14550 var textInstance = canHydrateTextInstance(nextInstance, text);
14551
14552 if (textInstance !== null) {
14553 fiber.stateNode = textInstance;
14554 return true;
14555 }
14556
14557 return false;
14558 }
14559
14560 case SuspenseComponent:
14561 {
14562
14563 return false;
14564 }
14565
14566 default:
14567 return false;
14568 }
14569}
14570
14571function tryToClaimNextHydratableInstance(fiber) {
14572 if (!isHydrating) {
14573 return;
14574 }
14575
14576 var nextInstance = nextHydratableInstance;
14577
14578 if (!nextInstance) {
14579 // Nothing to hydrate. Make it an insertion.
14580 insertNonHydratedInstance(hydrationParentFiber, fiber);
14581 isHydrating = false;
14582 hydrationParentFiber = fiber;
14583 return;
14584 }
14585
14586 var firstAttemptedInstance = nextInstance;
14587
14588 if (!tryHydrate(fiber, nextInstance)) {
14589 // If we can't hydrate this instance let's try the next one.
14590 // We use this as a heuristic. It's based on intuition and not data so it
14591 // might be flawed or unnecessary.
14592 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14593
14594 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14595 // Nothing to hydrate. Make it an insertion.
14596 insertNonHydratedInstance(hydrationParentFiber, fiber);
14597 isHydrating = false;
14598 hydrationParentFiber = fiber;
14599 return;
14600 } // We matched the next one, we'll now assume that the first one was
14601 // superfluous and we'll delete it. Since we can't eagerly delete it
14602 // we'll have to schedule a deletion. To do that, this node needs a dummy
14603 // fiber associated with it.
14604
14605
14606 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14607 }
14608
14609 hydrationParentFiber = fiber;
14610 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14611}
14612
14613function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14614
14615 var instance = fiber.stateNode;
14616 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
14617
14618 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
14619 // is a new ref we mark this as an update.
14620
14621 if (updatePayload !== null) {
14622 return true;
14623 }
14624
14625 return false;
14626}
14627
14628function prepareToHydrateHostTextInstance(fiber) {
14629
14630 var textInstance = fiber.stateNode;
14631 var textContent = fiber.memoizedProps;
14632 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14633
14634 {
14635 if (shouldUpdate) {
14636 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14637 // hydration parent is the parent host component of this host text.
14638 var returnFiber = hydrationParentFiber;
14639
14640 if (returnFiber !== null) {
14641 switch (returnFiber.tag) {
14642 case HostRoot:
14643 {
14644 var parentContainer = returnFiber.stateNode.containerInfo;
14645 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14646 break;
14647 }
14648
14649 case HostComponent:
14650 {
14651 var parentType = returnFiber.type;
14652 var parentProps = returnFiber.memoizedProps;
14653 var parentInstance = returnFiber.stateNode;
14654 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14655 break;
14656 }
14657 }
14658 }
14659 }
14660 }
14661
14662 return shouldUpdate;
14663}
14664
14665function skipPastDehydratedSuspenseInstance(fiber) {
14666
14667 var suspenseState = fiber.memoizedState;
14668 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14669
14670 if (!suspenseInstance) {
14671 {
14672 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." );
14673 }
14674 }
14675
14676 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14677}
14678
14679function popToNextHostParent(fiber) {
14680 var parent = fiber.return;
14681
14682 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
14683 parent = parent.return;
14684 }
14685
14686 hydrationParentFiber = parent;
14687}
14688
14689function popHydrationState(fiber) {
14690
14691 if (fiber !== hydrationParentFiber) {
14692 // We're deeper than the current hydration context, inside an inserted
14693 // tree.
14694 return false;
14695 }
14696
14697 if (!isHydrating) {
14698 // If we're not currently hydrating but we're in a hydration context, then
14699 // we were an insertion and now need to pop up reenter hydration of our
14700 // siblings.
14701 popToNextHostParent(fiber);
14702 isHydrating = true;
14703 return false;
14704 }
14705
14706 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
14707 // We only do this deeper than head and body since they tend to have random
14708 // other nodes in them. We also ignore components with pure text content in
14709 // side of them.
14710 // TODO: Better heuristic.
14711
14712 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14713 var nextInstance = nextHydratableInstance;
14714
14715 while (nextInstance) {
14716 deleteHydratableInstance(fiber, nextInstance);
14717 nextInstance = getNextHydratableSibling(nextInstance);
14718 }
14719 }
14720
14721 popToNextHostParent(fiber);
14722
14723 if (fiber.tag === SuspenseComponent) {
14724 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
14725 } else {
14726 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14727 }
14728
14729 return true;
14730}
14731
14732function resetHydrationState() {
14733
14734 hydrationParentFiber = null;
14735 nextHydratableInstance = null;
14736 isHydrating = false;
14737}
14738
14739function getIsHydrating() {
14740 return isHydrating;
14741}
14742
14743// and should be reset before starting a new render.
14744// This tracks which mutable sources need to be reset after a render.
14745
14746var workInProgressSources = [];
14747var rendererSigil$1;
14748
14749{
14750 // Used to detect multiple renderers using the same mutable source.
14751 rendererSigil$1 = {};
14752}
14753
14754function markSourceAsDirty(mutableSource) {
14755 workInProgressSources.push(mutableSource);
14756}
14757function resetWorkInProgressVersions() {
14758 for (var i = 0; i < workInProgressSources.length; i++) {
14759 var mutableSource = workInProgressSources[i];
14760
14761 {
14762 mutableSource._workInProgressVersionPrimary = null;
14763 }
14764 }
14765
14766 workInProgressSources.length = 0;
14767}
14768function getWorkInProgressVersion(mutableSource) {
14769 {
14770 return mutableSource._workInProgressVersionPrimary;
14771 }
14772}
14773function setWorkInProgressVersion(mutableSource, version) {
14774 {
14775 mutableSource._workInProgressVersionPrimary = version;
14776 }
14777
14778 workInProgressSources.push(mutableSource);
14779}
14780function warnAboutMultipleRenderersDEV(mutableSource) {
14781 {
14782 {
14783 if (mutableSource._currentPrimaryRenderer == null) {
14784 mutableSource._currentPrimaryRenderer = rendererSigil$1;
14785 } else if (mutableSource._currentPrimaryRenderer !== rendererSigil$1) {
14786 error('Detected multiple renderers concurrently rendering the ' + 'same mutable source. This is currently unsupported.');
14787 }
14788 }
14789 }
14790} // Eager reads the version of a mutable source and stores it on the root.
14791
14792var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
14793 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
14794var didWarnAboutMismatchedHooksForComponent;
14795var didWarnAboutUseOpaqueIdentifier;
14796
14797{
14798 didWarnAboutUseOpaqueIdentifier = {};
14799 didWarnAboutMismatchedHooksForComponent = new Set();
14800}
14801
14802// These are set right before calling the component.
14803var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
14804// the work-in-progress hook.
14805
14806var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
14807// current hook list is the list that belongs to the current fiber. The
14808// work-in-progress hook list is a new list that will be added to the
14809// work-in-progress fiber.
14810
14811var currentHook = null;
14812var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
14813// does not get reset if we do another render pass; only when we're completely
14814// finished evaluating this component. This is an optimization so we know
14815// whether we need to clear render phase updates after a throw.
14816
14817var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
14818// gets reset after each attempt.
14819// TODO: Maybe there's some way to consolidate this with
14820// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
14821
14822var didScheduleRenderPhaseUpdateDuringThisPass = false;
14823var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
14824
14825var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
14826// The list stores the order of hooks used during the initial render (mount).
14827// Subsequent renders (updates) reference this list.
14828
14829var hookTypesDev = null;
14830var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
14831// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14832// When true, such Hooks will always be "remounted". Only used during hot reload.
14833
14834var ignorePreviousDependencies = false;
14835
14836function mountHookTypesDev() {
14837 {
14838 var hookName = currentHookNameInDev;
14839
14840 if (hookTypesDev === null) {
14841 hookTypesDev = [hookName];
14842 } else {
14843 hookTypesDev.push(hookName);
14844 }
14845 }
14846}
14847
14848function updateHookTypesDev() {
14849 {
14850 var hookName = currentHookNameInDev;
14851
14852 if (hookTypesDev !== null) {
14853 hookTypesUpdateIndexDev++;
14854
14855 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14856 warnOnHookMismatchInDev(hookName);
14857 }
14858 }
14859 }
14860}
14861
14862function checkDepsAreArrayDev(deps) {
14863 {
14864 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14865 // Verify deps, but only on mount to avoid extra checks.
14866 // It's unlikely their type would change as usually you define them inline.
14867 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
14868 }
14869 }
14870}
14871
14872function warnOnHookMismatchInDev(currentHookName) {
14873 {
14874 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14875
14876 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14877 didWarnAboutMismatchedHooksForComponent.add(componentName);
14878
14879 if (hookTypesDev !== null) {
14880 var table = '';
14881 var secondColumnStart = 30;
14882
14883 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14884 var oldHookName = hookTypesDev[i];
14885 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
14886 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
14887 // lol @ IE not supporting String#repeat
14888
14889 while (row.length < secondColumnStart) {
14890 row += ' ';
14891 }
14892
14893 row += newHookName + '\n';
14894 table += row;
14895 }
14896
14897 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
14898 }
14899 }
14900 }
14901}
14902
14903function throwInvalidHookError() {
14904 {
14905 {
14906 throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem." );
14907 }
14908 }
14909}
14910
14911function areHookInputsEqual(nextDeps, prevDeps) {
14912 {
14913 if (ignorePreviousDependencies) {
14914 // Only true when this component is being hot reloaded.
14915 return false;
14916 }
14917 }
14918
14919 if (prevDeps === null) {
14920 {
14921 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);
14922 }
14923
14924 return false;
14925 }
14926
14927 {
14928 // Don't bother comparing lengths in prod because these arrays should be
14929 // passed inline.
14930 if (nextDeps.length !== prevDeps.length) {
14931 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
14932 }
14933 }
14934
14935 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
14936 if (objectIs(nextDeps[i], prevDeps[i])) {
14937 continue;
14938 }
14939
14940 return false;
14941 }
14942
14943 return true;
14944}
14945
14946function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
14947 renderLanes = nextRenderLanes;
14948 currentlyRenderingFiber$1 = workInProgress;
14949
14950 {
14951 hookTypesDev = current !== null ? current._debugHookTypes : null;
14952 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
14953
14954 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
14955 }
14956
14957 workInProgress.memoizedState = null;
14958 workInProgress.updateQueue = null;
14959 workInProgress.lanes = NoLanes; // The following should have already been reset
14960 // currentHook = null;
14961 // workInProgressHook = null;
14962 // didScheduleRenderPhaseUpdate = false;
14963 // TODO Warn if no hooks are used at all during mount, then some are used during update.
14964 // Currently we will identify the update render as a mount because memoizedState === null.
14965 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
14966 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
14967 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
14968 // so memoizedState would be null during updates and mounts.
14969
14970 {
14971 if (current !== null && current.memoizedState !== null) {
14972 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
14973 } else if (hookTypesDev !== null) {
14974 // This dispatcher handles an edge case where a component is updating,
14975 // but no stateful hooks have been used.
14976 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
14977 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
14978 // This dispatcher does that.
14979 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
14980 } else {
14981 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
14982 }
14983 }
14984
14985 var children = Component(props, secondArg); // Check if there was a render phase update
14986
14987 if (didScheduleRenderPhaseUpdateDuringThisPass) {
14988 // Keep rendering in a loop for as long as render phase updates continue to
14989 // be scheduled. Use a counter to prevent infinite loops.
14990 var numberOfReRenders = 0;
14991
14992 do {
14993 didScheduleRenderPhaseUpdateDuringThisPass = false;
14994
14995 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
14996 {
14997 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
14998 }
14999 }
15000
15001 numberOfReRenders += 1;
15002
15003 {
15004 // Even when hot reloading, allow dependencies to stabilize
15005 // after first render to prevent infinite render phase updates.
15006 ignorePreviousDependencies = false;
15007 } // Start over from the beginning of the list
15008
15009
15010 currentHook = null;
15011 workInProgressHook = null;
15012 workInProgress.updateQueue = null;
15013
15014 {
15015 // Also validate hook order for cascading updates.
15016 hookTypesUpdateIndexDev = -1;
15017 }
15018
15019 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
15020 children = Component(props, secondArg);
15021 } while (didScheduleRenderPhaseUpdateDuringThisPass);
15022 } // We can assume the previous dispatcher is always this one, since we set it
15023 // at the beginning of the render phase and there's no re-entrancy.
15024
15025
15026 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15027
15028 {
15029 workInProgress._debugHookTypes = hookTypesDev;
15030 } // This check uses currentHook so that it works the same in DEV and prod bundles.
15031 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15032
15033
15034 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15035 renderLanes = NoLanes;
15036 currentlyRenderingFiber$1 = null;
15037 currentHook = null;
15038 workInProgressHook = null;
15039
15040 {
15041 currentHookNameInDev = null;
15042 hookTypesDev = null;
15043 hookTypesUpdateIndexDev = -1;
15044 }
15045
15046 didScheduleRenderPhaseUpdate = false;
15047
15048 if (!!didRenderTooFewHooks) {
15049 {
15050 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
15051 }
15052 }
15053
15054 return children;
15055}
15056function bailoutHooks(current, workInProgress, lanes) {
15057 workInProgress.updateQueue = current.updateQueue;
15058 workInProgress.flags &= ~(Passive | Update);
15059 current.lanes = removeLanes(current.lanes, lanes);
15060}
15061function resetHooksAfterThrow() {
15062 // We can assume the previous dispatcher is always this one, since we set it
15063 // at the beginning of the render phase and there's no re-entrancy.
15064 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15065
15066 if (didScheduleRenderPhaseUpdate) {
15067 // There were render phase updates. These are only valid for this render
15068 // phase, which we are now aborting. Remove the updates from the queues so
15069 // they do not persist to the next render. Do not remove updates from hooks
15070 // that weren't processed.
15071 //
15072 // Only reset the updates from the queue if it has a clone. If it does
15073 // not have a clone, that means it wasn't processed, and the updates were
15074 // scheduled before we entered the render phase.
15075 var hook = currentlyRenderingFiber$1.memoizedState;
15076
15077 while (hook !== null) {
15078 var queue = hook.queue;
15079
15080 if (queue !== null) {
15081 queue.pending = null;
15082 }
15083
15084 hook = hook.next;
15085 }
15086
15087 didScheduleRenderPhaseUpdate = false;
15088 }
15089
15090 renderLanes = NoLanes;
15091 currentlyRenderingFiber$1 = null;
15092 currentHook = null;
15093 workInProgressHook = null;
15094
15095 {
15096 hookTypesDev = null;
15097 hookTypesUpdateIndexDev = -1;
15098 currentHookNameInDev = null;
15099 isUpdatingOpaqueValueInRenderPhase = false;
15100 }
15101
15102 didScheduleRenderPhaseUpdateDuringThisPass = false;
15103}
15104
15105function mountWorkInProgressHook() {
15106 var hook = {
15107 memoizedState: null,
15108 baseState: null,
15109 baseQueue: null,
15110 queue: null,
15111 next: null
15112 };
15113
15114 if (workInProgressHook === null) {
15115 // This is the first hook in the list
15116 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
15117 } else {
15118 // Append to the end of the list
15119 workInProgressHook = workInProgressHook.next = hook;
15120 }
15121
15122 return workInProgressHook;
15123}
15124
15125function updateWorkInProgressHook() {
15126 // This function is used both for updates and for re-renders triggered by a
15127 // render phase update. It assumes there is either a current hook we can
15128 // clone, or a work-in-progress hook from a previous render pass that we can
15129 // use as a base. When we reach the end of the base list, we must switch to
15130 // the dispatcher used for mounts.
15131 var nextCurrentHook;
15132
15133 if (currentHook === null) {
15134 var current = currentlyRenderingFiber$1.alternate;
15135
15136 if (current !== null) {
15137 nextCurrentHook = current.memoizedState;
15138 } else {
15139 nextCurrentHook = null;
15140 }
15141 } else {
15142 nextCurrentHook = currentHook.next;
15143 }
15144
15145 var nextWorkInProgressHook;
15146
15147 if (workInProgressHook === null) {
15148 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
15149 } else {
15150 nextWorkInProgressHook = workInProgressHook.next;
15151 }
15152
15153 if (nextWorkInProgressHook !== null) {
15154 // There's already a work-in-progress. Reuse it.
15155 workInProgressHook = nextWorkInProgressHook;
15156 nextWorkInProgressHook = workInProgressHook.next;
15157 currentHook = nextCurrentHook;
15158 } else {
15159 // Clone from the current hook.
15160 if (!(nextCurrentHook !== null)) {
15161 {
15162 throw Error( "Rendered more hooks than during the previous render." );
15163 }
15164 }
15165
15166 currentHook = nextCurrentHook;
15167 var newHook = {
15168 memoizedState: currentHook.memoizedState,
15169 baseState: currentHook.baseState,
15170 baseQueue: currentHook.baseQueue,
15171 queue: currentHook.queue,
15172 next: null
15173 };
15174
15175 if (workInProgressHook === null) {
15176 // This is the first hook in the list.
15177 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
15178 } else {
15179 // Append to the end of the list.
15180 workInProgressHook = workInProgressHook.next = newHook;
15181 }
15182 }
15183
15184 return workInProgressHook;
15185}
15186
15187function createFunctionComponentUpdateQueue() {
15188 return {
15189 lastEffect: null
15190 };
15191}
15192
15193function basicStateReducer(state, action) {
15194 // $FlowFixMe: Flow doesn't like mixed types
15195 return typeof action === 'function' ? action(state) : action;
15196}
15197
15198function mountReducer(reducer, initialArg, init) {
15199 var hook = mountWorkInProgressHook();
15200 var initialState;
15201
15202 if (init !== undefined) {
15203 initialState = init(initialArg);
15204 } else {
15205 initialState = initialArg;
15206 }
15207
15208 hook.memoizedState = hook.baseState = initialState;
15209 var queue = hook.queue = {
15210 pending: null,
15211 dispatch: null,
15212 lastRenderedReducer: reducer,
15213 lastRenderedState: initialState
15214 };
15215 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15216 return [hook.memoizedState, dispatch];
15217}
15218
15219function updateReducer(reducer, initialArg, init) {
15220 var hook = updateWorkInProgressHook();
15221 var queue = hook.queue;
15222
15223 if (!(queue !== null)) {
15224 {
15225 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15226 }
15227 }
15228
15229 queue.lastRenderedReducer = reducer;
15230 var current = currentHook; // The last rebase update that is NOT part of the base state.
15231
15232 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15233
15234 var pendingQueue = queue.pending;
15235
15236 if (pendingQueue !== null) {
15237 // We have new updates that haven't been processed yet.
15238 // We'll add them to the base queue.
15239 if (baseQueue !== null) {
15240 // Merge the pending queue and the base queue.
15241 var baseFirst = baseQueue.next;
15242 var pendingFirst = pendingQueue.next;
15243 baseQueue.next = pendingFirst;
15244 pendingQueue.next = baseFirst;
15245 }
15246
15247 {
15248 if (current.baseQueue !== baseQueue) {
15249 // Internal invariant that should never happen, but feasibly could in
15250 // the future if we implement resuming, or some form of that.
15251 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
15252 }
15253 }
15254
15255 current.baseQueue = baseQueue = pendingQueue;
15256 queue.pending = null;
15257 }
15258
15259 if (baseQueue !== null) {
15260 // We have a queue to process.
15261 var first = baseQueue.next;
15262 var newState = current.baseState;
15263 var newBaseState = null;
15264 var newBaseQueueFirst = null;
15265 var newBaseQueueLast = null;
15266 var update = first;
15267
15268 do {
15269 var updateLane = update.lane;
15270
15271 if (!isSubsetOfLanes(renderLanes, updateLane)) {
15272 // Priority is insufficient. Skip this update. If this is the first
15273 // skipped update, the previous update/state is the new base
15274 // update/state.
15275 var clone = {
15276 lane: updateLane,
15277 action: update.action,
15278 eagerReducer: update.eagerReducer,
15279 eagerState: update.eagerState,
15280 next: null
15281 };
15282
15283 if (newBaseQueueLast === null) {
15284 newBaseQueueFirst = newBaseQueueLast = clone;
15285 newBaseState = newState;
15286 } else {
15287 newBaseQueueLast = newBaseQueueLast.next = clone;
15288 } // Update the remaining priority in the queue.
15289 // TODO: Don't need to accumulate this. Instead, we can remove
15290 // renderLanes from the original lanes.
15291
15292
15293 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
15294 markSkippedUpdateLanes(updateLane);
15295 } else {
15296 // This update does have sufficient priority.
15297 if (newBaseQueueLast !== null) {
15298 var _clone = {
15299 // This update is going to be committed so we never want uncommit
15300 // it. Using NoLane works because 0 is a subset of all bitmasks, so
15301 // this will never be skipped by the check above.
15302 lane: NoLane,
15303 action: update.action,
15304 eagerReducer: update.eagerReducer,
15305 eagerState: update.eagerState,
15306 next: null
15307 };
15308 newBaseQueueLast = newBaseQueueLast.next = _clone;
15309 } // Process this update.
15310
15311
15312 if (update.eagerReducer === reducer) {
15313 // If this update was processed eagerly, and its reducer matches the
15314 // current reducer, we can use the eagerly computed state.
15315 newState = update.eagerState;
15316 } else {
15317 var action = update.action;
15318 newState = reducer(newState, action);
15319 }
15320 }
15321
15322 update = update.next;
15323 } while (update !== null && update !== first);
15324
15325 if (newBaseQueueLast === null) {
15326 newBaseState = newState;
15327 } else {
15328 newBaseQueueLast.next = newBaseQueueFirst;
15329 } // Mark that the fiber performed work, but only if the new state is
15330 // different from the current state.
15331
15332
15333 if (!objectIs(newState, hook.memoizedState)) {
15334 markWorkInProgressReceivedUpdate();
15335 }
15336
15337 hook.memoizedState = newState;
15338 hook.baseState = newBaseState;
15339 hook.baseQueue = newBaseQueueLast;
15340 queue.lastRenderedState = newState;
15341 }
15342
15343 var dispatch = queue.dispatch;
15344 return [hook.memoizedState, dispatch];
15345}
15346
15347function rerenderReducer(reducer, initialArg, init) {
15348 var hook = updateWorkInProgressHook();
15349 var queue = hook.queue;
15350
15351 if (!(queue !== null)) {
15352 {
15353 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15354 }
15355 }
15356
15357 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15358 // work-in-progress hook.
15359
15360 var dispatch = queue.dispatch;
15361 var lastRenderPhaseUpdate = queue.pending;
15362 var newState = hook.memoizedState;
15363
15364 if (lastRenderPhaseUpdate !== null) {
15365 // The queue doesn't persist past this render pass.
15366 queue.pending = null;
15367 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15368 var update = firstRenderPhaseUpdate;
15369
15370 do {
15371 // Process this render phase update. We don't have to check the
15372 // priority because it will always be the same as the current
15373 // render's.
15374 var action = update.action;
15375 newState = reducer(newState, action);
15376 update = update.next;
15377 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15378 // different from the current state.
15379
15380
15381 if (!objectIs(newState, hook.memoizedState)) {
15382 markWorkInProgressReceivedUpdate();
15383 }
15384
15385 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15386 // the base state unless the queue is empty.
15387 // TODO: Not sure if this is the desired semantics, but it's what we
15388 // do for gDSFP. I can't remember why.
15389
15390 if (hook.baseQueue === null) {
15391 hook.baseState = newState;
15392 }
15393
15394 queue.lastRenderedState = newState;
15395 }
15396
15397 return [newState, dispatch];
15398}
15399
15400function readFromUnsubcribedMutableSource(root, source, getSnapshot) {
15401 {
15402 warnAboutMultipleRenderersDEV(source);
15403 }
15404
15405 var getVersion = source._getVersion;
15406 var version = getVersion(source._source); // Is it safe for this component to read from this source during the current render?
15407
15408 var isSafeToReadFromSource = false; // Check the version first.
15409 // If this render has already been started with a specific version,
15410 // we can use it alone to determine if we can safely read from the source.
15411
15412 var currentRenderVersion = getWorkInProgressVersion(source);
15413
15414 if (currentRenderVersion !== null) {
15415 // It's safe to read if the store hasn't been mutated since the last time
15416 // we read something.
15417 isSafeToReadFromSource = currentRenderVersion === version;
15418 } else {
15419 // If there's no version, then this is the first time we've read from the
15420 // source during the current render pass, so we need to do a bit more work.
15421 // What we need to determine is if there are any hooks that already
15422 // subscribed to the source, and if so, whether there are any pending
15423 // mutations that haven't been synchronized yet.
15424 //
15425 // If there are no pending mutations, then `root.mutableReadLanes` will be
15426 // empty, and we know we can safely read.
15427 //
15428 // If there *are* pending mutations, we may still be able to safely read
15429 // if the currently rendering lanes are inclusive of the pending mutation
15430 // lanes, since that guarantees that the value we're about to read from
15431 // the source is consistent with the values that we read during the most
15432 // recent mutation.
15433 isSafeToReadFromSource = isSubsetOfLanes(renderLanes, root.mutableReadLanes);
15434
15435 if (isSafeToReadFromSource) {
15436 // If it's safe to read from this source during the current render,
15437 // store the version in case other components read from it.
15438 // A changed version number will let those components know to throw and restart the render.
15439 setWorkInProgressVersion(source, version);
15440 }
15441 }
15442
15443 if (isSafeToReadFromSource) {
15444 var snapshot = getSnapshot(source._source);
15445
15446 {
15447 if (typeof snapshot === 'function') {
15448 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');
15449 }
15450 }
15451
15452 return snapshot;
15453 } else {
15454 // This handles the special case of a mutable source being shared between renderers.
15455 // In that case, if the source is mutated between the first and second renderer,
15456 // The second renderer don't know that it needs to reset the WIP version during unwind,
15457 // (because the hook only marks sources as dirty if it's written to their WIP version).
15458 // That would cause this tear check to throw again and eventually be visible to the user.
15459 // We can avoid this infinite loop by explicitly marking the source as dirty.
15460 //
15461 // This can lead to tearing in the first renderer when it resumes,
15462 // but there's nothing we can do about that (short of throwing here and refusing to continue the render).
15463 markSourceAsDirty(source);
15464
15465 {
15466 {
15467 throw Error( "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." );
15468 }
15469 }
15470 }
15471}
15472
15473function useMutableSource(hook, source, getSnapshot, subscribe) {
15474 var root = getWorkInProgressRoot();
15475
15476 if (!(root !== null)) {
15477 {
15478 throw Error( "Expected a work-in-progress root. This is a bug in React. Please file an issue." );
15479 }
15480 }
15481
15482 var getVersion = source._getVersion;
15483 var version = getVersion(source._source);
15484 var dispatcher = ReactCurrentDispatcher$1.current; // eslint-disable-next-line prefer-const
15485
15486 var _dispatcher$useState = dispatcher.useState(function () {
15487 return readFromUnsubcribedMutableSource(root, source, getSnapshot);
15488 }),
15489 currentSnapshot = _dispatcher$useState[0],
15490 setSnapshot = _dispatcher$useState[1];
15491
15492 var snapshot = currentSnapshot; // Grab a handle to the state hook as well.
15493 // We use it to clear the pending update queue if we have a new source.
15494
15495 var stateHook = workInProgressHook;
15496 var memoizedState = hook.memoizedState;
15497 var refs = memoizedState.refs;
15498 var prevGetSnapshot = refs.getSnapshot;
15499 var prevSource = memoizedState.source;
15500 var prevSubscribe = memoizedState.subscribe;
15501 var fiber = currentlyRenderingFiber$1;
15502 hook.memoizedState = {
15503 refs: refs,
15504 source: source,
15505 subscribe: subscribe
15506 }; // Sync the values needed by our subscription handler after each commit.
15507
15508 dispatcher.useEffect(function () {
15509 refs.getSnapshot = getSnapshot; // Normally the dispatch function for a state hook never changes,
15510 // but this hook recreates the queue in certain cases to avoid updates from stale sources.
15511 // handleChange() below needs to reference the dispatch function without re-subscribing,
15512 // so we use a ref to ensure that it always has the latest version.
15513
15514 refs.setSnapshot = setSnapshot; // Check for a possible change between when we last rendered now.
15515
15516 var maybeNewVersion = getVersion(source._source);
15517
15518 if (!objectIs(version, maybeNewVersion)) {
15519 var maybeNewSnapshot = getSnapshot(source._source);
15520
15521 {
15522 if (typeof maybeNewSnapshot === 'function') {
15523 error('Mutable source should not return a function as the snapshot value. ' + 'Functions may close over mutable values and cause tearing.');
15524 }
15525 }
15526
15527 if (!objectIs(snapshot, maybeNewSnapshot)) {
15528 setSnapshot(maybeNewSnapshot);
15529 var lane = requestUpdateLane(fiber);
15530 markRootMutableRead(root, lane);
15531 } // If the source mutated between render and now,
15532 // there may be state updates already scheduled from the old source.
15533 // Entangle the updates so that they render in the same batch.
15534
15535
15536 markRootEntangled(root, root.mutableReadLanes);
15537 }
15538 }, [getSnapshot, source, subscribe]); // If we got a new source or subscribe function, re-subscribe in a passive effect.
15539
15540 dispatcher.useEffect(function () {
15541 var handleChange = function () {
15542 var latestGetSnapshot = refs.getSnapshot;
15543 var latestSetSnapshot = refs.setSnapshot;
15544
15545 try {
15546 latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time.
15547
15548 var lane = requestUpdateLane(fiber);
15549 markRootMutableRead(root, lane);
15550 } catch (error) {
15551 // A selector might throw after a source mutation.
15552 // e.g. it might try to read from a part of the store that no longer exists.
15553 // In this case we should still schedule an update with React.
15554 // Worst case the selector will throw again and then an error boundary will handle it.
15555 latestSetSnapshot(function () {
15556 throw error;
15557 });
15558 }
15559 };
15560
15561 var unsubscribe = subscribe(source._source, handleChange);
15562
15563 {
15564 if (typeof unsubscribe !== 'function') {
15565 error('Mutable source subscribe function must return an unsubscribe function.');
15566 }
15567 }
15568
15569 return unsubscribe;
15570 }, [source, subscribe]); // If any of the inputs to useMutableSource change, reading is potentially unsafe.
15571 //
15572 // If either the source or the subscription have changed we can't can't trust the update queue.
15573 // Maybe the source changed in a way that the old subscription ignored but the new one depends on.
15574 //
15575 // If the getSnapshot function changed, we also shouldn't rely on the update queue.
15576 // It's possible that the underlying source was mutated between the when the last "change" event fired,
15577 // and when the current render (with the new getSnapshot function) is processed.
15578 //
15579 // In both cases, we need to throw away pending updates (since they are no longer relevant)
15580 // and treat reading from the source as we do in the mount case.
15581
15582 if (!objectIs(prevGetSnapshot, getSnapshot) || !objectIs(prevSource, source) || !objectIs(prevSubscribe, subscribe)) {
15583 // Create a new queue and setState method,
15584 // So if there are interleaved updates, they get pushed to the older queue.
15585 // When this becomes current, the previous queue and dispatch method will be discarded,
15586 // including any interleaving updates that occur.
15587 var newQueue = {
15588 pending: null,
15589 dispatch: null,
15590 lastRenderedReducer: basicStateReducer,
15591 lastRenderedState: snapshot
15592 };
15593 newQueue.dispatch = setSnapshot = dispatchAction.bind(null, currentlyRenderingFiber$1, newQueue);
15594 stateHook.queue = newQueue;
15595 stateHook.baseQueue = null;
15596 snapshot = readFromUnsubcribedMutableSource(root, source, getSnapshot);
15597 stateHook.memoizedState = stateHook.baseState = snapshot;
15598 }
15599
15600 return snapshot;
15601}
15602
15603function mountMutableSource(source, getSnapshot, subscribe) {
15604 var hook = mountWorkInProgressHook();
15605 hook.memoizedState = {
15606 refs: {
15607 getSnapshot: getSnapshot,
15608 setSnapshot: null
15609 },
15610 source: source,
15611 subscribe: subscribe
15612 };
15613 return useMutableSource(hook, source, getSnapshot, subscribe);
15614}
15615
15616function updateMutableSource(source, getSnapshot, subscribe) {
15617 var hook = updateWorkInProgressHook();
15618 return useMutableSource(hook, source, getSnapshot, subscribe);
15619}
15620
15621function mountState(initialState) {
15622 var hook = mountWorkInProgressHook();
15623
15624 if (typeof initialState === 'function') {
15625 // $FlowFixMe: Flow doesn't like mixed types
15626 initialState = initialState();
15627 }
15628
15629 hook.memoizedState = hook.baseState = initialState;
15630 var queue = hook.queue = {
15631 pending: null,
15632 dispatch: null,
15633 lastRenderedReducer: basicStateReducer,
15634 lastRenderedState: initialState
15635 };
15636 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15637 return [hook.memoizedState, dispatch];
15638}
15639
15640function updateState(initialState) {
15641 return updateReducer(basicStateReducer);
15642}
15643
15644function rerenderState(initialState) {
15645 return rerenderReducer(basicStateReducer);
15646}
15647
15648function pushEffect(tag, create, destroy, deps) {
15649 var effect = {
15650 tag: tag,
15651 create: create,
15652 destroy: destroy,
15653 deps: deps,
15654 // Circular
15655 next: null
15656 };
15657 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
15658
15659 if (componentUpdateQueue === null) {
15660 componentUpdateQueue = createFunctionComponentUpdateQueue();
15661 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
15662 componentUpdateQueue.lastEffect = effect.next = effect;
15663 } else {
15664 var lastEffect = componentUpdateQueue.lastEffect;
15665
15666 if (lastEffect === null) {
15667 componentUpdateQueue.lastEffect = effect.next = effect;
15668 } else {
15669 var firstEffect = lastEffect.next;
15670 lastEffect.next = effect;
15671 effect.next = firstEffect;
15672 componentUpdateQueue.lastEffect = effect;
15673 }
15674 }
15675
15676 return effect;
15677}
15678
15679function mountRef(initialValue) {
15680 var hook = mountWorkInProgressHook();
15681 var ref = {
15682 current: initialValue
15683 };
15684
15685 {
15686 Object.seal(ref);
15687 }
15688
15689 hook.memoizedState = ref;
15690 return ref;
15691}
15692
15693function updateRef(initialValue) {
15694 var hook = updateWorkInProgressHook();
15695 return hook.memoizedState;
15696}
15697
15698function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
15699 var hook = mountWorkInProgressHook();
15700 var nextDeps = deps === undefined ? null : deps;
15701 currentlyRenderingFiber$1.flags |= fiberFlags;
15702 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
15703}
15704
15705function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
15706 var hook = updateWorkInProgressHook();
15707 var nextDeps = deps === undefined ? null : deps;
15708 var destroy = undefined;
15709
15710 if (currentHook !== null) {
15711 var prevEffect = currentHook.memoizedState;
15712 destroy = prevEffect.destroy;
15713
15714 if (nextDeps !== null) {
15715 var prevDeps = prevEffect.deps;
15716
15717 if (areHookInputsEqual(nextDeps, prevDeps)) {
15718 pushEffect(hookFlags, create, destroy, nextDeps);
15719 return;
15720 }
15721 }
15722 }
15723
15724 currentlyRenderingFiber$1.flags |= fiberFlags;
15725 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
15726}
15727
15728function mountEffect(create, deps) {
15729 {
15730 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15731 if ('undefined' !== typeof jest) {
15732 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15733 }
15734 }
15735
15736 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15737}
15738
15739function updateEffect(create, deps) {
15740 {
15741 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15742 if ('undefined' !== typeof jest) {
15743 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15744 }
15745 }
15746
15747 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15748}
15749
15750function mountLayoutEffect(create, deps) {
15751 return mountEffectImpl(Update, Layout, create, deps);
15752}
15753
15754function updateLayoutEffect(create, deps) {
15755 return updateEffectImpl(Update, Layout, create, deps);
15756}
15757
15758function imperativeHandleEffect(create, ref) {
15759 if (typeof ref === 'function') {
15760 var refCallback = ref;
15761
15762 var _inst = create();
15763
15764 refCallback(_inst);
15765 return function () {
15766 refCallback(null);
15767 };
15768 } else if (ref !== null && ref !== undefined) {
15769 var refObject = ref;
15770
15771 {
15772 if (!refObject.hasOwnProperty('current')) {
15773 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
15774 }
15775 }
15776
15777 var _inst2 = create();
15778
15779 refObject.current = _inst2;
15780 return function () {
15781 refObject.current = null;
15782 };
15783 }
15784}
15785
15786function mountImperativeHandle(ref, create, deps) {
15787 {
15788 if (typeof create !== 'function') {
15789 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15790 }
15791 } // TODO: If deps are provided, should we skip comparing the ref itself?
15792
15793
15794 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15795 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15796}
15797
15798function updateImperativeHandle(ref, create, deps) {
15799 {
15800 if (typeof create !== 'function') {
15801 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15802 }
15803 } // TODO: If deps are provided, should we skip comparing the ref itself?
15804
15805
15806 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15807 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15808}
15809
15810function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
15811 // The react-debug-hooks package injects its own implementation
15812 // so that e.g. DevTools can display custom hook values.
15813}
15814
15815var updateDebugValue = mountDebugValue;
15816
15817function mountCallback(callback, deps) {
15818 var hook = mountWorkInProgressHook();
15819 var nextDeps = deps === undefined ? null : deps;
15820 hook.memoizedState = [callback, nextDeps];
15821 return callback;
15822}
15823
15824function updateCallback(callback, deps) {
15825 var hook = updateWorkInProgressHook();
15826 var nextDeps = deps === undefined ? null : deps;
15827 var prevState = hook.memoizedState;
15828
15829 if (prevState !== null) {
15830 if (nextDeps !== null) {
15831 var prevDeps = prevState[1];
15832
15833 if (areHookInputsEqual(nextDeps, prevDeps)) {
15834 return prevState[0];
15835 }
15836 }
15837 }
15838
15839 hook.memoizedState = [callback, nextDeps];
15840 return callback;
15841}
15842
15843function mountMemo(nextCreate, deps) {
15844 var hook = mountWorkInProgressHook();
15845 var nextDeps = deps === undefined ? null : deps;
15846 var nextValue = nextCreate();
15847 hook.memoizedState = [nextValue, nextDeps];
15848 return nextValue;
15849}
15850
15851function updateMemo(nextCreate, deps) {
15852 var hook = updateWorkInProgressHook();
15853 var nextDeps = deps === undefined ? null : deps;
15854 var prevState = hook.memoizedState;
15855
15856 if (prevState !== null) {
15857 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15858 if (nextDeps !== null) {
15859 var prevDeps = prevState[1];
15860
15861 if (areHookInputsEqual(nextDeps, prevDeps)) {
15862 return prevState[0];
15863 }
15864 }
15865 }
15866
15867 var nextValue = nextCreate();
15868 hook.memoizedState = [nextValue, nextDeps];
15869 return nextValue;
15870}
15871
15872function mountDeferredValue(value) {
15873 var _mountState = mountState(value),
15874 prevValue = _mountState[0],
15875 setValue = _mountState[1];
15876
15877 mountEffect(function () {
15878 var prevTransition = ReactCurrentBatchConfig$1.transition;
15879 ReactCurrentBatchConfig$1.transition = 1;
15880
15881 try {
15882 setValue(value);
15883 } finally {
15884 ReactCurrentBatchConfig$1.transition = prevTransition;
15885 }
15886 }, [value]);
15887 return prevValue;
15888}
15889
15890function updateDeferredValue(value) {
15891 var _updateState = updateState(),
15892 prevValue = _updateState[0],
15893 setValue = _updateState[1];
15894
15895 updateEffect(function () {
15896 var prevTransition = ReactCurrentBatchConfig$1.transition;
15897 ReactCurrentBatchConfig$1.transition = 1;
15898
15899 try {
15900 setValue(value);
15901 } finally {
15902 ReactCurrentBatchConfig$1.transition = prevTransition;
15903 }
15904 }, [value]);
15905 return prevValue;
15906}
15907
15908function rerenderDeferredValue(value) {
15909 var _rerenderState = rerenderState(),
15910 prevValue = _rerenderState[0],
15911 setValue = _rerenderState[1];
15912
15913 updateEffect(function () {
15914 var prevTransition = ReactCurrentBatchConfig$1.transition;
15915 ReactCurrentBatchConfig$1.transition = 1;
15916
15917 try {
15918 setValue(value);
15919 } finally {
15920 ReactCurrentBatchConfig$1.transition = prevTransition;
15921 }
15922 }, [value]);
15923 return prevValue;
15924}
15925
15926function startTransition(setPending, callback) {
15927 var priorityLevel = getCurrentPriorityLevel();
15928
15929 {
15930 runWithPriority$1(priorityLevel < UserBlockingPriority$2 ? UserBlockingPriority$2 : priorityLevel, function () {
15931 setPending(true);
15932 });
15933 runWithPriority$1(priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function () {
15934 var prevTransition = ReactCurrentBatchConfig$1.transition;
15935 ReactCurrentBatchConfig$1.transition = 1;
15936
15937 try {
15938 setPending(false);
15939 callback();
15940 } finally {
15941 ReactCurrentBatchConfig$1.transition = prevTransition;
15942 }
15943 });
15944 }
15945}
15946
15947function mountTransition() {
15948 var _mountState2 = mountState(false),
15949 isPending = _mountState2[0],
15950 setPending = _mountState2[1]; // The `start` method can be stored on a ref, since `setPending`
15951 // never changes.
15952
15953
15954 var start = startTransition.bind(null, setPending);
15955 mountRef(start);
15956 return [start, isPending];
15957}
15958
15959function updateTransition() {
15960 var _updateState2 = updateState(),
15961 isPending = _updateState2[0];
15962
15963 var startRef = updateRef();
15964 var start = startRef.current;
15965 return [start, isPending];
15966}
15967
15968function rerenderTransition() {
15969 var _rerenderState2 = rerenderState(),
15970 isPending = _rerenderState2[0];
15971
15972 var startRef = updateRef();
15973 var start = startRef.current;
15974 return [start, isPending];
15975}
15976
15977var isUpdatingOpaqueValueInRenderPhase = false;
15978function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
15979 {
15980 return isUpdatingOpaqueValueInRenderPhase;
15981 }
15982}
15983
15984function warnOnOpaqueIdentifierAccessInDEV(fiber) {
15985 {
15986 // TODO: Should warn in effects and callbacks, too
15987 var name = getComponentName(fiber.type) || 'Unknown';
15988
15989 if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {
15990 error('The object passed back from useOpaqueIdentifier is meant to be ' + 'passed through to attributes only. Do not read the ' + 'value directly.');
15991
15992 didWarnAboutUseOpaqueIdentifier[name] = true;
15993 }
15994 }
15995}
15996
15997function mountOpaqueIdentifier() {
15998 var makeId = makeClientIdInDEV.bind(null, warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber$1)) ;
15999
16000 if (getIsHydrating()) {
16001 var didUpgrade = false;
16002 var fiber = currentlyRenderingFiber$1;
16003
16004 var readValue = function () {
16005 if (!didUpgrade) {
16006 // Only upgrade once. This works even inside the render phase because
16007 // the update is added to a shared queue, which outlasts the
16008 // in-progress render.
16009 didUpgrade = true;
16010
16011 {
16012 isUpdatingOpaqueValueInRenderPhase = true;
16013 setId(makeId());
16014 isUpdatingOpaqueValueInRenderPhase = false;
16015 warnOnOpaqueIdentifierAccessInDEV(fiber);
16016 }
16017 }
16018
16019 {
16020 {
16021 throw Error( "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly." );
16022 }
16023 }
16024 };
16025
16026 var id = makeOpaqueHydratingObject(readValue);
16027 var setId = mountState(id)[1];
16028
16029 if ((currentlyRenderingFiber$1.mode & BlockingMode) === NoMode) {
16030 currentlyRenderingFiber$1.flags |= Update | Passive;
16031 pushEffect(HasEffect | Passive$1, function () {
16032 setId(makeId());
16033 }, undefined, null);
16034 }
16035
16036 return id;
16037 } else {
16038 var _id = makeId();
16039
16040 mountState(_id);
16041 return _id;
16042 }
16043}
16044
16045function updateOpaqueIdentifier() {
16046 var id = updateState()[0];
16047 return id;
16048}
16049
16050function rerenderOpaqueIdentifier() {
16051 var id = rerenderState()[0];
16052 return id;
16053}
16054
16055function dispatchAction(fiber, queue, action) {
16056 {
16057 if (typeof arguments[3] === 'function') {
16058 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
16059 }
16060 }
16061
16062 var eventTime = requestEventTime();
16063 var lane = requestUpdateLane(fiber);
16064 var update = {
16065 lane: lane,
16066 action: action,
16067 eagerReducer: null,
16068 eagerState: null,
16069 next: null
16070 }; // Append the update to the end of the list.
16071
16072 var pending = queue.pending;
16073
16074 if (pending === null) {
16075 // This is the first update. Create a circular list.
16076 update.next = update;
16077 } else {
16078 update.next = pending.next;
16079 pending.next = update;
16080 }
16081
16082 queue.pending = update;
16083 var alternate = fiber.alternate;
16084
16085 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
16086 // This is a render phase update. Stash it in a lazily-created map of
16087 // queue -> linked list of updates. After this render pass, we'll restart
16088 // and apply the stashed updates on top of the work-in-progress hook.
16089 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
16090 } else {
16091 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
16092 // The queue is currently empty, which means we can eagerly compute the
16093 // next state before entering the render phase. If the new state is the
16094 // same as the current state, we may be able to bail out entirely.
16095 var lastRenderedReducer = queue.lastRenderedReducer;
16096
16097 if (lastRenderedReducer !== null) {
16098 var prevDispatcher;
16099
16100 {
16101 prevDispatcher = ReactCurrentDispatcher$1.current;
16102 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16103 }
16104
16105 try {
16106 var currentState = queue.lastRenderedState;
16107 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
16108 // it, on the update object. If the reducer hasn't changed by the
16109 // time we enter the render phase, then the eager state can be used
16110 // without calling the reducer again.
16111
16112 update.eagerReducer = lastRenderedReducer;
16113 update.eagerState = eagerState;
16114
16115 if (objectIs(eagerState, currentState)) {
16116 // Fast path. We can bail out without scheduling React to re-render.
16117 // It's still possible that we'll need to rebase this update later,
16118 // if the component re-renders for a different reason and by that
16119 // time the reducer has changed.
16120 return;
16121 }
16122 } catch (error) {// Suppress the error. It will throw again in the render phase.
16123 } finally {
16124 {
16125 ReactCurrentDispatcher$1.current = prevDispatcher;
16126 }
16127 }
16128 }
16129 }
16130
16131 {
16132 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
16133 if ('undefined' !== typeof jest) {
16134 warnIfNotScopedWithMatchingAct(fiber);
16135 warnIfNotCurrentlyActingUpdatesInDev(fiber);
16136 }
16137 }
16138
16139 scheduleUpdateOnFiber(fiber, lane, eventTime);
16140 }
16141}
16142
16143var ContextOnlyDispatcher = {
16144 readContext: readContext,
16145 useCallback: throwInvalidHookError,
16146 useContext: throwInvalidHookError,
16147 useEffect: throwInvalidHookError,
16148 useImperativeHandle: throwInvalidHookError,
16149 useLayoutEffect: throwInvalidHookError,
16150 useMemo: throwInvalidHookError,
16151 useReducer: throwInvalidHookError,
16152 useRef: throwInvalidHookError,
16153 useState: throwInvalidHookError,
16154 useDebugValue: throwInvalidHookError,
16155 useDeferredValue: throwInvalidHookError,
16156 useTransition: throwInvalidHookError,
16157 useMutableSource: throwInvalidHookError,
16158 useOpaqueIdentifier: throwInvalidHookError,
16159 unstable_isNewReconciler: enableNewReconciler
16160};
16161var HooksDispatcherOnMountInDEV = null;
16162var HooksDispatcherOnMountWithHookTypesInDEV = null;
16163var HooksDispatcherOnUpdateInDEV = null;
16164var HooksDispatcherOnRerenderInDEV = null;
16165var InvalidNestedHooksDispatcherOnMountInDEV = null;
16166var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
16167var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
16168
16169{
16170 var warnInvalidContextAccess = function () {
16171 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().');
16172 };
16173
16174 var warnInvalidHookAccess = function () {
16175 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');
16176 };
16177
16178 HooksDispatcherOnMountInDEV = {
16179 readContext: function (context, observedBits) {
16180 return readContext(context, observedBits);
16181 },
16182 useCallback: function (callback, deps) {
16183 currentHookNameInDev = 'useCallback';
16184 mountHookTypesDev();
16185 checkDepsAreArrayDev(deps);
16186 return mountCallback(callback, deps);
16187 },
16188 useContext: function (context, observedBits) {
16189 currentHookNameInDev = 'useContext';
16190 mountHookTypesDev();
16191 return readContext(context, observedBits);
16192 },
16193 useEffect: function (create, deps) {
16194 currentHookNameInDev = 'useEffect';
16195 mountHookTypesDev();
16196 checkDepsAreArrayDev(deps);
16197 return mountEffect(create, deps);
16198 },
16199 useImperativeHandle: function (ref, create, deps) {
16200 currentHookNameInDev = 'useImperativeHandle';
16201 mountHookTypesDev();
16202 checkDepsAreArrayDev(deps);
16203 return mountImperativeHandle(ref, create, deps);
16204 },
16205 useLayoutEffect: function (create, deps) {
16206 currentHookNameInDev = 'useLayoutEffect';
16207 mountHookTypesDev();
16208 checkDepsAreArrayDev(deps);
16209 return mountLayoutEffect(create, deps);
16210 },
16211 useMemo: function (create, deps) {
16212 currentHookNameInDev = 'useMemo';
16213 mountHookTypesDev();
16214 checkDepsAreArrayDev(deps);
16215 var prevDispatcher = ReactCurrentDispatcher$1.current;
16216 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16217
16218 try {
16219 return mountMemo(create, deps);
16220 } finally {
16221 ReactCurrentDispatcher$1.current = prevDispatcher;
16222 }
16223 },
16224 useReducer: function (reducer, initialArg, init) {
16225 currentHookNameInDev = 'useReducer';
16226 mountHookTypesDev();
16227 var prevDispatcher = ReactCurrentDispatcher$1.current;
16228 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16229
16230 try {
16231 return mountReducer(reducer, initialArg, init);
16232 } finally {
16233 ReactCurrentDispatcher$1.current = prevDispatcher;
16234 }
16235 },
16236 useRef: function (initialValue) {
16237 currentHookNameInDev = 'useRef';
16238 mountHookTypesDev();
16239 return mountRef(initialValue);
16240 },
16241 useState: function (initialState) {
16242 currentHookNameInDev = 'useState';
16243 mountHookTypesDev();
16244 var prevDispatcher = ReactCurrentDispatcher$1.current;
16245 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16246
16247 try {
16248 return mountState(initialState);
16249 } finally {
16250 ReactCurrentDispatcher$1.current = prevDispatcher;
16251 }
16252 },
16253 useDebugValue: function (value, formatterFn) {
16254 currentHookNameInDev = 'useDebugValue';
16255 mountHookTypesDev();
16256 return mountDebugValue();
16257 },
16258 useDeferredValue: function (value) {
16259 currentHookNameInDev = 'useDeferredValue';
16260 mountHookTypesDev();
16261 return mountDeferredValue(value);
16262 },
16263 useTransition: function () {
16264 currentHookNameInDev = 'useTransition';
16265 mountHookTypesDev();
16266 return mountTransition();
16267 },
16268 useMutableSource: function (source, getSnapshot, subscribe) {
16269 currentHookNameInDev = 'useMutableSource';
16270 mountHookTypesDev();
16271 return mountMutableSource(source, getSnapshot, subscribe);
16272 },
16273 useOpaqueIdentifier: function () {
16274 currentHookNameInDev = 'useOpaqueIdentifier';
16275 mountHookTypesDev();
16276 return mountOpaqueIdentifier();
16277 },
16278 unstable_isNewReconciler: enableNewReconciler
16279 };
16280 HooksDispatcherOnMountWithHookTypesInDEV = {
16281 readContext: function (context, observedBits) {
16282 return readContext(context, observedBits);
16283 },
16284 useCallback: function (callback, deps) {
16285 currentHookNameInDev = 'useCallback';
16286 updateHookTypesDev();
16287 return mountCallback(callback, deps);
16288 },
16289 useContext: function (context, observedBits) {
16290 currentHookNameInDev = 'useContext';
16291 updateHookTypesDev();
16292 return readContext(context, observedBits);
16293 },
16294 useEffect: function (create, deps) {
16295 currentHookNameInDev = 'useEffect';
16296 updateHookTypesDev();
16297 return mountEffect(create, deps);
16298 },
16299 useImperativeHandle: function (ref, create, deps) {
16300 currentHookNameInDev = 'useImperativeHandle';
16301 updateHookTypesDev();
16302 return mountImperativeHandle(ref, create, deps);
16303 },
16304 useLayoutEffect: function (create, deps) {
16305 currentHookNameInDev = 'useLayoutEffect';
16306 updateHookTypesDev();
16307 return mountLayoutEffect(create, deps);
16308 },
16309 useMemo: function (create, deps) {
16310 currentHookNameInDev = 'useMemo';
16311 updateHookTypesDev();
16312 var prevDispatcher = ReactCurrentDispatcher$1.current;
16313 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16314
16315 try {
16316 return mountMemo(create, deps);
16317 } finally {
16318 ReactCurrentDispatcher$1.current = prevDispatcher;
16319 }
16320 },
16321 useReducer: function (reducer, initialArg, init) {
16322 currentHookNameInDev = 'useReducer';
16323 updateHookTypesDev();
16324 var prevDispatcher = ReactCurrentDispatcher$1.current;
16325 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16326
16327 try {
16328 return mountReducer(reducer, initialArg, init);
16329 } finally {
16330 ReactCurrentDispatcher$1.current = prevDispatcher;
16331 }
16332 },
16333 useRef: function (initialValue) {
16334 currentHookNameInDev = 'useRef';
16335 updateHookTypesDev();
16336 return mountRef(initialValue);
16337 },
16338 useState: function (initialState) {
16339 currentHookNameInDev = 'useState';
16340 updateHookTypesDev();
16341 var prevDispatcher = ReactCurrentDispatcher$1.current;
16342 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16343
16344 try {
16345 return mountState(initialState);
16346 } finally {
16347 ReactCurrentDispatcher$1.current = prevDispatcher;
16348 }
16349 },
16350 useDebugValue: function (value, formatterFn) {
16351 currentHookNameInDev = 'useDebugValue';
16352 updateHookTypesDev();
16353 return mountDebugValue();
16354 },
16355 useDeferredValue: function (value) {
16356 currentHookNameInDev = 'useDeferredValue';
16357 updateHookTypesDev();
16358 return mountDeferredValue(value);
16359 },
16360 useTransition: function () {
16361 currentHookNameInDev = 'useTransition';
16362 updateHookTypesDev();
16363 return mountTransition();
16364 },
16365 useMutableSource: function (source, getSnapshot, subscribe) {
16366 currentHookNameInDev = 'useMutableSource';
16367 updateHookTypesDev();
16368 return mountMutableSource(source, getSnapshot, subscribe);
16369 },
16370 useOpaqueIdentifier: function () {
16371 currentHookNameInDev = 'useOpaqueIdentifier';
16372 updateHookTypesDev();
16373 return mountOpaqueIdentifier();
16374 },
16375 unstable_isNewReconciler: enableNewReconciler
16376 };
16377 HooksDispatcherOnUpdateInDEV = {
16378 readContext: function (context, observedBits) {
16379 return readContext(context, observedBits);
16380 },
16381 useCallback: function (callback, deps) {
16382 currentHookNameInDev = 'useCallback';
16383 updateHookTypesDev();
16384 return updateCallback(callback, deps);
16385 },
16386 useContext: function (context, observedBits) {
16387 currentHookNameInDev = 'useContext';
16388 updateHookTypesDev();
16389 return readContext(context, observedBits);
16390 },
16391 useEffect: function (create, deps) {
16392 currentHookNameInDev = 'useEffect';
16393 updateHookTypesDev();
16394 return updateEffect(create, deps);
16395 },
16396 useImperativeHandle: function (ref, create, deps) {
16397 currentHookNameInDev = 'useImperativeHandle';
16398 updateHookTypesDev();
16399 return updateImperativeHandle(ref, create, deps);
16400 },
16401 useLayoutEffect: function (create, deps) {
16402 currentHookNameInDev = 'useLayoutEffect';
16403 updateHookTypesDev();
16404 return updateLayoutEffect(create, deps);
16405 },
16406 useMemo: function (create, deps) {
16407 currentHookNameInDev = 'useMemo';
16408 updateHookTypesDev();
16409 var prevDispatcher = ReactCurrentDispatcher$1.current;
16410 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16411
16412 try {
16413 return updateMemo(create, deps);
16414 } finally {
16415 ReactCurrentDispatcher$1.current = prevDispatcher;
16416 }
16417 },
16418 useReducer: function (reducer, initialArg, init) {
16419 currentHookNameInDev = 'useReducer';
16420 updateHookTypesDev();
16421 var prevDispatcher = ReactCurrentDispatcher$1.current;
16422 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16423
16424 try {
16425 return updateReducer(reducer, initialArg, init);
16426 } finally {
16427 ReactCurrentDispatcher$1.current = prevDispatcher;
16428 }
16429 },
16430 useRef: function (initialValue) {
16431 currentHookNameInDev = 'useRef';
16432 updateHookTypesDev();
16433 return updateRef();
16434 },
16435 useState: function (initialState) {
16436 currentHookNameInDev = 'useState';
16437 updateHookTypesDev();
16438 var prevDispatcher = ReactCurrentDispatcher$1.current;
16439 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16440
16441 try {
16442 return updateState(initialState);
16443 } finally {
16444 ReactCurrentDispatcher$1.current = prevDispatcher;
16445 }
16446 },
16447 useDebugValue: function (value, formatterFn) {
16448 currentHookNameInDev = 'useDebugValue';
16449 updateHookTypesDev();
16450 return updateDebugValue();
16451 },
16452 useDeferredValue: function (value) {
16453 currentHookNameInDev = 'useDeferredValue';
16454 updateHookTypesDev();
16455 return updateDeferredValue(value);
16456 },
16457 useTransition: function () {
16458 currentHookNameInDev = 'useTransition';
16459 updateHookTypesDev();
16460 return updateTransition();
16461 },
16462 useMutableSource: function (source, getSnapshot, subscribe) {
16463 currentHookNameInDev = 'useMutableSource';
16464 updateHookTypesDev();
16465 return updateMutableSource(source, getSnapshot, subscribe);
16466 },
16467 useOpaqueIdentifier: function () {
16468 currentHookNameInDev = 'useOpaqueIdentifier';
16469 updateHookTypesDev();
16470 return updateOpaqueIdentifier();
16471 },
16472 unstable_isNewReconciler: enableNewReconciler
16473 };
16474 HooksDispatcherOnRerenderInDEV = {
16475 readContext: function (context, observedBits) {
16476 return readContext(context, observedBits);
16477 },
16478 useCallback: function (callback, deps) {
16479 currentHookNameInDev = 'useCallback';
16480 updateHookTypesDev();
16481 return updateCallback(callback, deps);
16482 },
16483 useContext: function (context, observedBits) {
16484 currentHookNameInDev = 'useContext';
16485 updateHookTypesDev();
16486 return readContext(context, observedBits);
16487 },
16488 useEffect: function (create, deps) {
16489 currentHookNameInDev = 'useEffect';
16490 updateHookTypesDev();
16491 return updateEffect(create, deps);
16492 },
16493 useImperativeHandle: function (ref, create, deps) {
16494 currentHookNameInDev = 'useImperativeHandle';
16495 updateHookTypesDev();
16496 return updateImperativeHandle(ref, create, deps);
16497 },
16498 useLayoutEffect: function (create, deps) {
16499 currentHookNameInDev = 'useLayoutEffect';
16500 updateHookTypesDev();
16501 return updateLayoutEffect(create, deps);
16502 },
16503 useMemo: function (create, deps) {
16504 currentHookNameInDev = 'useMemo';
16505 updateHookTypesDev();
16506 var prevDispatcher = ReactCurrentDispatcher$1.current;
16507 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16508
16509 try {
16510 return updateMemo(create, deps);
16511 } finally {
16512 ReactCurrentDispatcher$1.current = prevDispatcher;
16513 }
16514 },
16515 useReducer: function (reducer, initialArg, init) {
16516 currentHookNameInDev = 'useReducer';
16517 updateHookTypesDev();
16518 var prevDispatcher = ReactCurrentDispatcher$1.current;
16519 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16520
16521 try {
16522 return rerenderReducer(reducer, initialArg, init);
16523 } finally {
16524 ReactCurrentDispatcher$1.current = prevDispatcher;
16525 }
16526 },
16527 useRef: function (initialValue) {
16528 currentHookNameInDev = 'useRef';
16529 updateHookTypesDev();
16530 return updateRef();
16531 },
16532 useState: function (initialState) {
16533 currentHookNameInDev = 'useState';
16534 updateHookTypesDev();
16535 var prevDispatcher = ReactCurrentDispatcher$1.current;
16536 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16537
16538 try {
16539 return rerenderState(initialState);
16540 } finally {
16541 ReactCurrentDispatcher$1.current = prevDispatcher;
16542 }
16543 },
16544 useDebugValue: function (value, formatterFn) {
16545 currentHookNameInDev = 'useDebugValue';
16546 updateHookTypesDev();
16547 return updateDebugValue();
16548 },
16549 useDeferredValue: function (value) {
16550 currentHookNameInDev = 'useDeferredValue';
16551 updateHookTypesDev();
16552 return rerenderDeferredValue(value);
16553 },
16554 useTransition: function () {
16555 currentHookNameInDev = 'useTransition';
16556 updateHookTypesDev();
16557 return rerenderTransition();
16558 },
16559 useMutableSource: function (source, getSnapshot, subscribe) {
16560 currentHookNameInDev = 'useMutableSource';
16561 updateHookTypesDev();
16562 return updateMutableSource(source, getSnapshot, subscribe);
16563 },
16564 useOpaqueIdentifier: function () {
16565 currentHookNameInDev = 'useOpaqueIdentifier';
16566 updateHookTypesDev();
16567 return rerenderOpaqueIdentifier();
16568 },
16569 unstable_isNewReconciler: enableNewReconciler
16570 };
16571 InvalidNestedHooksDispatcherOnMountInDEV = {
16572 readContext: function (context, observedBits) {
16573 warnInvalidContextAccess();
16574 return readContext(context, observedBits);
16575 },
16576 useCallback: function (callback, deps) {
16577 currentHookNameInDev = 'useCallback';
16578 warnInvalidHookAccess();
16579 mountHookTypesDev();
16580 return mountCallback(callback, deps);
16581 },
16582 useContext: function (context, observedBits) {
16583 currentHookNameInDev = 'useContext';
16584 warnInvalidHookAccess();
16585 mountHookTypesDev();
16586 return readContext(context, observedBits);
16587 },
16588 useEffect: function (create, deps) {
16589 currentHookNameInDev = 'useEffect';
16590 warnInvalidHookAccess();
16591 mountHookTypesDev();
16592 return mountEffect(create, deps);
16593 },
16594 useImperativeHandle: function (ref, create, deps) {
16595 currentHookNameInDev = 'useImperativeHandle';
16596 warnInvalidHookAccess();
16597 mountHookTypesDev();
16598 return mountImperativeHandle(ref, create, deps);
16599 },
16600 useLayoutEffect: function (create, deps) {
16601 currentHookNameInDev = 'useLayoutEffect';
16602 warnInvalidHookAccess();
16603 mountHookTypesDev();
16604 return mountLayoutEffect(create, deps);
16605 },
16606 useMemo: function (create, deps) {
16607 currentHookNameInDev = 'useMemo';
16608 warnInvalidHookAccess();
16609 mountHookTypesDev();
16610 var prevDispatcher = ReactCurrentDispatcher$1.current;
16611 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16612
16613 try {
16614 return mountMemo(create, deps);
16615 } finally {
16616 ReactCurrentDispatcher$1.current = prevDispatcher;
16617 }
16618 },
16619 useReducer: function (reducer, initialArg, init) {
16620 currentHookNameInDev = 'useReducer';
16621 warnInvalidHookAccess();
16622 mountHookTypesDev();
16623 var prevDispatcher = ReactCurrentDispatcher$1.current;
16624 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16625
16626 try {
16627 return mountReducer(reducer, initialArg, init);
16628 } finally {
16629 ReactCurrentDispatcher$1.current = prevDispatcher;
16630 }
16631 },
16632 useRef: function (initialValue) {
16633 currentHookNameInDev = 'useRef';
16634 warnInvalidHookAccess();
16635 mountHookTypesDev();
16636 return mountRef(initialValue);
16637 },
16638 useState: function (initialState) {
16639 currentHookNameInDev = 'useState';
16640 warnInvalidHookAccess();
16641 mountHookTypesDev();
16642 var prevDispatcher = ReactCurrentDispatcher$1.current;
16643 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16644
16645 try {
16646 return mountState(initialState);
16647 } finally {
16648 ReactCurrentDispatcher$1.current = prevDispatcher;
16649 }
16650 },
16651 useDebugValue: function (value, formatterFn) {
16652 currentHookNameInDev = 'useDebugValue';
16653 warnInvalidHookAccess();
16654 mountHookTypesDev();
16655 return mountDebugValue();
16656 },
16657 useDeferredValue: function (value) {
16658 currentHookNameInDev = 'useDeferredValue';
16659 warnInvalidHookAccess();
16660 mountHookTypesDev();
16661 return mountDeferredValue(value);
16662 },
16663 useTransition: function () {
16664 currentHookNameInDev = 'useTransition';
16665 warnInvalidHookAccess();
16666 mountHookTypesDev();
16667 return mountTransition();
16668 },
16669 useMutableSource: function (source, getSnapshot, subscribe) {
16670 currentHookNameInDev = 'useMutableSource';
16671 warnInvalidHookAccess();
16672 mountHookTypesDev();
16673 return mountMutableSource(source, getSnapshot, subscribe);
16674 },
16675 useOpaqueIdentifier: function () {
16676 currentHookNameInDev = 'useOpaqueIdentifier';
16677 warnInvalidHookAccess();
16678 mountHookTypesDev();
16679 return mountOpaqueIdentifier();
16680 },
16681 unstable_isNewReconciler: enableNewReconciler
16682 };
16683 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16684 readContext: function (context, observedBits) {
16685 warnInvalidContextAccess();
16686 return readContext(context, observedBits);
16687 },
16688 useCallback: function (callback, deps) {
16689 currentHookNameInDev = 'useCallback';
16690 warnInvalidHookAccess();
16691 updateHookTypesDev();
16692 return updateCallback(callback, deps);
16693 },
16694 useContext: function (context, observedBits) {
16695 currentHookNameInDev = 'useContext';
16696 warnInvalidHookAccess();
16697 updateHookTypesDev();
16698 return readContext(context, observedBits);
16699 },
16700 useEffect: function (create, deps) {
16701 currentHookNameInDev = 'useEffect';
16702 warnInvalidHookAccess();
16703 updateHookTypesDev();
16704 return updateEffect(create, deps);
16705 },
16706 useImperativeHandle: function (ref, create, deps) {
16707 currentHookNameInDev = 'useImperativeHandle';
16708 warnInvalidHookAccess();
16709 updateHookTypesDev();
16710 return updateImperativeHandle(ref, create, deps);
16711 },
16712 useLayoutEffect: function (create, deps) {
16713 currentHookNameInDev = 'useLayoutEffect';
16714 warnInvalidHookAccess();
16715 updateHookTypesDev();
16716 return updateLayoutEffect(create, deps);
16717 },
16718 useMemo: function (create, deps) {
16719 currentHookNameInDev = 'useMemo';
16720 warnInvalidHookAccess();
16721 updateHookTypesDev();
16722 var prevDispatcher = ReactCurrentDispatcher$1.current;
16723 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16724
16725 try {
16726 return updateMemo(create, deps);
16727 } finally {
16728 ReactCurrentDispatcher$1.current = prevDispatcher;
16729 }
16730 },
16731 useReducer: function (reducer, initialArg, init) {
16732 currentHookNameInDev = 'useReducer';
16733 warnInvalidHookAccess();
16734 updateHookTypesDev();
16735 var prevDispatcher = ReactCurrentDispatcher$1.current;
16736 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16737
16738 try {
16739 return updateReducer(reducer, initialArg, init);
16740 } finally {
16741 ReactCurrentDispatcher$1.current = prevDispatcher;
16742 }
16743 },
16744 useRef: function (initialValue) {
16745 currentHookNameInDev = 'useRef';
16746 warnInvalidHookAccess();
16747 updateHookTypesDev();
16748 return updateRef();
16749 },
16750 useState: function (initialState) {
16751 currentHookNameInDev = 'useState';
16752 warnInvalidHookAccess();
16753 updateHookTypesDev();
16754 var prevDispatcher = ReactCurrentDispatcher$1.current;
16755 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16756
16757 try {
16758 return updateState(initialState);
16759 } finally {
16760 ReactCurrentDispatcher$1.current = prevDispatcher;
16761 }
16762 },
16763 useDebugValue: function (value, formatterFn) {
16764 currentHookNameInDev = 'useDebugValue';
16765 warnInvalidHookAccess();
16766 updateHookTypesDev();
16767 return updateDebugValue();
16768 },
16769 useDeferredValue: function (value) {
16770 currentHookNameInDev = 'useDeferredValue';
16771 warnInvalidHookAccess();
16772 updateHookTypesDev();
16773 return updateDeferredValue(value);
16774 },
16775 useTransition: function () {
16776 currentHookNameInDev = 'useTransition';
16777 warnInvalidHookAccess();
16778 updateHookTypesDev();
16779 return updateTransition();
16780 },
16781 useMutableSource: function (source, getSnapshot, subscribe) {
16782 currentHookNameInDev = 'useMutableSource';
16783 warnInvalidHookAccess();
16784 updateHookTypesDev();
16785 return updateMutableSource(source, getSnapshot, subscribe);
16786 },
16787 useOpaqueIdentifier: function () {
16788 currentHookNameInDev = 'useOpaqueIdentifier';
16789 warnInvalidHookAccess();
16790 updateHookTypesDev();
16791 return updateOpaqueIdentifier();
16792 },
16793 unstable_isNewReconciler: enableNewReconciler
16794 };
16795 InvalidNestedHooksDispatcherOnRerenderInDEV = {
16796 readContext: function (context, observedBits) {
16797 warnInvalidContextAccess();
16798 return readContext(context, observedBits);
16799 },
16800 useCallback: function (callback, deps) {
16801 currentHookNameInDev = 'useCallback';
16802 warnInvalidHookAccess();
16803 updateHookTypesDev();
16804 return updateCallback(callback, deps);
16805 },
16806 useContext: function (context, observedBits) {
16807 currentHookNameInDev = 'useContext';
16808 warnInvalidHookAccess();
16809 updateHookTypesDev();
16810 return readContext(context, observedBits);
16811 },
16812 useEffect: function (create, deps) {
16813 currentHookNameInDev = 'useEffect';
16814 warnInvalidHookAccess();
16815 updateHookTypesDev();
16816 return updateEffect(create, deps);
16817 },
16818 useImperativeHandle: function (ref, create, deps) {
16819 currentHookNameInDev = 'useImperativeHandle';
16820 warnInvalidHookAccess();
16821 updateHookTypesDev();
16822 return updateImperativeHandle(ref, create, deps);
16823 },
16824 useLayoutEffect: function (create, deps) {
16825 currentHookNameInDev = 'useLayoutEffect';
16826 warnInvalidHookAccess();
16827 updateHookTypesDev();
16828 return updateLayoutEffect(create, deps);
16829 },
16830 useMemo: function (create, deps) {
16831 currentHookNameInDev = 'useMemo';
16832 warnInvalidHookAccess();
16833 updateHookTypesDev();
16834 var prevDispatcher = ReactCurrentDispatcher$1.current;
16835 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16836
16837 try {
16838 return updateMemo(create, deps);
16839 } finally {
16840 ReactCurrentDispatcher$1.current = prevDispatcher;
16841 }
16842 },
16843 useReducer: function (reducer, initialArg, init) {
16844 currentHookNameInDev = 'useReducer';
16845 warnInvalidHookAccess();
16846 updateHookTypesDev();
16847 var prevDispatcher = ReactCurrentDispatcher$1.current;
16848 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16849
16850 try {
16851 return rerenderReducer(reducer, initialArg, init);
16852 } finally {
16853 ReactCurrentDispatcher$1.current = prevDispatcher;
16854 }
16855 },
16856 useRef: function (initialValue) {
16857 currentHookNameInDev = 'useRef';
16858 warnInvalidHookAccess();
16859 updateHookTypesDev();
16860 return updateRef();
16861 },
16862 useState: function (initialState) {
16863 currentHookNameInDev = 'useState';
16864 warnInvalidHookAccess();
16865 updateHookTypesDev();
16866 var prevDispatcher = ReactCurrentDispatcher$1.current;
16867 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16868
16869 try {
16870 return rerenderState(initialState);
16871 } finally {
16872 ReactCurrentDispatcher$1.current = prevDispatcher;
16873 }
16874 },
16875 useDebugValue: function (value, formatterFn) {
16876 currentHookNameInDev = 'useDebugValue';
16877 warnInvalidHookAccess();
16878 updateHookTypesDev();
16879 return updateDebugValue();
16880 },
16881 useDeferredValue: function (value) {
16882 currentHookNameInDev = 'useDeferredValue';
16883 warnInvalidHookAccess();
16884 updateHookTypesDev();
16885 return rerenderDeferredValue(value);
16886 },
16887 useTransition: function () {
16888 currentHookNameInDev = 'useTransition';
16889 warnInvalidHookAccess();
16890 updateHookTypesDev();
16891 return rerenderTransition();
16892 },
16893 useMutableSource: function (source, getSnapshot, subscribe) {
16894 currentHookNameInDev = 'useMutableSource';
16895 warnInvalidHookAccess();
16896 updateHookTypesDev();
16897 return updateMutableSource(source, getSnapshot, subscribe);
16898 },
16899 useOpaqueIdentifier: function () {
16900 currentHookNameInDev = 'useOpaqueIdentifier';
16901 warnInvalidHookAccess();
16902 updateHookTypesDev();
16903 return rerenderOpaqueIdentifier();
16904 },
16905 unstable_isNewReconciler: enableNewReconciler
16906 };
16907}
16908
16909var now$1 = Scheduler.unstable_now;
16910var commitTime = 0;
16911var profilerStartTime = -1;
16912
16913function getCommitTime() {
16914 return commitTime;
16915}
16916
16917function recordCommitTime() {
16918
16919 commitTime = now$1();
16920}
16921
16922function startProfilerTimer(fiber) {
16923
16924 profilerStartTime = now$1();
16925
16926 if (fiber.actualStartTime < 0) {
16927 fiber.actualStartTime = now$1();
16928 }
16929}
16930
16931function stopProfilerTimerIfRunning(fiber) {
16932
16933 profilerStartTime = -1;
16934}
16935
16936function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16937
16938 if (profilerStartTime >= 0) {
16939 var elapsedTime = now$1() - profilerStartTime;
16940 fiber.actualDuration += elapsedTime;
16941
16942 if (overrideBaseTime) {
16943 fiber.selfBaseDuration = elapsedTime;
16944 }
16945
16946 profilerStartTime = -1;
16947 }
16948}
16949
16950function transferActualDuration(fiber) {
16951 // Transfer time spent rendering these children so we don't lose it
16952 // after we rerender. This is used as a helper in special cases
16953 // where we should count the work of multiple passes.
16954 var child = fiber.child;
16955
16956 while (child) {
16957 fiber.actualDuration += child.actualDuration;
16958 child = child.sibling;
16959 }
16960}
16961
16962var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
16963var didReceiveUpdate = false;
16964var didWarnAboutBadClass;
16965var didWarnAboutModulePatternComponent;
16966var didWarnAboutContextTypeOnFunctionComponent;
16967var didWarnAboutGetDerivedStateOnFunctionComponent;
16968var didWarnAboutFunctionRefs;
16969var didWarnAboutReassigningProps;
16970var didWarnAboutRevealOrder;
16971var didWarnAboutTailOptions;
16972
16973{
16974 didWarnAboutBadClass = {};
16975 didWarnAboutModulePatternComponent = {};
16976 didWarnAboutContextTypeOnFunctionComponent = {};
16977 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16978 didWarnAboutFunctionRefs = {};
16979 didWarnAboutReassigningProps = false;
16980 didWarnAboutRevealOrder = {};
16981 didWarnAboutTailOptions = {};
16982}
16983
16984function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
16985 if (current === null) {
16986 // If this is a fresh new component that hasn't been rendered yet, we
16987 // won't update its child set by applying minimal side-effects. Instead,
16988 // we will add them all to the child before it gets rendered. That means
16989 // we can optimize this reconciliation pass by not tracking side-effects.
16990 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
16991 } else {
16992 // If the current child is the same as the work in progress, it means that
16993 // we haven't yet started any work on these children. Therefore, we use
16994 // the clone algorithm to create a copy of all the current children.
16995 // If we had any progressed work already, that is invalid at this point so
16996 // let's throw it out.
16997 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
16998 }
16999}
17000
17001function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
17002 // This function is fork of reconcileChildren. It's used in cases where we
17003 // want to reconcile without matching against the existing set. This has the
17004 // effect of all current children being unmounted; even if the type and key
17005 // are the same, the old child is unmounted and a new child is created.
17006 //
17007 // To do this, we're going to go through the reconcile algorithm twice. In
17008 // the first pass, we schedule a deletion for all the current children by
17009 // passing null.
17010 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
17011 // pass null in place of where we usually pass the current child set. This has
17012 // the effect of remounting all children regardless of whether their
17013 // identities match.
17014
17015 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
17016}
17017
17018function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
17019 // TODO: current can be non-null here even if the component
17020 // hasn't yet mounted. This happens after the first render suspends.
17021 // We'll need to figure out if this is fine or can cause issues.
17022 {
17023 if (workInProgress.type !== workInProgress.elementType) {
17024 // Lazy component props can't be validated in createElement
17025 // because they're only guaranteed to be resolved here.
17026 var innerPropTypes = Component.propTypes;
17027
17028 if (innerPropTypes) {
17029 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17030 'prop', getComponentName(Component));
17031 }
17032 }
17033 }
17034
17035 var render = Component.render;
17036 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
17037
17038 var nextChildren;
17039 prepareToReadContext(workInProgress, renderLanes);
17040
17041 {
17042 ReactCurrentOwner$1.current = workInProgress;
17043 setIsRendering(true);
17044 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
17045
17046 if ( workInProgress.mode & StrictMode) {
17047 disableLogs();
17048
17049 try {
17050 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
17051 } finally {
17052 reenableLogs();
17053 }
17054 }
17055
17056 setIsRendering(false);
17057 }
17058
17059 if (current !== null && !didReceiveUpdate) {
17060 bailoutHooks(current, workInProgress, renderLanes);
17061 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17062 } // React DevTools reads this flag.
17063
17064
17065 workInProgress.flags |= PerformedWork;
17066 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17067 return workInProgress.child;
17068}
17069
17070function updateMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) {
17071 if (current === null) {
17072 var type = Component.type;
17073
17074 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
17075 Component.defaultProps === undefined) {
17076 var resolvedType = type;
17077
17078 {
17079 resolvedType = resolveFunctionForHotReloading(type);
17080 } // If this is a plain function component without default props,
17081 // and with only the default shallow comparison, we upgrade it
17082 // to a SimpleMemoComponent to allow fast path updates.
17083
17084
17085 workInProgress.tag = SimpleMemoComponent;
17086 workInProgress.type = resolvedType;
17087
17088 {
17089 validateFunctionComponentInDev(workInProgress, type);
17090 }
17091
17092 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateLanes, renderLanes);
17093 }
17094
17095 {
17096 var innerPropTypes = type.propTypes;
17097
17098 if (innerPropTypes) {
17099 // Inner memo component props aren't currently validated in createElement.
17100 // We could move it there, but we'd still need this for lazy code path.
17101 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17102 'prop', getComponentName(type));
17103 }
17104 }
17105
17106 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
17107 child.ref = workInProgress.ref;
17108 child.return = workInProgress;
17109 workInProgress.child = child;
17110 return child;
17111 }
17112
17113 {
17114 var _type = Component.type;
17115 var _innerPropTypes = _type.propTypes;
17116
17117 if (_innerPropTypes) {
17118 // Inner memo component props aren't currently validated in createElement.
17119 // We could move it there, but we'd still need this for lazy code path.
17120 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
17121 'prop', getComponentName(_type));
17122 }
17123 }
17124
17125 var currentChild = current.child; // This is always exactly one child
17126
17127 if (!includesSomeLane(updateLanes, renderLanes)) {
17128 // This will be the props with resolved defaultProps,
17129 // unlike current.memoizedProps which will be the unresolved ones.
17130 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
17131
17132 var compare = Component.compare;
17133 compare = compare !== null ? compare : shallowEqual;
17134
17135 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
17136 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17137 }
17138 } // React DevTools reads this flag.
17139
17140
17141 workInProgress.flags |= PerformedWork;
17142 var newChild = createWorkInProgress(currentChild, nextProps);
17143 newChild.ref = workInProgress.ref;
17144 newChild.return = workInProgress;
17145 workInProgress.child = newChild;
17146 return newChild;
17147}
17148
17149function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateLanes, renderLanes) {
17150 // TODO: current can be non-null here even if the component
17151 // hasn't yet mounted. This happens when the inner render suspends.
17152 // We'll need to figure out if this is fine or can cause issues.
17153 {
17154 if (workInProgress.type !== workInProgress.elementType) {
17155 // Lazy component props can't be validated in createElement
17156 // because they're only guaranteed to be resolved here.
17157 var outerMemoType = workInProgress.elementType;
17158
17159 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
17160 // We warn when you define propTypes on lazy()
17161 // so let's just skip over it to find memo() outer wrapper.
17162 // Inner props for memo are validated later.
17163 var lazyComponent = outerMemoType;
17164 var payload = lazyComponent._payload;
17165 var init = lazyComponent._init;
17166
17167 try {
17168 outerMemoType = init(payload);
17169 } catch (x) {
17170 outerMemoType = null;
17171 } // Inner propTypes will be validated in the function component path.
17172
17173
17174 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
17175
17176 if (outerPropTypes) {
17177 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
17178 'prop', getComponentName(outerMemoType));
17179 }
17180 }
17181 }
17182 }
17183
17184 if (current !== null) {
17185 var prevProps = current.memoizedProps;
17186
17187 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
17188 workInProgress.type === current.type )) {
17189 didReceiveUpdate = false;
17190
17191 if (!includesSomeLane(renderLanes, updateLanes)) {
17192 // The pending lanes were cleared at the beginning of beginWork. We're
17193 // about to bail out, but there might be other lanes that weren't
17194 // included in the current render. Usually, the priority level of the
17195 // remaining updates is accumlated during the evaluation of the
17196 // component (i.e. when processing the update queue). But since since
17197 // we're bailing out early *without* evaluating the component, we need
17198 // to account for it here, too. Reset to the value of the current fiber.
17199 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
17200 // because a MemoComponent fiber does not have hooks or an update queue;
17201 // rather, it wraps around an inner component, which may or may not
17202 // contains hooks.
17203 // TODO: Move the reset at in beginWork out of the common path so that
17204 // this is no longer necessary.
17205 workInProgress.lanes = current.lanes;
17206 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17207 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
17208 // This is a special case that only exists for legacy mode.
17209 // See https://github.com/facebook/react/pull/19216.
17210 didReceiveUpdate = true;
17211 }
17212 }
17213 }
17214
17215 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
17216}
17217
17218function updateOffscreenComponent(current, workInProgress, renderLanes) {
17219 var nextProps = workInProgress.pendingProps;
17220 var nextChildren = nextProps.children;
17221 var prevState = current !== null ? current.memoizedState : null;
17222
17223 if (nextProps.mode === 'hidden' || nextProps.mode === 'unstable-defer-without-hiding') {
17224 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
17225 // In legacy sync mode, don't defer the subtree. Render it now.
17226 // TODO: Figure out what we should do in Blocking mode.
17227 var nextState = {
17228 baseLanes: NoLanes
17229 };
17230 workInProgress.memoizedState = nextState;
17231 pushRenderLanes(workInProgress, renderLanes);
17232 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
17233 var nextBaseLanes;
17234
17235 if (prevState !== null) {
17236 var prevBaseLanes = prevState.baseLanes;
17237 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
17238 } else {
17239 nextBaseLanes = renderLanes;
17240 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
17241
17242
17243 {
17244 markSpawnedWork(OffscreenLane);
17245 }
17246
17247 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
17248 var _nextState = {
17249 baseLanes: nextBaseLanes
17250 };
17251 workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway
17252 // to avoid a push/pop misalignment.
17253
17254 pushRenderLanes(workInProgress, nextBaseLanes);
17255 return null;
17256 } else {
17257 // Rendering at offscreen, so we can clear the base lanes.
17258 var _nextState2 = {
17259 baseLanes: NoLanes
17260 };
17261 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
17262
17263 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
17264 pushRenderLanes(workInProgress, subtreeRenderLanes);
17265 }
17266 } else {
17267 var _subtreeRenderLanes;
17268
17269 if (prevState !== null) {
17270 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state
17271
17272 workInProgress.memoizedState = null;
17273 } else {
17274 // We weren't previously hidden, and we still aren't, so there's nothing
17275 // special to do. Need to push to the stack regardless, though, to avoid
17276 // a push/pop misalignment.
17277 _subtreeRenderLanes = renderLanes;
17278 }
17279
17280 pushRenderLanes(workInProgress, _subtreeRenderLanes);
17281 }
17282
17283 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17284 return workInProgress.child;
17285} // Note: These happen to have identical begin phases, for now. We shouldn't hold
17286// ourselves to this constraint, though. If the behavior diverges, we should
17287// fork the function.
17288
17289
17290var updateLegacyHiddenComponent = updateOffscreenComponent;
17291
17292function updateFragment(current, workInProgress, renderLanes) {
17293 var nextChildren = workInProgress.pendingProps;
17294 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17295 return workInProgress.child;
17296}
17297
17298function updateMode(current, workInProgress, renderLanes) {
17299 var nextChildren = workInProgress.pendingProps.children;
17300 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17301 return workInProgress.child;
17302}
17303
17304function updateProfiler(current, workInProgress, renderLanes) {
17305 {
17306 workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase.
17307 // These are reset during render to allow the DevTools commit hook a chance to read them,
17308
17309 var stateNode = workInProgress.stateNode;
17310 stateNode.effectDuration = 0;
17311 stateNode.passiveEffectDuration = 0;
17312 }
17313
17314 var nextProps = workInProgress.pendingProps;
17315 var nextChildren = nextProps.children;
17316 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17317 return workInProgress.child;
17318}
17319
17320function markRef(current, workInProgress) {
17321 var ref = workInProgress.ref;
17322
17323 if (current === null && ref !== null || current !== null && current.ref !== ref) {
17324 // Schedule a Ref effect
17325 workInProgress.flags |= Ref;
17326 }
17327}
17328
17329function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
17330 {
17331 if (workInProgress.type !== workInProgress.elementType) {
17332 // Lazy component props can't be validated in createElement
17333 // because they're only guaranteed to be resolved here.
17334 var innerPropTypes = Component.propTypes;
17335
17336 if (innerPropTypes) {
17337 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17338 'prop', getComponentName(Component));
17339 }
17340 }
17341 }
17342
17343 var context;
17344
17345 {
17346 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17347 context = getMaskedContext(workInProgress, unmaskedContext);
17348 }
17349
17350 var nextChildren;
17351 prepareToReadContext(workInProgress, renderLanes);
17352
17353 {
17354 ReactCurrentOwner$1.current = workInProgress;
17355 setIsRendering(true);
17356 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
17357
17358 if ( workInProgress.mode & StrictMode) {
17359 disableLogs();
17360
17361 try {
17362 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
17363 } finally {
17364 reenableLogs();
17365 }
17366 }
17367
17368 setIsRendering(false);
17369 }
17370
17371 if (current !== null && !didReceiveUpdate) {
17372 bailoutHooks(current, workInProgress, renderLanes);
17373 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17374 } // React DevTools reads this flag.
17375
17376
17377 workInProgress.flags |= PerformedWork;
17378 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17379 return workInProgress.child;
17380}
17381
17382function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
17383 {
17384 if (workInProgress.type !== workInProgress.elementType) {
17385 // Lazy component props can't be validated in createElement
17386 // because they're only guaranteed to be resolved here.
17387 var innerPropTypes = Component.propTypes;
17388
17389 if (innerPropTypes) {
17390 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17391 'prop', getComponentName(Component));
17392 }
17393 }
17394 } // Push context providers early to prevent context stack mismatches.
17395 // During mounting we don't know the child context yet as the instance doesn't exist.
17396 // We will invalidate the child context in finishClassComponent() right after rendering.
17397
17398
17399 var hasContext;
17400
17401 if (isContextProvider(Component)) {
17402 hasContext = true;
17403 pushContextProvider(workInProgress);
17404 } else {
17405 hasContext = false;
17406 }
17407
17408 prepareToReadContext(workInProgress, renderLanes);
17409 var instance = workInProgress.stateNode;
17410 var shouldUpdate;
17411
17412 if (instance === null) {
17413 if (current !== null) {
17414 // A class component without an instance only mounts if it suspended
17415 // inside a non-concurrent tree, in an inconsistent state. We want to
17416 // treat it like a new mount, even though an empty version of it already
17417 // committed. Disconnect the alternate pointers.
17418 current.alternate = null;
17419 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17420
17421 workInProgress.flags |= Placement;
17422 } // In the initial pass we might need to construct the instance.
17423
17424
17425 constructClassInstance(workInProgress, Component, nextProps);
17426 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
17427 shouldUpdate = true;
17428 } else if (current === null) {
17429 // In a resume, we'll already have an instance we can reuse.
17430 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
17431 } else {
17432 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
17433 }
17434
17435 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
17436
17437 {
17438 var inst = workInProgress.stateNode;
17439
17440 if (shouldUpdate && inst.props !== nextProps) {
17441 if (!didWarnAboutReassigningProps) {
17442 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
17443 }
17444
17445 didWarnAboutReassigningProps = true;
17446 }
17447 }
17448
17449 return nextUnitOfWork;
17450}
17451
17452function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
17453 // Refs should update even if shouldComponentUpdate returns false
17454 markRef(current, workInProgress);
17455 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
17456
17457 if (!shouldUpdate && !didCaptureError) {
17458 // Context providers should defer to sCU for rendering
17459 if (hasContext) {
17460 invalidateContextProvider(workInProgress, Component, false);
17461 }
17462
17463 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17464 }
17465
17466 var instance = workInProgress.stateNode; // Rerender
17467
17468 ReactCurrentOwner$1.current = workInProgress;
17469 var nextChildren;
17470
17471 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17472 // If we captured an error, but getDerivedStateFromError is not defined,
17473 // unmount all the children. componentDidCatch will schedule an update to
17474 // re-render a fallback. This is temporary until we migrate everyone to
17475 // the new API.
17476 // TODO: Warn in a future release.
17477 nextChildren = null;
17478
17479 {
17480 stopProfilerTimerIfRunning();
17481 }
17482 } else {
17483 {
17484 setIsRendering(true);
17485 nextChildren = instance.render();
17486
17487 if ( workInProgress.mode & StrictMode) {
17488 disableLogs();
17489
17490 try {
17491 instance.render();
17492 } finally {
17493 reenableLogs();
17494 }
17495 }
17496
17497 setIsRendering(false);
17498 }
17499 } // React DevTools reads this flag.
17500
17501
17502 workInProgress.flags |= PerformedWork;
17503
17504 if (current !== null && didCaptureError) {
17505 // If we're recovering from an error, reconcile without reusing any of
17506 // the existing children. Conceptually, the normal children and the children
17507 // that are shown on error are two different sets, so we shouldn't reuse
17508 // normal children even if their identities match.
17509 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
17510 } else {
17511 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17512 } // Memoize state using the values we just used to render.
17513 // TODO: Restructure so we never read values from the instance.
17514
17515
17516 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
17517
17518 if (hasContext) {
17519 invalidateContextProvider(workInProgress, Component, true);
17520 }
17521
17522 return workInProgress.child;
17523}
17524
17525function pushHostRootContext(workInProgress) {
17526 var root = workInProgress.stateNode;
17527
17528 if (root.pendingContext) {
17529 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17530 } else if (root.context) {
17531 // Should always be set
17532 pushTopLevelContextObject(workInProgress, root.context, false);
17533 }
17534
17535 pushHostContainer(workInProgress, root.containerInfo);
17536}
17537
17538function updateHostRoot(current, workInProgress, renderLanes) {
17539 pushHostRootContext(workInProgress);
17540 var updateQueue = workInProgress.updateQueue;
17541
17542 if (!(current !== null && updateQueue !== null)) {
17543 {
17544 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." );
17545 }
17546 }
17547
17548 var nextProps = workInProgress.pendingProps;
17549 var prevState = workInProgress.memoizedState;
17550 var prevChildren = prevState !== null ? prevState.element : null;
17551 cloneUpdateQueue(current, workInProgress);
17552 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
17553 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
17554 // being called "element".
17555
17556 var nextChildren = nextState.element;
17557
17558 if (nextChildren === prevChildren) {
17559 resetHydrationState();
17560 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
17561 }
17562
17563 var root = workInProgress.stateNode;
17564
17565 if (root.hydrate && enterHydrationState(workInProgress)) {
17566 // If we don't have any current children this might be the first pass.
17567 // We always try to hydrate. If this isn't a hydration pass there won't
17568 // be any children to hydrate which is effectively the same thing as
17569 // not hydrating.
17570 {
17571 var mutableSourceEagerHydrationData = root.mutableSourceEagerHydrationData;
17572
17573 if (mutableSourceEagerHydrationData != null) {
17574 for (var i = 0; i < mutableSourceEagerHydrationData.length; i += 2) {
17575 var mutableSource = mutableSourceEagerHydrationData[i];
17576 var version = mutableSourceEagerHydrationData[i + 1];
17577 setWorkInProgressVersion(mutableSource, version);
17578 }
17579 }
17580 }
17581
17582 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
17583 workInProgress.child = child;
17584 var node = child;
17585
17586 while (node) {
17587 // Mark each child as hydrating. This is a fast path to know whether this
17588 // tree is part of a hydrating tree. This is used to determine if a child
17589 // node has fully mounted yet, and for scheduling event replaying.
17590 // Conceptually this is similar to Placement in that a new subtree is
17591 // inserted into the React tree here. It just happens to not need DOM
17592 // mutations because it already exists.
17593 node.flags = node.flags & ~Placement | Hydrating;
17594 node = node.sibling;
17595 }
17596 } else {
17597 // Otherwise reset hydration state in case we aborted and resumed another
17598 // root.
17599 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17600 resetHydrationState();
17601 }
17602
17603 return workInProgress.child;
17604}
17605
17606function updateHostComponent(current, workInProgress, renderLanes) {
17607 pushHostContext(workInProgress);
17608
17609 if (current === null) {
17610 tryToClaimNextHydratableInstance(workInProgress);
17611 }
17612
17613 var type = workInProgress.type;
17614 var nextProps = workInProgress.pendingProps;
17615 var prevProps = current !== null ? current.memoizedProps : null;
17616 var nextChildren = nextProps.children;
17617 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17618
17619 if (isDirectTextChild) {
17620 // We special case a direct text child of a host node. This is a common
17621 // case. We won't handle it as a reified child. We will instead handle
17622 // this in the host environment that also has access to this prop. That
17623 // avoids allocating another HostText fiber and traversing it.
17624 nextChildren = null;
17625 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17626 // If we're switching from a direct text child to a normal child, or to
17627 // empty, we need to schedule the text content to be reset.
17628 workInProgress.flags |= ContentReset;
17629 }
17630
17631 markRef(current, workInProgress);
17632 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
17633 return workInProgress.child;
17634}
17635
17636function updateHostText(current, workInProgress) {
17637 if (current === null) {
17638 tryToClaimNextHydratableInstance(workInProgress);
17639 } // Nothing to do here. This is terminal. We'll do the completion step
17640 // immediately after.
17641
17642
17643 return null;
17644}
17645
17646function mountLazyComponent(_current, workInProgress, elementType, updateLanes, renderLanes) {
17647 if (_current !== null) {
17648 // A lazy component only mounts if it suspended inside a non-
17649 // concurrent tree, in an inconsistent state. We want to treat it like
17650 // a new mount, even though an empty version of it already committed.
17651 // Disconnect the alternate pointers.
17652 _current.alternate = null;
17653 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17654
17655 workInProgress.flags |= Placement;
17656 }
17657
17658 var props = workInProgress.pendingProps;
17659 var lazyComponent = elementType;
17660 var payload = lazyComponent._payload;
17661 var init = lazyComponent._init;
17662 var Component = init(payload); // Store the unwrapped component in the type.
17663
17664 workInProgress.type = Component;
17665 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17666 var resolvedProps = resolveDefaultProps(Component, props);
17667 var child;
17668
17669 switch (resolvedTag) {
17670 case FunctionComponent:
17671 {
17672 {
17673 validateFunctionComponentInDev(workInProgress, Component);
17674 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17675 }
17676
17677 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
17678 return child;
17679 }
17680
17681 case ClassComponent:
17682 {
17683 {
17684 workInProgress.type = Component = resolveClassForHotReloading(Component);
17685 }
17686
17687 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
17688 return child;
17689 }
17690
17691 case ForwardRef:
17692 {
17693 {
17694 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17695 }
17696
17697 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
17698 return child;
17699 }
17700
17701 case MemoComponent:
17702 {
17703 {
17704 if (workInProgress.type !== workInProgress.elementType) {
17705 var outerPropTypes = Component.propTypes;
17706
17707 if (outerPropTypes) {
17708 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
17709 'prop', getComponentName(Component));
17710 }
17711 }
17712 }
17713
17714 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17715 updateLanes, renderLanes);
17716 return child;
17717 }
17718 }
17719
17720 var hint = '';
17721
17722 {
17723 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17724 hint = ' Did you wrap a component in React.lazy() more than once?';
17725 }
17726 } // This message intentionally doesn't mention ForwardRef or MemoComponent
17727 // because the fact that it's a separate type of work is an
17728 // implementation detail.
17729
17730
17731 {
17732 {
17733 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
17734 }
17735 }
17736}
17737
17738function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
17739 if (_current !== null) {
17740 // An incomplete component only mounts if it suspended inside a non-
17741 // concurrent tree, in an inconsistent state. We want to treat it like
17742 // a new mount, even though an empty version of it already committed.
17743 // Disconnect the alternate pointers.
17744 _current.alternate = null;
17745 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17746
17747 workInProgress.flags |= Placement;
17748 } // Promote the fiber to a class and try rendering again.
17749
17750
17751 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
17752 // Push context providers early to prevent context stack mismatches.
17753 // During mounting we don't know the child context yet as the instance doesn't exist.
17754 // We will invalidate the child context in finishClassComponent() right after rendering.
17755
17756 var hasContext;
17757
17758 if (isContextProvider(Component)) {
17759 hasContext = true;
17760 pushContextProvider(workInProgress);
17761 } else {
17762 hasContext = false;
17763 }
17764
17765 prepareToReadContext(workInProgress, renderLanes);
17766 constructClassInstance(workInProgress, Component, nextProps);
17767 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
17768 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
17769}
17770
17771function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
17772 if (_current !== null) {
17773 // An indeterminate component only mounts if it suspended inside a non-
17774 // concurrent tree, in an inconsistent state. We want to treat it like
17775 // a new mount, even though an empty version of it already committed.
17776 // Disconnect the alternate pointers.
17777 _current.alternate = null;
17778 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17779
17780 workInProgress.flags |= Placement;
17781 }
17782
17783 var props = workInProgress.pendingProps;
17784 var context;
17785
17786 {
17787 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17788 context = getMaskedContext(workInProgress, unmaskedContext);
17789 }
17790
17791 prepareToReadContext(workInProgress, renderLanes);
17792 var value;
17793
17794 {
17795 if (Component.prototype && typeof Component.prototype.render === 'function') {
17796 var componentName = getComponentName(Component) || 'Unknown';
17797
17798 if (!didWarnAboutBadClass[componentName]) {
17799 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);
17800
17801 didWarnAboutBadClass[componentName] = true;
17802 }
17803 }
17804
17805 if (workInProgress.mode & StrictMode) {
17806 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17807 }
17808
17809 setIsRendering(true);
17810 ReactCurrentOwner$1.current = workInProgress;
17811 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
17812 setIsRendering(false);
17813 } // React DevTools reads this flag.
17814
17815
17816 workInProgress.flags |= PerformedWork;
17817
17818 {
17819 // Support for module components is deprecated and is removed behind a flag.
17820 // Whether or not it would crash later, we want to show a good message in DEV first.
17821 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17822 var _componentName = getComponentName(Component) || 'Unknown';
17823
17824 if (!didWarnAboutModulePatternComponent[_componentName]) {
17825 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);
17826
17827 didWarnAboutModulePatternComponent[_componentName] = true;
17828 }
17829 }
17830 }
17831
17832 if ( // Run these checks in production only if the flag is off.
17833 // Eventually we'll delete this branch altogether.
17834 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17835 {
17836 var _componentName2 = getComponentName(Component) || 'Unknown';
17837
17838 if (!didWarnAboutModulePatternComponent[_componentName2]) {
17839 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);
17840
17841 didWarnAboutModulePatternComponent[_componentName2] = true;
17842 }
17843 } // Proceed under the assumption that this is a class instance
17844
17845
17846 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
17847
17848 workInProgress.memoizedState = null;
17849 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
17850 // During mounting we don't know the child context yet as the instance doesn't exist.
17851 // We will invalidate the child context in finishClassComponent() right after rendering.
17852
17853 var hasContext = false;
17854
17855 if (isContextProvider(Component)) {
17856 hasContext = true;
17857 pushContextProvider(workInProgress);
17858 } else {
17859 hasContext = false;
17860 }
17861
17862 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17863 initializeUpdateQueue(workInProgress);
17864 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17865
17866 if (typeof getDerivedStateFromProps === 'function') {
17867 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17868 }
17869
17870 adoptClassInstance(workInProgress, value);
17871 mountClassInstance(workInProgress, Component, props, renderLanes);
17872 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
17873 } else {
17874 // Proceed under the assumption that this is a function component
17875 workInProgress.tag = FunctionComponent;
17876
17877 {
17878
17879 if ( workInProgress.mode & StrictMode) {
17880 disableLogs();
17881
17882 try {
17883 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
17884 } finally {
17885 reenableLogs();
17886 }
17887 }
17888 }
17889
17890 reconcileChildren(null, workInProgress, value, renderLanes);
17891
17892 {
17893 validateFunctionComponentInDev(workInProgress, Component);
17894 }
17895
17896 return workInProgress.child;
17897 }
17898}
17899
17900function validateFunctionComponentInDev(workInProgress, Component) {
17901 {
17902 if (Component) {
17903 if (Component.childContextTypes) {
17904 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
17905 }
17906 }
17907
17908 if (workInProgress.ref !== null) {
17909 var info = '';
17910 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17911
17912 if (ownerName) {
17913 info += '\n\nCheck the render method of `' + ownerName + '`.';
17914 }
17915
17916 var warningKey = ownerName || workInProgress._debugID || '';
17917 var debugSource = workInProgress._debugSource;
17918
17919 if (debugSource) {
17920 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17921 }
17922
17923 if (!didWarnAboutFunctionRefs[warningKey]) {
17924 didWarnAboutFunctionRefs[warningKey] = true;
17925
17926 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17927 }
17928 }
17929
17930 if (typeof Component.getDerivedStateFromProps === 'function') {
17931 var _componentName3 = getComponentName(Component) || 'Unknown';
17932
17933 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
17934 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
17935
17936 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
17937 }
17938 }
17939
17940 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17941 var _componentName4 = getComponentName(Component) || 'Unknown';
17942
17943 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
17944 error('%s: Function components do not support contextType.', _componentName4);
17945
17946 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
17947 }
17948 }
17949 }
17950}
17951
17952var SUSPENDED_MARKER = {
17953 dehydrated: null,
17954 retryLane: NoLane
17955};
17956
17957function mountSuspenseOffscreenState(renderLanes) {
17958 return {
17959 baseLanes: renderLanes
17960 };
17961}
17962
17963function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
17964 return {
17965 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes)
17966 };
17967} // TODO: Probably should inline this back
17968
17969
17970function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
17971 // If we're already showing a fallback, there are cases where we need to
17972 // remain on that fallback regardless of whether the content has resolved.
17973 // For example, SuspenseList coordinates when nested content appears.
17974 if (current !== null) {
17975 var suspenseState = current.memoizedState;
17976
17977 if (suspenseState === null) {
17978 // Currently showing content. Don't hide it, even if ForceSuspenseFallack
17979 // is true. More precise name might be "ForceRemainSuspenseFallback".
17980 // Note: This is a factoring smell. Can't remain on a fallback if there's
17981 // no fallback to remain on.
17982 return false;
17983 }
17984 } // Not currently showing content. Consult the Suspense context.
17985
17986
17987 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
17988}
17989
17990function getRemainingWorkInPrimaryTree(current, renderLanes) {
17991 // TODO: Should not remove render lanes that were pinged during this render
17992 return removeLanes(current.childLanes, renderLanes);
17993}
17994
17995function updateSuspenseComponent(current, workInProgress, renderLanes) {
17996 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
17997
17998 {
17999 if (shouldSuspend(workInProgress)) {
18000 workInProgress.flags |= DidCapture;
18001 }
18002 }
18003
18004 var suspenseContext = suspenseStackCursor.current;
18005 var showFallback = false;
18006 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
18007
18008 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
18009 // Something in this boundary's subtree already suspended. Switch to
18010 // rendering the fallback children.
18011 showFallback = true;
18012 workInProgress.flags &= ~DidCapture;
18013 } else {
18014 // Attempting the main content
18015 if (current === null || current.memoizedState !== null) {
18016 // This is a new mount or this boundary is already showing a fallback state.
18017 // Mark this subtree context as having at least one invisible parent that could
18018 // handle the fallback state.
18019 // Boundaries without fallbacks or should be avoided are not considered since
18020 // they cannot handle preferred fallback states.
18021 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
18022 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
18023 }
18024 }
18025 }
18026
18027 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18028 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
18029 // boundary's children. This involves some custom reconcilation logic. Two
18030 // main reasons this is so complicated.
18031 //
18032 // First, Legacy Mode has different semantics for backwards compatibility. The
18033 // primary tree will commit in an inconsistent state, so when we do the
18034 // second pass to render the fallback, we do some exceedingly, uh, clever
18035 // hacks to make that not totally break. Like transferring effects and
18036 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
18037 // because we bailout on the primary tree completely and leave it in its old
18038 // state, no effects. Same as what we do for Offscreen (except that
18039 // Offscreen doesn't have the first render pass).
18040 //
18041 // Second is hydration. During hydration, the Suspense fiber has a slightly
18042 // different layout, where the child points to a dehydrated fragment, which
18043 // contains the DOM rendered by the server.
18044 //
18045 // Third, even if you set all that aside, Suspense is like error boundaries in
18046 // that we first we try to render one tree, and if that fails, we render again
18047 // and switch to a different tree. Like a try/catch block. So we have to track
18048 // which branch we're currently rendering. Ideally we would model this using
18049 // a stack.
18050
18051 if (current === null) {
18052 // Initial mount
18053 // If we're currently hydrating, try to hydrate this boundary.
18054 // But only if this has a fallback.
18055 if (nextProps.fallback !== undefined) {
18056 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
18057 }
18058
18059 var nextPrimaryChildren = nextProps.children;
18060 var nextFallbackChildren = nextProps.fallback;
18061
18062 if (showFallback) {
18063 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18064 var primaryChildFragment = workInProgress.child;
18065 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18066 workInProgress.memoizedState = SUSPENDED_MARKER;
18067 return fallbackFragment;
18068 } else if (typeof nextProps.unstable_expectedLoadTime === 'number') {
18069 // This is a CPU-bound tree. Skip this tree and show a placeholder to
18070 // unblock the surrounding content. Then immediately retry after the
18071 // initial commit.
18072 var _fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
18073
18074 var _primaryChildFragment = workInProgress.child;
18075 _primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
18076 workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to
18077 // get it started back up to attempt the next item. While in terms of
18078 // priority this work has the same priority as this current render, it's
18079 // not part of the same transition once the transition has committed. If
18080 // it's sync, we still want to yield so that it can be painted.
18081 // Conceptually, this is really the same as pinging. We can use any
18082 // RetryLane even if it's the one currently rendering since we're leaving
18083 // it behind on this node.
18084
18085 workInProgress.lanes = SomeRetryLane;
18086
18087 {
18088 markSpawnedWork(SomeRetryLane);
18089 }
18090
18091 return _fallbackFragment;
18092 } else {
18093 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren, renderLanes);
18094 }
18095 } else {
18096 // This is an update.
18097 // If the current fiber has a SuspenseState, that means it's already showing
18098 // a fallback.
18099 var prevState = current.memoizedState;
18100
18101 if (prevState !== null) {
18102
18103 if (showFallback) {
18104 var _nextFallbackChildren2 = nextProps.fallback;
18105 var _nextPrimaryChildren2 = nextProps.children;
18106
18107 var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes);
18108
18109 var _primaryChildFragment3 = workInProgress.child;
18110 var prevOffscreenState = current.child.memoizedState;
18111 _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
18112 _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
18113 workInProgress.memoizedState = SUSPENDED_MARKER;
18114 return _fallbackChildFragment;
18115 } else {
18116 var _nextPrimaryChildren3 = nextProps.children;
18117
18118 var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes);
18119
18120 workInProgress.memoizedState = null;
18121 return _primaryChildFragment4;
18122 }
18123 } else {
18124 // The current tree is not already showing a fallback.
18125 if (showFallback) {
18126 // Timed out.
18127 var _nextFallbackChildren3 = nextProps.fallback;
18128 var _nextPrimaryChildren4 = nextProps.children;
18129
18130 var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes);
18131
18132 var _primaryChildFragment5 = workInProgress.child;
18133 var _prevOffscreenState = current.child.memoizedState;
18134 _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
18135 _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
18136 // fallback children.
18137
18138 workInProgress.memoizedState = SUSPENDED_MARKER;
18139 return _fallbackChildFragment2;
18140 } else {
18141 // Still haven't timed out. Continue rendering the children, like we
18142 // normally do.
18143 var _nextPrimaryChildren5 = nextProps.children;
18144
18145 var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes);
18146
18147 workInProgress.memoizedState = null;
18148 return _primaryChildFragment6;
18149 }
18150 }
18151 }
18152}
18153
18154function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
18155 var mode = workInProgress.mode;
18156 var primaryChildProps = {
18157 mode: 'visible',
18158 children: primaryChildren
18159 };
18160 var primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, renderLanes, null);
18161 primaryChildFragment.return = workInProgress;
18162 workInProgress.child = primaryChildFragment;
18163 return primaryChildFragment;
18164}
18165
18166function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
18167 var mode = workInProgress.mode;
18168 var progressedPrimaryFragment = workInProgress.child;
18169 var primaryChildProps = {
18170 mode: 'hidden',
18171 children: primaryChildren
18172 };
18173 var primaryChildFragment;
18174 var fallbackChildFragment;
18175
18176 if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) {
18177 // In legacy mode, we commit the primary tree as if it successfully
18178 // completed, even though it's in an inconsistent state.
18179 primaryChildFragment = progressedPrimaryFragment;
18180 primaryChildFragment.childLanes = NoLanes;
18181 primaryChildFragment.pendingProps = primaryChildProps;
18182
18183 if ( workInProgress.mode & ProfileMode) {
18184 // Reset the durations from the first pass so they aren't included in the
18185 // final amounts. This seems counterintuitive, since we're intentionally
18186 // not measuring part of the render phase, but this makes it match what we
18187 // do in Concurrent Mode.
18188 primaryChildFragment.actualDuration = 0;
18189 primaryChildFragment.actualStartTime = -1;
18190 primaryChildFragment.selfBaseDuration = 0;
18191 primaryChildFragment.treeBaseDuration = 0;
18192 }
18193
18194 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
18195 } else {
18196 primaryChildFragment = createFiberFromOffscreen(primaryChildProps, mode, NoLanes, null);
18197 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
18198 }
18199
18200 primaryChildFragment.return = workInProgress;
18201 fallbackChildFragment.return = workInProgress;
18202 primaryChildFragment.sibling = fallbackChildFragment;
18203 workInProgress.child = primaryChildFragment;
18204 return fallbackChildFragment;
18205}
18206
18207function createWorkInProgressOffscreenFiber(current, offscreenProps) {
18208 // The props argument to `createWorkInProgress` is `any` typed, so we use this
18209 // wrapper function to constrain it.
18210 return createWorkInProgress(current, offscreenProps);
18211}
18212
18213function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
18214 var currentPrimaryChildFragment = current.child;
18215 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
18216 var primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
18217 mode: 'visible',
18218 children: primaryChildren
18219 });
18220
18221 if ((workInProgress.mode & BlockingMode) === NoMode) {
18222 primaryChildFragment.lanes = renderLanes;
18223 }
18224
18225 primaryChildFragment.return = workInProgress;
18226 primaryChildFragment.sibling = null;
18227
18228 if (currentFallbackChildFragment !== null) {
18229 // Delete the fallback child fragment
18230 currentFallbackChildFragment.nextEffect = null;
18231 currentFallbackChildFragment.flags = Deletion;
18232 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment;
18233 }
18234
18235 workInProgress.child = primaryChildFragment;
18236 return primaryChildFragment;
18237}
18238
18239function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
18240 var mode = workInProgress.mode;
18241 var currentPrimaryChildFragment = current.child;
18242 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
18243 var primaryChildProps = {
18244 mode: 'hidden',
18245 children: primaryChildren
18246 };
18247 var primaryChildFragment;
18248
18249 if ( // In legacy mode, we commit the primary tree as if it successfully
18250 // completed, even though it's in an inconsistent state.
18251 (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
18252 // already cloned. In legacy mode, the only case where this isn't true is
18253 // when DevTools forces us to display a fallback; we skip the first render
18254 // pass entirely and go straight to rendering the fallback. (In Concurrent
18255 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
18256 // only codepath.)
18257 workInProgress.child !== currentPrimaryChildFragment) {
18258 var progressedPrimaryFragment = workInProgress.child;
18259 primaryChildFragment = progressedPrimaryFragment;
18260 primaryChildFragment.childLanes = NoLanes;
18261 primaryChildFragment.pendingProps = primaryChildProps;
18262
18263 if ( workInProgress.mode & ProfileMode) {
18264 // Reset the durations from the first pass so they aren't included in the
18265 // final amounts. This seems counterintuitive, since we're intentionally
18266 // not measuring part of the render phase, but this makes it match what we
18267 // do in Concurrent Mode.
18268 primaryChildFragment.actualDuration = 0;
18269 primaryChildFragment.actualStartTime = -1;
18270 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
18271 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
18272 } // The fallback fiber was added as a deletion effect during the first pass.
18273 // However, since we're going to remain on the fallback, we no longer want
18274 // to delete it. So we need to remove it from the list. Deletions are stored
18275 // on the same list as effects. We want to keep the effects from the primary
18276 // tree. So we copy the primary child fragment's effect list, which does not
18277 // include the fallback deletion effect.
18278
18279
18280 var progressedLastEffect = primaryChildFragment.lastEffect;
18281
18282 if (progressedLastEffect !== null) {
18283 workInProgress.firstEffect = primaryChildFragment.firstEffect;
18284 workInProgress.lastEffect = progressedLastEffect;
18285 progressedLastEffect.nextEffect = null;
18286 } else {
18287 // TODO: Reset this somewhere else? Lol legacy mode is so weird.
18288 workInProgress.firstEffect = workInProgress.lastEffect = null;
18289 }
18290 } else {
18291 primaryChildFragment = createWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
18292 }
18293
18294 var fallbackChildFragment;
18295
18296 if (currentFallbackChildFragment !== null) {
18297 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
18298 } else {
18299 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
18300 // mounted but this is a new fiber.
18301
18302 fallbackChildFragment.flags |= Placement;
18303 }
18304
18305 fallbackChildFragment.return = workInProgress;
18306 primaryChildFragment.return = workInProgress;
18307 primaryChildFragment.sibling = fallbackChildFragment;
18308 workInProgress.child = primaryChildFragment;
18309 return fallbackChildFragment;
18310}
18311
18312function scheduleWorkOnFiber(fiber, renderLanes) {
18313 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
18314 var alternate = fiber.alternate;
18315
18316 if (alternate !== null) {
18317 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
18318 }
18319
18320 scheduleWorkOnParentPath(fiber.return, renderLanes);
18321}
18322
18323function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
18324 // Mark any Suspense boundaries with fallbacks as having work to do.
18325 // If they were previously forced into fallbacks, they may now be able
18326 // to unblock.
18327 var node = firstChild;
18328
18329 while (node !== null) {
18330 if (node.tag === SuspenseComponent) {
18331 var state = node.memoizedState;
18332
18333 if (state !== null) {
18334 scheduleWorkOnFiber(node, renderLanes);
18335 }
18336 } else if (node.tag === SuspenseListComponent) {
18337 // If the tail is hidden there might not be an Suspense boundaries
18338 // to schedule work on. In this case we have to schedule it on the
18339 // list itself.
18340 // We don't have to traverse to the children of the list since
18341 // the list will propagate the change when it rerenders.
18342 scheduleWorkOnFiber(node, renderLanes);
18343 } else if (node.child !== null) {
18344 node.child.return = node;
18345 node = node.child;
18346 continue;
18347 }
18348
18349 if (node === workInProgress) {
18350 return;
18351 }
18352
18353 while (node.sibling === null) {
18354 if (node.return === null || node.return === workInProgress) {
18355 return;
18356 }
18357
18358 node = node.return;
18359 }
18360
18361 node.sibling.return = node.return;
18362 node = node.sibling;
18363 }
18364}
18365
18366function findLastContentRow(firstChild) {
18367 // This is going to find the last row among these children that is already
18368 // showing content on the screen, as opposed to being in fallback state or
18369 // new. If a row has multiple Suspense boundaries, any of them being in the
18370 // fallback state, counts as the whole row being in a fallback state.
18371 // Note that the "rows" will be workInProgress, but any nested children
18372 // will still be current since we haven't rendered them yet. The mounted
18373 // order may not be the same as the new order. We use the new order.
18374 var row = firstChild;
18375 var lastContentRow = null;
18376
18377 while (row !== null) {
18378 var currentRow = row.alternate; // New rows can't be content rows.
18379
18380 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18381 lastContentRow = row;
18382 }
18383
18384 row = row.sibling;
18385 }
18386
18387 return lastContentRow;
18388}
18389
18390function validateRevealOrder(revealOrder) {
18391 {
18392 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
18393 didWarnAboutRevealOrder[revealOrder] = true;
18394
18395 if (typeof revealOrder === 'string') {
18396 switch (revealOrder.toLowerCase()) {
18397 case 'together':
18398 case 'forwards':
18399 case 'backwards':
18400 {
18401 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
18402
18403 break;
18404 }
18405
18406 case 'forward':
18407 case 'backward':
18408 {
18409 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
18410
18411 break;
18412 }
18413
18414 default:
18415 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18416
18417 break;
18418 }
18419 } else {
18420 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18421 }
18422 }
18423 }
18424}
18425
18426function validateTailOptions(tailMode, revealOrder) {
18427 {
18428 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
18429 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
18430 didWarnAboutTailOptions[tailMode] = true;
18431
18432 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
18433 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
18434 didWarnAboutTailOptions[tailMode] = true;
18435
18436 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18437 }
18438 }
18439 }
18440}
18441
18442function validateSuspenseListNestedChild(childSlot, index) {
18443 {
18444 var isArray = Array.isArray(childSlot);
18445 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18446
18447 if (isArray || isIterable) {
18448 var type = isArray ? 'array' : 'iterable';
18449
18450 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
18451
18452 return false;
18453 }
18454 }
18455
18456 return true;
18457}
18458
18459function validateSuspenseListChildren(children, revealOrder) {
18460 {
18461 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18462 if (Array.isArray(children)) {
18463 for (var i = 0; i < children.length; i++) {
18464 if (!validateSuspenseListNestedChild(children[i], i)) {
18465 return;
18466 }
18467 }
18468 } else {
18469 var iteratorFn = getIteratorFn(children);
18470
18471 if (typeof iteratorFn === 'function') {
18472 var childrenIterator = iteratorFn.call(children);
18473
18474 if (childrenIterator) {
18475 var step = childrenIterator.next();
18476 var _i = 0;
18477
18478 for (; !step.done; step = childrenIterator.next()) {
18479 if (!validateSuspenseListNestedChild(step.value, _i)) {
18480 return;
18481 }
18482
18483 _i++;
18484 }
18485 }
18486 } else {
18487 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
18488 }
18489 }
18490 }
18491 }
18492}
18493
18494function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18495 var renderState = workInProgress.memoizedState;
18496
18497 if (renderState === null) {
18498 workInProgress.memoizedState = {
18499 isBackwards: isBackwards,
18500 rendering: null,
18501 renderingStartTime: 0,
18502 last: lastContentRow,
18503 tail: tail,
18504 tailMode: tailMode,
18505 lastEffect: lastEffectBeforeRendering
18506 };
18507 } else {
18508 // We can reuse the existing object from previous renders.
18509 renderState.isBackwards = isBackwards;
18510 renderState.rendering = null;
18511 renderState.renderingStartTime = 0;
18512 renderState.last = lastContentRow;
18513 renderState.tail = tail;
18514 renderState.tailMode = tailMode;
18515 renderState.lastEffect = lastEffectBeforeRendering;
18516 }
18517} // This can end up rendering this component multiple passes.
18518// The first pass splits the children fibers into two sets. A head and tail.
18519// We first render the head. If anything is in fallback state, we do another
18520// pass through beginWork to rerender all children (including the tail) with
18521// the force suspend context. If the first render didn't have anything in
18522// in fallback state. Then we render each row in the tail one-by-one.
18523// That happens in the completeWork phase without going back to beginWork.
18524
18525
18526function updateSuspenseListComponent(current, workInProgress, renderLanes) {
18527 var nextProps = workInProgress.pendingProps;
18528 var revealOrder = nextProps.revealOrder;
18529 var tailMode = nextProps.tail;
18530 var newChildren = nextProps.children;
18531 validateRevealOrder(revealOrder);
18532 validateTailOptions(tailMode, revealOrder);
18533 validateSuspenseListChildren(newChildren, revealOrder);
18534 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18535 var suspenseContext = suspenseStackCursor.current;
18536 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18537
18538 if (shouldForceFallback) {
18539 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18540 workInProgress.flags |= DidCapture;
18541 } else {
18542 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
18543
18544 if (didSuspendBefore) {
18545 // If we previously forced a fallback, we need to schedule work
18546 // on any nested boundaries to let them know to try to render
18547 // again. This is the same as context updating.
18548 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
18549 }
18550
18551 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18552 }
18553
18554 pushSuspenseContext(workInProgress, suspenseContext);
18555
18556 if ((workInProgress.mode & BlockingMode) === NoMode) {
18557 // In legacy mode, SuspenseList doesn't work so we just
18558 // use make it a noop by treating it as the default revealOrder.
18559 workInProgress.memoizedState = null;
18560 } else {
18561 switch (revealOrder) {
18562 case 'forwards':
18563 {
18564 var lastContentRow = findLastContentRow(workInProgress.child);
18565 var tail;
18566
18567 if (lastContentRow === null) {
18568 // The whole list is part of the tail.
18569 // TODO: We could fast path by just rendering the tail now.
18570 tail = workInProgress.child;
18571 workInProgress.child = null;
18572 } else {
18573 // Disconnect the tail rows after the content row.
18574 // We're going to render them separately later.
18575 tail = lastContentRow.sibling;
18576 lastContentRow.sibling = null;
18577 }
18578
18579 initSuspenseListRenderState(workInProgress, false, // isBackwards
18580 tail, lastContentRow, tailMode, workInProgress.lastEffect);
18581 break;
18582 }
18583
18584 case 'backwards':
18585 {
18586 // We're going to find the first row that has existing content.
18587 // At the same time we're going to reverse the list of everything
18588 // we pass in the meantime. That's going to be our tail in reverse
18589 // order.
18590 var _tail = null;
18591 var row = workInProgress.child;
18592 workInProgress.child = null;
18593
18594 while (row !== null) {
18595 var currentRow = row.alternate; // New rows can't be content rows.
18596
18597 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18598 // This is the beginning of the main content.
18599 workInProgress.child = row;
18600 break;
18601 }
18602
18603 var nextRow = row.sibling;
18604 row.sibling = _tail;
18605 _tail = row;
18606 row = nextRow;
18607 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18608
18609
18610 initSuspenseListRenderState(workInProgress, true, // isBackwards
18611 _tail, null, // last
18612 tailMode, workInProgress.lastEffect);
18613 break;
18614 }
18615
18616 case 'together':
18617 {
18618 initSuspenseListRenderState(workInProgress, false, // isBackwards
18619 null, // tail
18620 null, // last
18621 undefined, workInProgress.lastEffect);
18622 break;
18623 }
18624
18625 default:
18626 {
18627 // The default reveal order is the same as not having
18628 // a boundary.
18629 workInProgress.memoizedState = null;
18630 }
18631 }
18632 }
18633
18634 return workInProgress.child;
18635}
18636
18637function updatePortalComponent(current, workInProgress, renderLanes) {
18638 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18639 var nextChildren = workInProgress.pendingProps;
18640
18641 if (current === null) {
18642 // Portals are special because we don't append the children during mount
18643 // but at commit. Therefore we need to track insertions which the normal
18644 // flow doesn't do during mount. This doesn't happen at the root because
18645 // the root always starts with a "current" with a null child.
18646 // TODO: Consider unifying this with how the root works.
18647 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
18648 } else {
18649 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
18650 }
18651
18652 return workInProgress.child;
18653}
18654
18655var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
18656
18657function updateContextProvider(current, workInProgress, renderLanes) {
18658 var providerType = workInProgress.type;
18659 var context = providerType._context;
18660 var newProps = workInProgress.pendingProps;
18661 var oldProps = workInProgress.memoizedProps;
18662 var newValue = newProps.value;
18663
18664 {
18665 if (!('value' in newProps)) {
18666 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
18667 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
18668
18669 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
18670 }
18671 }
18672
18673 var providerPropTypes = workInProgress.type.propTypes;
18674
18675 if (providerPropTypes) {
18676 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
18677 }
18678 }
18679
18680 pushProvider(workInProgress, newValue);
18681
18682 if (oldProps !== null) {
18683 var oldValue = oldProps.value;
18684 var changedBits = calculateChangedBits(context, newValue, oldValue);
18685
18686 if (changedBits === 0) {
18687 // No change. Bailout early if children are the same.
18688 if (oldProps.children === newProps.children && !hasContextChanged()) {
18689 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
18690 }
18691 } else {
18692 // The context value changed. Search for matching consumers and schedule
18693 // them to update.
18694 propagateContextChange(workInProgress, context, changedBits, renderLanes);
18695 }
18696 }
18697
18698 var newChildren = newProps.children;
18699 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18700 return workInProgress.child;
18701}
18702
18703var hasWarnedAboutUsingContextAsConsumer = false;
18704
18705function updateContextConsumer(current, workInProgress, renderLanes) {
18706 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
18707 // DEV mode, we create a separate object for Context.Consumer that acts
18708 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18709 // so we use the old behaviour (Context.Consumer references Context) to
18710 // reduce size and overhead. The separate object references context via
18711 // a property called "_context", which also gives us the ability to check
18712 // in DEV mode if this property exists or not and warn if it does not.
18713
18714 {
18715 if (context._context === undefined) {
18716 // This may be because it's a Context (rather than a Consumer).
18717 // Or it may be because it's older React where they're the same thing.
18718 // We only want to warn if we're sure it's a new React.
18719 if (context !== context.Consumer) {
18720 if (!hasWarnedAboutUsingContextAsConsumer) {
18721 hasWarnedAboutUsingContextAsConsumer = true;
18722
18723 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18724 }
18725 }
18726 } else {
18727 context = context._context;
18728 }
18729 }
18730
18731 var newProps = workInProgress.pendingProps;
18732 var render = newProps.children;
18733
18734 {
18735 if (typeof render !== 'function') {
18736 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.');
18737 }
18738 }
18739
18740 prepareToReadContext(workInProgress, renderLanes);
18741 var newValue = readContext(context, newProps.unstable_observedBits);
18742 var newChildren;
18743
18744 {
18745 ReactCurrentOwner$1.current = workInProgress;
18746 setIsRendering(true);
18747 newChildren = render(newValue);
18748 setIsRendering(false);
18749 } // React DevTools reads this flag.
18750
18751
18752 workInProgress.flags |= PerformedWork;
18753 reconcileChildren(current, workInProgress, newChildren, renderLanes);
18754 return workInProgress.child;
18755}
18756
18757function markWorkInProgressReceivedUpdate() {
18758 didReceiveUpdate = true;
18759}
18760
18761function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
18762 if (current !== null) {
18763 // Reuse previous dependencies
18764 workInProgress.dependencies = current.dependencies;
18765 }
18766
18767 {
18768 // Don't update "base" render times for bailouts.
18769 stopProfilerTimerIfRunning();
18770 }
18771
18772 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
18773
18774 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
18775 // The children don't have any work either. We can skip them.
18776 // TODO: Once we add back resuming, we should check if the children are
18777 // a work-in-progress set. If so, we need to transfer their effects.
18778 return null;
18779 } else {
18780 // This fiber doesn't have work, but its subtree does. Clone the child
18781 // fibers and continue.
18782 cloneChildFibers(current, workInProgress);
18783 return workInProgress.child;
18784 }
18785}
18786
18787function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18788 {
18789 var returnFiber = oldWorkInProgress.return;
18790
18791 if (returnFiber === null) {
18792 throw new Error('Cannot swap the root fiber.');
18793 } // Disconnect from the old current.
18794 // It will get deleted.
18795
18796
18797 current.alternate = null;
18798 oldWorkInProgress.alternate = null; // Connect to the new tree.
18799
18800 newWorkInProgress.index = oldWorkInProgress.index;
18801 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18802 newWorkInProgress.return = oldWorkInProgress.return;
18803 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
18804
18805 if (oldWorkInProgress === returnFiber.child) {
18806 returnFiber.child = newWorkInProgress;
18807 } else {
18808 var prevSibling = returnFiber.child;
18809
18810 if (prevSibling === null) {
18811 throw new Error('Expected parent to have a child.');
18812 }
18813
18814 while (prevSibling.sibling !== oldWorkInProgress) {
18815 prevSibling = prevSibling.sibling;
18816
18817 if (prevSibling === null) {
18818 throw new Error('Expected to find the previous sibling.');
18819 }
18820 }
18821
18822 prevSibling.sibling = newWorkInProgress;
18823 } // Delete the old fiber and place the new one.
18824 // Since the old fiber is disconnected, we have to schedule it manually.
18825
18826
18827 var last = returnFiber.lastEffect;
18828
18829 if (last !== null) {
18830 last.nextEffect = current;
18831 returnFiber.lastEffect = current;
18832 } else {
18833 returnFiber.firstEffect = returnFiber.lastEffect = current;
18834 }
18835
18836 current.nextEffect = null;
18837 current.flags = Deletion;
18838 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
18839
18840 return newWorkInProgress;
18841 }
18842}
18843
18844function beginWork(current, workInProgress, renderLanes) {
18845 var updateLanes = workInProgress.lanes;
18846
18847 {
18848 if (workInProgress._debugNeedsRemount && current !== null) {
18849 // This will restart the begin phase with a new fiber.
18850 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
18851 }
18852 }
18853
18854 if (current !== null) {
18855 var oldProps = current.memoizedProps;
18856 var newProps = workInProgress.pendingProps;
18857
18858 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
18859 workInProgress.type !== current.type )) {
18860 // If props or context changed, mark the fiber as having performed work.
18861 // This may be unset if the props are determined to be equal later (memo).
18862 didReceiveUpdate = true;
18863 } else if (!includesSomeLane(renderLanes, updateLanes)) {
18864 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
18865 // the begin phase. There's still some bookkeeping we that needs to be done
18866 // in this optimized path, mostly pushing stuff onto the stack.
18867
18868 switch (workInProgress.tag) {
18869 case HostRoot:
18870 pushHostRootContext(workInProgress);
18871 resetHydrationState();
18872 break;
18873
18874 case HostComponent:
18875 pushHostContext(workInProgress);
18876 break;
18877
18878 case ClassComponent:
18879 {
18880 var Component = workInProgress.type;
18881
18882 if (isContextProvider(Component)) {
18883 pushContextProvider(workInProgress);
18884 }
18885
18886 break;
18887 }
18888
18889 case HostPortal:
18890 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18891 break;
18892
18893 case ContextProvider:
18894 {
18895 var newValue = workInProgress.memoizedProps.value;
18896 pushProvider(workInProgress, newValue);
18897 break;
18898 }
18899
18900 case Profiler:
18901 {
18902 // Profiler should only call onRender when one of its descendants actually rendered.
18903 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
18904
18905 if (hasChildWork) {
18906 workInProgress.flags |= Update;
18907 } // Reset effect durations for the next eventual effect phase.
18908 // These are reset during render to allow the DevTools commit hook a chance to read them,
18909
18910
18911 var stateNode = workInProgress.stateNode;
18912 stateNode.effectDuration = 0;
18913 stateNode.passiveEffectDuration = 0;
18914 }
18915
18916 break;
18917
18918 case SuspenseComponent:
18919 {
18920 var state = workInProgress.memoizedState;
18921
18922 if (state !== null) {
18923 // whether to retry the primary children, or to skip over it and
18924 // go straight to the fallback. Check the priority of the primary
18925 // child fragment.
18926
18927
18928 var primaryChildFragment = workInProgress.child;
18929 var primaryChildLanes = primaryChildFragment.childLanes;
18930
18931 if (includesSomeLane(renderLanes, primaryChildLanes)) {
18932 // The primary children have pending work. Use the normal path
18933 // to attempt to render the primary children again.
18934 return updateSuspenseComponent(current, workInProgress, renderLanes);
18935 } else {
18936 // The primary child fragment does not have pending work marked
18937 // on it
18938 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
18939 // priority. Bailout.
18940
18941 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
18942
18943 if (child !== null) {
18944 // The fallback children have pending work. Skip over the
18945 // primary children and work on the fallback.
18946 return child.sibling;
18947 } else {
18948 return null;
18949 }
18950 }
18951 } else {
18952 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18953 }
18954
18955 break;
18956 }
18957
18958 case SuspenseListComponent:
18959 {
18960 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
18961
18962 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
18963
18964 if (didSuspendBefore) {
18965 if (_hasChildWork) {
18966 // If something was in fallback state last time, and we have all the
18967 // same children then we're still in progressive loading state.
18968 // Something might get unblocked by state updates or retries in the
18969 // tree which will affect the tail. So we need to use the normal
18970 // path to compute the correct tail.
18971 return updateSuspenseListComponent(current, workInProgress, renderLanes);
18972 } // If none of the children had any work, that means that none of
18973 // them got retried so they'll still be blocked in the same way
18974 // as before. We can fast bail out.
18975
18976
18977 workInProgress.flags |= DidCapture;
18978 } // If nothing suspended before and we're rendering the same children,
18979 // then the tail doesn't matter. Anything new that suspends will work
18980 // in the "together" mode, so we can continue from the state we had.
18981
18982
18983 var renderState = workInProgress.memoizedState;
18984
18985 if (renderState !== null) {
18986 // Reset to the "together" mode in case we've started a different
18987 // update in the past but didn't complete it.
18988 renderState.rendering = null;
18989 renderState.tail = null;
18990 renderState.lastEffect = null;
18991 }
18992
18993 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18994
18995 if (_hasChildWork) {
18996 break;
18997 } else {
18998 // If none of the children had any work, that means that none of
18999 // them got retried so they'll still be blocked in the same way
19000 // as before. We can fast bail out.
19001 return null;
19002 }
19003 }
19004
19005 case OffscreenComponent:
19006 case LegacyHiddenComponent:
19007 {
19008 // Need to check if the tree still needs to be deferred. This is
19009 // almost identical to the logic used in the normal update path,
19010 // so we'll just enter that. The only difference is we'll bail out
19011 // at the next level instead of this one, because the child props
19012 // have not changed. Which is fine.
19013 // TODO: Probably should refactor `beginWork` to split the bailout
19014 // path from the normal path. I'm tempted to do a labeled break here
19015 // but I won't :)
19016 workInProgress.lanes = NoLanes;
19017 return updateOffscreenComponent(current, workInProgress, renderLanes);
19018 }
19019 }
19020
19021 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19022 } else {
19023 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
19024 // This is a special case that only exists for legacy mode.
19025 // See https://github.com/facebook/react/pull/19216.
19026 didReceiveUpdate = true;
19027 } else {
19028 // An update was scheduled on this fiber, but there are no new props
19029 // nor legacy context. Set this to false. If an update queue or context
19030 // consumer produces a changed value, it will set this to true. Otherwise,
19031 // the component will assume the children have not changed and bail out.
19032 didReceiveUpdate = false;
19033 }
19034 }
19035 } else {
19036 didReceiveUpdate = false;
19037 } // Before entering the begin phase, clear pending update priority.
19038 // TODO: This assumes that we're about to evaluate the component and process
19039 // the update queue. However, there's an exception: SimpleMemoComponent
19040 // sometimes bails out later in the begin phase. This indicates that we should
19041 // move this assignment out of the common path and into each branch.
19042
19043
19044 workInProgress.lanes = NoLanes;
19045
19046 switch (workInProgress.tag) {
19047 case IndeterminateComponent:
19048 {
19049 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
19050 }
19051
19052 case LazyComponent:
19053 {
19054 var elementType = workInProgress.elementType;
19055 return mountLazyComponent(current, workInProgress, elementType, updateLanes, renderLanes);
19056 }
19057
19058 case FunctionComponent:
19059 {
19060 var _Component = workInProgress.type;
19061 var unresolvedProps = workInProgress.pendingProps;
19062 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
19063 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderLanes);
19064 }
19065
19066 case ClassComponent:
19067 {
19068 var _Component2 = workInProgress.type;
19069 var _unresolvedProps = workInProgress.pendingProps;
19070
19071 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
19072
19073 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderLanes);
19074 }
19075
19076 case HostRoot:
19077 return updateHostRoot(current, workInProgress, renderLanes);
19078
19079 case HostComponent:
19080 return updateHostComponent(current, workInProgress, renderLanes);
19081
19082 case HostText:
19083 return updateHostText(current, workInProgress);
19084
19085 case SuspenseComponent:
19086 return updateSuspenseComponent(current, workInProgress, renderLanes);
19087
19088 case HostPortal:
19089 return updatePortalComponent(current, workInProgress, renderLanes);
19090
19091 case ForwardRef:
19092 {
19093 var type = workInProgress.type;
19094 var _unresolvedProps2 = workInProgress.pendingProps;
19095
19096 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
19097
19098 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
19099 }
19100
19101 case Fragment:
19102 return updateFragment(current, workInProgress, renderLanes);
19103
19104 case Mode:
19105 return updateMode(current, workInProgress, renderLanes);
19106
19107 case Profiler:
19108 return updateProfiler(current, workInProgress, renderLanes);
19109
19110 case ContextProvider:
19111 return updateContextProvider(current, workInProgress, renderLanes);
19112
19113 case ContextConsumer:
19114 return updateContextConsumer(current, workInProgress, renderLanes);
19115
19116 case MemoComponent:
19117 {
19118 var _type2 = workInProgress.type;
19119 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
19120
19121 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
19122
19123 {
19124 if (workInProgress.type !== workInProgress.elementType) {
19125 var outerPropTypes = _type2.propTypes;
19126
19127 if (outerPropTypes) {
19128 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
19129 'prop', getComponentName(_type2));
19130 }
19131 }
19132 }
19133
19134 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
19135 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateLanes, renderLanes);
19136 }
19137
19138 case SimpleMemoComponent:
19139 {
19140 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateLanes, renderLanes);
19141 }
19142
19143 case IncompleteClassComponent:
19144 {
19145 var _Component3 = workInProgress.type;
19146 var _unresolvedProps4 = workInProgress.pendingProps;
19147
19148 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
19149
19150 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderLanes);
19151 }
19152
19153 case SuspenseListComponent:
19154 {
19155 return updateSuspenseListComponent(current, workInProgress, renderLanes);
19156 }
19157
19158 case FundamentalComponent:
19159 {
19160
19161 break;
19162 }
19163
19164 case ScopeComponent:
19165 {
19166
19167 break;
19168 }
19169
19170 case Block:
19171 {
19172
19173 break;
19174 }
19175
19176 case OffscreenComponent:
19177 {
19178 return updateOffscreenComponent(current, workInProgress, renderLanes);
19179 }
19180
19181 case LegacyHiddenComponent:
19182 {
19183 return updateLegacyHiddenComponent(current, workInProgress, renderLanes);
19184 }
19185 }
19186
19187 {
19188 {
19189 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19190 }
19191 }
19192}
19193
19194function markUpdate(workInProgress) {
19195 // Tag the fiber with an update effect. This turns a Placement into
19196 // a PlacementAndUpdate.
19197 workInProgress.flags |= Update;
19198}
19199
19200function markRef$1(workInProgress) {
19201 workInProgress.flags |= Ref;
19202}
19203
19204var appendAllChildren;
19205var updateHostContainer;
19206var updateHostComponent$1;
19207var updateHostText$1;
19208
19209{
19210 // Mutation mode
19211 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
19212 // We only have the top Fiber that was created but we need recurse down its
19213 // children to find all the terminal nodes.
19214 var node = workInProgress.child;
19215
19216 while (node !== null) {
19217 if (node.tag === HostComponent || node.tag === HostText) {
19218 appendInitialChild(parent, node.stateNode);
19219 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
19220 node.child.return = node;
19221 node = node.child;
19222 continue;
19223 }
19224
19225 if (node === workInProgress) {
19226 return;
19227 }
19228
19229 while (node.sibling === null) {
19230 if (node.return === null || node.return === workInProgress) {
19231 return;
19232 }
19233
19234 node = node.return;
19235 }
19236
19237 node.sibling.return = node.return;
19238 node = node.sibling;
19239 }
19240 };
19241
19242 updateHostContainer = function (workInProgress) {// Noop
19243 };
19244
19245 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
19246 // If we have an alternate, that means this is an update and we need to
19247 // schedule a side-effect to do the updates.
19248 var oldProps = current.memoizedProps;
19249
19250 if (oldProps === newProps) {
19251 // In mutation mode, this is sufficient for a bailout because
19252 // we won't touch this node even if children changed.
19253 return;
19254 } // If we get updated because one of our children updated, we don't
19255 // have newProps so we'll have to reuse them.
19256 // TODO: Split the update API as separate for the props vs. children.
19257 // Even better would be if children weren't special cased at all tho.
19258
19259
19260 var instance = workInProgress.stateNode;
19261 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
19262 // component is hitting the resume path. Figure out why. Possibly
19263 // related to `hidden`.
19264
19265 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
19266
19267 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
19268 // is a new ref we mark this as an update. All the work is done in commitWork.
19269
19270 if (updatePayload) {
19271 markUpdate(workInProgress);
19272 }
19273 };
19274
19275 updateHostText$1 = function (current, workInProgress, oldText, newText) {
19276 // If the text differs, mark it as an update. All the work in done in commitWork.
19277 if (oldText !== newText) {
19278 markUpdate(workInProgress);
19279 }
19280 };
19281}
19282
19283function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
19284 if (getIsHydrating()) {
19285 // If we're hydrating, we should consume as many items as we can
19286 // so we don't leave any behind.
19287 return;
19288 }
19289
19290 switch (renderState.tailMode) {
19291 case 'hidden':
19292 {
19293 // Any insertions at the end of the tail list after this point
19294 // should be invisible. If there are already mounted boundaries
19295 // anything before them are not considered for collapsing.
19296 // Therefore we need to go through the whole tail to find if
19297 // there are any.
19298 var tailNode = renderState.tail;
19299 var lastTailNode = null;
19300
19301 while (tailNode !== null) {
19302 if (tailNode.alternate !== null) {
19303 lastTailNode = tailNode;
19304 }
19305
19306 tailNode = tailNode.sibling;
19307 } // Next we're simply going to delete all insertions after the
19308 // last rendered item.
19309
19310
19311 if (lastTailNode === null) {
19312 // All remaining items in the tail are insertions.
19313 renderState.tail = null;
19314 } else {
19315 // Detach the insertion after the last node that was already
19316 // inserted.
19317 lastTailNode.sibling = null;
19318 }
19319
19320 break;
19321 }
19322
19323 case 'collapsed':
19324 {
19325 // Any insertions at the end of the tail list after this point
19326 // should be invisible. If there are already mounted boundaries
19327 // anything before them are not considered for collapsing.
19328 // Therefore we need to go through the whole tail to find if
19329 // there are any.
19330 var _tailNode = renderState.tail;
19331 var _lastTailNode = null;
19332
19333 while (_tailNode !== null) {
19334 if (_tailNode.alternate !== null) {
19335 _lastTailNode = _tailNode;
19336 }
19337
19338 _tailNode = _tailNode.sibling;
19339 } // Next we're simply going to delete all insertions after the
19340 // last rendered item.
19341
19342
19343 if (_lastTailNode === null) {
19344 // All remaining items in the tail are insertions.
19345 if (!hasRenderedATailFallback && renderState.tail !== null) {
19346 // We suspended during the head. We want to show at least one
19347 // row at the tail. So we'll keep on and cut off the rest.
19348 renderState.tail.sibling = null;
19349 } else {
19350 renderState.tail = null;
19351 }
19352 } else {
19353 // Detach the insertion after the last node that was already
19354 // inserted.
19355 _lastTailNode.sibling = null;
19356 }
19357
19358 break;
19359 }
19360 }
19361}
19362
19363function completeWork(current, workInProgress, renderLanes) {
19364 var newProps = workInProgress.pendingProps;
19365
19366 switch (workInProgress.tag) {
19367 case IndeterminateComponent:
19368 case LazyComponent:
19369 case SimpleMemoComponent:
19370 case FunctionComponent:
19371 case ForwardRef:
19372 case Fragment:
19373 case Mode:
19374 case Profiler:
19375 case ContextConsumer:
19376 case MemoComponent:
19377 return null;
19378
19379 case ClassComponent:
19380 {
19381 var Component = workInProgress.type;
19382
19383 if (isContextProvider(Component)) {
19384 popContext(workInProgress);
19385 }
19386
19387 return null;
19388 }
19389
19390 case HostRoot:
19391 {
19392 popHostContainer(workInProgress);
19393 popTopLevelContextObject(workInProgress);
19394 resetWorkInProgressVersions();
19395 var fiberRoot = workInProgress.stateNode;
19396
19397 if (fiberRoot.pendingContext) {
19398 fiberRoot.context = fiberRoot.pendingContext;
19399 fiberRoot.pendingContext = null;
19400 }
19401
19402 if (current === null || current.child === null) {
19403 // If we hydrated, pop so that we can delete any remaining children
19404 // that weren't hydrated.
19405 var wasHydrated = popHydrationState(workInProgress);
19406
19407 if (wasHydrated) {
19408 // If we hydrated, then we'll need to schedule an update for
19409 // the commit side-effects on the root.
19410 markUpdate(workInProgress);
19411 } else if (!fiberRoot.hydrate) {
19412 // Schedule an effect to clear this container at the start of the next commit.
19413 // This handles the case of React rendering into a container with previous children.
19414 // It's also safe to do for updates too, because current.child would only be null
19415 // if the previous render was null (so the the container would already be empty).
19416 workInProgress.flags |= Snapshot;
19417 }
19418 }
19419
19420 updateHostContainer(workInProgress);
19421 return null;
19422 }
19423
19424 case HostComponent:
19425 {
19426 popHostContext(workInProgress);
19427 var rootContainerInstance = getRootHostContainer();
19428 var type = workInProgress.type;
19429
19430 if (current !== null && workInProgress.stateNode != null) {
19431 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19432
19433 if (current.ref !== workInProgress.ref) {
19434 markRef$1(workInProgress);
19435 }
19436 } else {
19437 if (!newProps) {
19438 if (!(workInProgress.stateNode !== null)) {
19439 {
19440 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19441 }
19442 } // This can happen when we abort work.
19443
19444
19445 return null;
19446 }
19447
19448 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
19449 // "stack" as the parent. Then append children as we go in beginWork
19450 // or completeWork depending on whether we want to add them top->down or
19451 // bottom->up. Top->down is faster in IE11.
19452
19453 var _wasHydrated = popHydrationState(workInProgress);
19454
19455 if (_wasHydrated) {
19456 // TODO: Move this and createInstance step into the beginPhase
19457 // to consolidate.
19458 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19459 // If changes to the hydrated node need to be applied at the
19460 // commit-phase we mark this as such.
19461 markUpdate(workInProgress);
19462 }
19463 } else {
19464 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19465 appendAllChildren(instance, workInProgress, false, false);
19466 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
19467 // (eg DOM renderer supports auto-focus for certain elements).
19468 // Make sure such renderers get scheduled for later work.
19469
19470 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
19471 markUpdate(workInProgress);
19472 }
19473 }
19474
19475 if (workInProgress.ref !== null) {
19476 // If there is a ref on a host node we need to schedule a callback
19477 markRef$1(workInProgress);
19478 }
19479 }
19480
19481 return null;
19482 }
19483
19484 case HostText:
19485 {
19486 var newText = newProps;
19487
19488 if (current && workInProgress.stateNode != null) {
19489 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
19490 // to schedule a side-effect to do the updates.
19491
19492 updateHostText$1(current, workInProgress, oldText, newText);
19493 } else {
19494 if (typeof newText !== 'string') {
19495 if (!(workInProgress.stateNode !== null)) {
19496 {
19497 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19498 }
19499 } // This can happen when we abort work.
19500
19501 }
19502
19503 var _rootContainerInstance = getRootHostContainer();
19504
19505 var _currentHostContext = getHostContext();
19506
19507 var _wasHydrated2 = popHydrationState(workInProgress);
19508
19509 if (_wasHydrated2) {
19510 if (prepareToHydrateHostTextInstance(workInProgress)) {
19511 markUpdate(workInProgress);
19512 }
19513 } else {
19514 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19515 }
19516 }
19517
19518 return null;
19519 }
19520
19521 case SuspenseComponent:
19522 {
19523 popSuspenseContext(workInProgress);
19524 var nextState = workInProgress.memoizedState;
19525
19526 if ((workInProgress.flags & DidCapture) !== NoFlags) {
19527 // Something suspended. Re-render with the fallback children.
19528 workInProgress.lanes = renderLanes; // Do not reset the effect list.
19529
19530 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19531 transferActualDuration(workInProgress);
19532 }
19533
19534 return workInProgress;
19535 }
19536
19537 var nextDidTimeout = nextState !== null;
19538 var prevDidTimeout = false;
19539
19540 if (current === null) {
19541 if (workInProgress.memoizedProps.fallback !== undefined) {
19542 popHydrationState(workInProgress);
19543 }
19544 } else {
19545 var prevState = current.memoizedState;
19546 prevDidTimeout = prevState !== null;
19547 }
19548
19549 if (nextDidTimeout && !prevDidTimeout) {
19550 // If this subtreee is running in blocking mode we can suspend,
19551 // otherwise we won't suspend.
19552 // TODO: This will still suspend a synchronous tree if anything
19553 // in the concurrent tree already suspended during this render.
19554 // This is a known bug.
19555 if ((workInProgress.mode & BlockingMode) !== NoMode) {
19556 // TODO: Move this back to throwException because this is too late
19557 // if this is a large tree which is common for initial loads. We
19558 // don't know if we should restart a render or not until we get
19559 // this marker, and this is too late.
19560 // If this render already had a ping or lower pri updates,
19561 // and this is the first time we know we're going to suspend we
19562 // should be able to immediately restart from within throwException.
19563 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19564
19565 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19566 // If this was in an invisible tree or a new render, then showing
19567 // this boundary is ok.
19568 renderDidSuspend();
19569 } else {
19570 // Otherwise, we're going to have to hide content so we should
19571 // suspend for longer if possible.
19572 renderDidSuspendDelayIfPossible();
19573 }
19574 }
19575 }
19576
19577 {
19578 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19579 if (nextDidTimeout || prevDidTimeout) {
19580 // If this boundary just timed out, schedule an effect to attach a
19581 // retry listener to the promise. This flag is also used to hide the
19582 // primary children. In mutation mode, we also need the flag to
19583 // *unhide* children that were previously hidden, so check if this
19584 // is currently timed out, too.
19585 workInProgress.flags |= Update;
19586 }
19587 }
19588
19589 return null;
19590 }
19591
19592 case HostPortal:
19593 popHostContainer(workInProgress);
19594 updateHostContainer(workInProgress);
19595
19596 if (current === null) {
19597 preparePortalMount(workInProgress.stateNode.containerInfo);
19598 }
19599
19600 return null;
19601
19602 case ContextProvider:
19603 // Pop provider fiber
19604 popProvider(workInProgress);
19605 return null;
19606
19607 case IncompleteClassComponent:
19608 {
19609 // Same as class component case. I put it down here so that the tags are
19610 // sequential to ensure this switch is compiled to a jump table.
19611 var _Component = workInProgress.type;
19612
19613 if (isContextProvider(_Component)) {
19614 popContext(workInProgress);
19615 }
19616
19617 return null;
19618 }
19619
19620 case SuspenseListComponent:
19621 {
19622 popSuspenseContext(workInProgress);
19623 var renderState = workInProgress.memoizedState;
19624
19625 if (renderState === null) {
19626 // We're running in the default, "independent" mode.
19627 // We don't do anything in this mode.
19628 return null;
19629 }
19630
19631 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
19632 var renderedTail = renderState.rendering;
19633
19634 if (renderedTail === null) {
19635 // We just rendered the head.
19636 if (!didSuspendAlready) {
19637 // This is the first pass. We need to figure out if anything is still
19638 // suspended in the rendered set.
19639 // If new content unsuspended, but there's still some content that
19640 // didn't. Then we need to do a second pass that forces everything
19641 // to keep showing their fallbacks.
19642 // We might be suspended if something in this render pass suspended, or
19643 // something in the previous committed pass suspended. Otherwise,
19644 // there's no chance so we can skip the expensive call to
19645 // findFirstSuspended.
19646 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
19647
19648 if (!cannotBeSuspended) {
19649 var row = workInProgress.child;
19650
19651 while (row !== null) {
19652 var suspended = findFirstSuspended(row);
19653
19654 if (suspended !== null) {
19655 didSuspendAlready = true;
19656 workInProgress.flags |= DidCapture;
19657 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19658 // part of the second pass. In that case nothing will subscribe to
19659 // its thennables. Instead, we'll transfer its thennables to the
19660 // SuspenseList so that it can retry if they resolve.
19661 // There might be multiple of these in the list but since we're
19662 // going to wait for all of them anyway, it doesn't really matter
19663 // which ones gets to ping. In theory we could get clever and keep
19664 // track of how many dependencies remain but it gets tricky because
19665 // in the meantime, we can add/remove/change items and dependencies.
19666 // We might bail out of the loop before finding any but that
19667 // doesn't matter since that means that the other boundaries that
19668 // we did find already has their listeners attached.
19669
19670 var newThennables = suspended.updateQueue;
19671
19672 if (newThennables !== null) {
19673 workInProgress.updateQueue = newThennables;
19674 workInProgress.flags |= Update;
19675 } // Rerender the whole list, but this time, we'll force fallbacks
19676 // to stay in place.
19677 // Reset the effect list before doing the second pass since that's now invalid.
19678
19679
19680 if (renderState.lastEffect === null) {
19681 workInProgress.firstEffect = null;
19682 }
19683
19684 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19685
19686 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
19687 // rerender the children.
19688
19689 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19690 return workInProgress.child;
19691 }
19692
19693 row = row.sibling;
19694 }
19695 }
19696
19697 if (renderState.tail !== null && now() > getRenderTargetTime()) {
19698 // We have already passed our CPU deadline but we still have rows
19699 // left in the tail. We'll just give up further attempts to render
19700 // the main content and only render fallbacks.
19701 workInProgress.flags |= DidCapture;
19702 didSuspendAlready = true;
19703 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19704 // to get it started back up to attempt the next item. While in terms
19705 // of priority this work has the same priority as this current render,
19706 // it's not part of the same transition once the transition has
19707 // committed. If it's sync, we still want to yield so that it can be
19708 // painted. Conceptually, this is really the same as pinging.
19709 // We can use any RetryLane even if it's the one currently rendering
19710 // since we're leaving it behind on this node.
19711
19712 workInProgress.lanes = SomeRetryLane;
19713
19714 {
19715 markSpawnedWork(SomeRetryLane);
19716 }
19717 }
19718 } else {
19719 cutOffTailIfNeeded(renderState, false);
19720 } // Next we're going to render the tail.
19721
19722 } else {
19723 // Append the rendered row to the child list.
19724 if (!didSuspendAlready) {
19725 var _suspended = findFirstSuspended(renderedTail);
19726
19727 if (_suspended !== null) {
19728 workInProgress.flags |= DidCapture;
19729 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19730 // get lost if this row ends up dropped during a second pass.
19731
19732 var _newThennables = _suspended.updateQueue;
19733
19734 if (_newThennables !== null) {
19735 workInProgress.updateQueue = _newThennables;
19736 workInProgress.flags |= Update;
19737 }
19738
19739 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19740
19741 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
19742 ) {
19743 // We need to delete the row we just rendered.
19744 // Reset the effect list to what it was before we rendered this
19745 // child. The nested children have already appended themselves.
19746 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19747
19748 if (lastEffect !== null) {
19749 lastEffect.nextEffect = null;
19750 } // We're done.
19751
19752
19753 return null;
19754 }
19755 } else if ( // The time it took to render last row is greater than the remaining
19756 // time we have to render. So rendering one more row would likely
19757 // exceed it.
19758 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
19759 // We have now passed our CPU deadline and we'll just give up further
19760 // attempts to render the main content and only render fallbacks.
19761 // The assumption is that this is usually faster.
19762 workInProgress.flags |= DidCapture;
19763 didSuspendAlready = true;
19764 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19765 // to get it started back up to attempt the next item. While in terms
19766 // of priority this work has the same priority as this current render,
19767 // it's not part of the same transition once the transition has
19768 // committed. If it's sync, we still want to yield so that it can be
19769 // painted. Conceptually, this is really the same as pinging.
19770 // We can use any RetryLane even if it's the one currently rendering
19771 // since we're leaving it behind on this node.
19772
19773 workInProgress.lanes = SomeRetryLane;
19774
19775 {
19776 markSpawnedWork(SomeRetryLane);
19777 }
19778 }
19779 }
19780
19781 if (renderState.isBackwards) {
19782 // The effect list of the backwards tail will have been added
19783 // to the end. This breaks the guarantee that life-cycles fire in
19784 // sibling order but that isn't a strong guarantee promised by React.
19785 // Especially since these might also just pop in during future commits.
19786 // Append to the beginning of the list.
19787 renderedTail.sibling = workInProgress.child;
19788 workInProgress.child = renderedTail;
19789 } else {
19790 var previousSibling = renderState.last;
19791
19792 if (previousSibling !== null) {
19793 previousSibling.sibling = renderedTail;
19794 } else {
19795 workInProgress.child = renderedTail;
19796 }
19797
19798 renderState.last = renderedTail;
19799 }
19800 }
19801
19802 if (renderState.tail !== null) {
19803 // We still have tail rows to render.
19804 // Pop a row.
19805 var next = renderState.tail;
19806 renderState.rendering = next;
19807 renderState.tail = next.sibling;
19808 renderState.lastEffect = workInProgress.lastEffect;
19809 renderState.renderingStartTime = now();
19810 next.sibling = null; // Restore the context.
19811 // TODO: We can probably just avoid popping it instead and only
19812 // setting it the first time we go from not suspended to suspended.
19813
19814 var suspenseContext = suspenseStackCursor.current;
19815
19816 if (didSuspendAlready) {
19817 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19818 } else {
19819 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19820 }
19821
19822 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19823
19824 return next;
19825 }
19826
19827 return null;
19828 }
19829
19830 case FundamentalComponent:
19831 {
19832
19833 break;
19834 }
19835
19836 case ScopeComponent:
19837 {
19838
19839 break;
19840 }
19841
19842 case Block:
19843
19844 break;
19845
19846 case OffscreenComponent:
19847 case LegacyHiddenComponent:
19848 {
19849 popRenderLanes(workInProgress);
19850
19851 if (current !== null) {
19852 var _nextState = workInProgress.memoizedState;
19853 var _prevState = current.memoizedState;
19854 var prevIsHidden = _prevState !== null;
19855 var nextIsHidden = _nextState !== null;
19856
19857 if (prevIsHidden !== nextIsHidden && newProps.mode !== 'unstable-defer-without-hiding') {
19858 workInProgress.flags |= Update;
19859 }
19860 }
19861
19862 return null;
19863 }
19864 }
19865
19866 {
19867 {
19868 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19869 }
19870 }
19871}
19872
19873function unwindWork(workInProgress, renderLanes) {
19874 switch (workInProgress.tag) {
19875 case ClassComponent:
19876 {
19877 var Component = workInProgress.type;
19878
19879 if (isContextProvider(Component)) {
19880 popContext(workInProgress);
19881 }
19882
19883 var flags = workInProgress.flags;
19884
19885 if (flags & ShouldCapture) {
19886 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
19887
19888 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19889 transferActualDuration(workInProgress);
19890 }
19891
19892 return workInProgress;
19893 }
19894
19895 return null;
19896 }
19897
19898 case HostRoot:
19899 {
19900 popHostContainer(workInProgress);
19901 popTopLevelContextObject(workInProgress);
19902 resetWorkInProgressVersions();
19903 var _flags = workInProgress.flags;
19904
19905 if (!((_flags & DidCapture) === NoFlags)) {
19906 {
19907 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
19908 }
19909 }
19910
19911 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
19912 return workInProgress;
19913 }
19914
19915 case HostComponent:
19916 {
19917 // TODO: popHydrationState
19918 popHostContext(workInProgress);
19919 return null;
19920 }
19921
19922 case SuspenseComponent:
19923 {
19924 popSuspenseContext(workInProgress);
19925
19926 var _flags2 = workInProgress.flags;
19927
19928 if (_flags2 & ShouldCapture) {
19929 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
19930
19931 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19932 transferActualDuration(workInProgress);
19933 }
19934
19935 return workInProgress;
19936 }
19937
19938 return null;
19939 }
19940
19941 case SuspenseListComponent:
19942 {
19943 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
19944 // caught by a nested boundary. If not, it should bubble through.
19945
19946 return null;
19947 }
19948
19949 case HostPortal:
19950 popHostContainer(workInProgress);
19951 return null;
19952
19953 case ContextProvider:
19954 popProvider(workInProgress);
19955 return null;
19956
19957 case OffscreenComponent:
19958 case LegacyHiddenComponent:
19959 popRenderLanes(workInProgress);
19960 return null;
19961
19962 default:
19963 return null;
19964 }
19965}
19966
19967function unwindInterruptedWork(interruptedWork) {
19968 switch (interruptedWork.tag) {
19969 case ClassComponent:
19970 {
19971 var childContextTypes = interruptedWork.type.childContextTypes;
19972
19973 if (childContextTypes !== null && childContextTypes !== undefined) {
19974 popContext(interruptedWork);
19975 }
19976
19977 break;
19978 }
19979
19980 case HostRoot:
19981 {
19982 popHostContainer(interruptedWork);
19983 popTopLevelContextObject(interruptedWork);
19984 resetWorkInProgressVersions();
19985 break;
19986 }
19987
19988 case HostComponent:
19989 {
19990 popHostContext(interruptedWork);
19991 break;
19992 }
19993
19994 case HostPortal:
19995 popHostContainer(interruptedWork);
19996 break;
19997
19998 case SuspenseComponent:
19999 popSuspenseContext(interruptedWork);
20000 break;
20001
20002 case SuspenseListComponent:
20003 popSuspenseContext(interruptedWork);
20004 break;
20005
20006 case ContextProvider:
20007 popProvider(interruptedWork);
20008 break;
20009
20010 case OffscreenComponent:
20011 case LegacyHiddenComponent:
20012 popRenderLanes(interruptedWork);
20013 break;
20014 }
20015}
20016
20017function createCapturedValue(value, source) {
20018 // If the value is an error, call this function immediately after it is thrown
20019 // so the stack is accurate.
20020 return {
20021 value: value,
20022 source: source,
20023 stack: getStackByFiberInDevAndProd(source)
20024 };
20025}
20026
20027// This module is forked in different environments.
20028// By default, return `true` to log errors to the console.
20029// Forks can return `false` if this isn't desirable.
20030function showErrorDialog(boundary, errorInfo) {
20031 return true;
20032}
20033
20034function logCapturedError(boundary, errorInfo) {
20035 try {
20036 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
20037 // This enables renderers like ReactNative to better manage redbox behavior.
20038
20039 if (logError === false) {
20040 return;
20041 }
20042
20043 var error = errorInfo.value;
20044
20045 if (true) {
20046 var source = errorInfo.source;
20047 var stack = errorInfo.stack;
20048 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
20049 // `preventDefault()` in window `error` handler.
20050 // We record this information as an expando on the error.
20051
20052 if (error != null && error._suppressLogging) {
20053 if (boundary.tag === ClassComponent) {
20054 // The error is recoverable and was silenced.
20055 // Ignore it and don't print the stack addendum.
20056 // This is handy for testing error boundaries without noise.
20057 return;
20058 } // The error is fatal. Since the silencing might have
20059 // been accidental, we'll surface it anyway.
20060 // However, the browser would have silenced the original error
20061 // so we'll print it first, and then print the stack addendum.
20062
20063
20064 console['error'](error); // Don't transform to our wrapper
20065 // For a more detailed description of this block, see:
20066 // https://github.com/facebook/react/pull/13384
20067 }
20068
20069 var componentName = source ? getComponentName(source.type) : null;
20070 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
20071 var errorBoundaryMessage;
20072 var errorBoundaryName = getComponentName(boundary.type);
20073
20074 if (errorBoundaryName) {
20075 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
20076 } else {
20077 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.';
20078 }
20079
20080 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
20081 // We don't include the original error message and JS stack because the browser
20082 // has already printed it. Even if the application swallows the error, it is still
20083 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
20084
20085 console['error'](combinedMessage); // Don't transform to our wrapper
20086 } else {
20087 // In production, we print the error directly.
20088 // This will include the message, the JS stack, and anything the browser wants to show.
20089 // We pass the error object instead of custom message so that the browser displays the error natively.
20090 console['error'](error); // Don't transform to our wrapper
20091 }
20092 } catch (e) {
20093 // This method must not throw, or React internal state will get messed up.
20094 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
20095 // we want to report this error outside of the normal stack as a last resort.
20096 // https://github.com/facebook/react/issues/13188
20097 setTimeout(function () {
20098 throw e;
20099 });
20100 }
20101}
20102
20103var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20104
20105function createRootErrorUpdate(fiber, errorInfo, lane) {
20106 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
20107
20108 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20109 // being called "element".
20110
20111 update.payload = {
20112 element: null
20113 };
20114 var error = errorInfo.value;
20115
20116 update.callback = function () {
20117 onUncaughtError(error);
20118 logCapturedError(fiber, errorInfo);
20119 };
20120
20121 return update;
20122}
20123
20124function createClassErrorUpdate(fiber, errorInfo, lane) {
20125 var update = createUpdate(NoTimestamp, lane);
20126 update.tag = CaptureUpdate;
20127 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20128
20129 if (typeof getDerivedStateFromError === 'function') {
20130 var error$1 = errorInfo.value;
20131
20132 update.payload = function () {
20133 logCapturedError(fiber, errorInfo);
20134 return getDerivedStateFromError(error$1);
20135 };
20136 }
20137
20138 var inst = fiber.stateNode;
20139
20140 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20141 update.callback = function callback() {
20142 {
20143 markFailedErrorBoundaryForHotReloading(fiber);
20144 }
20145
20146 if (typeof getDerivedStateFromError !== 'function') {
20147 // To preserve the preexisting retry behavior of error boundaries,
20148 // we keep track of which ones already failed during this batch.
20149 // This gets reset before we yield back to the browser.
20150 // TODO: Warn in strict mode if getDerivedStateFromError is
20151 // not defined.
20152 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
20153
20154 logCapturedError(fiber, errorInfo);
20155 }
20156
20157 var error$1 = errorInfo.value;
20158 var stack = errorInfo.stack;
20159 this.componentDidCatch(error$1, {
20160 componentStack: stack !== null ? stack : ''
20161 });
20162
20163 {
20164 if (typeof getDerivedStateFromError !== 'function') {
20165 // If componentDidCatch is the only error boundary method defined,
20166 // then it needs to call setState to recover from errors.
20167 // If no state update is scheduled then the boundary will swallow the error.
20168 if (!includesSomeLane(fiber.lanes, SyncLane)) {
20169 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
20170 }
20171 }
20172 }
20173 };
20174 } else {
20175 update.callback = function () {
20176 markFailedErrorBoundaryForHotReloading(fiber);
20177 };
20178 }
20179
20180 return update;
20181}
20182
20183function attachPingListener(root, wakeable, lanes) {
20184 // Attach a listener to the promise to "ping" the root and retry. But only if
20185 // one does not already exist for the lanes we're currently rendering (which
20186 // acts like a "thread ID" here).
20187 var pingCache = root.pingCache;
20188 var threadIDs;
20189
20190 if (pingCache === null) {
20191 pingCache = root.pingCache = new PossiblyWeakMap$1();
20192 threadIDs = new Set();
20193 pingCache.set(wakeable, threadIDs);
20194 } else {
20195 threadIDs = pingCache.get(wakeable);
20196
20197 if (threadIDs === undefined) {
20198 threadIDs = new Set();
20199 pingCache.set(wakeable, threadIDs);
20200 }
20201 }
20202
20203 if (!threadIDs.has(lanes)) {
20204 // Memoize using the thread ID to prevent redundant listeners.
20205 threadIDs.add(lanes);
20206 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
20207 wakeable.then(ping, ping);
20208 }
20209}
20210
20211function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
20212 // The source fiber did not complete.
20213 sourceFiber.flags |= Incomplete; // Its effect list is no longer valid.
20214
20215 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20216
20217 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20218 // This is a wakeable.
20219 var wakeable = value;
20220
20221 if ((sourceFiber.mode & BlockingMode) === NoMode) {
20222 // Reset the memoizedState to what it was before we attempted
20223 // to render it.
20224 var currentSource = sourceFiber.alternate;
20225
20226 if (currentSource) {
20227 sourceFiber.updateQueue = currentSource.updateQueue;
20228 sourceFiber.memoizedState = currentSource.memoizedState;
20229 sourceFiber.lanes = currentSource.lanes;
20230 } else {
20231 sourceFiber.updateQueue = null;
20232 sourceFiber.memoizedState = null;
20233 }
20234 }
20235
20236 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
20237
20238 var _workInProgress = returnFiber;
20239
20240 do {
20241 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
20242 // Found the nearest boundary.
20243 // Stash the promise on the boundary fiber. If the boundary times out, we'll
20244 // attach another listener to flip the boundary back to its normal state.
20245 var wakeables = _workInProgress.updateQueue;
20246
20247 if (wakeables === null) {
20248 var updateQueue = new Set();
20249 updateQueue.add(wakeable);
20250 _workInProgress.updateQueue = updateQueue;
20251 } else {
20252 wakeables.add(wakeable);
20253 } // If the boundary is outside of blocking mode, we should *not*
20254 // suspend the commit. Pretend as if the suspended component rendered
20255 // null and keep rendering. In the commit phase, we'll schedule a
20256 // subsequent synchronous update to re-render the Suspense.
20257 //
20258 // Note: It doesn't matter whether the component that suspended was
20259 // inside a blocking mode tree. If the Suspense is outside of it, we
20260 // should *not* suspend the commit.
20261
20262
20263 if ((_workInProgress.mode & BlockingMode) === NoMode) {
20264 _workInProgress.flags |= DidCapture;
20265 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
20266 // But we shouldn't call any lifecycle methods or callbacks. Remove
20267 // all lifecycle effect tags.
20268
20269 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
20270
20271 if (sourceFiber.tag === ClassComponent) {
20272 var currentSourceFiber = sourceFiber.alternate;
20273
20274 if (currentSourceFiber === null) {
20275 // This is a new mount. Change the tag so it's not mistaken for a
20276 // completed class component. For example, we should not call
20277 // componentWillUnmount if it is deleted.
20278 sourceFiber.tag = IncompleteClassComponent;
20279 } else {
20280 // When we try rendering again, we should not reuse the current fiber,
20281 // since it's known to be in an inconsistent state. Use a force update to
20282 // prevent a bail out.
20283 var update = createUpdate(NoTimestamp, SyncLane);
20284 update.tag = ForceUpdate;
20285 enqueueUpdate(sourceFiber, update);
20286 }
20287 } // The source fiber did not complete. Mark it with Sync priority to
20288 // indicate that it still has pending work.
20289
20290
20291 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending.
20292
20293 return;
20294 } // Confirmed that the boundary is in a concurrent mode tree. Continue
20295 // with the normal suspend path.
20296 //
20297 // After this we'll use a set of heuristics to determine whether this
20298 // render pass will run to completion or restart or "suspend" the commit.
20299 // The actual logic for this is spread out in different places.
20300 //
20301 // This first principle is that if we're going to suspend when we complete
20302 // a root, then we should also restart if we get an update or ping that
20303 // might unsuspend it, and vice versa. The only reason to suspend is
20304 // because you think you might want to restart before committing. However,
20305 // it doesn't make sense to restart only while in the period we're suspended.
20306 //
20307 // Restarting too aggressively is also not good because it starves out any
20308 // intermediate loading state. So we use heuristics to determine when.
20309 // Suspense Heuristics
20310 //
20311 // If nothing threw a Promise or all the same fallbacks are already showing,
20312 // then don't suspend/restart.
20313 //
20314 // If this is an initial render of a new tree of Suspense boundaries and
20315 // those trigger a fallback, then don't suspend/restart. We want to ensure
20316 // that we can show the initial loading state as quickly as possible.
20317 //
20318 // If we hit a "Delayed" case, such as when we'd switch from content back into
20319 // a fallback, then we should always suspend/restart. Transitions apply
20320 // to this case. If none is defined, JND is used instead.
20321 //
20322 // If we're already showing a fallback and it gets "retried", allowing us to show
20323 // another level, but there's still an inner boundary that would show a fallback,
20324 // then we suspend/restart for 500ms since the last time we showed a fallback
20325 // anywhere in the tree. This effectively throttles progressive loading into a
20326 // consistent train of commits. This also gives us an opportunity to restart to
20327 // get to the completed state slightly earlier.
20328 //
20329 // If there's ambiguity due to batching it's resolved in preference of:
20330 // 1) "delayed", 2) "initial render", 3) "retry".
20331 //
20332 // We want to ensure that a "busy" state doesn't get force committed. We want to
20333 // ensure that new initial loading states can commit as soon as possible.
20334
20335
20336 attachPingListener(root, wakeable, rootRenderLanes);
20337 _workInProgress.flags |= ShouldCapture;
20338 _workInProgress.lanes = rootRenderLanes;
20339 return;
20340 } // This boundary already captured during this render. Continue to the next
20341 // boundary.
20342
20343
20344 _workInProgress = _workInProgress.return;
20345 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
20346 // TODO: Use invariant so the message is stripped in prod?
20347
20348
20349 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.');
20350 } // We didn't find a boundary that could handle this type of exception. Start
20351 // over and traverse parent path again, this time treating the exception
20352 // as an error.
20353
20354
20355 renderDidError();
20356 value = createCapturedValue(value, sourceFiber);
20357 var workInProgress = returnFiber;
20358
20359 do {
20360 switch (workInProgress.tag) {
20361 case HostRoot:
20362 {
20363 var _errorInfo = value;
20364 workInProgress.flags |= ShouldCapture;
20365 var lane = pickArbitraryLane(rootRenderLanes);
20366 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
20367
20368 var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
20369
20370 enqueueCapturedUpdate(workInProgress, _update);
20371 return;
20372 }
20373
20374 case ClassComponent:
20375 // Capture and retry
20376 var errorInfo = value;
20377 var ctor = workInProgress.type;
20378 var instance = workInProgress.stateNode;
20379
20380 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
20381 workInProgress.flags |= ShouldCapture;
20382
20383 var _lane = pickArbitraryLane(rootRenderLanes);
20384
20385 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
20386
20387 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, _lane);
20388
20389 enqueueCapturedUpdate(workInProgress, _update2);
20390 return;
20391 }
20392
20393 break;
20394 }
20395
20396 workInProgress = workInProgress.return;
20397 } while (workInProgress !== null);
20398}
20399
20400var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
20401
20402{
20403 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
20404}
20405
20406var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
20407
20408var callComponentWillUnmountWithTimer = function (current, instance) {
20409 instance.props = current.memoizedProps;
20410 instance.state = current.memoizedState;
20411
20412 {
20413 instance.componentWillUnmount();
20414 }
20415}; // Capture errors so they don't interrupt unmounting.
20416
20417
20418function safelyCallComponentWillUnmount(current, instance) {
20419 {
20420 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
20421
20422 if (hasCaughtError()) {
20423 var unmountError = clearCaughtError();
20424 captureCommitPhaseError(current, unmountError);
20425 }
20426 }
20427}
20428
20429function safelyDetachRef(current) {
20430 var ref = current.ref;
20431
20432 if (ref !== null) {
20433 if (typeof ref === 'function') {
20434 {
20435 invokeGuardedCallback(null, ref, null, null);
20436
20437 if (hasCaughtError()) {
20438 var refError = clearCaughtError();
20439 captureCommitPhaseError(current, refError);
20440 }
20441 }
20442 } else {
20443 ref.current = null;
20444 }
20445 }
20446}
20447
20448function safelyCallDestroy(current, destroy) {
20449 {
20450 invokeGuardedCallback(null, destroy, null);
20451
20452 if (hasCaughtError()) {
20453 var error = clearCaughtError();
20454 captureCommitPhaseError(current, error);
20455 }
20456 }
20457}
20458
20459function commitBeforeMutationLifeCycles(current, finishedWork) {
20460 switch (finishedWork.tag) {
20461 case FunctionComponent:
20462 case ForwardRef:
20463 case SimpleMemoComponent:
20464 case Block:
20465 {
20466 return;
20467 }
20468
20469 case ClassComponent:
20470 {
20471 if (finishedWork.flags & Snapshot) {
20472 if (current !== null) {
20473 var prevProps = current.memoizedProps;
20474 var prevState = current.memoizedState;
20475 var instance = finishedWork.stateNode; // We could update instance props and state here,
20476 // but instead we rely on them being set during last render.
20477 // TODO: revisit this when we implement resuming.
20478
20479 {
20480 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20481 if (instance.props !== finishedWork.memoizedProps) {
20482 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20483 }
20484
20485 if (instance.state !== finishedWork.memoizedState) {
20486 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20487 }
20488 }
20489 }
20490
20491 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
20492
20493 {
20494 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
20495
20496 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
20497 didWarnSet.add(finishedWork.type);
20498
20499 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
20500 }
20501 }
20502
20503 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
20504 }
20505 }
20506
20507 return;
20508 }
20509
20510 case HostRoot:
20511 {
20512 {
20513 if (finishedWork.flags & Snapshot) {
20514 var root = finishedWork.stateNode;
20515 clearContainer(root.containerInfo);
20516 }
20517 }
20518
20519 return;
20520 }
20521
20522 case HostComponent:
20523 case HostText:
20524 case HostPortal:
20525 case IncompleteClassComponent:
20526 // Nothing to do for these component types
20527 return;
20528 }
20529
20530 {
20531 {
20532 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
20533 }
20534 }
20535}
20536
20537function commitHookEffectListUnmount(tag, finishedWork) {
20538 var updateQueue = finishedWork.updateQueue;
20539 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20540
20541 if (lastEffect !== null) {
20542 var firstEffect = lastEffect.next;
20543 var effect = firstEffect;
20544
20545 do {
20546 if ((effect.tag & tag) === tag) {
20547 // Unmount
20548 var destroy = effect.destroy;
20549 effect.destroy = undefined;
20550
20551 if (destroy !== undefined) {
20552 destroy();
20553 }
20554 }
20555
20556 effect = effect.next;
20557 } while (effect !== firstEffect);
20558 }
20559}
20560
20561function commitHookEffectListMount(tag, finishedWork) {
20562 var updateQueue = finishedWork.updateQueue;
20563 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20564
20565 if (lastEffect !== null) {
20566 var firstEffect = lastEffect.next;
20567 var effect = firstEffect;
20568
20569 do {
20570 if ((effect.tag & tag) === tag) {
20571 // Mount
20572 var create = effect.create;
20573 effect.destroy = create();
20574
20575 {
20576 var destroy = effect.destroy;
20577
20578 if (destroy !== undefined && typeof destroy !== 'function') {
20579 var addendum = void 0;
20580
20581 if (destroy === null) {
20582 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
20583 } else if (typeof destroy.then === 'function') {
20584 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching';
20585 } else {
20586 addendum = ' You returned: ' + destroy;
20587 }
20588
20589 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s', addendum);
20590 }
20591 }
20592 }
20593
20594 effect = effect.next;
20595 } while (effect !== firstEffect);
20596 }
20597}
20598
20599function schedulePassiveEffects(finishedWork) {
20600 var updateQueue = finishedWork.updateQueue;
20601 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20602
20603 if (lastEffect !== null) {
20604 var firstEffect = lastEffect.next;
20605 var effect = firstEffect;
20606
20607 do {
20608 var _effect = effect,
20609 next = _effect.next,
20610 tag = _effect.tag;
20611
20612 if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) {
20613 enqueuePendingPassiveHookEffectUnmount(finishedWork, effect);
20614 enqueuePendingPassiveHookEffectMount(finishedWork, effect);
20615 }
20616
20617 effect = next;
20618 } while (effect !== firstEffect);
20619 }
20620}
20621
20622function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) {
20623 switch (finishedWork.tag) {
20624 case FunctionComponent:
20625 case ForwardRef:
20626 case SimpleMemoComponent:
20627 case Block:
20628 {
20629 // At this point layout effects have already been destroyed (during mutation phase).
20630 // This is done to prevent sibling component effects from interfering with each other,
20631 // e.g. a destroy function in one component should never override a ref set
20632 // by a create function in another component during the same commit.
20633 {
20634 commitHookEffectListMount(Layout | HasEffect, finishedWork);
20635 }
20636
20637 schedulePassiveEffects(finishedWork);
20638 return;
20639 }
20640
20641 case ClassComponent:
20642 {
20643 var instance = finishedWork.stateNode;
20644
20645 if (finishedWork.flags & Update) {
20646 if (current === null) {
20647 // We could update instance props and state here,
20648 // but instead we rely on them being set during last render.
20649 // TODO: revisit this when we implement resuming.
20650 {
20651 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20652 if (instance.props !== finishedWork.memoizedProps) {
20653 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20654 }
20655
20656 if (instance.state !== finishedWork.memoizedState) {
20657 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20658 }
20659 }
20660 }
20661
20662 {
20663 instance.componentDidMount();
20664 }
20665 } else {
20666 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
20667 var prevState = current.memoizedState; // We could update instance props and state here,
20668 // but instead we rely on them being set during last render.
20669 // TODO: revisit this when we implement resuming.
20670
20671 {
20672 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20673 if (instance.props !== finishedWork.memoizedProps) {
20674 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20675 }
20676
20677 if (instance.state !== finishedWork.memoizedState) {
20678 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20679 }
20680 }
20681 }
20682
20683 {
20684 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
20685 }
20686 }
20687 } // TODO: I think this is now always non-null by the time it reaches the
20688 // commit phase. Consider removing the type check.
20689
20690
20691 var updateQueue = finishedWork.updateQueue;
20692
20693 if (updateQueue !== null) {
20694 {
20695 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20696 if (instance.props !== finishedWork.memoizedProps) {
20697 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20698 }
20699
20700 if (instance.state !== finishedWork.memoizedState) {
20701 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
20702 }
20703 }
20704 } // We could update instance props and state here,
20705 // but instead we rely on them being set during last render.
20706 // TODO: revisit this when we implement resuming.
20707
20708
20709 commitUpdateQueue(finishedWork, updateQueue, instance);
20710 }
20711
20712 return;
20713 }
20714
20715 case HostRoot:
20716 {
20717 // TODO: I think this is now always non-null by the time it reaches the
20718 // commit phase. Consider removing the type check.
20719 var _updateQueue = finishedWork.updateQueue;
20720
20721 if (_updateQueue !== null) {
20722 var _instance = null;
20723
20724 if (finishedWork.child !== null) {
20725 switch (finishedWork.child.tag) {
20726 case HostComponent:
20727 _instance = getPublicInstance(finishedWork.child.stateNode);
20728 break;
20729
20730 case ClassComponent:
20731 _instance = finishedWork.child.stateNode;
20732 break;
20733 }
20734 }
20735
20736 commitUpdateQueue(finishedWork, _updateQueue, _instance);
20737 }
20738
20739 return;
20740 }
20741
20742 case HostComponent:
20743 {
20744 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
20745 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20746 // These effects should only be committed when components are first mounted,
20747 // aka when there is no current/alternate.
20748
20749 if (current === null && finishedWork.flags & Update) {
20750 var type = finishedWork.type;
20751 var props = finishedWork.memoizedProps;
20752 commitMount(_instance2, type, props);
20753 }
20754
20755 return;
20756 }
20757
20758 case HostText:
20759 {
20760 // We have no life-cycles associated with text.
20761 return;
20762 }
20763
20764 case HostPortal:
20765 {
20766 // We have no life-cycles associated with portals.
20767 return;
20768 }
20769
20770 case Profiler:
20771 {
20772 {
20773 var _finishedWork$memoize2 = finishedWork.memoizedProps,
20774 onCommit = _finishedWork$memoize2.onCommit,
20775 onRender = _finishedWork$memoize2.onRender;
20776 var effectDuration = finishedWork.stateNode.effectDuration;
20777 var commitTime = getCommitTime();
20778
20779 if (typeof onRender === 'function') {
20780 {
20781 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime, finishedRoot.memoizedInteractions);
20782 }
20783 }
20784 }
20785
20786 return;
20787 }
20788
20789 case SuspenseComponent:
20790 {
20791 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
20792 return;
20793 }
20794
20795 case SuspenseListComponent:
20796 case IncompleteClassComponent:
20797 case FundamentalComponent:
20798 case ScopeComponent:
20799 case OffscreenComponent:
20800 case LegacyHiddenComponent:
20801 return;
20802 }
20803
20804 {
20805 {
20806 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
20807 }
20808 }
20809}
20810
20811function hideOrUnhideAllChildren(finishedWork, isHidden) {
20812 {
20813 // We only have the top Fiber that was inserted but we need to recurse down its
20814 // children to find all the terminal nodes.
20815 var node = finishedWork;
20816
20817 while (true) {
20818 if (node.tag === HostComponent) {
20819 var instance = node.stateNode;
20820
20821 if (isHidden) {
20822 hideInstance(instance);
20823 } else {
20824 unhideInstance(node.stateNode, node.memoizedProps);
20825 }
20826 } else if (node.tag === HostText) {
20827 var _instance3 = node.stateNode;
20828
20829 if (isHidden) {
20830 hideTextInstance(_instance3);
20831 } else {
20832 unhideTextInstance(_instance3, node.memoizedProps);
20833 }
20834 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
20835 node.child.return = node;
20836 node = node.child;
20837 continue;
20838 }
20839
20840 if (node === finishedWork) {
20841 return;
20842 }
20843
20844 while (node.sibling === null) {
20845 if (node.return === null || node.return === finishedWork) {
20846 return;
20847 }
20848
20849 node = node.return;
20850 }
20851
20852 node.sibling.return = node.return;
20853 node = node.sibling;
20854 }
20855 }
20856}
20857
20858function commitAttachRef(finishedWork) {
20859 var ref = finishedWork.ref;
20860
20861 if (ref !== null) {
20862 var instance = finishedWork.stateNode;
20863 var instanceToUse;
20864
20865 switch (finishedWork.tag) {
20866 case HostComponent:
20867 instanceToUse = getPublicInstance(instance);
20868 break;
20869
20870 default:
20871 instanceToUse = instance;
20872 } // Moved outside to ensure DCE works with this flag
20873
20874 if (typeof ref === 'function') {
20875 ref(instanceToUse);
20876 } else {
20877 {
20878 if (!ref.hasOwnProperty('current')) {
20879 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentName(finishedWork.type));
20880 }
20881 }
20882
20883 ref.current = instanceToUse;
20884 }
20885 }
20886}
20887
20888function commitDetachRef(current) {
20889 var currentRef = current.ref;
20890
20891 if (currentRef !== null) {
20892 if (typeof currentRef === 'function') {
20893 currentRef(null);
20894 } else {
20895 currentRef.current = null;
20896 }
20897 }
20898} // User-originating errors (lifecycles and refs) should not interrupt
20899// deletion, so don't let them throw. Host-originating errors should
20900// interrupt deletion, so it's okay
20901
20902
20903function commitUnmount(finishedRoot, current, renderPriorityLevel) {
20904 onCommitUnmount(current);
20905
20906 switch (current.tag) {
20907 case FunctionComponent:
20908 case ForwardRef:
20909 case MemoComponent:
20910 case SimpleMemoComponent:
20911 case Block:
20912 {
20913 var updateQueue = current.updateQueue;
20914
20915 if (updateQueue !== null) {
20916 var lastEffect = updateQueue.lastEffect;
20917
20918 if (lastEffect !== null) {
20919 var firstEffect = lastEffect.next;
20920 var effect = firstEffect;
20921
20922 do {
20923 var _effect2 = effect,
20924 destroy = _effect2.destroy,
20925 tag = _effect2.tag;
20926
20927 if (destroy !== undefined) {
20928 if ((tag & Passive$1) !== NoFlags$1) {
20929 enqueuePendingPassiveHookEffectUnmount(current, effect);
20930 } else {
20931 {
20932 safelyCallDestroy(current, destroy);
20933 }
20934 }
20935 }
20936
20937 effect = effect.next;
20938 } while (effect !== firstEffect);
20939 }
20940 }
20941
20942 return;
20943 }
20944
20945 case ClassComponent:
20946 {
20947 safelyDetachRef(current);
20948 var instance = current.stateNode;
20949
20950 if (typeof instance.componentWillUnmount === 'function') {
20951 safelyCallComponentWillUnmount(current, instance);
20952 }
20953
20954 return;
20955 }
20956
20957 case HostComponent:
20958 {
20959 safelyDetachRef(current);
20960 return;
20961 }
20962
20963 case HostPortal:
20964 {
20965 // TODO: this is recursive.
20966 // We are also not using this parent because
20967 // the portal will get pushed immediately.
20968 {
20969 unmountHostComponents(finishedRoot, current);
20970 }
20971
20972 return;
20973 }
20974
20975 case FundamentalComponent:
20976 {
20977
20978 return;
20979 }
20980
20981 case DehydratedFragment:
20982 {
20983
20984 return;
20985 }
20986
20987 case ScopeComponent:
20988 {
20989
20990 return;
20991 }
20992 }
20993}
20994
20995function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
20996 // While we're inside a removed host node we don't want to call
20997 // removeChild on the inner nodes because they're removed by the top
20998 // call anyway. We also want to call componentWillUnmount on all
20999 // composites before this host node is removed from the tree. Therefore
21000 // we do an inner loop while we're still inside the host node.
21001 var node = root;
21002
21003 while (true) {
21004 commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes.
21005 // Skip portals because commitUnmount() currently visits them recursively.
21006
21007 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
21008 // If we don't use mutation we drill down into portals here instead.
21009 node.tag !== HostPortal)) {
21010 node.child.return = node;
21011 node = node.child;
21012 continue;
21013 }
21014
21015 if (node === root) {
21016 return;
21017 }
21018
21019 while (node.sibling === null) {
21020 if (node.return === null || node.return === root) {
21021 return;
21022 }
21023
21024 node = node.return;
21025 }
21026
21027 node.sibling.return = node.return;
21028 node = node.sibling;
21029 }
21030}
21031
21032function detachFiberMutation(fiber) {
21033 // Cut off the return pointers to disconnect it from the tree. Ideally, we
21034 // should clear the child pointer of the parent alternate to let this
21035 // get GC:ed but we don't know which for sure which parent is the current
21036 // one so we'll settle for GC:ing the subtree of this child. This child
21037 // itself will be GC:ed when the parent updates the next time.
21038 // Note: we cannot null out sibling here, otherwise it can cause issues
21039 // with findDOMNode and how it requires the sibling field to carry out
21040 // traversal in a later effect. See PR #16820. We now clear the sibling
21041 // field after effects, see: detachFiberAfterEffects.
21042 //
21043 // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects.
21044 // It may be required if the current component is an error boundary,
21045 // and one of its descendants throws while unmounting a passive effect.
21046 fiber.alternate = null;
21047 fiber.child = null;
21048 fiber.dependencies = null;
21049 fiber.firstEffect = null;
21050 fiber.lastEffect = null;
21051 fiber.memoizedProps = null;
21052 fiber.memoizedState = null;
21053 fiber.pendingProps = null;
21054 fiber.return = null;
21055 fiber.updateQueue = null;
21056
21057 {
21058 fiber._debugOwner = null;
21059 }
21060}
21061
21062function getHostParentFiber(fiber) {
21063 var parent = fiber.return;
21064
21065 while (parent !== null) {
21066 if (isHostParent(parent)) {
21067 return parent;
21068 }
21069
21070 parent = parent.return;
21071 }
21072
21073 {
21074 {
21075 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
21076 }
21077 }
21078}
21079
21080function isHostParent(fiber) {
21081 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
21082}
21083
21084function getHostSibling(fiber) {
21085 // We're going to search forward into the tree until we find a sibling host
21086 // node. Unfortunately, if multiple insertions are done in a row we have to
21087 // search past them. This leads to exponential search for the next sibling.
21088 // TODO: Find a more efficient way to do this.
21089 var node = fiber;
21090
21091 siblings: while (true) {
21092 // If we didn't find anything, let's try the next sibling.
21093 while (node.sibling === null) {
21094 if (node.return === null || isHostParent(node.return)) {
21095 // If we pop out of the root or hit the parent the fiber we are the
21096 // last sibling.
21097 return null;
21098 }
21099
21100 node = node.return;
21101 }
21102
21103 node.sibling.return = node.return;
21104 node = node.sibling;
21105
21106 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
21107 // If it is not host node and, we might have a host node inside it.
21108 // Try to search down until we find one.
21109 if (node.flags & Placement) {
21110 // If we don't have a child, try the siblings instead.
21111 continue siblings;
21112 } // If we don't have a child, try the siblings instead.
21113 // We also skip portals because they are not part of this host tree.
21114
21115
21116 if (node.child === null || node.tag === HostPortal) {
21117 continue siblings;
21118 } else {
21119 node.child.return = node;
21120 node = node.child;
21121 }
21122 } // Check if this host node is stable or about to be placed.
21123
21124
21125 if (!(node.flags & Placement)) {
21126 // Found it!
21127 return node.stateNode;
21128 }
21129 }
21130}
21131
21132function commitPlacement(finishedWork) {
21133
21134
21135 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
21136
21137 var parent;
21138 var isContainer;
21139 var parentStateNode = parentFiber.stateNode;
21140
21141 switch (parentFiber.tag) {
21142 case HostComponent:
21143 parent = parentStateNode;
21144 isContainer = false;
21145 break;
21146
21147 case HostRoot:
21148 parent = parentStateNode.containerInfo;
21149 isContainer = true;
21150 break;
21151
21152 case HostPortal:
21153 parent = parentStateNode.containerInfo;
21154 isContainer = true;
21155 break;
21156
21157 case FundamentalComponent:
21158
21159 // eslint-disable-next-line-no-fallthrough
21160
21161 default:
21162 {
21163 {
21164 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
21165 }
21166 }
21167
21168 }
21169
21170 if (parentFiber.flags & ContentReset) {
21171 // Reset the text content of the parent before doing any insertions
21172 resetTextContent(parent); // Clear ContentReset from the effect tag
21173
21174 parentFiber.flags &= ~ContentReset;
21175 }
21176
21177 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
21178 // children to find all the terminal nodes.
21179
21180 if (isContainer) {
21181 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
21182 } else {
21183 insertOrAppendPlacementNode(finishedWork, before, parent);
21184 }
21185}
21186
21187function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
21188 var tag = node.tag;
21189 var isHost = tag === HostComponent || tag === HostText;
21190
21191 if (isHost || enableFundamentalAPI ) {
21192 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
21193
21194 if (before) {
21195 insertInContainerBefore(parent, stateNode, before);
21196 } else {
21197 appendChildToContainer(parent, stateNode);
21198 }
21199 } else if (tag === HostPortal) ; else {
21200 var child = node.child;
21201
21202 if (child !== null) {
21203 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
21204 var sibling = child.sibling;
21205
21206 while (sibling !== null) {
21207 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
21208 sibling = sibling.sibling;
21209 }
21210 }
21211 }
21212}
21213
21214function insertOrAppendPlacementNode(node, before, parent) {
21215 var tag = node.tag;
21216 var isHost = tag === HostComponent || tag === HostText;
21217
21218 if (isHost || enableFundamentalAPI ) {
21219 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
21220
21221 if (before) {
21222 insertBefore(parent, stateNode, before);
21223 } else {
21224 appendChild(parent, stateNode);
21225 }
21226 } else if (tag === HostPortal) ; else {
21227 var child = node.child;
21228
21229 if (child !== null) {
21230 insertOrAppendPlacementNode(child, before, parent);
21231 var sibling = child.sibling;
21232
21233 while (sibling !== null) {
21234 insertOrAppendPlacementNode(sibling, before, parent);
21235 sibling = sibling.sibling;
21236 }
21237 }
21238 }
21239}
21240
21241function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
21242 // We only have the top Fiber that was deleted but we need to recurse down its
21243 // children to find all the terminal nodes.
21244 var node = current; // Each iteration, currentParent is populated with node's host parent if not
21245 // currentParentIsValid.
21246
21247 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
21248
21249 var currentParent;
21250 var currentParentIsContainer;
21251
21252 while (true) {
21253 if (!currentParentIsValid) {
21254 var parent = node.return;
21255
21256 findParent: while (true) {
21257 if (!(parent !== null)) {
21258 {
21259 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
21260 }
21261 }
21262
21263 var parentStateNode = parent.stateNode;
21264
21265 switch (parent.tag) {
21266 case HostComponent:
21267 currentParent = parentStateNode;
21268 currentParentIsContainer = false;
21269 break findParent;
21270
21271 case HostRoot:
21272 currentParent = parentStateNode.containerInfo;
21273 currentParentIsContainer = true;
21274 break findParent;
21275
21276 case HostPortal:
21277 currentParent = parentStateNode.containerInfo;
21278 currentParentIsContainer = true;
21279 break findParent;
21280
21281 }
21282
21283 parent = parent.return;
21284 }
21285
21286 currentParentIsValid = true;
21287 }
21288
21289 if (node.tag === HostComponent || node.tag === HostText) {
21290 commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the
21291 // node from the tree.
21292
21293 if (currentParentIsContainer) {
21294 removeChildFromContainer(currentParent, node.stateNode);
21295 } else {
21296 removeChild(currentParent, node.stateNode);
21297 } // Don't visit children because we already visited them.
21298
21299 } else if (node.tag === HostPortal) {
21300 if (node.child !== null) {
21301 // When we go into a portal, it becomes the parent to remove from.
21302 // We will reassign it back when we pop the portal on the way up.
21303 currentParent = node.stateNode.containerInfo;
21304 currentParentIsContainer = true; // Visit children because portals might contain host components.
21305
21306 node.child.return = node;
21307 node = node.child;
21308 continue;
21309 }
21310 } else {
21311 commitUnmount(finishedRoot, node); // Visit children because we may find more host components below.
21312
21313 if (node.child !== null) {
21314 node.child.return = node;
21315 node = node.child;
21316 continue;
21317 }
21318 }
21319
21320 if (node === current) {
21321 return;
21322 }
21323
21324 while (node.sibling === null) {
21325 if (node.return === null || node.return === current) {
21326 return;
21327 }
21328
21329 node = node.return;
21330
21331 if (node.tag === HostPortal) {
21332 // When we go out of the portal, we need to restore the parent.
21333 // Since we don't keep a stack of them, we will search for it.
21334 currentParentIsValid = false;
21335 }
21336 }
21337
21338 node.sibling.return = node.return;
21339 node = node.sibling;
21340 }
21341}
21342
21343function commitDeletion(finishedRoot, current, renderPriorityLevel) {
21344 {
21345 // Recursively delete all host nodes from the parent.
21346 // Detach refs and call componentWillUnmount() on the whole subtree.
21347 unmountHostComponents(finishedRoot, current);
21348 }
21349
21350 var alternate = current.alternate;
21351 detachFiberMutation(current);
21352
21353 if (alternate !== null) {
21354 detachFiberMutation(alternate);
21355 }
21356}
21357
21358function commitWork(current, finishedWork) {
21359
21360 switch (finishedWork.tag) {
21361 case FunctionComponent:
21362 case ForwardRef:
21363 case MemoComponent:
21364 case SimpleMemoComponent:
21365 case Block:
21366 {
21367 // Layout effects are destroyed during the mutation phase so that all
21368 // destroy functions for all fibers are called before any create functions.
21369 // This prevents sibling component effects from interfering with each other,
21370 // e.g. a destroy function in one component should never override a ref set
21371 // by a create function in another component during the same commit.
21372 {
21373 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
21374 }
21375
21376 return;
21377 }
21378
21379 case ClassComponent:
21380 {
21381 return;
21382 }
21383
21384 case HostComponent:
21385 {
21386 var instance = finishedWork.stateNode;
21387
21388 if (instance != null) {
21389 // Commit the work prepared earlier.
21390 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
21391 // as the newProps. The updatePayload will contain the real change in
21392 // this case.
21393
21394 var oldProps = current !== null ? current.memoizedProps : newProps;
21395 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
21396
21397 var updatePayload = finishedWork.updateQueue;
21398 finishedWork.updateQueue = null;
21399
21400 if (updatePayload !== null) {
21401 commitUpdate(instance, updatePayload, type, oldProps, newProps);
21402 }
21403 }
21404
21405 return;
21406 }
21407
21408 case HostText:
21409 {
21410 if (!(finishedWork.stateNode !== null)) {
21411 {
21412 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
21413 }
21414 }
21415
21416 var textInstance = finishedWork.stateNode;
21417 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
21418 // as the newProps. The updatePayload will contain the real change in
21419 // this case.
21420
21421 var oldText = current !== null ? current.memoizedProps : newText;
21422 commitTextUpdate(textInstance, oldText, newText);
21423 return;
21424 }
21425
21426 case HostRoot:
21427 {
21428 {
21429 var _root = finishedWork.stateNode;
21430
21431 if (_root.hydrate) {
21432 // We've just hydrated. No need to hydrate again.
21433 _root.hydrate = false;
21434 commitHydratedContainer(_root.containerInfo);
21435 }
21436 }
21437
21438 return;
21439 }
21440
21441 case Profiler:
21442 {
21443 return;
21444 }
21445
21446 case SuspenseComponent:
21447 {
21448 commitSuspenseComponent(finishedWork);
21449 attachSuspenseRetryListeners(finishedWork);
21450 return;
21451 }
21452
21453 case SuspenseListComponent:
21454 {
21455 attachSuspenseRetryListeners(finishedWork);
21456 return;
21457 }
21458
21459 case IncompleteClassComponent:
21460 {
21461 return;
21462 }
21463
21464 case FundamentalComponent:
21465 {
21466
21467 break;
21468 }
21469
21470 case ScopeComponent:
21471 {
21472
21473 break;
21474 }
21475
21476 case OffscreenComponent:
21477 case LegacyHiddenComponent:
21478 {
21479 var newState = finishedWork.memoizedState;
21480 var isHidden = newState !== null;
21481 hideOrUnhideAllChildren(finishedWork, isHidden);
21482 return;
21483 }
21484 }
21485
21486 {
21487 {
21488 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
21489 }
21490 }
21491}
21492
21493function commitSuspenseComponent(finishedWork) {
21494 var newState = finishedWork.memoizedState;
21495
21496 if (newState !== null) {
21497 markCommitTimeOfFallback();
21498
21499 {
21500 // Hide the Offscreen component that contains the primary children. TODO:
21501 // Ideally, this effect would have been scheduled on the Offscreen fiber
21502 // itself. That's how unhiding works: the Offscreen component schedules an
21503 // effect on itself. However, in this case, the component didn't complete,
21504 // so the fiber was never added to the effect list in the normal path. We
21505 // could have appended it to the effect list in the Suspense component's
21506 // second pass, but doing it this way is less complicated. This would be
21507 // simpler if we got rid of the effect list and traversed the tree, like
21508 // we're planning to do.
21509 var primaryChildParent = finishedWork.child;
21510 hideOrUnhideAllChildren(primaryChildParent, true);
21511 }
21512 }
21513}
21514
21515function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
21516
21517 var newState = finishedWork.memoizedState;
21518
21519 if (newState === null) {
21520 var current = finishedWork.alternate;
21521
21522 if (current !== null) {
21523 var prevState = current.memoizedState;
21524
21525 if (prevState !== null) {
21526 var suspenseInstance = prevState.dehydrated;
21527
21528 if (suspenseInstance !== null) {
21529 commitHydratedSuspenseInstance(suspenseInstance);
21530 }
21531 }
21532 }
21533 }
21534}
21535
21536function attachSuspenseRetryListeners(finishedWork) {
21537 // If this boundary just timed out, then it will have a set of wakeables.
21538 // For each wakeable, attach a listener so that when it resolves, React
21539 // attempts to re-render the boundary in the primary (pre-timeout) state.
21540 var wakeables = finishedWork.updateQueue;
21541
21542 if (wakeables !== null) {
21543 finishedWork.updateQueue = null;
21544 var retryCache = finishedWork.stateNode;
21545
21546 if (retryCache === null) {
21547 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
21548 }
21549
21550 wakeables.forEach(function (wakeable) {
21551 // Memoize using the boundary fiber to prevent redundant listeners.
21552 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
21553
21554 if (!retryCache.has(wakeable)) {
21555 {
21556 if (wakeable.__reactDoNotTraceInteractions !== true) {
21557 retry = tracing.unstable_wrap(retry);
21558 }
21559 }
21560
21561 retryCache.add(wakeable);
21562 wakeable.then(retry, retry);
21563 }
21564 });
21565 }
21566} // This function detects when a Suspense boundary goes from visible to hidden.
21567// It returns false if the boundary is already hidden.
21568// TODO: Use an effect tag.
21569
21570
21571function isSuspenseBoundaryBeingHidden(current, finishedWork) {
21572 if (current !== null) {
21573 var oldState = current.memoizedState;
21574
21575 if (oldState === null || oldState.dehydrated !== null) {
21576 var newState = finishedWork.memoizedState;
21577 return newState !== null && newState.dehydrated === null;
21578 }
21579 }
21580
21581 return false;
21582}
21583
21584function commitResetTextContent(current) {
21585
21586 resetTextContent(current.stateNode);
21587}
21588
21589var COMPONENT_TYPE = 0;
21590var HAS_PSEUDO_CLASS_TYPE = 1;
21591var ROLE_TYPE = 2;
21592var TEST_NAME_TYPE = 3;
21593var TEXT_TYPE = 4;
21594
21595if (typeof Symbol === 'function' && Symbol.for) {
21596 var symbolFor$1 = Symbol.for;
21597 COMPONENT_TYPE = symbolFor$1('selector.component');
21598 HAS_PSEUDO_CLASS_TYPE = symbolFor$1('selector.has_pseudo_class');
21599 ROLE_TYPE = symbolFor$1('selector.role');
21600 TEST_NAME_TYPE = symbolFor$1('selector.test_id');
21601 TEXT_TYPE = symbolFor$1('selector.text');
21602}
21603var commitHooks = [];
21604function onCommitRoot$1() {
21605 {
21606 commitHooks.forEach(function (commitHook) {
21607 return commitHook();
21608 });
21609 }
21610}
21611
21612var ceil = Math.ceil;
21613var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
21614 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
21615 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21616var NoContext =
21617/* */
216180;
21619var BatchedContext =
21620/* */
216211;
21622var EventContext =
21623/* */
216242;
21625var DiscreteEventContext =
21626/* */
216274;
21628var LegacyUnbatchedContext =
21629/* */
216308;
21631var RenderContext =
21632/* */
2163316;
21634var CommitContext =
21635/* */
2163632;
21637var RetryAfterError =
21638/* */
2163964;
21640var RootIncomplete = 0;
21641var RootFatalErrored = 1;
21642var RootErrored = 2;
21643var RootSuspended = 3;
21644var RootSuspendedWithDelay = 4;
21645var RootCompleted = 5; // Describes where we are in the React execution stack
21646
21647var executionContext = NoContext; // The root we're working on
21648
21649var workInProgressRoot = null; // The fiber we're working on
21650
21651var workInProgress = null; // The lanes we're rendering
21652
21653var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
21654// This is a superset of the lanes we started working on at the root. The only
21655// case where it's different from `workInProgressRootRenderLanes` is when we
21656// enter a subtree that is hidden and needs to be unhidden: Suspense and
21657// Offscreen component.
21658//
21659// Most things in the work loop should deal with workInProgressRootRenderLanes.
21660// Most things in begin/complete phases should deal with subtreeRenderLanes.
21661
21662var subtreeRenderLanes = NoLanes;
21663var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
21664
21665var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
21666
21667var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
21668// slightly different than `renderLanes` because `renderLanes` can change as you
21669// enter and exit an Offscreen tree. This value is the combination of all render
21670// lanes for the entire render phase.
21671
21672var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
21673// includes unprocessed updates, not work in bailed out children.
21674
21675var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
21676
21677var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render.
21678
21679var workInProgressRootPingedLanes = NoLanes;
21680var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train
21681// model where we don't commit new loading states in too quick succession.
21682
21683var globalMostRecentFallbackTime = 0;
21684var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
21685// more and prefer CPU suspense heuristics instead.
21686
21687var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
21688// suspense heuristics and opt out of rendering more content.
21689
21690var RENDER_TIMEOUT_MS = 500;
21691
21692function resetRenderTimer() {
21693 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
21694}
21695
21696function getRenderTargetTime() {
21697 return workInProgressRootRenderTargetTime;
21698}
21699var nextEffect = null;
21700var hasUncaughtError = false;
21701var firstUncaughtError = null;
21702var legacyErrorBoundariesThatAlreadyFailed = null;
21703var rootDoesHavePassiveEffects = false;
21704var rootWithPendingPassiveEffects = null;
21705var pendingPassiveEffectsRenderPriority = NoPriority$1;
21706var pendingPassiveEffectsLanes = NoLanes;
21707var pendingPassiveHookEffectsMount = [];
21708var pendingPassiveHookEffectsUnmount = [];
21709var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21710
21711var NESTED_UPDATE_LIMIT = 50;
21712var nestedUpdateCount = 0;
21713var rootWithNestedUpdates = null;
21714var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21715var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes
21716// during the commit phase. This enables them to be traced across components
21717// that spawn new work during render. E.g. hidden boundaries, suspended SSR
21718// hydration or SuspenseList.
21719// TODO: Can use a bitmask instead of an array
21720
21721var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their
21722// event times as simultaneous, even if the actual clock time has advanced
21723// between the first and second call.
21724
21725var currentEventTime = NoTimestamp;
21726var currentEventWipLanes = NoLanes;
21727var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed.
21728// We warn about state updates for unmounted components differently in this case.
21729
21730var isFlushingPassiveEffects = false;
21731var focusedInstanceHandle = null;
21732var shouldFireAfterActiveInstanceBlur = false;
21733function getWorkInProgressRoot() {
21734 return workInProgressRoot;
21735}
21736function requestEventTime() {
21737 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21738 // We're inside React, so it's fine to read the actual time.
21739 return now();
21740 } // We're not inside React, so we may be in the middle of a browser event.
21741
21742
21743 if (currentEventTime !== NoTimestamp) {
21744 // Use the same start time for all updates until we enter React again.
21745 return currentEventTime;
21746 } // This is the first update since React yielded. Compute a new start time.
21747
21748
21749 currentEventTime = now();
21750 return currentEventTime;
21751}
21752function requestUpdateLane(fiber) {
21753 // Special cases
21754 var mode = fiber.mode;
21755
21756 if ((mode & BlockingMode) === NoMode) {
21757 return SyncLane;
21758 } else if ((mode & ConcurrentMode) === NoMode) {
21759 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane;
21760 } // The algorithm for assigning an update to a lane should be stable for all
21761 // updates at the same priority within the same event. To do this, the inputs
21762 // to the algorithm must be the same. For example, we use the `renderLanes`
21763 // to avoid choosing a lane that is already in the middle of rendering.
21764 //
21765 // However, the "included" lanes could be mutated in between updates in the
21766 // same event, like if you perform an update inside `flushSync`. Or any other
21767 // code path that might call `prepareFreshStack`.
21768 //
21769 // The trick we use is to cache the first of each of these inputs within an
21770 // event. Then reset the cached values once we can be sure the event is over.
21771 // Our heuristic for that is whenever we enter a concurrent work loop.
21772 //
21773 // We'll do the same for `currentEventPendingLanes` below.
21774
21775
21776 if (currentEventWipLanes === NoLanes) {
21777 currentEventWipLanes = workInProgressRootIncludedLanes;
21778 }
21779
21780 var isTransition = requestCurrentTransition() !== NoTransition;
21781
21782 if (isTransition) {
21783 if (currentEventPendingLanes !== NoLanes) {
21784 currentEventPendingLanes = mostRecentlyUpdatedRoot !== null ? mostRecentlyUpdatedRoot.pendingLanes : NoLanes;
21785 }
21786
21787 return findTransitionLane(currentEventWipLanes, currentEventPendingLanes);
21788 } // TODO: Remove this dependency on the Scheduler priority.
21789 // To do that, we're replacing it with an update lane priority.
21790
21791
21792 var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler.
21793 // This couples React to the Scheduler internals, so we're replacing it
21794 // with the currentUpdateLanePriority above. As an example of how this
21795 // could be problematic, if we're not inside `Scheduler.runWithPriority`,
21796 // then we'll get the priority of the current running Scheduler task,
21797 // which is probably not what we want.
21798
21799 var lane;
21800
21801 if ( // TODO: Temporary. We're removing the concept of discrete updates.
21802 (executionContext & DiscreteEventContext) !== NoContext && schedulerPriority === UserBlockingPriority$2) {
21803 lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
21804 } else {
21805 var schedulerLanePriority = schedulerPriorityToLanePriority(schedulerPriority);
21806
21807 lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
21808 }
21809
21810 return lane;
21811}
21812
21813function requestRetryLane(fiber) {
21814 // This is a fork of `requestUpdateLane` designed specifically for Suspense
21815 // "retries" — a special update that attempts to flip a Suspense boundary
21816 // from its placeholder state to its primary/resolved state.
21817 // Special cases
21818 var mode = fiber.mode;
21819
21820 if ((mode & BlockingMode) === NoMode) {
21821 return SyncLane;
21822 } else if ((mode & ConcurrentMode) === NoMode) {
21823 return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane;
21824 } // See `requestUpdateLane` for explanation of `currentEventWipLanes`
21825
21826
21827 if (currentEventWipLanes === NoLanes) {
21828 currentEventWipLanes = workInProgressRootIncludedLanes;
21829 }
21830
21831 return findRetryLane(currentEventWipLanes);
21832}
21833
21834function scheduleUpdateOnFiber(fiber, lane, eventTime) {
21835 checkForNestedUpdates();
21836 warnAboutRenderPhaseUpdatesInDEV(fiber);
21837 var root = markUpdateLaneFromFiberToRoot(fiber, lane);
21838
21839 if (root === null) {
21840 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21841 return null;
21842 } // Mark that the root has a pending update.
21843
21844
21845 markRootUpdated(root, lane, eventTime);
21846
21847 if (root === workInProgressRoot) {
21848 // Received an update to a tree that's in the middle of rendering. Mark
21849 // that there was an interleaved update work on this root. Unless the
21850 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
21851 // phase update. In that case, we don't treat render phase updates as if
21852 // they were interleaved, for backwards compat reasons.
21853 {
21854 workInProgressRootUpdatedLanes = mergeLanes(workInProgressRootUpdatedLanes, lane);
21855 }
21856
21857 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21858 // The root already suspended with a delay, which means this render
21859 // definitely won't finish. Since we have a new update, let's mark it as
21860 // suspended now, right before marking the incoming update. This has the
21861 // effect of interrupting the current render and switching to the update.
21862 // TODO: Make sure this doesn't override pings that happen while we've
21863 // already started rendering.
21864 markRootSuspended$1(root, workInProgressRootRenderLanes);
21865 }
21866 } // TODO: requestUpdateLanePriority also reads the priority. Pass the
21867 // priority as an argument to that function and this one.
21868
21869
21870 var priorityLevel = getCurrentPriorityLevel();
21871
21872 if (lane === SyncLane) {
21873 if ( // Check if we're inside unbatchedUpdates
21874 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
21875 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21876 // Register pending interactions on the root to avoid losing traced interaction data.
21877 schedulePendingInteractions(root, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21878 // root inside of batchedUpdates should be synchronous, but layout updates
21879 // should be deferred until the end of the batch.
21880
21881 performSyncWorkOnRoot(root);
21882 } else {
21883 ensureRootIsScheduled(root, eventTime);
21884 schedulePendingInteractions(root, lane);
21885
21886 if (executionContext === NoContext) {
21887 // Flush the synchronous work now, unless we're already working or inside
21888 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21889 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21890 // without immediately flushing it. We only do this for user-initiated
21891 // updates, to preserve historical behavior of legacy mode.
21892 resetRenderTimer();
21893 flushSyncCallbackQueue();
21894 }
21895 }
21896 } else {
21897 // Schedule a discrete update but only if it's not Sync.
21898 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
21899 // discrete, even inside a discrete event.
21900 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority$1)) {
21901 // This is the result of a discrete event. Track the lowest priority
21902 // discrete update per root so we can flush them early, if needed.
21903 if (rootsWithPendingDiscreteUpdates === null) {
21904 rootsWithPendingDiscreteUpdates = new Set([root]);
21905 } else {
21906 rootsWithPendingDiscreteUpdates.add(root);
21907 }
21908 } // Schedule other updates after in case the callback is sync.
21909
21910
21911 ensureRootIsScheduled(root, eventTime);
21912 schedulePendingInteractions(root, lane);
21913 } // We use this when assigning a lane for a transition inside
21914 // `requestUpdateLane`. We assume it's the same as the root being updated,
21915 // since in the common case of a single root app it probably is. If it's not
21916 // the same root, then it's not a huge deal, we just might batch more stuff
21917 // together more than necessary.
21918
21919
21920 mostRecentlyUpdatedRoot = root;
21921} // This is split into a separate function so we can mark a fiber with pending
21922// work without treating it as a typical update that originates from an event;
21923// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21924// on a fiber.
21925
21926function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
21927 // Update the source fiber's lanes
21928 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
21929 var alternate = sourceFiber.alternate;
21930
21931 if (alternate !== null) {
21932 alternate.lanes = mergeLanes(alternate.lanes, lane);
21933 }
21934
21935 {
21936 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
21937 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
21938 }
21939 } // Walk the parent path to the root and update the child expiration time.
21940
21941
21942 var node = sourceFiber;
21943 var parent = sourceFiber.return;
21944
21945 while (parent !== null) {
21946 parent.childLanes = mergeLanes(parent.childLanes, lane);
21947 alternate = parent.alternate;
21948
21949 if (alternate !== null) {
21950 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
21951 } else {
21952 {
21953 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
21954 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
21955 }
21956 }
21957 }
21958
21959 node = parent;
21960 parent = parent.return;
21961 }
21962
21963 if (node.tag === HostRoot) {
21964 var root = node.stateNode;
21965 return root;
21966 } else {
21967 return null;
21968 }
21969} // Use this function to schedule a task for a root. There's only one task per
21970// root; if a task was already scheduled, we'll check to make sure the priority
21971// of the existing task is the same as the priority of the next level that the
21972// root has work on. This function is called on every update, and right before
21973// exiting a task.
21974
21975
21976function ensureRootIsScheduled(root, currentTime) {
21977 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
21978 // expired so we know to work on those next.
21979
21980 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
21981
21982 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call.
21983
21984 var newCallbackPriority = returnNextLanesPriority();
21985
21986 if (nextLanes === NoLanes) {
21987 // Special case: There's nothing to work on.
21988 if (existingCallbackNode !== null) {
21989 cancelCallback(existingCallbackNode);
21990 root.callbackNode = null;
21991 root.callbackPriority = NoLanePriority;
21992 }
21993
21994 return;
21995 } // Check if there's an existing task. We may be able to reuse it.
21996
21997
21998 if (existingCallbackNode !== null) {
21999 var existingCallbackPriority = root.callbackPriority;
22000
22001 if (existingCallbackPriority === newCallbackPriority) {
22002 // The priority hasn't changed. We can reuse the existing task. Exit.
22003 return;
22004 } // The priority changed. Cancel the existing callback. We'll schedule a new
22005 // one below.
22006
22007
22008 cancelCallback(existingCallbackNode);
22009 } // Schedule a new callback.
22010
22011
22012 var newCallbackNode;
22013
22014 if (newCallbackPriority === SyncLanePriority) {
22015 // Special case: Sync React callbacks are scheduled on a special
22016 // internal queue
22017 newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
22018 } else if (newCallbackPriority === SyncBatchedLanePriority) {
22019 newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root));
22020 } else {
22021 var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority);
22022 newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
22023 }
22024
22025 root.callbackPriority = newCallbackPriority;
22026 root.callbackNode = newCallbackNode;
22027} // This is the entry point for every concurrent task, i.e. anything that
22028// goes through Scheduler.
22029
22030
22031function performConcurrentWorkOnRoot(root) {
22032 // Since we know we're in a React event, we can clear the current
22033 // event time. The next update will compute a new event time.
22034 currentEventTime = NoTimestamp;
22035 currentEventWipLanes = NoLanes;
22036 currentEventPendingLanes = NoLanes;
22037
22038 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22039 {
22040 throw Error( "Should not already be working." );
22041 }
22042 } // Flush any pending passive effects before deciding which lanes to work on,
22043 // in case they schedule additional work.
22044
22045
22046 var originalCallbackNode = root.callbackNode;
22047 var didFlushPassiveEffects = flushPassiveEffects();
22048
22049 if (didFlushPassiveEffects) {
22050 // Something in the passive effect phase may have canceled the current task.
22051 // Check if the task node for this root was changed.
22052 if (root.callbackNode !== originalCallbackNode) {
22053 // The current task was canceled. Exit. We don't need to call
22054 // `ensureRootIsScheduled` because the check above implies either that
22055 // there's a new task, or that there's no remaining work on this root.
22056 return null;
22057 }
22058 } // Determine the next expiration time to work on, using the fields stored
22059 // on the root.
22060
22061
22062 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
22063
22064 if (lanes === NoLanes) {
22065 // Defensive coding. This is never expected to happen.
22066 return null;
22067 }
22068
22069 var exitStatus = renderRootConcurrent(root, lanes);
22070
22071 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {
22072 // The render included lanes that were updated during the render phase.
22073 // For example, when unhiding a hidden tree, we include all the lanes
22074 // that were previously skipped when the tree was hidden. That set of
22075 // lanes is a superset of the lanes we started rendering with.
22076 //
22077 // So we'll throw out the current work and restart.
22078 prepareFreshStack(root, NoLanes);
22079 } else if (exitStatus !== RootIncomplete) {
22080 if (exitStatus === RootErrored) {
22081 executionContext |= RetryAfterError; // If an error occurred during hydration,
22082 // discard server response and fall back to client side render.
22083
22084 if (root.hydrate) {
22085 root.hydrate = false;
22086 clearContainer(root.containerInfo);
22087 } // If something threw an error, try rendering one more time. We'll render
22088 // synchronously to block concurrent data mutations, and we'll includes
22089 // all pending updates are included. If it still fails after the second
22090 // attempt, we'll give up and commit the resulting tree.
22091
22092
22093 lanes = getLanesToRetrySynchronouslyOnError(root);
22094
22095 if (lanes !== NoLanes) {
22096 exitStatus = renderRootSync(root, lanes);
22097 }
22098 }
22099
22100 if (exitStatus === RootFatalErrored) {
22101 var fatalError = workInProgressRootFatalError;
22102 prepareFreshStack(root, NoLanes);
22103 markRootSuspended$1(root, lanes);
22104 ensureRootIsScheduled(root, now());
22105 throw fatalError;
22106 } // We now have a consistent tree. The next step is either to commit it,
22107 // or, if something suspended, wait to commit it after a timeout.
22108
22109
22110 var finishedWork = root.current.alternate;
22111 root.finishedWork = finishedWork;
22112 root.finishedLanes = lanes;
22113 finishConcurrentRender(root, exitStatus, lanes);
22114 }
22115
22116 ensureRootIsScheduled(root, now());
22117
22118 if (root.callbackNode === originalCallbackNode) {
22119 // The task node scheduled for this root is the same one that's
22120 // currently executed. Need to return a continuation.
22121 return performConcurrentWorkOnRoot.bind(null, root);
22122 }
22123
22124 return null;
22125}
22126
22127function finishConcurrentRender(root, exitStatus, lanes) {
22128 switch (exitStatus) {
22129 case RootIncomplete:
22130 case RootFatalErrored:
22131 {
22132 {
22133 {
22134 throw Error( "Root did not complete. This is a bug in React." );
22135 }
22136 }
22137 }
22138 // Flow knows about invariant, so it complains if I add a break
22139 // statement, but eslint doesn't know about invariant, so it complains
22140 // if I do. eslint-disable-next-line no-fallthrough
22141
22142 case RootErrored:
22143 {
22144 // We should have already attempted to retry this tree. If we reached
22145 // this point, it errored again. Commit it.
22146 commitRoot(root);
22147 break;
22148 }
22149
22150 case RootSuspended:
22151 {
22152 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
22153 // should immediately commit it or wait a bit.
22154
22155 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
22156 !shouldForceFlushFallbacksInDEV()) {
22157 // This render only included retries, no updates. Throttle committing
22158 // retries so that we don't show too many loading states too quickly.
22159 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
22160
22161 if (msUntilTimeout > 10) {
22162 var nextLanes = getNextLanes(root, NoLanes);
22163
22164 if (nextLanes !== NoLanes) {
22165 // There's additional work on this root.
22166 break;
22167 }
22168
22169 var suspendedLanes = root.suspendedLanes;
22170
22171 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
22172 // We should prefer to render the fallback of at the last
22173 // suspended level. Ping the last suspended level to try
22174 // rendering it again.
22175 // FIXME: What if the suspended lanes are Idle? Should not restart.
22176 var eventTime = requestEventTime();
22177 markRootPinged(root, suspendedLanes);
22178 break;
22179 } // The render is suspended, it hasn't timed out, and there's no
22180 // lower priority work to do. Instead of committing the fallback
22181 // immediately, wait for more data to arrive.
22182
22183
22184 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
22185 break;
22186 }
22187 } // The work expired. Commit immediately.
22188
22189
22190 commitRoot(root);
22191 break;
22192 }
22193
22194 case RootSuspendedWithDelay:
22195 {
22196 markRootSuspended$1(root, lanes);
22197
22198 if (includesOnlyTransitions(lanes)) {
22199 // This is a transition, so we should exit without committing a
22200 // placeholder and without scheduling a timeout. Delay indefinitely
22201 // until we receive more data.
22202 break;
22203 }
22204
22205 if (!shouldForceFlushFallbacksInDEV()) {
22206 // This is not a transition, but we did trigger an avoided state.
22207 // Schedule a placeholder to display after a short delay, using the Just
22208 // Noticeable Difference.
22209 // TODO: Is the JND optimization worth the added complexity? If this is
22210 // the only reason we track the event time, then probably not.
22211 // Consider removing.
22212 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
22213 var eventTimeMs = mostRecentEventTime;
22214 var timeElapsedMs = now() - eventTimeMs;
22215
22216 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
22217
22218
22219 if (_msUntilTimeout > 10) {
22220 // Instead of committing the fallback immediately, wait for more data
22221 // to arrive.
22222 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
22223 break;
22224 }
22225 } // Commit the placeholder.
22226
22227
22228 commitRoot(root);
22229 break;
22230 }
22231
22232 case RootCompleted:
22233 {
22234 // The work completed. Ready to commit.
22235 commitRoot(root);
22236 break;
22237 }
22238
22239 default:
22240 {
22241 {
22242 {
22243 throw Error( "Unknown root exit status." );
22244 }
22245 }
22246 }
22247 }
22248}
22249
22250function markRootSuspended$1(root, suspendedLanes) {
22251 // When suspending, we should always exclude lanes that were pinged or (more
22252 // rarely, since we try to avoid it) updated during the render phase.
22253 // TODO: Lol maybe there's a better way to factor this besides this
22254 // obnoxiously named function :)
22255 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
22256 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);
22257 markRootSuspended(root, suspendedLanes);
22258} // This is the entry point for synchronous tasks that don't go
22259// through Scheduler
22260
22261
22262function performSyncWorkOnRoot(root) {
22263 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22264 {
22265 throw Error( "Should not already be working." );
22266 }
22267 }
22268
22269 flushPassiveEffects();
22270 var lanes;
22271 var exitStatus;
22272
22273 if (root === workInProgressRoot && includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)) {
22274 // There's a partial tree, and at least one of its lanes has expired. Finish
22275 // rendering it before rendering the rest of the expired work.
22276 lanes = workInProgressRootRenderLanes;
22277 exitStatus = renderRootSync(root, lanes);
22278
22279 if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {
22280 // The render included lanes that were updated during the render phase.
22281 // For example, when unhiding a hidden tree, we include all the lanes
22282 // that were previously skipped when the tree was hidden. That set of
22283 // lanes is a superset of the lanes we started rendering with.
22284 //
22285 // Note that this only happens when part of the tree is rendered
22286 // concurrently. If the whole tree is rendered synchronously, then there
22287 // are no interleaved events.
22288 lanes = getNextLanes(root, lanes);
22289 exitStatus = renderRootSync(root, lanes);
22290 }
22291 } else {
22292 lanes = getNextLanes(root, NoLanes);
22293 exitStatus = renderRootSync(root, lanes);
22294 }
22295
22296 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
22297 executionContext |= RetryAfterError; // If an error occurred during hydration,
22298 // discard server response and fall back to client side render.
22299
22300 if (root.hydrate) {
22301 root.hydrate = false;
22302 clearContainer(root.containerInfo);
22303 } // If something threw an error, try rendering one more time. We'll render
22304 // synchronously to block concurrent data mutations, and we'll includes
22305 // all pending updates are included. If it still fails after the second
22306 // attempt, we'll give up and commit the resulting tree.
22307
22308
22309 lanes = getLanesToRetrySynchronouslyOnError(root);
22310
22311 if (lanes !== NoLanes) {
22312 exitStatus = renderRootSync(root, lanes);
22313 }
22314 }
22315
22316 if (exitStatus === RootFatalErrored) {
22317 var fatalError = workInProgressRootFatalError;
22318 prepareFreshStack(root, NoLanes);
22319 markRootSuspended$1(root, lanes);
22320 ensureRootIsScheduled(root, now());
22321 throw fatalError;
22322 } // We now have a consistent tree. Because this is a sync render, we
22323 // will commit it even if something suspended.
22324
22325
22326 var finishedWork = root.current.alternate;
22327 root.finishedWork = finishedWork;
22328 root.finishedLanes = lanes;
22329 commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next
22330 // pending level.
22331
22332 ensureRootIsScheduled(root, now());
22333 return null;
22334}
22335function flushDiscreteUpdates() {
22336 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
22337 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
22338 // those two cases. Need to fix this before exposing flushDiscreteUpdates
22339 // as a public API.
22340 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
22341 {
22342 if ((executionContext & RenderContext) !== NoContext) {
22343 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
22344 }
22345 } // We're already rendering, so we can't synchronously flush pending work.
22346 // This is probably a nested event dispatch triggered by a lifecycle/effect,
22347 // like `el.focus()`. Exit.
22348
22349
22350 return;
22351 }
22352
22353 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
22354 // they fire before the next serial event.
22355
22356 flushPassiveEffects();
22357}
22358
22359function flushPendingDiscreteUpdates() {
22360 if (rootsWithPendingDiscreteUpdates !== null) {
22361 // For each root with pending discrete updates, schedule a callback to
22362 // immediately flush them.
22363 var roots = rootsWithPendingDiscreteUpdates;
22364 rootsWithPendingDiscreteUpdates = null;
22365 roots.forEach(function (root) {
22366 markDiscreteUpdatesExpired(root);
22367 ensureRootIsScheduled(root, now());
22368 });
22369 } // Now flush the immediate queue.
22370
22371
22372 flushSyncCallbackQueue();
22373}
22374
22375function batchedUpdates$1(fn, a) {
22376 var prevExecutionContext = executionContext;
22377 executionContext |= BatchedContext;
22378
22379 try {
22380 return fn(a);
22381 } finally {
22382 executionContext = prevExecutionContext;
22383
22384 if (executionContext === NoContext) {
22385 // Flush the immediate callbacks that were scheduled during this batch
22386 resetRenderTimer();
22387 flushSyncCallbackQueue();
22388 }
22389 }
22390}
22391function batchedEventUpdates$1(fn, a) {
22392 var prevExecutionContext = executionContext;
22393 executionContext |= EventContext;
22394
22395 try {
22396 return fn(a);
22397 } finally {
22398 executionContext = prevExecutionContext;
22399
22400 if (executionContext === NoContext) {
22401 // Flush the immediate callbacks that were scheduled during this batch
22402 resetRenderTimer();
22403 flushSyncCallbackQueue();
22404 }
22405 }
22406}
22407function discreteUpdates$1(fn, a, b, c, d) {
22408 var prevExecutionContext = executionContext;
22409 executionContext |= DiscreteEventContext;
22410
22411 {
22412 try {
22413 return runWithPriority$1(UserBlockingPriority$2, fn.bind(null, a, b, c, d));
22414 } finally {
22415 executionContext = prevExecutionContext;
22416
22417 if (executionContext === NoContext) {
22418 // Flush the immediate callbacks that were scheduled during this batch
22419 resetRenderTimer();
22420 flushSyncCallbackQueue();
22421 }
22422 }
22423 }
22424}
22425function unbatchedUpdates(fn, a) {
22426 var prevExecutionContext = executionContext;
22427 executionContext &= ~BatchedContext;
22428 executionContext |= LegacyUnbatchedContext;
22429
22430 try {
22431 return fn(a);
22432 } finally {
22433 executionContext = prevExecutionContext;
22434
22435 if (executionContext === NoContext) {
22436 // Flush the immediate callbacks that were scheduled during this batch
22437 resetRenderTimer();
22438 flushSyncCallbackQueue();
22439 }
22440 }
22441}
22442function flushSync(fn, a) {
22443 var prevExecutionContext = executionContext;
22444
22445 if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) {
22446 {
22447 error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.');
22448 }
22449
22450 return fn(a);
22451 }
22452
22453 executionContext |= BatchedContext;
22454
22455 {
22456 try {
22457 if (fn) {
22458 return runWithPriority$1(ImmediatePriority$1, fn.bind(null, a));
22459 } else {
22460 return undefined;
22461 }
22462 } finally {
22463 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
22464 // Note that this will happen even if batchedUpdates is higher up
22465 // the stack.
22466
22467 flushSyncCallbackQueue();
22468 }
22469 }
22470}
22471function pushRenderLanes(fiber, lanes) {
22472 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
22473 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
22474 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
22475}
22476function popRenderLanes(fiber) {
22477 subtreeRenderLanes = subtreeRenderLanesCursor.current;
22478 pop(subtreeRenderLanesCursor, fiber);
22479}
22480
22481function prepareFreshStack(root, lanes) {
22482 root.finishedWork = null;
22483 root.finishedLanes = NoLanes;
22484 var timeoutHandle = root.timeoutHandle;
22485
22486 if (timeoutHandle !== noTimeout) {
22487 // The root previous suspended and scheduled a timeout to commit a fallback
22488 // state. Now that we have additional work, cancel the timeout.
22489 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
22490
22491 cancelTimeout(timeoutHandle);
22492 }
22493
22494 if (workInProgress !== null) {
22495 var interruptedWork = workInProgress.return;
22496
22497 while (interruptedWork !== null) {
22498 unwindInterruptedWork(interruptedWork);
22499 interruptedWork = interruptedWork.return;
22500 }
22501 }
22502
22503 workInProgressRoot = root;
22504 workInProgress = createWorkInProgress(root.current, null);
22505 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
22506 workInProgressRootExitStatus = RootIncomplete;
22507 workInProgressRootFatalError = null;
22508 workInProgressRootSkippedLanes = NoLanes;
22509 workInProgressRootUpdatedLanes = NoLanes;
22510 workInProgressRootPingedLanes = NoLanes;
22511
22512 {
22513 spawnedWorkDuringRender = null;
22514 }
22515
22516 {
22517 ReactStrictModeWarnings.discardPendingWarnings();
22518 }
22519}
22520
22521function handleError(root, thrownValue) {
22522 do {
22523 var erroredWork = workInProgress;
22524
22525 try {
22526 // Reset module-level state that was set during the render phase.
22527 resetContextDependencies();
22528 resetHooksAfterThrow();
22529 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
22530 // separate issue. Write a regression test using string refs.
22531
22532 ReactCurrentOwner$2.current = null;
22533
22534 if (erroredWork === null || erroredWork.return === null) {
22535 // Expected to be working on a non-root fiber. This is a fatal error
22536 // because there's no ancestor that can handle it; the root is
22537 // supposed to capture all errors that weren't caught by an error
22538 // boundary.
22539 workInProgressRootExitStatus = RootFatalErrored;
22540 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
22541 // sibling, or the parent if there are no siblings. But since the root
22542 // has no siblings nor a parent, we set it to null. Usually this is
22543 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
22544 // intentionally not calling those, we need set it here.
22545 // TODO: Consider calling `unwindWork` to pop the contexts.
22546
22547 workInProgress = null;
22548 return;
22549 }
22550
22551 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
22552 // Record the time spent rendering before an error was thrown. This
22553 // avoids inaccurate Profiler durations in the case of a
22554 // suspended render.
22555 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
22556 }
22557
22558 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
22559 completeUnitOfWork(erroredWork);
22560 } catch (yetAnotherThrownValue) {
22561 // Something in the return path also threw.
22562 thrownValue = yetAnotherThrownValue;
22563
22564 if (workInProgress === erroredWork && erroredWork !== null) {
22565 // If this boundary has already errored, then we had trouble processing
22566 // the error. Bubble it to the next boundary.
22567 erroredWork = erroredWork.return;
22568 workInProgress = erroredWork;
22569 } else {
22570 erroredWork = workInProgress;
22571 }
22572
22573 continue;
22574 } // Return to the normal work loop.
22575
22576
22577 return;
22578 } while (true);
22579}
22580
22581function pushDispatcher() {
22582 var prevDispatcher = ReactCurrentDispatcher$2.current;
22583 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
22584
22585 if (prevDispatcher === null) {
22586 // The React isomorphic package does not include a default dispatcher.
22587 // Instead the first renderer will lazily attach one, in order to give
22588 // nicer error messages.
22589 return ContextOnlyDispatcher;
22590 } else {
22591 return prevDispatcher;
22592 }
22593}
22594
22595function popDispatcher(prevDispatcher) {
22596 ReactCurrentDispatcher$2.current = prevDispatcher;
22597}
22598
22599function pushInteractions(root) {
22600 {
22601 var prevInteractions = tracing.__interactionsRef.current;
22602 tracing.__interactionsRef.current = root.memoizedInteractions;
22603 return prevInteractions;
22604 }
22605}
22606
22607function popInteractions(prevInteractions) {
22608 {
22609 tracing.__interactionsRef.current = prevInteractions;
22610 }
22611}
22612
22613function markCommitTimeOfFallback() {
22614 globalMostRecentFallbackTime = now();
22615}
22616function markSkippedUpdateLanes(lane) {
22617 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
22618}
22619function renderDidSuspend() {
22620 if (workInProgressRootExitStatus === RootIncomplete) {
22621 workInProgressRootExitStatus = RootSuspended;
22622 }
22623}
22624function renderDidSuspendDelayIfPossible() {
22625 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22626 workInProgressRootExitStatus = RootSuspendedWithDelay;
22627 } // Check if there are updates that we skipped tree that might have unblocked
22628 // this render.
22629
22630
22631 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootUpdatedLanes))) {
22632 // Mark the current render as suspended so that we switch to working on
22633 // the updates that were skipped. Usually we only suspend at the end of
22634 // the render phase.
22635 // TODO: We should probably always mark the root as suspended immediately
22636 // (inside this function), since by suspending at the end of the render
22637 // phase introduces a potential mistake where we suspend lanes that were
22638 // pinged or updated while we were rendering.
22639 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
22640 }
22641}
22642function renderDidError() {
22643 if (workInProgressRootExitStatus !== RootCompleted) {
22644 workInProgressRootExitStatus = RootErrored;
22645 }
22646} // Called during render to determine if anything has suspended.
22647// Returns false if we're not sure.
22648
22649function renderHasNotSuspendedYet() {
22650 // If something errored or completed, we can't really be sure,
22651 // so those are false.
22652 return workInProgressRootExitStatus === RootIncomplete;
22653}
22654
22655function renderRootSync(root, lanes) {
22656 var prevExecutionContext = executionContext;
22657 executionContext |= RenderContext;
22658 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
22659 // and prepare a fresh one. Otherwise we'll continue where we left off.
22660
22661 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
22662 prepareFreshStack(root, lanes);
22663 startWorkOnPendingInteractions(root, lanes);
22664 }
22665
22666 var prevInteractions = pushInteractions(root);
22667
22668 do {
22669 try {
22670 workLoopSync();
22671 break;
22672 } catch (thrownValue) {
22673 handleError(root, thrownValue);
22674 }
22675 } while (true);
22676
22677 resetContextDependencies();
22678
22679 {
22680 popInteractions(prevInteractions);
22681 }
22682
22683 executionContext = prevExecutionContext;
22684 popDispatcher(prevDispatcher);
22685
22686 if (workInProgress !== null) {
22687 // This is a sync render, so we should have finished the whole tree.
22688 {
22689 {
22690 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
22691 }
22692 }
22693 }
22694
22695
22696 workInProgressRoot = null;
22697 workInProgressRootRenderLanes = NoLanes;
22698 return workInProgressRootExitStatus;
22699} // The work loop is an extremely hot path. Tell Closure not to inline it.
22700
22701/** @noinline */
22702
22703
22704function workLoopSync() {
22705 // Already timed out, so perform work without checking if we need to yield.
22706 while (workInProgress !== null) {
22707 performUnitOfWork(workInProgress);
22708 }
22709}
22710
22711function renderRootConcurrent(root, lanes) {
22712 var prevExecutionContext = executionContext;
22713 executionContext |= RenderContext;
22714 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
22715 // and prepare a fresh one. Otherwise we'll continue where we left off.
22716
22717 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
22718 resetRenderTimer();
22719 prepareFreshStack(root, lanes);
22720 startWorkOnPendingInteractions(root, lanes);
22721 }
22722
22723 var prevInteractions = pushInteractions(root);
22724
22725 do {
22726 try {
22727 workLoopConcurrent();
22728 break;
22729 } catch (thrownValue) {
22730 handleError(root, thrownValue);
22731 }
22732 } while (true);
22733
22734 resetContextDependencies();
22735
22736 {
22737 popInteractions(prevInteractions);
22738 }
22739
22740 popDispatcher(prevDispatcher);
22741 executionContext = prevExecutionContext;
22742
22743
22744 if (workInProgress !== null) {
22745
22746 return RootIncomplete;
22747 } else {
22748
22749
22750 workInProgressRoot = null;
22751 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
22752
22753 return workInProgressRootExitStatus;
22754 }
22755}
22756/** @noinline */
22757
22758
22759function workLoopConcurrent() {
22760 // Perform work until Scheduler asks us to yield
22761 while (workInProgress !== null && !shouldYield()) {
22762 performUnitOfWork(workInProgress);
22763 }
22764}
22765
22766function performUnitOfWork(unitOfWork) {
22767 // The current, flushed, state of this fiber is the alternate. Ideally
22768 // nothing should rely on this, but relying on it here means that we don't
22769 // need an additional field on the work in progress.
22770 var current = unitOfWork.alternate;
22771 setCurrentFiber(unitOfWork);
22772 var next;
22773
22774 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
22775 startProfilerTimer(unitOfWork);
22776 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
22777 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22778 } else {
22779 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
22780 }
22781
22782 resetCurrentFiber();
22783 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22784
22785 if (next === null) {
22786 // If this doesn't spawn new work, complete the current work.
22787 completeUnitOfWork(unitOfWork);
22788 } else {
22789 workInProgress = next;
22790 }
22791
22792 ReactCurrentOwner$2.current = null;
22793}
22794
22795function completeUnitOfWork(unitOfWork) {
22796 // Attempt to complete the current unit of work, then move to the next
22797 // sibling. If there are no more siblings, return to the parent fiber.
22798 var completedWork = unitOfWork;
22799
22800 do {
22801 // The current, flushed, state of this fiber is the alternate. Ideally
22802 // nothing should rely on this, but relying on it here means that we don't
22803 // need an additional field on the work in progress.
22804 var current = completedWork.alternate;
22805 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
22806
22807 if ((completedWork.flags & Incomplete) === NoFlags) {
22808 setCurrentFiber(completedWork);
22809 var next = void 0;
22810
22811 if ( (completedWork.mode & ProfileMode) === NoMode) {
22812 next = completeWork(current, completedWork, subtreeRenderLanes);
22813 } else {
22814 startProfilerTimer(completedWork);
22815 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
22816
22817 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
22818 }
22819
22820 resetCurrentFiber();
22821
22822 if (next !== null) {
22823 // Completing this fiber spawned new work. Work on that next.
22824 workInProgress = next;
22825 return;
22826 }
22827
22828 resetChildLanes(completedWork);
22829
22830 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22831 (returnFiber.flags & Incomplete) === NoFlags) {
22832 // Append all the effects of the subtree and this fiber onto the effect
22833 // list of the parent. The completion order of the children affects the
22834 // side-effect order.
22835 if (returnFiber.firstEffect === null) {
22836 returnFiber.firstEffect = completedWork.firstEffect;
22837 }
22838
22839 if (completedWork.lastEffect !== null) {
22840 if (returnFiber.lastEffect !== null) {
22841 returnFiber.lastEffect.nextEffect = completedWork.firstEffect;
22842 }
22843
22844 returnFiber.lastEffect = completedWork.lastEffect;
22845 } // If this fiber had side-effects, we append it AFTER the children's
22846 // side-effects. We can perform certain side-effects earlier if needed,
22847 // by doing multiple passes over the effect list. We don't want to
22848 // schedule our own side-effect on our own list because if end up
22849 // reusing children we'll schedule this effect onto itself since we're
22850 // at the end.
22851
22852
22853 var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect
22854 // list. PerformedWork effect is read by React DevTools but shouldn't be
22855 // committed.
22856
22857 if (flags > PerformedWork) {
22858 if (returnFiber.lastEffect !== null) {
22859 returnFiber.lastEffect.nextEffect = completedWork;
22860 } else {
22861 returnFiber.firstEffect = completedWork;
22862 }
22863
22864 returnFiber.lastEffect = completedWork;
22865 }
22866 }
22867 } else {
22868 // This fiber did not complete because something threw. Pop values off
22869 // the stack without entering the complete phase. If this is a boundary,
22870 // capture values if possible.
22871 var _next = unwindWork(completedWork); // Because this fiber did not complete, don't reset its expiration time.
22872
22873
22874 if (_next !== null) {
22875 // If completing this work spawned new work, do that next. We'll come
22876 // back here again.
22877 // Since we're restarting, remove anything that is not a host effect
22878 // from the effect tag.
22879 _next.flags &= HostEffectMask;
22880 workInProgress = _next;
22881 return;
22882 }
22883
22884 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22885 // Record the render duration for the fiber that errored.
22886 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
22887
22888 var actualDuration = completedWork.actualDuration;
22889 var child = completedWork.child;
22890
22891 while (child !== null) {
22892 actualDuration += child.actualDuration;
22893 child = child.sibling;
22894 }
22895
22896 completedWork.actualDuration = actualDuration;
22897 }
22898
22899 if (returnFiber !== null) {
22900 // Mark the parent fiber as incomplete and clear its effect list.
22901 returnFiber.firstEffect = returnFiber.lastEffect = null;
22902 returnFiber.flags |= Incomplete;
22903 }
22904 }
22905
22906 var siblingFiber = completedWork.sibling;
22907
22908 if (siblingFiber !== null) {
22909 // If there is more work to do in this returnFiber, do that next.
22910 workInProgress = siblingFiber;
22911 return;
22912 } // Otherwise, return to the parent
22913
22914
22915 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
22916
22917 workInProgress = completedWork;
22918 } while (completedWork !== null); // We've reached the root.
22919
22920
22921 if (workInProgressRootExitStatus === RootIncomplete) {
22922 workInProgressRootExitStatus = RootCompleted;
22923 }
22924}
22925
22926function resetChildLanes(completedWork) {
22927 if ( // TODO: Move this check out of the hot path by moving `resetChildLanes`
22928 // to switch statement in `completeWork`.
22929 (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) {
22930 // The children of this component are hidden. Don't bubble their
22931 // expiration times.
22932 return;
22933 }
22934
22935 var newChildLanes = NoLanes; // Bubble up the earliest expiration time.
22936
22937 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22938 // In profiling mode, resetChildExpirationTime is also used to reset
22939 // profiler durations.
22940 var actualDuration = completedWork.actualDuration;
22941 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22942 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22943 // When work is done, it should bubble to the parent's actualDuration. If
22944 // the fiber has not been cloned though, (meaning no work was done), then
22945 // this value will reflect the amount of time spent working on a previous
22946 // render. In that case it should not bubble. We determine whether it was
22947 // cloned by comparing the child pointer.
22948
22949 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22950 var child = completedWork.child;
22951
22952 while (child !== null) {
22953 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
22954
22955 if (shouldBubbleActualDurations) {
22956 actualDuration += child.actualDuration;
22957 }
22958
22959 treeBaseDuration += child.treeBaseDuration;
22960 child = child.sibling;
22961 }
22962
22963 var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null;
22964
22965 if (isTimedOutSuspense) {
22966 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22967 var primaryChildFragment = completedWork.child;
22968
22969 if (primaryChildFragment !== null) {
22970 treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22971 }
22972 }
22973
22974 completedWork.actualDuration = actualDuration;
22975 completedWork.treeBaseDuration = treeBaseDuration;
22976 } else {
22977 var _child = completedWork.child;
22978
22979 while (_child !== null) {
22980 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
22981 _child = _child.sibling;
22982 }
22983 }
22984
22985 completedWork.childLanes = newChildLanes;
22986}
22987
22988function commitRoot(root) {
22989 var renderPriorityLevel = getCurrentPriorityLevel();
22990 runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));
22991 return null;
22992}
22993
22994function commitRootImpl(root, renderPriorityLevel) {
22995 do {
22996 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
22997 // means `flushPassiveEffects` will sometimes result in additional
22998 // passive effects. So we need to keep flushing in a loop until there are
22999 // no more pending effects.
23000 // TODO: Might be better if `flushPassiveEffects` did not automatically
23001 // flush synchronous work at the end, to avoid factoring hazards like this.
23002 flushPassiveEffects();
23003 } while (rootWithPendingPassiveEffects !== null);
23004
23005 flushRenderPhaseStrictModeWarningsInDEV();
23006
23007 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
23008 {
23009 throw Error( "Should not already be working." );
23010 }
23011 }
23012
23013 var finishedWork = root.finishedWork;
23014 var lanes = root.finishedLanes;
23015
23016 if (finishedWork === null) {
23017
23018 return null;
23019 }
23020
23021 root.finishedWork = null;
23022 root.finishedLanes = NoLanes;
23023
23024 if (!(finishedWork !== root.current)) {
23025 {
23026 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
23027 }
23028 } // commitRoot never returns a continuation; it always finishes synchronously.
23029 // So we can clear these now to allow a new callback to be scheduled.
23030
23031
23032 root.callbackNode = null; // Update the first and last pending times on this root. The new first
23033 // pending time is whatever is left on the root fiber.
23034
23035 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
23036 markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of
23037 // `flushDiscreteUpdates` starts a useless render pass which may cancels
23038 // a scheduled timeout.
23039
23040 if (rootsWithPendingDiscreteUpdates !== null) {
23041 if (!hasDiscreteLanes(remainingLanes) && rootsWithPendingDiscreteUpdates.has(root)) {
23042 rootsWithPendingDiscreteUpdates.delete(root);
23043 }
23044 }
23045
23046 if (root === workInProgressRoot) {
23047 // We can reset these now that they are finished.
23048 workInProgressRoot = null;
23049 workInProgress = null;
23050 workInProgressRootRenderLanes = NoLanes;
23051 } // Get the list of effects.
23052
23053
23054 var firstEffect;
23055
23056 if (finishedWork.flags > PerformedWork) {
23057 // A fiber's effect list consists only of its children, not itself. So if
23058 // the root has an effect, we need to add it to the end of the list. The
23059 // resulting list is the set that would belong to the root's parent, if it
23060 // had one; that is, all the effects in the tree including the root.
23061 if (finishedWork.lastEffect !== null) {
23062 finishedWork.lastEffect.nextEffect = finishedWork;
23063 firstEffect = finishedWork.firstEffect;
23064 } else {
23065 firstEffect = finishedWork;
23066 }
23067 } else {
23068 // There is no effect on the root.
23069 firstEffect = finishedWork.firstEffect;
23070 }
23071
23072 if (firstEffect !== null) {
23073
23074 var prevExecutionContext = executionContext;
23075 executionContext |= CommitContext;
23076 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
23077
23078 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
23079 // of the effect list for each phase: all mutation effects come before all
23080 // layout effects, and so on.
23081 // The first phase a "before mutation" phase. We use this phase to read the
23082 // state of the host tree right before we mutate it. This is where
23083 // getSnapshotBeforeUpdate is called.
23084
23085 focusedInstanceHandle = prepareForCommit(root.containerInfo);
23086 shouldFireAfterActiveInstanceBlur = false;
23087 nextEffect = firstEffect;
23088
23089 do {
23090 {
23091 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
23092
23093 if (hasCaughtError()) {
23094 if (!(nextEffect !== null)) {
23095 {
23096 throw Error( "Should be working on an effect." );
23097 }
23098 }
23099
23100 var error = clearCaughtError();
23101 captureCommitPhaseError(nextEffect, error);
23102 nextEffect = nextEffect.nextEffect;
23103 }
23104 }
23105 } while (nextEffect !== null); // We no longer need to track the active instance fiber
23106
23107
23108 focusedInstanceHandle = null;
23109
23110 {
23111 // Mark the current commit time to be shared by all Profilers in this
23112 // batch. This enables them to be grouped later.
23113 recordCommitTime();
23114 } // The next phase is the mutation phase, where we mutate the host tree.
23115
23116
23117 nextEffect = firstEffect;
23118
23119 do {
23120 {
23121 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
23122
23123 if (hasCaughtError()) {
23124 if (!(nextEffect !== null)) {
23125 {
23126 throw Error( "Should be working on an effect." );
23127 }
23128 }
23129
23130 var _error = clearCaughtError();
23131
23132 captureCommitPhaseError(nextEffect, _error);
23133 nextEffect = nextEffect.nextEffect;
23134 }
23135 }
23136 } while (nextEffect !== null);
23137
23138 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
23139 // the mutation phase, so that the previous tree is still current during
23140 // componentWillUnmount, but before the layout phase, so that the finished
23141 // work is current during componentDidMount/Update.
23142
23143 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
23144 // the host tree after it's been mutated. The idiomatic use case for this is
23145 // layout, but class component lifecycles also fire here for legacy reasons.
23146
23147 nextEffect = firstEffect;
23148
23149 do {
23150 {
23151 invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes);
23152
23153 if (hasCaughtError()) {
23154 if (!(nextEffect !== null)) {
23155 {
23156 throw Error( "Should be working on an effect." );
23157 }
23158 }
23159
23160 var _error2 = clearCaughtError();
23161
23162 captureCommitPhaseError(nextEffect, _error2);
23163 nextEffect = nextEffect.nextEffect;
23164 }
23165 }
23166 } while (nextEffect !== null);
23167
23168 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
23169 // opportunity to paint.
23170
23171 requestPaint();
23172
23173 {
23174 popInteractions(prevInteractions);
23175 }
23176
23177 executionContext = prevExecutionContext;
23178 } else {
23179 // No effects.
23180 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
23181 // no effects.
23182 // TODO: Maybe there's a better way to report this.
23183
23184 {
23185 recordCommitTime();
23186 }
23187 }
23188
23189 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
23190
23191 if (rootDoesHavePassiveEffects) {
23192 // This commit has passive effects. Stash a reference to them. But don't
23193 // schedule a callback until after flushing layout work.
23194 rootDoesHavePassiveEffects = false;
23195 rootWithPendingPassiveEffects = root;
23196 pendingPassiveEffectsLanes = lanes;
23197 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
23198 } else {
23199 // We are done with the effect chain at this point so let's clear the
23200 // nextEffect pointers to assist with GC. If we have passive effects, we'll
23201 // clear this in flushPassiveEffects.
23202 nextEffect = firstEffect;
23203
23204 while (nextEffect !== null) {
23205 var nextNextEffect = nextEffect.nextEffect;
23206 nextEffect.nextEffect = null;
23207
23208 if (nextEffect.flags & Deletion) {
23209 detachFiberAfterEffects(nextEffect);
23210 }
23211
23212 nextEffect = nextNextEffect;
23213 }
23214 } // Read this again, since an effect might have updated it
23215
23216
23217 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
23218
23219 if (remainingLanes !== NoLanes) {
23220 {
23221 if (spawnedWorkDuringRender !== null) {
23222 var expirationTimes = spawnedWorkDuringRender;
23223 spawnedWorkDuringRender = null;
23224
23225 for (var i = 0; i < expirationTimes.length; i++) {
23226 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
23227 }
23228 }
23229
23230 schedulePendingInteractions(root, remainingLanes);
23231 }
23232 } else {
23233 // If there's no remaining work, we can clear the set of already failed
23234 // error boundaries.
23235 legacyErrorBoundariesThatAlreadyFailed = null;
23236 }
23237
23238 {
23239 if (!rootDidHavePassiveEffects) {
23240 // If there are no passive effects, then we can complete the pending interactions.
23241 // Otherwise, we'll wait until after the passive effects are flushed.
23242 // Wait to do this until after remaining work has been scheduled,
23243 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
23244 finishPendingInteractions(root, lanes);
23245 }
23246 }
23247
23248 if (remainingLanes === SyncLane) {
23249 // Count the number of times the root synchronously re-renders without
23250 // finishing. If there are too many, it indicates an infinite update loop.
23251 if (root === rootWithNestedUpdates) {
23252 nestedUpdateCount++;
23253 } else {
23254 nestedUpdateCount = 0;
23255 rootWithNestedUpdates = root;
23256 }
23257 } else {
23258 nestedUpdateCount = 0;
23259 }
23260
23261 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
23262
23263 {
23264 onCommitRoot$1();
23265 } // Always call this before exiting `commitRoot`, to ensure that any
23266 // additional work on this root is scheduled.
23267
23268
23269 ensureRootIsScheduled(root, now());
23270
23271 if (hasUncaughtError) {
23272 hasUncaughtError = false;
23273 var _error3 = firstUncaughtError;
23274 firstUncaughtError = null;
23275 throw _error3;
23276 }
23277
23278 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
23279 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
23280 // synchronously, but layout updates should be deferred until the end
23281 // of the batch.
23282
23283
23284 return null;
23285 } // If layout work was scheduled, flush it now.
23286
23287
23288 flushSyncCallbackQueue();
23289
23290 return null;
23291}
23292
23293function commitBeforeMutationEffects() {
23294 while (nextEffect !== null) {
23295 var current = nextEffect.alternate;
23296
23297 if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {
23298 if ((nextEffect.flags & Deletion) !== NoFlags) {
23299 if (doesFiberContain(nextEffect, focusedInstanceHandle)) {
23300 shouldFireAfterActiveInstanceBlur = true;
23301 }
23302 } else {
23303 // TODO: Move this out of the hot path using a dedicated effect tag.
23304 if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) {
23305 shouldFireAfterActiveInstanceBlur = true;
23306 }
23307 }
23308 }
23309
23310 var flags = nextEffect.flags;
23311
23312 if ((flags & Snapshot) !== NoFlags) {
23313 setCurrentFiber(nextEffect);
23314 commitBeforeMutationLifeCycles(current, nextEffect);
23315 resetCurrentFiber();
23316 }
23317
23318 if ((flags & Passive) !== NoFlags) {
23319 // If there are passive effects, schedule a callback to flush at
23320 // the earliest opportunity.
23321 if (!rootDoesHavePassiveEffects) {
23322 rootDoesHavePassiveEffects = true;
23323 scheduleCallback(NormalPriority$1, function () {
23324 flushPassiveEffects();
23325 return null;
23326 });
23327 }
23328 }
23329
23330 nextEffect = nextEffect.nextEffect;
23331 }
23332}
23333
23334function commitMutationEffects(root, renderPriorityLevel) {
23335 // TODO: Should probably move the bulk of this function to commitWork.
23336 while (nextEffect !== null) {
23337 setCurrentFiber(nextEffect);
23338 var flags = nextEffect.flags;
23339
23340 if (flags & ContentReset) {
23341 commitResetTextContent(nextEffect);
23342 }
23343
23344 if (flags & Ref) {
23345 var current = nextEffect.alternate;
23346
23347 if (current !== null) {
23348 commitDetachRef(current);
23349 }
23350 } // The following switch statement is only concerned about placement,
23351 // updates, and deletions. To avoid needing to add a case for every possible
23352 // bitmap value, we remove the secondary effects from the effect tag and
23353 // switch on that value.
23354
23355
23356 var primaryFlags = flags & (Placement | Update | Deletion | Hydrating);
23357
23358 switch (primaryFlags) {
23359 case Placement:
23360 {
23361 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23362 // inserted, before any life-cycles like componentDidMount gets called.
23363 // TODO: findDOMNode doesn't rely on this any more but isMounted does
23364 // and isMounted is deprecated anyway so we should be able to kill this.
23365
23366 nextEffect.flags &= ~Placement;
23367 break;
23368 }
23369
23370 case PlacementAndUpdate:
23371 {
23372 // Placement
23373 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
23374 // inserted, before any life-cycles like componentDidMount gets called.
23375
23376 nextEffect.flags &= ~Placement; // Update
23377
23378 var _current = nextEffect.alternate;
23379 commitWork(_current, nextEffect);
23380 break;
23381 }
23382
23383 case Hydrating:
23384 {
23385 nextEffect.flags &= ~Hydrating;
23386 break;
23387 }
23388
23389 case HydratingAndUpdate:
23390 {
23391 nextEffect.flags &= ~Hydrating; // Update
23392
23393 var _current2 = nextEffect.alternate;
23394 commitWork(_current2, nextEffect);
23395 break;
23396 }
23397
23398 case Update:
23399 {
23400 var _current3 = nextEffect.alternate;
23401 commitWork(_current3, nextEffect);
23402 break;
23403 }
23404
23405 case Deletion:
23406 {
23407 commitDeletion(root, nextEffect);
23408 break;
23409 }
23410 }
23411
23412 resetCurrentFiber();
23413 nextEffect = nextEffect.nextEffect;
23414 }
23415}
23416
23417function commitLayoutEffects(root, committedLanes) {
23418
23419
23420 while (nextEffect !== null) {
23421 setCurrentFiber(nextEffect);
23422 var flags = nextEffect.flags;
23423
23424 if (flags & (Update | Callback)) {
23425 var current = nextEffect.alternate;
23426 commitLifeCycles(root, current, nextEffect);
23427 }
23428
23429 {
23430 if (flags & Ref) {
23431 commitAttachRef(nextEffect);
23432 }
23433 }
23434
23435 resetCurrentFiber();
23436 nextEffect = nextEffect.nextEffect;
23437 }
23438}
23439
23440function flushPassiveEffects() {
23441 // Returns whether passive effects were flushed.
23442 if (pendingPassiveEffectsRenderPriority !== NoPriority$1) {
23443 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority$1 ? NormalPriority$1 : pendingPassiveEffectsRenderPriority;
23444 pendingPassiveEffectsRenderPriority = NoPriority$1;
23445
23446 {
23447 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
23448 }
23449 }
23450
23451 return false;
23452}
23453function enqueuePendingPassiveHookEffectMount(fiber, effect) {
23454 pendingPassiveHookEffectsMount.push(effect, fiber);
23455
23456 if (!rootDoesHavePassiveEffects) {
23457 rootDoesHavePassiveEffects = true;
23458 scheduleCallback(NormalPriority$1, function () {
23459 flushPassiveEffects();
23460 return null;
23461 });
23462 }
23463}
23464function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {
23465 pendingPassiveHookEffectsUnmount.push(effect, fiber);
23466
23467 {
23468 fiber.flags |= PassiveUnmountPendingDev;
23469 var alternate = fiber.alternate;
23470
23471 if (alternate !== null) {
23472 alternate.flags |= PassiveUnmountPendingDev;
23473 }
23474 }
23475
23476 if (!rootDoesHavePassiveEffects) {
23477 rootDoesHavePassiveEffects = true;
23478 scheduleCallback(NormalPriority$1, function () {
23479 flushPassiveEffects();
23480 return null;
23481 });
23482 }
23483}
23484
23485function invokePassiveEffectCreate(effect) {
23486 var create = effect.create;
23487 effect.destroy = create();
23488}
23489
23490function flushPassiveEffectsImpl() {
23491 if (rootWithPendingPassiveEffects === null) {
23492 return false;
23493 }
23494
23495 var root = rootWithPendingPassiveEffects;
23496 var lanes = pendingPassiveEffectsLanes;
23497 rootWithPendingPassiveEffects = null;
23498 pendingPassiveEffectsLanes = NoLanes;
23499
23500 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
23501 {
23502 throw Error( "Cannot flush passive effects while already rendering." );
23503 }
23504 }
23505
23506 {
23507 isFlushingPassiveEffects = true;
23508 }
23509
23510 var prevExecutionContext = executionContext;
23511 executionContext |= CommitContext;
23512 var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called
23513 // before ANY passive effect create functions are called.
23514 // Otherwise effects in sibling components might interfere with each other.
23515 // e.g. a destroy function in one component may unintentionally override a ref
23516 // value set by a create function in another component.
23517 // Layout effects have the same constraint.
23518 // First pass: Destroy stale passive effects.
23519
23520 var unmountEffects = pendingPassiveHookEffectsUnmount;
23521 pendingPassiveHookEffectsUnmount = [];
23522
23523 for (var i = 0; i < unmountEffects.length; i += 2) {
23524 var _effect = unmountEffects[i];
23525 var fiber = unmountEffects[i + 1];
23526 var destroy = _effect.destroy;
23527 _effect.destroy = undefined;
23528
23529 {
23530 fiber.flags &= ~PassiveUnmountPendingDev;
23531 var alternate = fiber.alternate;
23532
23533 if (alternate !== null) {
23534 alternate.flags &= ~PassiveUnmountPendingDev;
23535 }
23536 }
23537
23538 if (typeof destroy === 'function') {
23539 {
23540 setCurrentFiber(fiber);
23541
23542 {
23543 invokeGuardedCallback(null, destroy, null);
23544 }
23545
23546 if (hasCaughtError()) {
23547 if (!(fiber !== null)) {
23548 {
23549 throw Error( "Should be working on an effect." );
23550 }
23551 }
23552
23553 var error = clearCaughtError();
23554 captureCommitPhaseError(fiber, error);
23555 }
23556
23557 resetCurrentFiber();
23558 }
23559 }
23560 } // Second pass: Create new passive effects.
23561
23562
23563 var mountEffects = pendingPassiveHookEffectsMount;
23564 pendingPassiveHookEffectsMount = [];
23565
23566 for (var _i = 0; _i < mountEffects.length; _i += 2) {
23567 var _effect2 = mountEffects[_i];
23568 var _fiber = mountEffects[_i + 1];
23569
23570 {
23571 setCurrentFiber(_fiber);
23572
23573 {
23574 invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2);
23575 }
23576
23577 if (hasCaughtError()) {
23578 if (!(_fiber !== null)) {
23579 {
23580 throw Error( "Should be working on an effect." );
23581 }
23582 }
23583
23584 var _error4 = clearCaughtError();
23585
23586 captureCommitPhaseError(_fiber, _error4);
23587 }
23588
23589 resetCurrentFiber();
23590 }
23591 } // Note: This currently assumes there are no passive effects on the root fiber
23592 // because the root is not part of its own effect list.
23593 // This could change in the future.
23594
23595
23596 var effect = root.current.firstEffect;
23597
23598 while (effect !== null) {
23599 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
23600
23601 effect.nextEffect = null;
23602
23603 if (effect.flags & Deletion) {
23604 detachFiberAfterEffects(effect);
23605 }
23606
23607 effect = nextNextEffect;
23608 }
23609
23610 {
23611 popInteractions(prevInteractions);
23612 finishPendingInteractions(root, lanes);
23613 }
23614
23615 {
23616 isFlushingPassiveEffects = false;
23617 }
23618
23619 executionContext = prevExecutionContext;
23620 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
23621 // exceeds the limit, we'll fire a warning.
23622
23623 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
23624 return true;
23625}
23626
23627function isAlreadyFailedLegacyErrorBoundary(instance) {
23628 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
23629}
23630function markLegacyErrorBoundaryAsFailed(instance) {
23631 if (legacyErrorBoundariesThatAlreadyFailed === null) {
23632 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
23633 } else {
23634 legacyErrorBoundariesThatAlreadyFailed.add(instance);
23635 }
23636}
23637
23638function prepareToThrowUncaughtError(error) {
23639 if (!hasUncaughtError) {
23640 hasUncaughtError = true;
23641 firstUncaughtError = error;
23642 }
23643}
23644
23645var onUncaughtError = prepareToThrowUncaughtError;
23646
23647function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23648 var errorInfo = createCapturedValue(error, sourceFiber);
23649 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
23650 enqueueUpdate(rootFiber, update);
23651 var eventTime = requestEventTime();
23652 var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);
23653
23654 if (root !== null) {
23655 markRootUpdated(root, SyncLane, eventTime);
23656 ensureRootIsScheduled(root, eventTime);
23657 schedulePendingInteractions(root, SyncLane);
23658 }
23659}
23660
23661function captureCommitPhaseError(sourceFiber, error) {
23662 if (sourceFiber.tag === HostRoot) {
23663 // Error was thrown at the root. There is no parent, so the root
23664 // itself should capture it.
23665 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
23666 return;
23667 }
23668
23669 var fiber = sourceFiber.return;
23670
23671 while (fiber !== null) {
23672 if (fiber.tag === HostRoot) {
23673 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
23674 return;
23675 } else if (fiber.tag === ClassComponent) {
23676 var ctor = fiber.type;
23677 var instance = fiber.stateNode;
23678
23679 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23680 var errorInfo = createCapturedValue(error, sourceFiber);
23681 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
23682 enqueueUpdate(fiber, update);
23683 var eventTime = requestEventTime();
23684 var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);
23685
23686 if (root !== null) {
23687 markRootUpdated(root, SyncLane, eventTime);
23688 ensureRootIsScheduled(root, eventTime);
23689 schedulePendingInteractions(root, SyncLane);
23690 } else {
23691 // This component has already been unmounted.
23692 // We can't schedule any follow up work for the root because the fiber is already unmounted,
23693 // but we can still call the log-only boundary so the error isn't swallowed.
23694 //
23695 // TODO This is only a temporary bandaid for the old reconciler fork.
23696 // We can delete this special case once the new fork is merged.
23697 if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23698 try {
23699 instance.componentDidCatch(error, errorInfo);
23700 } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it?
23701 // This is kind of an edge case.
23702 }
23703 }
23704 }
23705
23706 return;
23707 }
23708 }
23709
23710 fiber = fiber.return;
23711 }
23712}
23713function pingSuspendedRoot(root, wakeable, pingedLanes) {
23714 var pingCache = root.pingCache;
23715
23716 if (pingCache !== null) {
23717 // The wakeable resolved, so we no longer need to memoize, because it will
23718 // never be thrown again.
23719 pingCache.delete(wakeable);
23720 }
23721
23722 var eventTime = requestEventTime();
23723 markRootPinged(root, pingedLanes);
23724
23725 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
23726 // Received a ping at the same priority level at which we're currently
23727 // rendering. We might want to restart this render. This should mirror
23728 // the logic of whether or not a root suspends once it completes.
23729 // TODO: If we're rendering sync either due to Sync, Batched or expired,
23730 // we should probably never restart.
23731 // If we're suspended with delay, or if it's a retry, we'll always suspend
23732 // so we can always restart.
23733 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
23734 // Restart from the root.
23735 prepareFreshStack(root, NoLanes);
23736 } else {
23737 // Even though we can't restart right now, we might get an
23738 // opportunity later. So we mark this render as having a ping.
23739 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
23740 }
23741 }
23742
23743 ensureRootIsScheduled(root, eventTime);
23744 schedulePendingInteractions(root, pingedLanes);
23745}
23746
23747function retryTimedOutBoundary(boundaryFiber, retryLane) {
23748 // The boundary fiber (a Suspense component or SuspenseList component)
23749 // previously was rendered in its fallback state. One of the promises that
23750 // suspended it has resolved, which means at least part of the tree was
23751 // likely unblocked. Try rendering again, at a new expiration time.
23752 if (retryLane === NoLane) {
23753 retryLane = requestRetryLane(boundaryFiber);
23754 } // TODO: Special case idle priority?
23755
23756
23757 var eventTime = requestEventTime();
23758 var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);
23759
23760 if (root !== null) {
23761 markRootUpdated(root, retryLane, eventTime);
23762 ensureRootIsScheduled(root, eventTime);
23763 schedulePendingInteractions(root, retryLane);
23764 }
23765}
23766function resolveRetryWakeable(boundaryFiber, wakeable) {
23767 var retryLane = NoLane; // Default
23768
23769 var retryCache;
23770
23771 {
23772 retryCache = boundaryFiber.stateNode;
23773 }
23774
23775 if (retryCache !== null) {
23776 // The wakeable resolved, so we no longer need to memoize, because it will
23777 // never be thrown again.
23778 retryCache.delete(wakeable);
23779 }
23780
23781 retryTimedOutBoundary(boundaryFiber, retryLane);
23782} // Computes the next Just Noticeable Difference (JND) boundary.
23783// The theory is that a person can't tell the difference between small differences in time.
23784// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23785// difference in the experience. However, waiting for longer might mean that we can avoid
23786// showing an intermediate loading state. The longer we have already waited, the harder it
23787// is to tell small differences in time. Therefore, the longer we've already waited,
23788// the longer we can wait additionally. At some point we have to give up though.
23789// We pick a train model where the next boundary commits at a consistent schedule.
23790// These particular numbers are vague estimates. We expect to adjust them based on research.
23791
23792function jnd(timeElapsed) {
23793 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23794}
23795
23796function checkForNestedUpdates() {
23797 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23798 nestedUpdateCount = 0;
23799 rootWithNestedUpdates = null;
23800
23801 {
23802 {
23803 throw Error( "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." );
23804 }
23805 }
23806 }
23807
23808 {
23809 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23810 nestedPassiveUpdateCount = 0;
23811
23812 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
23813 }
23814 }
23815}
23816
23817function flushRenderPhaseStrictModeWarningsInDEV() {
23818 {
23819 ReactStrictModeWarnings.flushLegacyContextWarning();
23820
23821 {
23822 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23823 }
23824 }
23825}
23826
23827var didWarnStateUpdateForNotYetMountedComponent = null;
23828
23829function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
23830 {
23831 if ((executionContext & RenderContext) !== NoContext) {
23832 // We let the other warning about render phase updates deal with this one.
23833 return;
23834 }
23835
23836 if (!(fiber.mode & (BlockingMode | ConcurrentMode))) {
23837 return;
23838 }
23839
23840 var tag = fiber.tag;
23841
23842 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23843 // Only warn for user-defined components, not internal ones like Suspense.
23844 return;
23845 } // We show the whole stack but dedupe on the top component's name because
23846 // the problematic code almost always lies inside that component.
23847
23848
23849 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23850
23851 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
23852 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
23853 return;
23854 }
23855
23856 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
23857 } else {
23858 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
23859 }
23860
23861 var previousFiber = current;
23862
23863 try {
23864 setCurrentFiber(fiber);
23865
23866 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');
23867 } finally {
23868 if (previousFiber) {
23869 setCurrentFiber(fiber);
23870 } else {
23871 resetCurrentFiber();
23872 }
23873 }
23874 }
23875}
23876
23877var didWarnStateUpdateForUnmountedComponent = null;
23878
23879function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23880 {
23881 var tag = fiber.tag;
23882
23883 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23884 // Only warn for user-defined components, not internal ones like Suspense.
23885 return;
23886 } // If there are pending passive effects unmounts for this Fiber,
23887 // we can assume that they would have prevented this update.
23888
23889
23890 if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) {
23891 return;
23892 } // We show the whole stack but dedupe on the top component's name because
23893 // the problematic code almost always lies inside that component.
23894
23895
23896 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23897
23898 if (didWarnStateUpdateForUnmountedComponent !== null) {
23899 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23900 return;
23901 }
23902
23903 didWarnStateUpdateForUnmountedComponent.add(componentName);
23904 } else {
23905 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23906 }
23907
23908 if (isFlushingPassiveEffects) ; else {
23909 var previousFiber = current;
23910
23911 try {
23912 setCurrentFiber(fiber);
23913
23914 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function');
23915 } finally {
23916 if (previousFiber) {
23917 setCurrentFiber(fiber);
23918 } else {
23919 resetCurrentFiber();
23920 }
23921 }
23922 }
23923 }
23924}
23925
23926var beginWork$1;
23927
23928{
23929 var dummyFiber = null;
23930
23931 beginWork$1 = function (current, unitOfWork, lanes) {
23932 // If a component throws an error, we replay it again in a synchronously
23933 // dispatched event, so that the debugger will treat it as an uncaught
23934 // error See ReactErrorUtils for more information.
23935 // Before entering the begin phase, copy the work-in-progress onto a dummy
23936 // fiber. If beginWork throws, we'll use this to reset the state.
23937 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23938
23939 try {
23940 return beginWork(current, unitOfWork, lanes);
23941 } catch (originalError) {
23942 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23943 // Don't replay promises. Treat everything else like an error.
23944 throw originalError;
23945 } // Keep this code in sync with handleError; any changes here must have
23946 // corresponding changes there.
23947
23948
23949 resetContextDependencies();
23950 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
23951 // same fiber again.
23952 // Unwind the failed stack frame
23953
23954 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
23955
23956 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23957
23958 if ( unitOfWork.mode & ProfileMode) {
23959 // Reset the profiler timer.
23960 startProfilerTimer(unitOfWork);
23961 } // Run beginWork again.
23962
23963
23964 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
23965
23966 if (hasCaughtError()) {
23967 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23968 // Rethrow this error instead of the original one.
23969
23970 throw replayError;
23971 } else {
23972 // This branch is reachable if the render phase is impure.
23973 throw originalError;
23974 }
23975 }
23976 };
23977}
23978
23979var didWarnAboutUpdateInRender = false;
23980var didWarnAboutUpdateInRenderForAnotherComponent;
23981
23982{
23983 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
23984}
23985
23986function warnAboutRenderPhaseUpdatesInDEV(fiber) {
23987 {
23988 if (isRendering && (executionContext & RenderContext) !== NoContext && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
23989 switch (fiber.tag) {
23990 case FunctionComponent:
23991 case ForwardRef:
23992 case SimpleMemoComponent:
23993 {
23994 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
23995
23996 var dedupeKey = renderingComponentName;
23997
23998 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
23999 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
24000 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
24001
24002 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
24003 }
24004
24005 break;
24006 }
24007
24008 case ClassComponent:
24009 {
24010 if (!didWarnAboutUpdateInRender) {
24011 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
24012
24013 didWarnAboutUpdateInRender = true;
24014 }
24015
24016 break;
24017 }
24018 }
24019 }
24020 }
24021} // a 'shared' variable that changes when act() opens/closes in tests.
24022
24023
24024var IsThisRendererActing = {
24025 current: false
24026};
24027function warnIfNotScopedWithMatchingAct(fiber) {
24028 {
24029 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
24030 var previousFiber = current;
24031
24032 try {
24033 setCurrentFiber(fiber);
24034
24035 error("It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + // Break up imports to avoid accidentally parsing them as dependencies.
24036 'import {act} fr' + "om 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + // Break up imports to avoid accidentally parsing them as dependencies.
24037 'import TestRenderer fr' + "om react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);');
24038 } finally {
24039 if (previousFiber) {
24040 setCurrentFiber(fiber);
24041 } else {
24042 resetCurrentFiber();
24043 }
24044 }
24045 }
24046 }
24047}
24048function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
24049 {
24050 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
24051 error('An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentName(fiber.type));
24052 }
24053 }
24054}
24055
24056function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
24057 {
24058 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
24059 var previousFiber = current;
24060
24061 try {
24062 setCurrentFiber(fiber);
24063
24064 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentName(fiber.type));
24065 } finally {
24066 if (previousFiber) {
24067 setCurrentFiber(fiber);
24068 } else {
24069 resetCurrentFiber();
24070 }
24071 }
24072 }
24073 }
24074}
24075
24076var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
24077
24078var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
24079// scheduler is the actual recommendation. The alternative could be a testing build,
24080// a new lib, or whatever; we dunno just yet. This message is for early adopters
24081// to get their tests right.
24082
24083function warnIfUnmockedScheduler(fiber) {
24084 {
24085 if (didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined) {
24086 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
24087 didWarnAboutUnmockedScheduler = true;
24088
24089 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + // Break up requires to avoid accidentally parsing them as dependencies.
24090 "jest.mock('scheduler', () => require" + "('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://reactjs.org/link/mock-scheduler');
24091 }
24092 }
24093 }
24094}
24095
24096function computeThreadID(root, lane) {
24097 // Interaction threads are unique per root and expiration time.
24098 // NOTE: Intentionally unsound cast. All that matters is that it's a number
24099 // and it represents a batch of work. Could make a helper function instead,
24100 // but meh this is fine for now.
24101 return lane * 1000 + root.interactionThreadID;
24102}
24103
24104function markSpawnedWork(lane) {
24105
24106 if (spawnedWorkDuringRender === null) {
24107 spawnedWorkDuringRender = [lane];
24108 } else {
24109 spawnedWorkDuringRender.push(lane);
24110 }
24111}
24112
24113function scheduleInteractions(root, lane, interactions) {
24114
24115 if (interactions.size > 0) {
24116 var pendingInteractionMap = root.pendingInteractionMap;
24117 var pendingInteractions = pendingInteractionMap.get(lane);
24118
24119 if (pendingInteractions != null) {
24120 interactions.forEach(function (interaction) {
24121 if (!pendingInteractions.has(interaction)) {
24122 // Update the pending async work count for previously unscheduled interaction.
24123 interaction.__count++;
24124 }
24125
24126 pendingInteractions.add(interaction);
24127 });
24128 } else {
24129 pendingInteractionMap.set(lane, new Set(interactions)); // Update the pending async work count for the current interactions.
24130
24131 interactions.forEach(function (interaction) {
24132 interaction.__count++;
24133 });
24134 }
24135
24136 var subscriber = tracing.__subscriberRef.current;
24137
24138 if (subscriber !== null) {
24139 var threadID = computeThreadID(root, lane);
24140 subscriber.onWorkScheduled(interactions, threadID);
24141 }
24142 }
24143}
24144
24145function schedulePendingInteractions(root, lane) {
24146
24147 scheduleInteractions(root, lane, tracing.__interactionsRef.current);
24148}
24149
24150function startWorkOnPendingInteractions(root, lanes) {
24151 // we can accurately attribute time spent working on it, And so that cascading
24152 // work triggered during the render phase will be associated with it.
24153
24154
24155 var interactions = new Set();
24156 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledLane) {
24157 if (includesSomeLane(lanes, scheduledLane)) {
24158 scheduledInteractions.forEach(function (interaction) {
24159 return interactions.add(interaction);
24160 });
24161 }
24162 }); // Store the current set of interactions on the FiberRoot for a few reasons:
24163 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
24164 // without having to recalculate it. We will also use it in commitWork() to
24165 // pass to any Profiler onRender() hooks. This also provides DevTools with a
24166 // way to access it when the onCommitRoot() hook is called.
24167
24168 root.memoizedInteractions = interactions;
24169
24170 if (interactions.size > 0) {
24171 var subscriber = tracing.__subscriberRef.current;
24172
24173 if (subscriber !== null) {
24174 var threadID = computeThreadID(root, lanes);
24175
24176 try {
24177 subscriber.onWorkStarted(interactions, threadID);
24178 } catch (error) {
24179 // If the subscriber throws, rethrow it in a separate task
24180 scheduleCallback(ImmediatePriority$1, function () {
24181 throw error;
24182 });
24183 }
24184 }
24185 }
24186}
24187
24188function finishPendingInteractions(root, committedLanes) {
24189
24190 var remainingLanesAfterCommit = root.pendingLanes;
24191 var subscriber;
24192
24193 try {
24194 subscriber = tracing.__subscriberRef.current;
24195
24196 if (subscriber !== null && root.memoizedInteractions.size > 0) {
24197 // FIXME: More than one lane can finish in a single commit.
24198 var threadID = computeThreadID(root, committedLanes);
24199 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
24200 }
24201 } catch (error) {
24202 // If the subscriber throws, rethrow it in a separate task
24203 scheduleCallback(ImmediatePriority$1, function () {
24204 throw error;
24205 });
24206 } finally {
24207 // Clear completed interactions from the pending Map.
24208 // Unless the render was suspended or cascading work was scheduled,
24209 // In which case– leave pending interactions until the subsequent render.
24210 var pendingInteractionMap = root.pendingInteractionMap;
24211 pendingInteractionMap.forEach(function (scheduledInteractions, lane) {
24212 // Only decrement the pending interaction count if we're done.
24213 // If there's still work at the current priority,
24214 // That indicates that we are waiting for suspense data.
24215 if (!includesSomeLane(remainingLanesAfterCommit, lane)) {
24216 pendingInteractionMap.delete(lane);
24217 scheduledInteractions.forEach(function (interaction) {
24218 interaction.__count--;
24219
24220 if (subscriber !== null && interaction.__count === 0) {
24221 try {
24222 subscriber.onInteractionScheduledWorkCompleted(interaction);
24223 } catch (error) {
24224 // If the subscriber throws, rethrow it in a separate task
24225 scheduleCallback(ImmediatePriority$1, function () {
24226 throw error;
24227 });
24228 }
24229 }
24230 });
24231 }
24232 });
24233 }
24234} // `act` testing API
24235
24236function shouldForceFlushFallbacksInDEV() {
24237 // Never force flush in production. This function should get stripped out.
24238 return actingUpdatesScopeDepth > 0;
24239}
24240// so we can tell if any async act() calls try to run in parallel.
24241
24242
24243var actingUpdatesScopeDepth = 0;
24244
24245function detachFiberAfterEffects(fiber) {
24246 fiber.sibling = null;
24247 fiber.stateNode = null;
24248}
24249
24250var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
24251
24252var failedBoundaries = null;
24253var setRefreshHandler = function (handler) {
24254 {
24255 resolveFamily = handler;
24256 }
24257};
24258function resolveFunctionForHotReloading(type) {
24259 {
24260 if (resolveFamily === null) {
24261 // Hot reloading is disabled.
24262 return type;
24263 }
24264
24265 var family = resolveFamily(type);
24266
24267 if (family === undefined) {
24268 return type;
24269 } // Use the latest known implementation.
24270
24271
24272 return family.current;
24273 }
24274}
24275function resolveClassForHotReloading(type) {
24276 // No implementation differences.
24277 return resolveFunctionForHotReloading(type);
24278}
24279function resolveForwardRefForHotReloading(type) {
24280 {
24281 if (resolveFamily === null) {
24282 // Hot reloading is disabled.
24283 return type;
24284 }
24285
24286 var family = resolveFamily(type);
24287
24288 if (family === undefined) {
24289 // Check if we're dealing with a real forwardRef. Don't want to crash early.
24290 if (type !== null && type !== undefined && typeof type.render === 'function') {
24291 // ForwardRef is special because its resolved .type is an object,
24292 // but it's possible that we only have its inner render function in the map.
24293 // If that inner render function is different, we'll build a new forwardRef type.
24294 var currentRender = resolveFunctionForHotReloading(type.render);
24295
24296 if (type.render !== currentRender) {
24297 var syntheticType = {
24298 $$typeof: REACT_FORWARD_REF_TYPE,
24299 render: currentRender
24300 };
24301
24302 if (type.displayName !== undefined) {
24303 syntheticType.displayName = type.displayName;
24304 }
24305
24306 return syntheticType;
24307 }
24308 }
24309
24310 return type;
24311 } // Use the latest known implementation.
24312
24313
24314 return family.current;
24315 }
24316}
24317function isCompatibleFamilyForHotReloading(fiber, element) {
24318 {
24319 if (resolveFamily === null) {
24320 // Hot reloading is disabled.
24321 return false;
24322 }
24323
24324 var prevType = fiber.elementType;
24325 var nextType = element.type; // If we got here, we know types aren't === equal.
24326
24327 var needsCompareFamilies = false;
24328 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
24329
24330 switch (fiber.tag) {
24331 case ClassComponent:
24332 {
24333 if (typeof nextType === 'function') {
24334 needsCompareFamilies = true;
24335 }
24336
24337 break;
24338 }
24339
24340 case FunctionComponent:
24341 {
24342 if (typeof nextType === 'function') {
24343 needsCompareFamilies = true;
24344 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24345 // We don't know the inner type yet.
24346 // We're going to assume that the lazy inner type is stable,
24347 // and so it is sufficient to avoid reconciling it away.
24348 // We're not going to unwrap or actually use the new lazy type.
24349 needsCompareFamilies = true;
24350 }
24351
24352 break;
24353 }
24354
24355 case ForwardRef:
24356 {
24357 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
24358 needsCompareFamilies = true;
24359 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24360 needsCompareFamilies = true;
24361 }
24362
24363 break;
24364 }
24365
24366 case MemoComponent:
24367 case SimpleMemoComponent:
24368 {
24369 if ($$typeofNextType === REACT_MEMO_TYPE) {
24370 // TODO: if it was but can no longer be simple,
24371 // we shouldn't set this.
24372 needsCompareFamilies = true;
24373 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
24374 needsCompareFamilies = true;
24375 }
24376
24377 break;
24378 }
24379
24380 default:
24381 return false;
24382 } // Check if both types have a family and it's the same one.
24383
24384
24385 if (needsCompareFamilies) {
24386 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
24387 // This means both of them need to be registered to preserve state.
24388 // If we unwrapped and compared the inner types for wrappers instead,
24389 // then we would risk falsely saying two separate memo(Foo)
24390 // calls are equivalent because they wrap the same Foo function.
24391 var prevFamily = resolveFamily(prevType);
24392
24393 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
24394 return true;
24395 }
24396 }
24397
24398 return false;
24399 }
24400}
24401function markFailedErrorBoundaryForHotReloading(fiber) {
24402 {
24403 if (resolveFamily === null) {
24404 // Hot reloading is disabled.
24405 return;
24406 }
24407
24408 if (typeof WeakSet !== 'function') {
24409 return;
24410 }
24411
24412 if (failedBoundaries === null) {
24413 failedBoundaries = new WeakSet();
24414 }
24415
24416 failedBoundaries.add(fiber);
24417 }
24418}
24419var scheduleRefresh = function (root, update) {
24420 {
24421 if (resolveFamily === null) {
24422 // Hot reloading is disabled.
24423 return;
24424 }
24425
24426 var staleFamilies = update.staleFamilies,
24427 updatedFamilies = update.updatedFamilies;
24428 flushPassiveEffects();
24429 flushSync(function () {
24430 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
24431 });
24432 }
24433};
24434var scheduleRoot = function (root, element) {
24435 {
24436 if (root.context !== emptyContextObject) {
24437 // Super edge case: root has a legacy _renderSubtree context
24438 // but we don't know the parentComponent so we can't pass it.
24439 // Just ignore. We'll delete this with _renderSubtree code path later.
24440 return;
24441 }
24442
24443 flushPassiveEffects();
24444 flushSync(function () {
24445 updateContainer(element, root, null, null);
24446 });
24447 }
24448};
24449
24450function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
24451 {
24452 var alternate = fiber.alternate,
24453 child = fiber.child,
24454 sibling = fiber.sibling,
24455 tag = fiber.tag,
24456 type = fiber.type;
24457 var candidateType = null;
24458
24459 switch (tag) {
24460 case FunctionComponent:
24461 case SimpleMemoComponent:
24462 case ClassComponent:
24463 candidateType = type;
24464 break;
24465
24466 case ForwardRef:
24467 candidateType = type.render;
24468 break;
24469 }
24470
24471 if (resolveFamily === null) {
24472 throw new Error('Expected resolveFamily to be set during hot reload.');
24473 }
24474
24475 var needsRender = false;
24476 var needsRemount = false;
24477
24478 if (candidateType !== null) {
24479 var family = resolveFamily(candidateType);
24480
24481 if (family !== undefined) {
24482 if (staleFamilies.has(family)) {
24483 needsRemount = true;
24484 } else if (updatedFamilies.has(family)) {
24485 if (tag === ClassComponent) {
24486 needsRemount = true;
24487 } else {
24488 needsRender = true;
24489 }
24490 }
24491 }
24492 }
24493
24494 if (failedBoundaries !== null) {
24495 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
24496 needsRemount = true;
24497 }
24498 }
24499
24500 if (needsRemount) {
24501 fiber._debugNeedsRemount = true;
24502 }
24503
24504 if (needsRemount || needsRender) {
24505 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
24506 }
24507
24508 if (child !== null && !needsRemount) {
24509 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
24510 }
24511
24512 if (sibling !== null) {
24513 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
24514 }
24515 }
24516}
24517
24518var findHostInstancesForRefresh = function (root, families) {
24519 {
24520 var hostInstances = new Set();
24521 var types = new Set(families.map(function (family) {
24522 return family.current;
24523 }));
24524 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
24525 return hostInstances;
24526 }
24527};
24528
24529function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
24530 {
24531 var child = fiber.child,
24532 sibling = fiber.sibling,
24533 tag = fiber.tag,
24534 type = fiber.type;
24535 var candidateType = null;
24536
24537 switch (tag) {
24538 case FunctionComponent:
24539 case SimpleMemoComponent:
24540 case ClassComponent:
24541 candidateType = type;
24542 break;
24543
24544 case ForwardRef:
24545 candidateType = type.render;
24546 break;
24547 }
24548
24549 var didMatch = false;
24550
24551 if (candidateType !== null) {
24552 if (types.has(candidateType)) {
24553 didMatch = true;
24554 }
24555 }
24556
24557 if (didMatch) {
24558 // We have a match. This only drills down to the closest host components.
24559 // There's no need to search deeper because for the purpose of giving
24560 // visual feedback, "flashing" outermost parent rectangles is sufficient.
24561 findHostInstancesForFiberShallowly(fiber, hostInstances);
24562 } else {
24563 // If there's no match, maybe there will be one further down in the child tree.
24564 if (child !== null) {
24565 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
24566 }
24567 }
24568
24569 if (sibling !== null) {
24570 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
24571 }
24572 }
24573}
24574
24575function findHostInstancesForFiberShallowly(fiber, hostInstances) {
24576 {
24577 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
24578
24579 if (foundHostInstances) {
24580 return;
24581 } // If we didn't find any host children, fallback to closest host parent.
24582
24583
24584 var node = fiber;
24585
24586 while (true) {
24587 switch (node.tag) {
24588 case HostComponent:
24589 hostInstances.add(node.stateNode);
24590 return;
24591
24592 case HostPortal:
24593 hostInstances.add(node.stateNode.containerInfo);
24594 return;
24595
24596 case HostRoot:
24597 hostInstances.add(node.stateNode.containerInfo);
24598 return;
24599 }
24600
24601 if (node.return === null) {
24602 throw new Error('Expected to reach root first.');
24603 }
24604
24605 node = node.return;
24606 }
24607 }
24608}
24609
24610function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
24611 {
24612 var node = fiber;
24613 var foundHostInstances = false;
24614
24615 while (true) {
24616 if (node.tag === HostComponent) {
24617 // We got a match.
24618 foundHostInstances = true;
24619 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
24620 } else if (node.child !== null) {
24621 node.child.return = node;
24622 node = node.child;
24623 continue;
24624 }
24625
24626 if (node === fiber) {
24627 return foundHostInstances;
24628 }
24629
24630 while (node.sibling === null) {
24631 if (node.return === null || node.return === fiber) {
24632 return foundHostInstances;
24633 }
24634
24635 node = node.return;
24636 }
24637
24638 node.sibling.return = node.return;
24639 node = node.sibling;
24640 }
24641 }
24642
24643 return false;
24644}
24645
24646var hasBadMapPolyfill;
24647
24648{
24649 hasBadMapPolyfill = false;
24650
24651 try {
24652 var nonExtensibleObject = Object.preventExtensions({});
24653 /* eslint-disable no-new */
24654
24655 new Map([[nonExtensibleObject, null]]);
24656 new Set([nonExtensibleObject]);
24657 /* eslint-enable no-new */
24658 } catch (e) {
24659 // TODO: Consider warning about bad polyfills
24660 hasBadMapPolyfill = true;
24661 }
24662}
24663
24664var debugCounter = 1;
24665
24666function FiberNode(tag, pendingProps, key, mode) {
24667 // Instance
24668 this.tag = tag;
24669 this.key = key;
24670 this.elementType = null;
24671 this.type = null;
24672 this.stateNode = null; // Fiber
24673
24674 this.return = null;
24675 this.child = null;
24676 this.sibling = null;
24677 this.index = 0;
24678 this.ref = null;
24679 this.pendingProps = pendingProps;
24680 this.memoizedProps = null;
24681 this.updateQueue = null;
24682 this.memoizedState = null;
24683 this.dependencies = null;
24684 this.mode = mode; // Effects
24685
24686 this.flags = NoFlags;
24687 this.nextEffect = null;
24688 this.firstEffect = null;
24689 this.lastEffect = null;
24690 this.lanes = NoLanes;
24691 this.childLanes = NoLanes;
24692 this.alternate = null;
24693
24694 {
24695 // Note: The following is done to avoid a v8 performance cliff.
24696 //
24697 // Initializing the fields below to smis and later updating them with
24698 // double values will cause Fibers to end up having separate shapes.
24699 // This behavior/bug has something to do with Object.preventExtension().
24700 // Fortunately this only impacts DEV builds.
24701 // Unfortunately it makes React unusably slow for some applications.
24702 // To work around this, initialize the fields below with doubles.
24703 //
24704 // Learn more about this here:
24705 // https://github.com/facebook/react/issues/14365
24706 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
24707 this.actualDuration = Number.NaN;
24708 this.actualStartTime = Number.NaN;
24709 this.selfBaseDuration = Number.NaN;
24710 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
24711 // This won't trigger the performance cliff mentioned above,
24712 // and it simplifies other profiler code (including DevTools).
24713
24714 this.actualDuration = 0;
24715 this.actualStartTime = -1;
24716 this.selfBaseDuration = 0;
24717 this.treeBaseDuration = 0;
24718 }
24719
24720 {
24721 // This isn't directly used but is handy for debugging internals:
24722 this._debugID = debugCounter++;
24723 this._debugSource = null;
24724 this._debugOwner = null;
24725 this._debugNeedsRemount = false;
24726 this._debugHookTypes = null;
24727
24728 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
24729 Object.preventExtensions(this);
24730 }
24731 }
24732} // This is a constructor function, rather than a POJO constructor, still
24733// please ensure we do the following:
24734// 1) Nobody should add any instance methods on this. Instance methods can be
24735// more difficult to predict when they get optimized and they are almost
24736// never inlined properly in static compilers.
24737// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
24738// always know when it is a fiber.
24739// 3) We might want to experiment with using numeric keys since they are easier
24740// to optimize in a non-JIT environment.
24741// 4) We can easily go from a constructor to a createFiber object literal if that
24742// is faster.
24743// 5) It should be easy to port this to a C struct and keep a C implementation
24744// compatible.
24745
24746
24747var createFiber = function (tag, pendingProps, key, mode) {
24748 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
24749 return new FiberNode(tag, pendingProps, key, mode);
24750};
24751
24752function shouldConstruct$1(Component) {
24753 var prototype = Component.prototype;
24754 return !!(prototype && prototype.isReactComponent);
24755}
24756
24757function isSimpleFunctionComponent(type) {
24758 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
24759}
24760function resolveLazyComponentTag(Component) {
24761 if (typeof Component === 'function') {
24762 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
24763 } else if (Component !== undefined && Component !== null) {
24764 var $$typeof = Component.$$typeof;
24765
24766 if ($$typeof === REACT_FORWARD_REF_TYPE) {
24767 return ForwardRef;
24768 }
24769
24770 if ($$typeof === REACT_MEMO_TYPE) {
24771 return MemoComponent;
24772 }
24773 }
24774
24775 return IndeterminateComponent;
24776} // This is used to create an alternate fiber to do work on.
24777
24778function createWorkInProgress(current, pendingProps) {
24779 var workInProgress = current.alternate;
24780
24781 if (workInProgress === null) {
24782 // We use a double buffering pooling technique because we know that we'll
24783 // only ever need at most two versions of a tree. We pool the "other" unused
24784 // node that we're free to reuse. This is lazily created to avoid allocating
24785 // extra objects for things that are never updated. It also allow us to
24786 // reclaim the extra memory if needed.
24787 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
24788 workInProgress.elementType = current.elementType;
24789 workInProgress.type = current.type;
24790 workInProgress.stateNode = current.stateNode;
24791
24792 {
24793 // DEV-only fields
24794 workInProgress._debugID = current._debugID;
24795 workInProgress._debugSource = current._debugSource;
24796 workInProgress._debugOwner = current._debugOwner;
24797 workInProgress._debugHookTypes = current._debugHookTypes;
24798 }
24799
24800 workInProgress.alternate = current;
24801 current.alternate = workInProgress;
24802 } else {
24803 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
24804
24805 workInProgress.type = current.type; // We already have an alternate.
24806 // Reset the effect tag.
24807
24808 workInProgress.flags = NoFlags; // The effect list is no longer valid.
24809
24810 workInProgress.nextEffect = null;
24811 workInProgress.firstEffect = null;
24812 workInProgress.lastEffect = null;
24813
24814 {
24815 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
24816 // This prevents time from endlessly accumulating in new commits.
24817 // This has the downside of resetting values for different priority renders,
24818 // But works for yielding (the common case) and should support resuming.
24819 workInProgress.actualDuration = 0;
24820 workInProgress.actualStartTime = -1;
24821 }
24822 }
24823
24824 workInProgress.childLanes = current.childLanes;
24825 workInProgress.lanes = current.lanes;
24826 workInProgress.child = current.child;
24827 workInProgress.memoizedProps = current.memoizedProps;
24828 workInProgress.memoizedState = current.memoizedState;
24829 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
24830 // it cannot be shared with the current fiber.
24831
24832 var currentDependencies = current.dependencies;
24833 workInProgress.dependencies = currentDependencies === null ? null : {
24834 lanes: currentDependencies.lanes,
24835 firstContext: currentDependencies.firstContext
24836 }; // These will be overridden during the parent's reconciliation
24837
24838 workInProgress.sibling = current.sibling;
24839 workInProgress.index = current.index;
24840 workInProgress.ref = current.ref;
24841
24842 {
24843 workInProgress.selfBaseDuration = current.selfBaseDuration;
24844 workInProgress.treeBaseDuration = current.treeBaseDuration;
24845 }
24846
24847 {
24848 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
24849
24850 switch (workInProgress.tag) {
24851 case IndeterminateComponent:
24852 case FunctionComponent:
24853 case SimpleMemoComponent:
24854 workInProgress.type = resolveFunctionForHotReloading(current.type);
24855 break;
24856
24857 case ClassComponent:
24858 workInProgress.type = resolveClassForHotReloading(current.type);
24859 break;
24860
24861 case ForwardRef:
24862 workInProgress.type = resolveForwardRefForHotReloading(current.type);
24863 break;
24864 }
24865 }
24866
24867 return workInProgress;
24868} // Used to reuse a Fiber for a second pass.
24869
24870function resetWorkInProgress(workInProgress, renderLanes) {
24871 // This resets the Fiber to what createFiber or createWorkInProgress would
24872 // have set the values to before during the first pass. Ideally this wouldn't
24873 // be necessary but unfortunately many code paths reads from the workInProgress
24874 // when they should be reading from current and writing to workInProgress.
24875 // We assume pendingProps, index, key, ref, return are still untouched to
24876 // avoid doing another reconciliation.
24877 // Reset the effect tag but keep any Placement tags, since that's something
24878 // that child fiber is setting, not the reconciliation.
24879 workInProgress.flags &= Placement; // The effect list is no longer valid.
24880
24881 workInProgress.nextEffect = null;
24882 workInProgress.firstEffect = null;
24883 workInProgress.lastEffect = null;
24884 var current = workInProgress.alternate;
24885
24886 if (current === null) {
24887 // Reset to createFiber's initial values.
24888 workInProgress.childLanes = NoLanes;
24889 workInProgress.lanes = renderLanes;
24890 workInProgress.child = null;
24891 workInProgress.memoizedProps = null;
24892 workInProgress.memoizedState = null;
24893 workInProgress.updateQueue = null;
24894 workInProgress.dependencies = null;
24895 workInProgress.stateNode = null;
24896
24897 {
24898 // Note: We don't reset the actualTime counts. It's useful to accumulate
24899 // actual time across multiple render passes.
24900 workInProgress.selfBaseDuration = 0;
24901 workInProgress.treeBaseDuration = 0;
24902 }
24903 } else {
24904 // Reset to the cloned values that createWorkInProgress would've.
24905 workInProgress.childLanes = current.childLanes;
24906 workInProgress.lanes = current.lanes;
24907 workInProgress.child = current.child;
24908 workInProgress.memoizedProps = current.memoizedProps;
24909 workInProgress.memoizedState = current.memoizedState;
24910 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
24911
24912 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
24913 // it cannot be shared with the current fiber.
24914
24915 var currentDependencies = current.dependencies;
24916 workInProgress.dependencies = currentDependencies === null ? null : {
24917 lanes: currentDependencies.lanes,
24918 firstContext: currentDependencies.firstContext
24919 };
24920
24921 {
24922 // Note: We don't reset the actualTime counts. It's useful to accumulate
24923 // actual time across multiple render passes.
24924 workInProgress.selfBaseDuration = current.selfBaseDuration;
24925 workInProgress.treeBaseDuration = current.treeBaseDuration;
24926 }
24927 }
24928
24929 return workInProgress;
24930}
24931function createHostRootFiber(tag) {
24932 var mode;
24933
24934 if (tag === ConcurrentRoot) {
24935 mode = ConcurrentMode | BlockingMode | StrictMode;
24936 } else if (tag === BlockingRoot) {
24937 mode = BlockingMode | StrictMode;
24938 } else {
24939 mode = NoMode;
24940 }
24941
24942 if ( isDevToolsPresent) {
24943 // Always collect profile timings when DevTools are present.
24944 // This enables DevTools to start capturing timing at any point–
24945 // Without some nodes in the tree having empty base times.
24946 mode |= ProfileMode;
24947 }
24948
24949 return createFiber(HostRoot, null, null, mode);
24950}
24951function createFiberFromTypeAndProps(type, // React$ElementType
24952key, pendingProps, owner, mode, lanes) {
24953 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
24954
24955 var resolvedType = type;
24956
24957 if (typeof type === 'function') {
24958 if (shouldConstruct$1(type)) {
24959 fiberTag = ClassComponent;
24960
24961 {
24962 resolvedType = resolveClassForHotReloading(resolvedType);
24963 }
24964 } else {
24965 {
24966 resolvedType = resolveFunctionForHotReloading(resolvedType);
24967 }
24968 }
24969 } else if (typeof type === 'string') {
24970 fiberTag = HostComponent;
24971 } else {
24972 getTag: switch (type) {
24973 case REACT_FRAGMENT_TYPE:
24974 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
24975
24976 case REACT_DEBUG_TRACING_MODE_TYPE:
24977 fiberTag = Mode;
24978 mode |= DebugTracingMode;
24979 break;
24980
24981 case REACT_STRICT_MODE_TYPE:
24982 fiberTag = Mode;
24983 mode |= StrictMode;
24984 break;
24985
24986 case REACT_PROFILER_TYPE:
24987 return createFiberFromProfiler(pendingProps, mode, lanes, key);
24988
24989 case REACT_SUSPENSE_TYPE:
24990 return createFiberFromSuspense(pendingProps, mode, lanes, key);
24991
24992 case REACT_SUSPENSE_LIST_TYPE:
24993 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
24994
24995 case REACT_OFFSCREEN_TYPE:
24996 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
24997
24998 case REACT_LEGACY_HIDDEN_TYPE:
24999 return createFiberFromLegacyHidden(pendingProps, mode, lanes, key);
25000
25001 case REACT_SCOPE_TYPE:
25002
25003 // eslint-disable-next-line no-fallthrough
25004
25005 default:
25006 {
25007 if (typeof type === 'object' && type !== null) {
25008 switch (type.$$typeof) {
25009 case REACT_PROVIDER_TYPE:
25010 fiberTag = ContextProvider;
25011 break getTag;
25012
25013 case REACT_CONTEXT_TYPE:
25014 // This is a consumer
25015 fiberTag = ContextConsumer;
25016 break getTag;
25017
25018 case REACT_FORWARD_REF_TYPE:
25019 fiberTag = ForwardRef;
25020
25021 {
25022 resolvedType = resolveForwardRefForHotReloading(resolvedType);
25023 }
25024
25025 break getTag;
25026
25027 case REACT_MEMO_TYPE:
25028 fiberTag = MemoComponent;
25029 break getTag;
25030
25031 case REACT_LAZY_TYPE:
25032 fiberTag = LazyComponent;
25033 resolvedType = null;
25034 break getTag;
25035
25036 case REACT_BLOCK_TYPE:
25037 fiberTag = Block;
25038 break getTag;
25039 }
25040 }
25041
25042 var info = '';
25043
25044 {
25045 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
25046 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.';
25047 }
25048
25049 var ownerName = owner ? getComponentName(owner.type) : null;
25050
25051 if (ownerName) {
25052 info += '\n\nCheck the render method of `' + ownerName + '`.';
25053 }
25054 }
25055
25056 {
25057 {
25058 throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info );
25059 }
25060 }
25061 }
25062 }
25063 }
25064
25065 var fiber = createFiber(fiberTag, pendingProps, key, mode);
25066 fiber.elementType = type;
25067 fiber.type = resolvedType;
25068 fiber.lanes = lanes;
25069
25070 {
25071 fiber._debugOwner = owner;
25072 }
25073
25074 return fiber;
25075}
25076function createFiberFromElement(element, mode, lanes) {
25077 var owner = null;
25078
25079 {
25080 owner = element._owner;
25081 }
25082
25083 var type = element.type;
25084 var key = element.key;
25085 var pendingProps = element.props;
25086 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
25087
25088 {
25089 fiber._debugSource = element._source;
25090 fiber._debugOwner = element._owner;
25091 }
25092
25093 return fiber;
25094}
25095function createFiberFromFragment(elements, mode, lanes, key) {
25096 var fiber = createFiber(Fragment, elements, key, mode);
25097 fiber.lanes = lanes;
25098 return fiber;
25099}
25100
25101function createFiberFromProfiler(pendingProps, mode, lanes, key) {
25102 {
25103 if (typeof pendingProps.id !== 'string') {
25104 error('Profiler must specify an "id" as a prop');
25105 }
25106 }
25107
25108 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
25109
25110 fiber.elementType = REACT_PROFILER_TYPE;
25111 fiber.type = REACT_PROFILER_TYPE;
25112 fiber.lanes = lanes;
25113
25114 {
25115 fiber.stateNode = {
25116 effectDuration: 0,
25117 passiveEffectDuration: 0
25118 };
25119 }
25120
25121 return fiber;
25122}
25123
25124function createFiberFromSuspense(pendingProps, mode, lanes, key) {
25125 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
25126 // This needs to be fixed in getComponentName so that it relies on the tag
25127 // instead.
25128
25129 fiber.type = REACT_SUSPENSE_TYPE;
25130 fiber.elementType = REACT_SUSPENSE_TYPE;
25131 fiber.lanes = lanes;
25132 return fiber;
25133}
25134function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
25135 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
25136
25137 {
25138 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
25139 // This needs to be fixed in getComponentName so that it relies on the tag
25140 // instead.
25141 fiber.type = REACT_SUSPENSE_LIST_TYPE;
25142 }
25143
25144 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
25145 fiber.lanes = lanes;
25146 return fiber;
25147}
25148function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
25149 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); // TODO: The OffscreenComponent fiber shouldn't have a type. It has a tag.
25150 // This needs to be fixed in getComponentName so that it relies on the tag
25151 // instead.
25152
25153 {
25154 fiber.type = REACT_OFFSCREEN_TYPE;
25155 }
25156
25157 fiber.elementType = REACT_OFFSCREEN_TYPE;
25158 fiber.lanes = lanes;
25159 return fiber;
25160}
25161function createFiberFromLegacyHidden(pendingProps, mode, lanes, key) {
25162 var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); // TODO: The LegacyHidden fiber shouldn't have a type. It has a tag.
25163 // This needs to be fixed in getComponentName so that it relies on the tag
25164 // instead.
25165
25166 {
25167 fiber.type = REACT_LEGACY_HIDDEN_TYPE;
25168 }
25169
25170 fiber.elementType = REACT_LEGACY_HIDDEN_TYPE;
25171 fiber.lanes = lanes;
25172 return fiber;
25173}
25174function createFiberFromText(content, mode, lanes) {
25175 var fiber = createFiber(HostText, content, null, mode);
25176 fiber.lanes = lanes;
25177 return fiber;
25178}
25179function createFiberFromHostInstanceForDeletion() {
25180 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
25181
25182 fiber.elementType = 'DELETED';
25183 fiber.type = 'DELETED';
25184 return fiber;
25185}
25186function createFiberFromPortal(portal, mode, lanes) {
25187 var pendingProps = portal.children !== null ? portal.children : [];
25188 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
25189 fiber.lanes = lanes;
25190 fiber.stateNode = {
25191 containerInfo: portal.containerInfo,
25192 pendingChildren: null,
25193 // Used by persistent updates
25194 implementation: portal.implementation
25195 };
25196 return fiber;
25197} // Used for stashing WIP properties to replay failed work in DEV.
25198
25199function assignFiberPropertiesInDEV(target, source) {
25200 if (target === null) {
25201 // This Fiber's initial properties will always be overwritten.
25202 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
25203 target = createFiber(IndeterminateComponent, null, null, NoMode);
25204 } // This is intentionally written as a list of all properties.
25205 // We tried to use Object.assign() instead but this is called in
25206 // the hottest path, and Object.assign() was too slow:
25207 // https://github.com/facebook/react/issues/12502
25208 // This code is DEV-only so size is not a concern.
25209
25210
25211 target.tag = source.tag;
25212 target.key = source.key;
25213 target.elementType = source.elementType;
25214 target.type = source.type;
25215 target.stateNode = source.stateNode;
25216 target.return = source.return;
25217 target.child = source.child;
25218 target.sibling = source.sibling;
25219 target.index = source.index;
25220 target.ref = source.ref;
25221 target.pendingProps = source.pendingProps;
25222 target.memoizedProps = source.memoizedProps;
25223 target.updateQueue = source.updateQueue;
25224 target.memoizedState = source.memoizedState;
25225 target.dependencies = source.dependencies;
25226 target.mode = source.mode;
25227 target.flags = source.flags;
25228 target.nextEffect = source.nextEffect;
25229 target.firstEffect = source.firstEffect;
25230 target.lastEffect = source.lastEffect;
25231 target.lanes = source.lanes;
25232 target.childLanes = source.childLanes;
25233 target.alternate = source.alternate;
25234
25235 {
25236 target.actualDuration = source.actualDuration;
25237 target.actualStartTime = source.actualStartTime;
25238 target.selfBaseDuration = source.selfBaseDuration;
25239 target.treeBaseDuration = source.treeBaseDuration;
25240 }
25241
25242 target._debugID = source._debugID;
25243 target._debugSource = source._debugSource;
25244 target._debugOwner = source._debugOwner;
25245 target._debugNeedsRemount = source._debugNeedsRemount;
25246 target._debugHookTypes = source._debugHookTypes;
25247 return target;
25248}
25249
25250function FiberRootNode(containerInfo, tag, hydrate) {
25251 this.tag = tag;
25252 this.containerInfo = containerInfo;
25253 this.pendingChildren = null;
25254 this.current = null;
25255 this.pingCache = null;
25256 this.finishedWork = null;
25257 this.timeoutHandle = noTimeout;
25258 this.context = null;
25259 this.pendingContext = null;
25260 this.hydrate = hydrate;
25261 this.callbackNode = null;
25262 this.callbackPriority = NoLanePriority;
25263 this.eventTimes = createLaneMap(NoLanes);
25264 this.expirationTimes = createLaneMap(NoTimestamp);
25265 this.pendingLanes = NoLanes;
25266 this.suspendedLanes = NoLanes;
25267 this.pingedLanes = NoLanes;
25268 this.expiredLanes = NoLanes;
25269 this.mutableReadLanes = NoLanes;
25270 this.finishedLanes = NoLanes;
25271 this.entangledLanes = NoLanes;
25272 this.entanglements = createLaneMap(NoLanes);
25273
25274 {
25275 this.mutableSourceEagerHydrationData = null;
25276 }
25277
25278 {
25279 this.interactionThreadID = tracing.unstable_getThreadID();
25280 this.memoizedInteractions = new Set();
25281 this.pendingInteractionMap = new Map();
25282 }
25283
25284 {
25285 switch (tag) {
25286 case BlockingRoot:
25287 this._debugRootType = 'createBlockingRoot()';
25288 break;
25289
25290 case ConcurrentRoot:
25291 this._debugRootType = 'createRoot()';
25292 break;
25293
25294 case LegacyRoot:
25295 this._debugRootType = 'createLegacyRoot()';
25296 break;
25297 }
25298 }
25299}
25300
25301function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
25302 var root = new FiberRootNode(containerInfo, tag, hydrate);
25303 // stateNode is any.
25304
25305
25306 var uninitializedFiber = createHostRootFiber(tag);
25307 root.current = uninitializedFiber;
25308 uninitializedFiber.stateNode = root;
25309 initializeUpdateQueue(uninitializedFiber);
25310 return root;
25311}
25312
25313// This ensures that the version used for server rendering matches the one
25314// that is eventually read during hydration.
25315// If they don't match there's a potential tear and a full deopt render is required.
25316
25317function registerMutableSourceForHydration(root, mutableSource) {
25318 var getVersion = mutableSource._getVersion;
25319 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
25320 // Retaining it forever may interfere with GC.
25321
25322 if (root.mutableSourceEagerHydrationData == null) {
25323 root.mutableSourceEagerHydrationData = [mutableSource, version];
25324 } else {
25325 root.mutableSourceEagerHydrationData.push(mutableSource, version);
25326 }
25327}
25328
25329function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
25330implementation) {
25331 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
25332 return {
25333 // This tag allow us to uniquely identify this as a React Portal
25334 $$typeof: REACT_PORTAL_TYPE,
25335 key: key == null ? null : '' + key,
25336 children: children,
25337 containerInfo: containerInfo,
25338 implementation: implementation
25339 };
25340}
25341
25342var didWarnAboutNestedUpdates;
25343var didWarnAboutFindNodeInStrictMode;
25344
25345{
25346 didWarnAboutNestedUpdates = false;
25347 didWarnAboutFindNodeInStrictMode = {};
25348}
25349
25350function getContextForSubtree(parentComponent) {
25351 if (!parentComponent) {
25352 return emptyContextObject;
25353 }
25354
25355 var fiber = get(parentComponent);
25356 var parentContext = findCurrentUnmaskedContext(fiber);
25357
25358 if (fiber.tag === ClassComponent) {
25359 var Component = fiber.type;
25360
25361 if (isContextProvider(Component)) {
25362 return processChildContext(fiber, Component, parentContext);
25363 }
25364 }
25365
25366 return parentContext;
25367}
25368
25369function findHostInstanceWithWarning(component, methodName) {
25370 {
25371 var fiber = get(component);
25372
25373 if (fiber === undefined) {
25374 if (typeof component.render === 'function') {
25375 {
25376 {
25377 throw Error( "Unable to find node on an unmounted component." );
25378 }
25379 }
25380 } else {
25381 {
25382 {
25383 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) );
25384 }
25385 }
25386 }
25387 }
25388
25389 var hostFiber = findCurrentHostFiber(fiber);
25390
25391 if (hostFiber === null) {
25392 return null;
25393 }
25394
25395 if (hostFiber.mode & StrictMode) {
25396 var componentName = getComponentName(fiber.type) || 'Component';
25397
25398 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
25399 didWarnAboutFindNodeInStrictMode[componentName] = true;
25400 var previousFiber = current;
25401
25402 try {
25403 setCurrentFiber(hostFiber);
25404
25405 if (fiber.mode & StrictMode) {
25406 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
25407 } else {
25408 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
25409 }
25410 } finally {
25411 // Ideally this should reset to previous but this shouldn't be called in
25412 // render and there's another warning for that anyway.
25413 if (previousFiber) {
25414 setCurrentFiber(previousFiber);
25415 } else {
25416 resetCurrentFiber();
25417 }
25418 }
25419 }
25420 }
25421
25422 return hostFiber.stateNode;
25423 }
25424}
25425
25426function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
25427 return createFiberRoot(containerInfo, tag, hydrate);
25428}
25429function updateContainer(element, container, parentComponent, callback) {
25430 {
25431 onScheduleRoot(container, element);
25432 }
25433
25434 var current$1 = container.current;
25435 var eventTime = requestEventTime();
25436
25437 {
25438 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
25439 if ('undefined' !== typeof jest) {
25440 warnIfUnmockedScheduler(current$1);
25441 warnIfNotScopedWithMatchingAct(current$1);
25442 }
25443 }
25444
25445 var lane = requestUpdateLane(current$1);
25446
25447 var context = getContextForSubtree(parentComponent);
25448
25449 if (container.context === null) {
25450 container.context = context;
25451 } else {
25452 container.pendingContext = context;
25453 }
25454
25455 {
25456 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
25457 didWarnAboutNestedUpdates = true;
25458
25459 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current.type) || 'Unknown');
25460 }
25461 }
25462
25463 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
25464 // being called "element".
25465
25466 update.payload = {
25467 element: element
25468 };
25469 callback = callback === undefined ? null : callback;
25470
25471 if (callback !== null) {
25472 {
25473 if (typeof callback !== 'function') {
25474 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
25475 }
25476 }
25477
25478 update.callback = callback;
25479 }
25480
25481 enqueueUpdate(current$1, update);
25482 scheduleUpdateOnFiber(current$1, lane, eventTime);
25483 return lane;
25484}
25485function getPublicRootInstance(container) {
25486 var containerFiber = container.current;
25487
25488 if (!containerFiber.child) {
25489 return null;
25490 }
25491
25492 switch (containerFiber.child.tag) {
25493 case HostComponent:
25494 return getPublicInstance(containerFiber.child.stateNode);
25495
25496 default:
25497 return containerFiber.child.stateNode;
25498 }
25499}
25500
25501function markRetryLaneImpl(fiber, retryLane) {
25502 var suspenseState = fiber.memoizedState;
25503
25504 if (suspenseState !== null && suspenseState.dehydrated !== null) {
25505 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
25506 }
25507} // Increases the priority of thennables when they resolve within this boundary.
25508
25509
25510function markRetryLaneIfNotHydrated(fiber, retryLane) {
25511 markRetryLaneImpl(fiber, retryLane);
25512 var alternate = fiber.alternate;
25513
25514 if (alternate) {
25515 markRetryLaneImpl(alternate, retryLane);
25516 }
25517}
25518
25519function attemptUserBlockingHydration$1(fiber) {
25520 if (fiber.tag !== SuspenseComponent) {
25521 // We ignore HostRoots here because we can't increase
25522 // their priority and they should not suspend on I/O,
25523 // since you have to wrap anything that might suspend in
25524 // Suspense.
25525 return;
25526 }
25527
25528 var eventTime = requestEventTime();
25529 var lane = InputDiscreteHydrationLane;
25530 scheduleUpdateOnFiber(fiber, lane, eventTime);
25531 markRetryLaneIfNotHydrated(fiber, lane);
25532}
25533function attemptContinuousHydration$1(fiber) {
25534 if (fiber.tag !== SuspenseComponent) {
25535 // We ignore HostRoots here because we can't increase
25536 // their priority and they should not suspend on I/O,
25537 // since you have to wrap anything that might suspend in
25538 // Suspense.
25539 return;
25540 }
25541
25542 var eventTime = requestEventTime();
25543 var lane = SelectiveHydrationLane;
25544 scheduleUpdateOnFiber(fiber, lane, eventTime);
25545 markRetryLaneIfNotHydrated(fiber, lane);
25546}
25547function attemptHydrationAtCurrentPriority$1(fiber) {
25548 if (fiber.tag !== SuspenseComponent) {
25549 // We ignore HostRoots here because we can't increase
25550 // their priority other than synchronously flush it.
25551 return;
25552 }
25553
25554 var eventTime = requestEventTime();
25555 var lane = requestUpdateLane(fiber);
25556 scheduleUpdateOnFiber(fiber, lane, eventTime);
25557 markRetryLaneIfNotHydrated(fiber, lane);
25558}
25559function runWithPriority$2(priority, fn) {
25560
25561 try {
25562 setCurrentUpdateLanePriority(priority);
25563 return fn();
25564 } finally {
25565 }
25566}
25567function findHostInstanceWithNoPortals(fiber) {
25568 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
25569
25570 if (hostFiber === null) {
25571 return null;
25572 }
25573
25574 if (hostFiber.tag === FundamentalComponent) {
25575 return hostFiber.stateNode.instance;
25576 }
25577
25578 return hostFiber.stateNode;
25579}
25580
25581var shouldSuspendImpl = function (fiber) {
25582 return false;
25583};
25584
25585function shouldSuspend(fiber) {
25586 return shouldSuspendImpl(fiber);
25587}
25588var overrideHookState = null;
25589var overrideHookStateDeletePath = null;
25590var overrideHookStateRenamePath = null;
25591var overrideProps = null;
25592var overridePropsDeletePath = null;
25593var overridePropsRenamePath = null;
25594var scheduleUpdate = null;
25595var setSuspenseHandler = null;
25596
25597{
25598 var copyWithDeleteImpl = function (obj, path, index) {
25599 var key = path[index];
25600 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
25601
25602 if (index + 1 === path.length) {
25603 if (Array.isArray(updated)) {
25604 updated.splice(key, 1);
25605 } else {
25606 delete updated[key];
25607 }
25608
25609 return updated;
25610 } // $FlowFixMe number or string is fine here
25611
25612
25613 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
25614 return updated;
25615 };
25616
25617 var copyWithDelete = function (obj, path) {
25618 return copyWithDeleteImpl(obj, path, 0);
25619 };
25620
25621 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
25622 var oldKey = oldPath[index];
25623 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
25624
25625 if (index + 1 === oldPath.length) {
25626 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
25627
25628 updated[newKey] = updated[oldKey];
25629
25630 if (Array.isArray(updated)) {
25631 updated.splice(oldKey, 1);
25632 } else {
25633 delete updated[oldKey];
25634 }
25635 } else {
25636 // $FlowFixMe number or string is fine here
25637 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
25638 obj[oldKey], oldPath, newPath, index + 1);
25639 }
25640
25641 return updated;
25642 };
25643
25644 var copyWithRename = function (obj, oldPath, newPath) {
25645 if (oldPath.length !== newPath.length) {
25646 warn('copyWithRename() expects paths of the same length');
25647
25648 return;
25649 } else {
25650 for (var i = 0; i < newPath.length - 1; i++) {
25651 if (oldPath[i] !== newPath[i]) {
25652 warn('copyWithRename() expects paths to be the same except for the deepest key');
25653
25654 return;
25655 }
25656 }
25657 }
25658
25659 return copyWithRenameImpl(obj, oldPath, newPath, 0);
25660 };
25661
25662 var copyWithSetImpl = function (obj, path, index, value) {
25663 if (index >= path.length) {
25664 return value;
25665 }
25666
25667 var key = path[index];
25668 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
25669
25670 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
25671 return updated;
25672 };
25673
25674 var copyWithSet = function (obj, path, value) {
25675 return copyWithSetImpl(obj, path, 0, value);
25676 };
25677
25678 var findHook = function (fiber, id) {
25679 // For now, the "id" of stateful hooks is just the stateful hook index.
25680 // This may change in the future with e.g. nested hooks.
25681 var currentHook = fiber.memoizedState;
25682
25683 while (currentHook !== null && id > 0) {
25684 currentHook = currentHook.next;
25685 id--;
25686 }
25687
25688 return currentHook;
25689 }; // Support DevTools editable values for useState and useReducer.
25690
25691
25692 overrideHookState = function (fiber, id, path, value) {
25693 var hook = findHook(fiber, id);
25694
25695 if (hook !== null) {
25696 var newState = copyWithSet(hook.memoizedState, path, value);
25697 hook.memoizedState = newState;
25698 hook.baseState = newState; // We aren't actually adding an update to the queue,
25699 // because there is no update we can add for useReducer hooks that won't trigger an error.
25700 // (There's no appropriate action type for DevTools overrides.)
25701 // As a result though, React will see the scheduled update as a noop and bailout.
25702 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25703
25704 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25705 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25706 }
25707 };
25708
25709 overrideHookStateDeletePath = function (fiber, id, path) {
25710 var hook = findHook(fiber, id);
25711
25712 if (hook !== null) {
25713 var newState = copyWithDelete(hook.memoizedState, path);
25714 hook.memoizedState = newState;
25715 hook.baseState = newState; // We aren't actually adding an update to the queue,
25716 // because there is no update we can add for useReducer hooks that won't trigger an error.
25717 // (There's no appropriate action type for DevTools overrides.)
25718 // As a result though, React will see the scheduled update as a noop and bailout.
25719 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25720
25721 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25722 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25723 }
25724 };
25725
25726 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
25727 var hook = findHook(fiber, id);
25728
25729 if (hook !== null) {
25730 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
25731 hook.memoizedState = newState;
25732 hook.baseState = newState; // We aren't actually adding an update to the queue,
25733 // because there is no update we can add for useReducer hooks that won't trigger an error.
25734 // (There's no appropriate action type for DevTools overrides.)
25735 // As a result though, React will see the scheduled update as a noop and bailout.
25736 // Shallow cloning props works as a workaround for now to bypass the bailout check.
25737
25738 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
25739 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25740 }
25741 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
25742
25743
25744 overrideProps = function (fiber, path, value) {
25745 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
25746
25747 if (fiber.alternate) {
25748 fiber.alternate.pendingProps = fiber.pendingProps;
25749 }
25750
25751 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25752 };
25753
25754 overridePropsDeletePath = function (fiber, path) {
25755 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
25756
25757 if (fiber.alternate) {
25758 fiber.alternate.pendingProps = fiber.pendingProps;
25759 }
25760
25761 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25762 };
25763
25764 overridePropsRenamePath = function (fiber, oldPath, newPath) {
25765 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
25766
25767 if (fiber.alternate) {
25768 fiber.alternate.pendingProps = fiber.pendingProps;
25769 }
25770
25771 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25772 };
25773
25774 scheduleUpdate = function (fiber) {
25775 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
25776 };
25777
25778 setSuspenseHandler = function (newShouldSuspendImpl) {
25779 shouldSuspendImpl = newShouldSuspendImpl;
25780 };
25781}
25782
25783function findHostInstanceByFiber(fiber) {
25784 var hostFiber = findCurrentHostFiber(fiber);
25785
25786 if (hostFiber === null) {
25787 return null;
25788 }
25789
25790 return hostFiber.stateNode;
25791}
25792
25793function emptyFindFiberByHostInstance(instance) {
25794 return null;
25795}
25796
25797function getCurrentFiberForDevTools() {
25798 return current;
25799}
25800
25801function injectIntoDevTools(devToolsConfig) {
25802 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
25803 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
25804 return injectInternals({
25805 bundleType: devToolsConfig.bundleType,
25806 version: devToolsConfig.version,
25807 rendererPackageName: devToolsConfig.rendererPackageName,
25808 rendererConfig: devToolsConfig.rendererConfig,
25809 overrideHookState: overrideHookState,
25810 overrideHookStateDeletePath: overrideHookStateDeletePath,
25811 overrideHookStateRenamePath: overrideHookStateRenamePath,
25812 overrideProps: overrideProps,
25813 overridePropsDeletePath: overridePropsDeletePath,
25814 overridePropsRenamePath: overridePropsRenamePath,
25815 setSuspenseHandler: setSuspenseHandler,
25816 scheduleUpdate: scheduleUpdate,
25817 currentDispatcherRef: ReactCurrentDispatcher,
25818 findHostInstanceByFiber: findHostInstanceByFiber,
25819 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
25820 // React Refresh
25821 findHostInstancesForRefresh: findHostInstancesForRefresh ,
25822 scheduleRefresh: scheduleRefresh ,
25823 scheduleRoot: scheduleRoot ,
25824 setRefreshHandler: setRefreshHandler ,
25825 // Enables DevTools to append owner stacks to error messages in DEV mode.
25826 getCurrentFiber: getCurrentFiberForDevTools
25827 });
25828}
25829
25830function ReactDOMRoot(container, options) {
25831 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
25832}
25833
25834function ReactDOMBlockingRoot(container, tag, options) {
25835 this._internalRoot = createRootImpl(container, tag, options);
25836}
25837
25838ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {
25839 var root = this._internalRoot;
25840
25841 {
25842 if (typeof arguments[1] === 'function') {
25843 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
25844 }
25845
25846 var container = root.containerInfo;
25847
25848 if (container.nodeType !== COMMENT_NODE) {
25849 var hostInstance = findHostInstanceWithNoPortals(root.current);
25850
25851 if (hostInstance) {
25852 if (hostInstance.parentNode !== container) {
25853 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container.");
25854 }
25855 }
25856 }
25857 }
25858
25859 updateContainer(children, root, null, null);
25860};
25861
25862ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {
25863 {
25864 if (typeof arguments[0] === 'function') {
25865 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
25866 }
25867 }
25868
25869 var root = this._internalRoot;
25870 var container = root.containerInfo;
25871 updateContainer(null, root, null, function () {
25872 unmarkContainerAsRoot(container);
25873 });
25874};
25875
25876function createRootImpl(container, tag, options) {
25877 // Tag is either LegacyRoot or Concurrent Root
25878 var hydrate = options != null && options.hydrate === true;
25879 var hydrationCallbacks = options != null && options.hydrationOptions || null;
25880 var mutableSources = options != null && options.hydrationOptions != null && options.hydrationOptions.mutableSources || null;
25881 var root = createContainer(container, tag, hydrate);
25882 markContainerAsRoot(root.current, container);
25883 var containerNodeType = container.nodeType;
25884
25885 {
25886 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
25887 listenToAllSupportedEvents(rootContainerElement);
25888 }
25889
25890 if (mutableSources) {
25891 for (var i = 0; i < mutableSources.length; i++) {
25892 var mutableSource = mutableSources[i];
25893 registerMutableSourceForHydration(root, mutableSource);
25894 }
25895 }
25896
25897 return root;
25898}
25899function createLegacyRoot(container, options) {
25900 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
25901}
25902function isValidContainer(node) {
25903 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable '));
25904}
25905
25906var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
25907var topLevelUpdateWarnings;
25908var warnedAboutHydrateAPI = false;
25909
25910{
25911 topLevelUpdateWarnings = function (container) {
25912 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
25913 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
25914
25915 if (hostInstance) {
25916 if (hostInstance.parentNode !== container) {
25917 error('render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.');
25918 }
25919 }
25920 }
25921
25922 var isRootRenderedBySomeReact = !!container._reactRootContainer;
25923 var rootEl = getReactRootElementInContainer(container);
25924 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
25925
25926 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
25927 error('render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.');
25928 }
25929
25930 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
25931 error('render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.');
25932 }
25933 };
25934}
25935
25936function getReactRootElementInContainer(container) {
25937 if (!container) {
25938 return null;
25939 }
25940
25941 if (container.nodeType === DOCUMENT_NODE) {
25942 return container.documentElement;
25943 } else {
25944 return container.firstChild;
25945 }
25946}
25947
25948function shouldHydrateDueToLegacyHeuristic(container) {
25949 var rootElement = getReactRootElementInContainer(container);
25950 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
25951}
25952
25953function legacyCreateRootFromDOMContainer(container, forceHydrate) {
25954 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
25955
25956 if (!shouldHydrate) {
25957 var warned = false;
25958 var rootSibling;
25959
25960 while (rootSibling = container.lastChild) {
25961 {
25962 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
25963 warned = true;
25964
25965 error('render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.');
25966 }
25967 }
25968
25969 container.removeChild(rootSibling);
25970 }
25971 }
25972
25973 {
25974 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
25975 warnedAboutHydrateAPI = true;
25976
25977 warn('render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v18. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');
25978 }
25979 }
25980
25981 return createLegacyRoot(container, shouldHydrate ? {
25982 hydrate: true
25983 } : undefined);
25984}
25985
25986function warnOnInvalidCallback$1(callback, callerName) {
25987 {
25988 if (callback !== null && typeof callback !== 'function') {
25989 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
25990 }
25991 }
25992}
25993
25994function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
25995 {
25996 topLevelUpdateWarnings(container);
25997 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
25998 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
25999 // member of intersection type." Whyyyyyy.
26000
26001
26002 var root = container._reactRootContainer;
26003 var fiberRoot;
26004
26005 if (!root) {
26006 // Initial mount
26007 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
26008 fiberRoot = root._internalRoot;
26009
26010 if (typeof callback === 'function') {
26011 var originalCallback = callback;
26012
26013 callback = function () {
26014 var instance = getPublicRootInstance(fiberRoot);
26015 originalCallback.call(instance);
26016 };
26017 } // Initial mount should not be batched.
26018
26019
26020 unbatchedUpdates(function () {
26021 updateContainer(children, fiberRoot, parentComponent, callback);
26022 });
26023 } else {
26024 fiberRoot = root._internalRoot;
26025
26026 if (typeof callback === 'function') {
26027 var _originalCallback = callback;
26028
26029 callback = function () {
26030 var instance = getPublicRootInstance(fiberRoot);
26031
26032 _originalCallback.call(instance);
26033 };
26034 } // Update
26035
26036
26037 updateContainer(children, fiberRoot, parentComponent, callback);
26038 }
26039
26040 return getPublicRootInstance(fiberRoot);
26041}
26042
26043function findDOMNode(componentOrElement) {
26044 {
26045 var owner = ReactCurrentOwner$3.current;
26046
26047 if (owner !== null && owner.stateNode !== null) {
26048 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
26049
26050 if (!warnedAboutRefsInRender) {
26051 error('%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(owner.type) || 'A component');
26052 }
26053
26054 owner.stateNode._warnedAboutRefsInRender = true;
26055 }
26056 }
26057
26058 if (componentOrElement == null) {
26059 return null;
26060 }
26061
26062 if (componentOrElement.nodeType === ELEMENT_NODE) {
26063 return componentOrElement;
26064 }
26065
26066 {
26067 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
26068 }
26069}
26070function hydrate(element, container, callback) {
26071 if (!isValidContainer(container)) {
26072 {
26073 throw Error( "Target container is not a DOM element." );
26074 }
26075 }
26076
26077 {
26078 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26079
26080 if (isModernRoot) {
26081 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');
26082 }
26083 } // TODO: throw or warn if we couldn't hydrate?
26084
26085
26086 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
26087}
26088function render(element, container, callback) {
26089 if (!isValidContainer(container)) {
26090 {
26091 throw Error( "Target container is not a DOM element." );
26092 }
26093 }
26094
26095 {
26096 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26097
26098 if (isModernRoot) {
26099 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
26100 }
26101 }
26102
26103 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
26104}
26105function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
26106 if (!isValidContainer(containerNode)) {
26107 {
26108 throw Error( "Target container is not a DOM element." );
26109 }
26110 }
26111
26112 if (!(parentComponent != null && has(parentComponent))) {
26113 {
26114 throw Error( "parentComponent must be a valid React Component" );
26115 }
26116 }
26117
26118 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
26119}
26120function unmountComponentAtNode(container) {
26121 if (!isValidContainer(container)) {
26122 {
26123 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." );
26124 }
26125 }
26126
26127 {
26128 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
26129
26130 if (isModernRoot) {
26131 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');
26132 }
26133 }
26134
26135 if (container._reactRootContainer) {
26136 {
26137 var rootEl = getReactRootElementInContainer(container);
26138 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
26139
26140 if (renderedByDifferentReact) {
26141 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
26142 }
26143 } // Unmount should not be batched.
26144
26145
26146 unbatchedUpdates(function () {
26147 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
26148 // $FlowFixMe This should probably use `delete container._reactRootContainer`
26149 container._reactRootContainer = null;
26150 unmarkContainerAsRoot(container);
26151 });
26152 }); // If you call unmountComponentAtNode twice in quick succession, you'll
26153 // get `true` twice. That's probably fine?
26154
26155 return true;
26156 } else {
26157 {
26158 var _rootEl = getReactRootElementInContainer(container);
26159
26160 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
26161
26162 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
26163
26164 if (hasNonRootReactChild) {
26165 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.');
26166 }
26167 }
26168
26169 return false;
26170 }
26171}
26172
26173setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
26174setAttemptContinuousHydration(attemptContinuousHydration$1);
26175setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
26176setAttemptHydrationAtPriority(runWithPriority$2);
26177var didWarnAboutUnstableCreatePortal = false;
26178
26179{
26180 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
26181 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
26182 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
26183 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills');
26184 }
26185}
26186
26187setRestoreImplementation(restoreControlledState$3);
26188setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
26189
26190function createPortal$1(children, container) {
26191 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
26192
26193 if (!isValidContainer(container)) {
26194 {
26195 throw Error( "Target container is not a DOM element." );
26196 }
26197 } // TODO: pass ReactDOM portal implementation as third argument
26198 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
26199
26200
26201 return createPortal(children, container, null, key);
26202}
26203
26204function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
26205
26206 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
26207}
26208
26209function unstable_createPortal(children, container) {
26210 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
26211
26212 {
26213 if (!didWarnAboutUnstableCreatePortal) {
26214 didWarnAboutUnstableCreatePortal = true;
26215
26216 warn('The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 18+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.');
26217 }
26218 }
26219
26220 return createPortal$1(children, container, key);
26221}
26222
26223var Internals = {
26224 // Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
26225 // This is an array for better minification.
26226 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, flushPassiveEffects, // TODO: This is related to `act`, not events. Move to separate key?
26227 IsThisRendererActing]
26228};
26229var foundDevTools = injectIntoDevTools({
26230 findFiberByHostInstance: getClosestInstanceFromNode,
26231 bundleType: 1 ,
26232 version: ReactVersion,
26233 rendererPackageName: 'react-dom'
26234});
26235
26236{
26237 if (!foundDevTools && canUseDOM && window.top === window.self) {
26238 // If we're in Chrome or Firefox, provide a download link if not installed.
26239 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
26240 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
26241
26242 if (/^(https?|file):$/.test(protocol)) {
26243 // eslint-disable-next-line react-internal/no-production-logging
26244 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://reactjs.org/link/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://reactjs.org/link/react-devtools-faq' : ''), 'font-weight:bold');
26245 }
26246 }
26247 }
26248}
26249
26250exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
26251exports.createPortal = createPortal$1;
26252exports.findDOMNode = findDOMNode;
26253exports.flushSync = flushSync;
26254exports.hydrate = hydrate;
26255exports.render = render;
26256exports.unmountComponentAtNode = unmountComponentAtNode;
26257exports.unstable_batchedUpdates = batchedUpdates$1;
26258exports.unstable_createPortal = unstable_createPortal;
26259exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
26260exports.version = ReactVersion;
26261 })();
26262}