· 8 years ago · Mar 05, 2018, 02:18 PM
1/** @license React v16.3.0-alpha.1
2 * react-dom.development.js
3 *
4 * Copyright (c) 2013-present, Facebook, Inc.
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
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactDOM = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18/**
19 * WARNING: DO NOT manually require this module.
20 * This is a replacement for `invariant(...)` used by the error code system
21 * and will _only_ be required by the corresponding babel pass.
22 * It always throws.
23 */
24
25/**
26 * Copyright (c) 2013-present, Facebook, Inc.
27 *
28 * This source code is licensed under the MIT license found in the
29 * LICENSE file in the root directory of this source tree.
30 *
31 */
32
33
34
35/**
36 * Use invariant() to assert state which your program assumes to be true.
37 *
38 * Provide sprintf-style format (only %s is supported) and arguments
39 * to provide information about what broke and what you were
40 * expecting.
41 *
42 * The invariant message will be stripped in production, but the invariant
43 * will remain to ensure logic does not differ in production.
44 */
45
46var validateFormat = function validateFormat(format) {};
47
48{
49 validateFormat = function validateFormat(format) {
50 if (format === undefined) {
51 throw new Error('invariant requires an error message argument');
52 }
53 };
54}
55
56function invariant(condition, format, a, b, c, d, e, f) {
57 validateFormat(format);
58
59 if (!condition) {
60 var error;
61 if (format === undefined) {
62 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
63 } else {
64 var args = [a, b, c, d, e, f];
65 var argIndex = 0;
66 error = new Error(format.replace(/%s/g, function () {
67 return args[argIndex++];
68 }));
69 error.name = 'Invariant Violation';
70 }
71
72 error.framesToPop = 1; // we don't care about invariant's own frame
73 throw error;
74 }
75}
76
77var invariant_1 = invariant;
78
79!React ? invariant_1(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
80
81var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) {
82 this._hasCaughtError = false;
83 this._caughtError = null;
84 var funcArgs = Array.prototype.slice.call(arguments, 3);
85 try {
86 func.apply(context, funcArgs);
87 } catch (error) {
88 this._caughtError = error;
89 this._hasCaughtError = true;
90 }
91};
92
93{
94 // In DEV mode, we swap out invokeGuardedCallback for a special version
95 // that plays more nicely with the browser's DevTools. The idea is to preserve
96 // "Pause on exceptions" behavior. Because React wraps all user-provided
97 // functions in invokeGuardedCallback, and the production version of
98 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
99 // like caught exceptions, and the DevTools won't pause unless the developer
100 // takes the extra step of enabling pause on caught exceptions. This is
101 // untintuitive, though, because even though React has caught the error, from
102 // the developer's perspective, the error is uncaught.
103 //
104 // To preserve the expected "Pause on exceptions" behavior, we don't use a
105 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
106 // DOM node, and call the user-provided callback from inside an event handler
107 // for that fake event. If the callback throws, the error is "captured" using
108 // a global event handler. But because the error happens in a different
109 // event loop context, it does not interrupt the normal program flow.
110 // Effectively, this gives us try-catch behavior without actually using
111 // try-catch. Neat!
112
113 // Check that the browser supports the APIs we need to implement our special
114 // DEV version of invokeGuardedCallback
115 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
116 var fakeNode = document.createElement('react');
117
118 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
119 // If document doesn't exist we know for sure we will crash in this method
120 // when we call document.createEvent(). However this can cause confusing
121 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
122 // So we preemptively throw with a better message instead.
123 !(typeof document !== 'undefined') ? invariant_1(false, '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.') : void 0;
124 var evt = document.createEvent('Event');
125
126 // Keeps track of whether the user-provided callback threw an error. We
127 // set this to true at the beginning, then set it to false right after
128 // calling the function. If the function errors, `didError` will never be
129 // set to false. This strategy works even if the browser is flaky and
130 // fails to call our global error handler, because it doesn't rely on
131 // the error event at all.
132 var didError = true;
133
134 // Create an event handler for our fake event. We will synchronously
135 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
136 // call the user-provided callback.
137 var funcArgs = Array.prototype.slice.call(arguments, 3);
138 function callCallback() {
139 // We immediately remove the callback from event listeners so that
140 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
141 // nested call would trigger the fake event handlers of any call higher
142 // in the stack.
143 fakeNode.removeEventListener(evtType, callCallback, false);
144 func.apply(context, funcArgs);
145 didError = false;
146 }
147
148 // Create a global error event handler. We use this to capture the value
149 // that was thrown. It's possible that this error handler will fire more
150 // than once; for example, if non-React code also calls `dispatchEvent`
151 // and a handler for that event throws. We should be resilient to most of
152 // those cases. Even if our error event handler fires more than once, the
153 // last error event is always used. If the callback actually does error,
154 // we know that the last error event is the correct one, because it's not
155 // possible for anything else to have happened in between our callback
156 // erroring and the code that follows the `dispatchEvent` call below. If
157 // the callback doesn't error, but the error event was fired, we know to
158 // ignore it because `didError` will be false, as described above.
159 var error = void 0;
160 // Use this to track whether the error event is ever called.
161 var didSetError = false;
162 var isCrossOriginError = false;
163
164 function onError(event) {
165 error = event.error;
166 didSetError = true;
167 if (error === null && event.colno === 0 && event.lineno === 0) {
168 isCrossOriginError = true;
169 }
170 }
171
172 // Create a fake event type.
173 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
174
175 // Attach our event handlers
176 window.addEventListener('error', onError);
177 fakeNode.addEventListener(evtType, callCallback, false);
178
179 // Synchronously dispatch our fake event. If the user-provided function
180 // errors, it will trigger our global error handler.
181 evt.initEvent(evtType, false, false);
182 fakeNode.dispatchEvent(evt);
183
184 if (didError) {
185 if (!didSetError) {
186 // The callback errored, but the error event never fired.
187 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.');
188 } else if (isCrossOriginError) {
189 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
190 }
191 this._hasCaughtError = true;
192 this._caughtError = error;
193 } else {
194 this._hasCaughtError = false;
195 this._caughtError = null;
196 }
197
198 // Remove our event listeners
199 window.removeEventListener('error', onError);
200 };
201
202 invokeGuardedCallback = invokeGuardedCallbackDev;
203 }
204}
205
206var invokeGuardedCallback$1 = invokeGuardedCallback;
207
208var ReactErrorUtils = {
209 // Used by Fiber to simulate a try-catch.
210 _caughtError: null,
211 _hasCaughtError: false,
212
213 // Used by event system to capture/rethrow the first error.
214 _rethrowError: null,
215 _hasRethrowError: false,
216
217 /**
218 * Call a function while guarding against errors that happens within it.
219 * Returns an error if it throws, otherwise null.
220 *
221 * In production, this is implemented using a try-catch. The reason we don't
222 * use a try-catch directly is so that we can swap out a different
223 * implementation in DEV mode.
224 *
225 * @param {String} name of the guard to use for logging or debugging
226 * @param {Function} func The function to invoke
227 * @param {*} context The context to use when calling the function
228 * @param {...*} args Arguments for function
229 */
230 invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) {
231 invokeGuardedCallback$1.apply(ReactErrorUtils, arguments);
232 },
233
234 /**
235 * Same as invokeGuardedCallback, but instead of returning an error, it stores
236 * it in a global so it can be rethrown by `rethrowCaughtError` later.
237 * TODO: See if _caughtError and _rethrowError can be unified.
238 *
239 * @param {String} name of the guard to use for logging or debugging
240 * @param {Function} func The function to invoke
241 * @param {*} context The context to use when calling the function
242 * @param {...*} args Arguments for function
243 */
244 invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) {
245 ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
246 if (ReactErrorUtils.hasCaughtError()) {
247 var error = ReactErrorUtils.clearCaughtError();
248 if (!ReactErrorUtils._hasRethrowError) {
249 ReactErrorUtils._hasRethrowError = true;
250 ReactErrorUtils._rethrowError = error;
251 }
252 }
253 },
254
255 /**
256 * During execution of guarded functions we will capture the first error which
257 * we will rethrow to be handled by the top level error handler.
258 */
259 rethrowCaughtError: function () {
260 return rethrowCaughtError.apply(ReactErrorUtils, arguments);
261 },
262
263 hasCaughtError: function () {
264 return ReactErrorUtils._hasCaughtError;
265 },
266
267 clearCaughtError: function () {
268 if (ReactErrorUtils._hasCaughtError) {
269 var error = ReactErrorUtils._caughtError;
270 ReactErrorUtils._caughtError = null;
271 ReactErrorUtils._hasCaughtError = false;
272 return error;
273 } else {
274 invariant_1(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
275 }
276 }
277};
278
279var rethrowCaughtError = function () {
280 if (ReactErrorUtils._hasRethrowError) {
281 var error = ReactErrorUtils._rethrowError;
282 ReactErrorUtils._rethrowError = null;
283 ReactErrorUtils._hasRethrowError = false;
284 throw error;
285 }
286};
287
288/**
289 * Injectable ordering of event plugins.
290 */
291var eventPluginOrder = null;
292
293/**
294 * Injectable mapping from names to event plugin modules.
295 */
296var namesToPlugins = {};
297
298/**
299 * Recomputes the plugin list using the injected plugins and plugin ordering.
300 *
301 * @private
302 */
303function recomputePluginOrdering() {
304 if (!eventPluginOrder) {
305 // Wait until an `eventPluginOrder` is injected.
306 return;
307 }
308 for (var pluginName in namesToPlugins) {
309 var pluginModule = namesToPlugins[pluginName];
310 var pluginIndex = eventPluginOrder.indexOf(pluginName);
311 !(pluginIndex > -1) ? invariant_1(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
312 if (plugins[pluginIndex]) {
313 continue;
314 }
315 !pluginModule.extractEvents ? invariant_1(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
316 plugins[pluginIndex] = pluginModule;
317 var publishedEvents = pluginModule.eventTypes;
318 for (var eventName in publishedEvents) {
319 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant_1(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
320 }
321 }
322}
323
324/**
325 * Publishes an event so that it can be dispatched by the supplied plugin.
326 *
327 * @param {object} dispatchConfig Dispatch configuration for the event.
328 * @param {object} PluginModule Plugin publishing the event.
329 * @return {boolean} True if the event was successfully published.
330 * @private
331 */
332function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
333 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
334 eventNameDispatchConfigs[eventName] = dispatchConfig;
335
336 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
337 if (phasedRegistrationNames) {
338 for (var phaseName in phasedRegistrationNames) {
339 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
340 var phasedRegistrationName = phasedRegistrationNames[phaseName];
341 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
342 }
343 }
344 return true;
345 } else if (dispatchConfig.registrationName) {
346 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
347 return true;
348 }
349 return false;
350}
351
352/**
353 * Publishes a registration name that is used to identify dispatched events.
354 *
355 * @param {string} registrationName Registration name to add.
356 * @param {object} PluginModule Plugin publishing the event.
357 * @private
358 */
359function publishRegistrationName(registrationName, pluginModule, eventName) {
360 !!registrationNameModules[registrationName] ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
361 registrationNameModules[registrationName] = pluginModule;
362 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
363
364 {
365 var lowerCasedName = registrationName.toLowerCase();
366 possibleRegistrationNames[lowerCasedName] = registrationName;
367
368 if (registrationName === 'onDoubleClick') {
369 possibleRegistrationNames.ondblclick = registrationName;
370 }
371 }
372}
373
374/**
375 * Registers plugins so that they can extract and dispatch events.
376 *
377 * @see {EventPluginHub}
378 */
379
380/**
381 * Ordered list of injected plugins.
382 */
383var plugins = [];
384
385/**
386 * Mapping from event name to dispatch config
387 */
388var eventNameDispatchConfigs = {};
389
390/**
391 * Mapping from registration name to plugin module
392 */
393var registrationNameModules = {};
394
395/**
396 * Mapping from registration name to event name
397 */
398var registrationNameDependencies = {};
399
400/**
401 * Mapping from lowercase registration names to the properly cased version,
402 * used to warn in the case of missing event handlers. Available
403 * only in true.
404 * @type {Object}
405 */
406var possibleRegistrationNames = {};
407// Trust the developer to only use possibleRegistrationNames in true
408
409/**
410 * Injects an ordering of plugins (by plugin name). This allows the ordering
411 * to be decoupled from injection of the actual plugins so that ordering is
412 * always deterministic regardless of packaging, on-the-fly injection, etc.
413 *
414 * @param {array} InjectedEventPluginOrder
415 * @internal
416 * @see {EventPluginHub.injection.injectEventPluginOrder}
417 */
418function injectEventPluginOrder(injectedEventPluginOrder) {
419 !!eventPluginOrder ? invariant_1(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
420 // Clone the ordering so it cannot be dynamically mutated.
421 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
422 recomputePluginOrdering();
423}
424
425/**
426 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
427 * in the ordering injected by `injectEventPluginOrder`.
428 *
429 * Plugins can be injected as part of page initialization or on-the-fly.
430 *
431 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
432 * @internal
433 * @see {EventPluginHub.injection.injectEventPluginsByName}
434 */
435function injectEventPluginsByName(injectedNamesToPlugins) {
436 var isOrderingDirty = false;
437 for (var pluginName in injectedNamesToPlugins) {
438 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
439 continue;
440 }
441 var pluginModule = injectedNamesToPlugins[pluginName];
442 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
443 !!namesToPlugins[pluginName] ? invariant_1(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
444 namesToPlugins[pluginName] = pluginModule;
445 isOrderingDirty = true;
446 }
447 }
448 if (isOrderingDirty) {
449 recomputePluginOrdering();
450 }
451}
452
453var EventPluginRegistry = Object.freeze({
454 plugins: plugins,
455 eventNameDispatchConfigs: eventNameDispatchConfigs,
456 registrationNameModules: registrationNameModules,
457 registrationNameDependencies: registrationNameDependencies,
458 possibleRegistrationNames: possibleRegistrationNames,
459 injectEventPluginOrder: injectEventPluginOrder,
460 injectEventPluginsByName: injectEventPluginsByName
461});
462
463/**
464 * Copyright (c) 2013-present, Facebook, Inc.
465 *
466 * This source code is licensed under the MIT license found in the
467 * LICENSE file in the root directory of this source tree.
468 *
469 *
470 */
471
472function makeEmptyFunction(arg) {
473 return function () {
474 return arg;
475 };
476}
477
478/**
479 * This function accepts and discards inputs; it has no side effects. This is
480 * primarily useful idiomatically for overridable function endpoints which
481 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
482 */
483var emptyFunction = function emptyFunction() {};
484
485emptyFunction.thatReturns = makeEmptyFunction;
486emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
487emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
488emptyFunction.thatReturnsNull = makeEmptyFunction(null);
489emptyFunction.thatReturnsThis = function () {
490 return this;
491};
492emptyFunction.thatReturnsArgument = function (arg) {
493 return arg;
494};
495
496var emptyFunction_1 = emptyFunction;
497
498/**
499 * Copyright (c) 2014-present, Facebook, Inc.
500 *
501 * This source code is licensed under the MIT license found in the
502 * LICENSE file in the root directory of this source tree.
503 *
504 */
505
506
507
508
509
510/**
511 * Similar to invariant but only logs a warning if the condition is not met.
512 * This can be used to log issues in development environments in critical
513 * paths. Removing the logging code for production environments will keep the
514 * same logic and follow the same code paths.
515 */
516
517var warning = emptyFunction_1;
518
519{
520 var printWarning = function printWarning(format) {
521 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
522 args[_key - 1] = arguments[_key];
523 }
524
525 var argIndex = 0;
526 var message = 'Warning: ' + format.replace(/%s/g, function () {
527 return args[argIndex++];
528 });
529 if (typeof console !== 'undefined') {
530 console.error(message);
531 }
532 try {
533 // --- Welcome to debugging React ---
534 // This error was thrown as a convenience so that you can use this stack
535 // to find the callsite that caused this warning to fire.
536 throw new Error(message);
537 } catch (x) {}
538 };
539
540 warning = function warning(condition, format) {
541 if (format === undefined) {
542 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
543 }
544
545 if (format.indexOf('Failed Composite propType: ') === 0) {
546 return; // Ignore CompositeComponent proptype check.
547 }
548
549 if (!condition) {
550 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
551 args[_key2 - 2] = arguments[_key2];
552 }
553
554 printWarning.apply(undefined, [format].concat(args));
555 }
556 };
557}
558
559var warning_1 = warning;
560
561var getFiberCurrentPropsFromNode = null;
562var getInstanceFromNode = null;
563var getNodeFromInstance = null;
564
565var injection$1 = {
566 injectComponentTree: function (Injected) {
567 getFiberCurrentPropsFromNode = Injected.getFiberCurrentPropsFromNode;
568 getInstanceFromNode = Injected.getInstanceFromNode;
569 getNodeFromInstance = Injected.getNodeFromInstance;
570
571 {
572 warning_1(getNodeFromInstance && getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
573 }
574 }
575};
576
577
578
579
580
581
582var validateEventDispatches = void 0;
583{
584 validateEventDispatches = function (event) {
585 var dispatchListeners = event._dispatchListeners;
586 var dispatchInstances = event._dispatchInstances;
587
588 var listenersIsArr = Array.isArray(dispatchListeners);
589 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
590
591 var instancesIsArr = Array.isArray(dispatchInstances);
592 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
593
594 warning_1(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.');
595 };
596}
597
598/**
599 * Dispatch the event to the listener.
600 * @param {SyntheticEvent} event SyntheticEvent to handle
601 * @param {boolean} simulated If the event is simulated (changes exn behavior)
602 * @param {function} listener Application-level callback
603 * @param {*} inst Internal component instance
604 */
605function executeDispatch(event, simulated, listener, inst) {
606 var type = event.type || 'unknown-event';
607 event.currentTarget = getNodeFromInstance(inst);
608 ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
609 event.currentTarget = null;
610}
611
612/**
613 * Standard/simple iteration through an event's collected dispatches.
614 */
615function executeDispatchesInOrder(event, simulated) {
616 var dispatchListeners = event._dispatchListeners;
617 var dispatchInstances = event._dispatchInstances;
618 {
619 validateEventDispatches(event);
620 }
621 if (Array.isArray(dispatchListeners)) {
622 for (var i = 0; i < dispatchListeners.length; i++) {
623 if (event.isPropagationStopped()) {
624 break;
625 }
626 // Listeners and Instances are two parallel arrays that are always in sync.
627 executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
628 }
629 } else if (dispatchListeners) {
630 executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
631 }
632 event._dispatchListeners = null;
633 event._dispatchInstances = null;
634}
635
636/**
637 * @see executeDispatchesInOrderStopAtTrueImpl
638 */
639
640
641/**
642 * Execution of a "direct" dispatch - there must be at most one dispatch
643 * accumulated on the event or it is considered an error. It doesn't really make
644 * sense for an event with multiple dispatches (bubbled) to keep track of the
645 * return values at each dispatch execution, but it does tend to make sense when
646 * dealing with "direct" dispatches.
647 *
648 * @return {*} The return value of executing the single dispatch.
649 */
650
651
652/**
653 * @param {SyntheticEvent} event
654 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
655 */
656
657/**
658 * Accumulates items that must not be null or undefined into the first one. This
659 * is used to conserve memory by avoiding array allocations, and thus sacrifices
660 * API cleanness. Since `current` can be null before being passed in and not
661 * null after this function, make sure to assign it back to `current`:
662 *
663 * `a = accumulateInto(a, b);`
664 *
665 * This API should be sparingly used. Try `accumulate` for something cleaner.
666 *
667 * @return {*|array<*>} An accumulation of items.
668 */
669
670function accumulateInto(current, next) {
671 !(next != null) ? invariant_1(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
672
673 if (current == null) {
674 return next;
675 }
676
677 // Both are not empty. Warning: Never call x.concat(y) when you are not
678 // certain that x is an Array (x could be a string with concat method).
679 if (Array.isArray(current)) {
680 if (Array.isArray(next)) {
681 current.push.apply(current, next);
682 return current;
683 }
684 current.push(next);
685 return current;
686 }
687
688 if (Array.isArray(next)) {
689 // A bit too dangerous to mutate `next`.
690 return [current].concat(next);
691 }
692
693 return [current, next];
694}
695
696/**
697 * @param {array} arr an "accumulation" of items which is either an Array or
698 * a single item. Useful when paired with the `accumulate` module. This is a
699 * simple utility that allows us to reason about a collection of items, but
700 * handling the case when there is exactly one item (and we do not need to
701 * allocate an array).
702 * @param {function} cb Callback invoked with each element or a collection.
703 * @param {?} [scope] Scope used as `this` in a callback.
704 */
705function forEachAccumulated(arr, cb, scope) {
706 if (Array.isArray(arr)) {
707 arr.forEach(cb, scope);
708 } else if (arr) {
709 cb.call(scope, arr);
710 }
711}
712
713/**
714 * Internal queue of events that have accumulated their dispatches and are
715 * waiting to have their dispatches executed.
716 */
717var eventQueue = null;
718
719/**
720 * Dispatches an event and releases it back into the pool, unless persistent.
721 *
722 * @param {?object} event Synthetic event to be dispatched.
723 * @param {boolean} simulated If the event is simulated (changes exn behavior)
724 * @private
725 */
726var executeDispatchesAndRelease = function (event, simulated) {
727 if (event) {
728 executeDispatchesInOrder(event, simulated);
729
730 if (!event.isPersistent()) {
731 event.constructor.release(event);
732 }
733 }
734};
735var executeDispatchesAndReleaseSimulated = function (e) {
736 return executeDispatchesAndRelease(e, true);
737};
738var executeDispatchesAndReleaseTopLevel = function (e) {
739 return executeDispatchesAndRelease(e, false);
740};
741
742function isInteractive(tag) {
743 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
744}
745
746function shouldPreventMouseEvent(name, type, props) {
747 switch (name) {
748 case 'onClick':
749 case 'onClickCapture':
750 case 'onDoubleClick':
751 case 'onDoubleClickCapture':
752 case 'onMouseDown':
753 case 'onMouseDownCapture':
754 case 'onMouseMove':
755 case 'onMouseMoveCapture':
756 case 'onMouseUp':
757 case 'onMouseUpCapture':
758 return !!(props.disabled && isInteractive(type));
759 default:
760 return false;
761 }
762}
763
764/**
765 * This is a unified interface for event plugins to be installed and configured.
766 *
767 * Event plugins can implement the following properties:
768 *
769 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
770 * Required. When a top-level event is fired, this method is expected to
771 * extract synthetic events that will in turn be queued and dispatched.
772 *
773 * `eventTypes` {object}
774 * Optional, plugins that fire events must publish a mapping of registration
775 * names that are used to register listeners. Values of this mapping must
776 * be objects that contain `registrationName` or `phasedRegistrationNames`.
777 *
778 * `executeDispatch` {function(object, function, string)}
779 * Optional, allows plugins to override how an event gets dispatched. By
780 * default, the listener is simply invoked.
781 *
782 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
783 *
784 * @public
785 */
786
787/**
788 * Methods for injecting dependencies.
789 */
790var injection = {
791 /**
792 * @param {array} InjectedEventPluginOrder
793 * @public
794 */
795 injectEventPluginOrder: injectEventPluginOrder,
796
797 /**
798 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
799 */
800 injectEventPluginsByName: injectEventPluginsByName
801};
802
803/**
804 * @param {object} inst The instance, which is the source of events.
805 * @param {string} registrationName Name of listener (e.g. `onClick`).
806 * @return {?function} The stored callback.
807 */
808function getListener(inst, registrationName) {
809 var listener = void 0;
810
811 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
812 // live here; needs to be moved to a better place soon
813 var stateNode = inst.stateNode;
814 if (!stateNode) {
815 // Work in progress (ex: onload events in incremental mode).
816 return null;
817 }
818 var props = getFiberCurrentPropsFromNode(stateNode);
819 if (!props) {
820 // Work in progress.
821 return null;
822 }
823 listener = props[registrationName];
824 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
825 return null;
826 }
827 !(!listener || typeof listener === 'function') ? invariant_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
828 return listener;
829}
830
831/**
832 * Allows registered plugins an opportunity to extract events from top-level
833 * native browser events.
834 *
835 * @return {*} An accumulation of synthetic events.
836 * @internal
837 */
838function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
839 var events = null;
840 for (var i = 0; i < plugins.length; i++) {
841 // Not every plugin in the ordering may be loaded at runtime.
842 var possiblePlugin = plugins[i];
843 if (possiblePlugin) {
844 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
845 if (extractedEvents) {
846 events = accumulateInto(events, extractedEvents);
847 }
848 }
849 }
850 return events;
851}
852
853function runEventsInBatch(events, simulated) {
854 if (events !== null) {
855 eventQueue = accumulateInto(eventQueue, events);
856 }
857
858 // Set `eventQueue` to null before processing it so that we can tell if more
859 // events get enqueued while processing.
860 var processingEventQueue = eventQueue;
861 eventQueue = null;
862
863 if (!processingEventQueue) {
864 return;
865 }
866
867 if (simulated) {
868 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
869 } else {
870 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
871 }
872 !!eventQueue ? invariant_1(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
873 // This would be a good time to rethrow if any of the event handlers threw.
874 ReactErrorUtils.rethrowCaughtError();
875}
876
877function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
878 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
879 runEventsInBatch(events, false);
880}
881
882var EventPluginHub = Object.freeze({
883 injection: injection,
884 getListener: getListener,
885 runEventsInBatch: runEventsInBatch,
886 runExtractedEventsInBatch: runExtractedEventsInBatch
887});
888
889var IndeterminateComponent = 0; // Before we know whether it is functional or class
890var FunctionalComponent = 1;
891var ClassComponent = 2;
892var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
893var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
894var HostComponent = 5;
895var HostText = 6;
896var CallComponent = 7;
897var CallHandlerPhase = 8;
898var ReturnComponent = 9;
899var Fragment = 10;
900var Mode = 11;
901var ContextConsumer = 12;
902var ContextProvider = 13;
903
904var randomKey = Math.random().toString(36).slice(2);
905var internalInstanceKey = '__reactInternalInstance$' + randomKey;
906var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
907
908function precacheFiberNode$1(hostInst, node) {
909 node[internalInstanceKey] = hostInst;
910}
911
912/**
913 * Given a DOM node, return the closest ReactDOMComponent or
914 * ReactDOMTextComponent instance ancestor.
915 */
916function getClosestInstanceFromNode(node) {
917 if (node[internalInstanceKey]) {
918 return node[internalInstanceKey];
919 }
920
921 while (!node[internalInstanceKey]) {
922 if (node.parentNode) {
923 node = node.parentNode;
924 } else {
925 // Top of the tree. This node must not be part of a React tree (or is
926 // unmounted, potentially).
927 return null;
928 }
929 }
930
931 var inst = node[internalInstanceKey];
932 if (inst.tag === HostComponent || inst.tag === HostText) {
933 // In Fiber, this will always be the deepest root.
934 return inst;
935 }
936
937 return null;
938}
939
940/**
941 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
942 * instance, or null if the node was not rendered by this React.
943 */
944function getInstanceFromNode$1(node) {
945 var inst = node[internalInstanceKey];
946 if (inst) {
947 if (inst.tag === HostComponent || inst.tag === HostText) {
948 return inst;
949 } else {
950 return null;
951 }
952 }
953 return null;
954}
955
956/**
957 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
958 * DOM node.
959 */
960function getNodeFromInstance$1(inst) {
961 if (inst.tag === HostComponent || inst.tag === HostText) {
962 // In Fiber this, is just the state node right now. We assume it will be
963 // a host component or host text.
964 return inst.stateNode;
965 }
966
967 // Without this first invariant, passing a non-DOM-component triggers the next
968 // invariant for a missing parent, which is super confusing.
969 invariant_1(false, 'getNodeFromInstance: Invalid argument.');
970}
971
972function getFiberCurrentPropsFromNode$1(node) {
973 return node[internalEventHandlersKey] || null;
974}
975
976function updateFiberProps$1(node, props) {
977 node[internalEventHandlersKey] = props;
978}
979
980var ReactDOMComponentTree = Object.freeze({
981 precacheFiberNode: precacheFiberNode$1,
982 getClosestInstanceFromNode: getClosestInstanceFromNode,
983 getInstanceFromNode: getInstanceFromNode$1,
984 getNodeFromInstance: getNodeFromInstance$1,
985 getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode$1,
986 updateFiberProps: updateFiberProps$1
987});
988
989function getParent(inst) {
990 do {
991 inst = inst['return'];
992 // TODO: If this is a HostRoot we might want to bail out.
993 // That is depending on if we want nested subtrees (layers) to bubble
994 // events to their parent. We could also go through parentNode on the
995 // host node but that wouldn't work for React Native and doesn't let us
996 // do the portal feature.
997 } while (inst && inst.tag !== HostComponent);
998 if (inst) {
999 return inst;
1000 }
1001 return null;
1002}
1003
1004/**
1005 * Return the lowest common ancestor of A and B, or null if they are in
1006 * different trees.
1007 */
1008function getLowestCommonAncestor(instA, instB) {
1009 var depthA = 0;
1010 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1011 depthA++;
1012 }
1013 var depthB = 0;
1014 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1015 depthB++;
1016 }
1017
1018 // If A is deeper, crawl up.
1019 while (depthA - depthB > 0) {
1020 instA = getParent(instA);
1021 depthA--;
1022 }
1023
1024 // If B is deeper, crawl up.
1025 while (depthB - depthA > 0) {
1026 instB = getParent(instB);
1027 depthB--;
1028 }
1029
1030 // Walk in lockstep until we find a match.
1031 var depth = depthA;
1032 while (depth--) {
1033 if (instA === instB || instA === instB.alternate) {
1034 return instA;
1035 }
1036 instA = getParent(instA);
1037 instB = getParent(instB);
1038 }
1039 return null;
1040}
1041
1042/**
1043 * Return if A is an ancestor of B.
1044 */
1045
1046
1047/**
1048 * Return the parent instance of the passed-in instance.
1049 */
1050function getParentInstance(inst) {
1051 return getParent(inst);
1052}
1053
1054/**
1055 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1056 */
1057function traverseTwoPhase(inst, fn, arg) {
1058 var path = [];
1059 while (inst) {
1060 path.push(inst);
1061 inst = getParent(inst);
1062 }
1063 var i = void 0;
1064 for (i = path.length; i-- > 0;) {
1065 fn(path[i], 'captured', arg);
1066 }
1067 for (i = 0; i < path.length; i++) {
1068 fn(path[i], 'bubbled', arg);
1069 }
1070}
1071
1072/**
1073 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1074 * should would receive a `mouseEnter` or `mouseLeave` event.
1075 *
1076 * Does not invoke the callback on the nearest common ancestor because nothing
1077 * "entered" or "left" that element.
1078 */
1079function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1080 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1081 var pathFrom = [];
1082 while (true) {
1083 if (!from) {
1084 break;
1085 }
1086 if (from === common) {
1087 break;
1088 }
1089 var alternate = from.alternate;
1090 if (alternate !== null && alternate === common) {
1091 break;
1092 }
1093 pathFrom.push(from);
1094 from = getParent(from);
1095 }
1096 var pathTo = [];
1097 while (true) {
1098 if (!to) {
1099 break;
1100 }
1101 if (to === common) {
1102 break;
1103 }
1104 var _alternate = to.alternate;
1105 if (_alternate !== null && _alternate === common) {
1106 break;
1107 }
1108 pathTo.push(to);
1109 to = getParent(to);
1110 }
1111 for (var i = 0; i < pathFrom.length; i++) {
1112 fn(pathFrom[i], 'bubbled', argFrom);
1113 }
1114 for (var _i = pathTo.length; _i-- > 0;) {
1115 fn(pathTo[_i], 'captured', argTo);
1116 }
1117}
1118
1119/**
1120 * Some event types have a notion of different registration names for different
1121 * "phases" of propagation. This finds listeners by a given phase.
1122 */
1123function listenerAtPhase(inst, event, propagationPhase) {
1124 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1125 return getListener(inst, registrationName);
1126}
1127
1128/**
1129 * A small set of propagation patterns, each of which will accept a small amount
1130 * of information, and generate a set of "dispatch ready event objects" - which
1131 * are sets of events that have already been annotated with a set of dispatched
1132 * listener functions/ids. The API is designed this way to discourage these
1133 * propagation strategies from actually executing the dispatches, since we
1134 * always want to collect the entire set of dispatches before executing even a
1135 * single one.
1136 */
1137
1138/**
1139 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1140 * here, allows us to not have to bind or create functions for each event.
1141 * Mutating the event's members allows us to not have to create a wrapping
1142 * "dispatch" object that pairs the event with the listener.
1143 */
1144function accumulateDirectionalDispatches(inst, phase, event) {
1145 {
1146 warning_1(inst, 'Dispatching inst must not be null');
1147 }
1148 var listener = listenerAtPhase(inst, event, phase);
1149 if (listener) {
1150 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1151 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1152 }
1153}
1154
1155/**
1156 * Collect dispatches (must be entirely collected before dispatching - see unit
1157 * tests). Lazily allocate the array to conserve memory. We must loop through
1158 * each event and perform the traversal for each one. We cannot perform a
1159 * single traversal for the entire collection of events because each event may
1160 * have a different target.
1161 */
1162function accumulateTwoPhaseDispatchesSingle(event) {
1163 if (event && event.dispatchConfig.phasedRegistrationNames) {
1164 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1165 }
1166}
1167
1168/**
1169 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
1170 */
1171function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
1172 if (event && event.dispatchConfig.phasedRegistrationNames) {
1173 var targetInst = event._targetInst;
1174 var parentInst = targetInst ? getParentInstance(targetInst) : null;
1175 traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
1176 }
1177}
1178
1179/**
1180 * Accumulates without regard to direction, does not look for phased
1181 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1182 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1183 */
1184function accumulateDispatches(inst, ignoredDirection, event) {
1185 if (inst && event && event.dispatchConfig.registrationName) {
1186 var registrationName = event.dispatchConfig.registrationName;
1187 var listener = getListener(inst, registrationName);
1188 if (listener) {
1189 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1190 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1191 }
1192 }
1193}
1194
1195/**
1196 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1197 * `dispatchMarker`.
1198 * @param {SyntheticEvent} event
1199 */
1200function accumulateDirectDispatchesSingle(event) {
1201 if (event && event.dispatchConfig.registrationName) {
1202 accumulateDispatches(event._targetInst, null, event);
1203 }
1204}
1205
1206function accumulateTwoPhaseDispatches(events) {
1207 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1208}
1209
1210function accumulateTwoPhaseDispatchesSkipTarget(events) {
1211 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
1212}
1213
1214function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1215 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1216}
1217
1218function accumulateDirectDispatches(events) {
1219 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1220}
1221
1222var EventPropagators = Object.freeze({
1223 accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
1224 accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
1225 accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
1226 accumulateDirectDispatches: accumulateDirectDispatches
1227});
1228
1229/**
1230 * Copyright (c) 2013-present, Facebook, Inc.
1231 *
1232 * This source code is licensed under the MIT license found in the
1233 * LICENSE file in the root directory of this source tree.
1234 *
1235 */
1236
1237
1238
1239var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1240
1241/**
1242 * Simple, lightweight module assisting with the detection and context of
1243 * Worker. Helps avoid circular dependencies and allows code to reason about
1244 * whether or not they are in a Worker, even if they never include the main
1245 * `ReactWorker` dependency.
1246 */
1247var ExecutionEnvironment = {
1248
1249 canUseDOM: canUseDOM,
1250
1251 canUseWorkers: typeof Worker !== 'undefined',
1252
1253 canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
1254
1255 canUseViewport: canUseDOM && !!window.screen,
1256
1257 isInWorker: !canUseDOM // For now, this is true - might change in the future.
1258
1259};
1260
1261var ExecutionEnvironment_1 = ExecutionEnvironment;
1262
1263var contentKey = null;
1264
1265/**
1266 * Gets the key used to access text content on a DOM node.
1267 *
1268 * @return {?string} Key used to access text content.
1269 * @internal
1270 */
1271function getTextContentAccessor() {
1272 if (!contentKey && ExecutionEnvironment_1.canUseDOM) {
1273 // Prefer textContent to innerText because many browsers support both but
1274 // SVG <text> elements don't support innerText even when <div> does.
1275 contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
1276 }
1277 return contentKey;
1278}
1279
1280/**
1281 * This helper object stores information about text content of a target node,
1282 * allowing comparison of content before and after a given event.
1283 *
1284 * Identify the node where selection currently begins, then observe
1285 * both its text content and its current position in the DOM. Since the
1286 * browser may natively replace the target node during composition, we can
1287 * use its position to find its replacement.
1288 *
1289 *
1290 */
1291var compositionState = {
1292 _root: null,
1293 _startText: null,
1294 _fallbackText: null
1295};
1296
1297function initialize(nativeEventTarget) {
1298 compositionState._root = nativeEventTarget;
1299 compositionState._startText = getText();
1300 return true;
1301}
1302
1303function reset() {
1304 compositionState._root = null;
1305 compositionState._startText = null;
1306 compositionState._fallbackText = null;
1307}
1308
1309function getData() {
1310 if (compositionState._fallbackText) {
1311 return compositionState._fallbackText;
1312 }
1313
1314 var start = void 0;
1315 var startValue = compositionState._startText;
1316 var startLength = startValue.length;
1317 var end = void 0;
1318 var endValue = getText();
1319 var endLength = endValue.length;
1320
1321 for (start = 0; start < startLength; start++) {
1322 if (startValue[start] !== endValue[start]) {
1323 break;
1324 }
1325 }
1326
1327 var minEnd = startLength - start;
1328 for (end = 1; end <= minEnd; end++) {
1329 if (startValue[startLength - end] !== endValue[endLength - end]) {
1330 break;
1331 }
1332 }
1333
1334 var sliceTail = end > 1 ? 1 - end : undefined;
1335 compositionState._fallbackText = endValue.slice(start, sliceTail);
1336 return compositionState._fallbackText;
1337}
1338
1339function getText() {
1340 if ('value' in compositionState._root) {
1341 return compositionState._root.value;
1342 }
1343 return compositionState._root[getTextContentAccessor()];
1344}
1345
1346var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1347
1348var _assign = ReactInternals.assign;
1349
1350/* eslint valid-typeof: 0 */
1351
1352var didWarnForAddedNewProperty = false;
1353var EVENT_POOL_SIZE = 10;
1354
1355var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
1356
1357/**
1358 * @interface Event
1359 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1360 */
1361var EventInterface = {
1362 type: null,
1363 target: null,
1364 // currentTarget is set when dispatching; no use in copying it here
1365 currentTarget: emptyFunction_1.thatReturnsNull,
1366 eventPhase: null,
1367 bubbles: null,
1368 cancelable: null,
1369 timeStamp: function (event) {
1370 return event.timeStamp || Date.now();
1371 },
1372 defaultPrevented: null,
1373 isTrusted: null
1374};
1375
1376/**
1377 * Synthetic events are dispatched by event plugins, typically in response to a
1378 * top-level event delegation handler.
1379 *
1380 * These systems should generally use pooling to reduce the frequency of garbage
1381 * collection. The system should check `isPersistent` to determine whether the
1382 * event should be released into the pool after being dispatched. Users that
1383 * need a persisted event should invoke `persist`.
1384 *
1385 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1386 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1387 * DOM interface; custom application-specific events can also subclass this.
1388 *
1389 * @param {object} dispatchConfig Configuration used to dispatch this event.
1390 * @param {*} targetInst Marker identifying the event target.
1391 * @param {object} nativeEvent Native browser event.
1392 * @param {DOMEventTarget} nativeEventTarget Target node.
1393 */
1394function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1395 {
1396 // these have a getter/setter for warnings
1397 delete this.nativeEvent;
1398 delete this.preventDefault;
1399 delete this.stopPropagation;
1400 }
1401
1402 this.dispatchConfig = dispatchConfig;
1403 this._targetInst = targetInst;
1404 this.nativeEvent = nativeEvent;
1405
1406 var Interface = this.constructor.Interface;
1407 for (var propName in Interface) {
1408 if (!Interface.hasOwnProperty(propName)) {
1409 continue;
1410 }
1411 {
1412 delete this[propName]; // this has a getter/setter for warnings
1413 }
1414 var normalize = Interface[propName];
1415 if (normalize) {
1416 this[propName] = normalize(nativeEvent);
1417 } else {
1418 if (propName === 'target') {
1419 this.target = nativeEventTarget;
1420 } else {
1421 this[propName] = nativeEvent[propName];
1422 }
1423 }
1424 }
1425
1426 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1427 if (defaultPrevented) {
1428 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1429 } else {
1430 this.isDefaultPrevented = emptyFunction_1.thatReturnsFalse;
1431 }
1432 this.isPropagationStopped = emptyFunction_1.thatReturnsFalse;
1433 return this;
1434}
1435
1436_assign(SyntheticEvent.prototype, {
1437 preventDefault: function () {
1438 this.defaultPrevented = true;
1439 var event = this.nativeEvent;
1440 if (!event) {
1441 return;
1442 }
1443
1444 if (event.preventDefault) {
1445 event.preventDefault();
1446 } else if (typeof event.returnValue !== 'unknown') {
1447 event.returnValue = false;
1448 }
1449 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1450 },
1451
1452 stopPropagation: function () {
1453 var event = this.nativeEvent;
1454 if (!event) {
1455 return;
1456 }
1457
1458 if (event.stopPropagation) {
1459 event.stopPropagation();
1460 } else if (typeof event.cancelBubble !== 'unknown') {
1461 // The ChangeEventPlugin registers a "propertychange" event for
1462 // IE. This event does not support bubbling or cancelling, and
1463 // any references to cancelBubble throw "Member not found". A
1464 // typeof check of "unknown" circumvents this issue (and is also
1465 // IE specific).
1466 event.cancelBubble = true;
1467 }
1468
1469 this.isPropagationStopped = emptyFunction_1.thatReturnsTrue;
1470 },
1471
1472 /**
1473 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1474 * them back into the pool. This allows a way to hold onto a reference that
1475 * won't be added back into the pool.
1476 */
1477 persist: function () {
1478 this.isPersistent = emptyFunction_1.thatReturnsTrue;
1479 },
1480
1481 /**
1482 * Checks if this event should be released back into the pool.
1483 *
1484 * @return {boolean} True if this should not be released, false otherwise.
1485 */
1486 isPersistent: emptyFunction_1.thatReturnsFalse,
1487
1488 /**
1489 * `PooledClass` looks for `destructor` on each instance it releases.
1490 */
1491 destructor: function () {
1492 var Interface = this.constructor.Interface;
1493 for (var propName in Interface) {
1494 {
1495 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1496 }
1497 }
1498 for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
1499 this[shouldBeReleasedProperties[i]] = null;
1500 }
1501 {
1502 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1503 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction_1));
1504 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction_1));
1505 }
1506 }
1507});
1508
1509SyntheticEvent.Interface = EventInterface;
1510
1511/**
1512 * Helper to reduce boilerplate when creating subclasses.
1513 */
1514SyntheticEvent.extend = function (Interface) {
1515 var Super = this;
1516
1517 var E = function () {};
1518 E.prototype = Super.prototype;
1519 var prototype = new E();
1520
1521 function Class() {
1522 return Super.apply(this, arguments);
1523 }
1524 _assign(prototype, Class.prototype);
1525 Class.prototype = prototype;
1526 Class.prototype.constructor = Class;
1527
1528 Class.Interface = _assign({}, Super.Interface, Interface);
1529 Class.extend = Super.extend;
1530 addEventPoolingTo(Class);
1531
1532 return Class;
1533};
1534
1535/** Proxying after everything set on SyntheticEvent
1536 * to resolve Proxy issue on some WebKit browsers
1537 * in which some Event properties are set to undefined (GH#10010)
1538 */
1539{
1540 var isProxySupported = typeof Proxy === 'function' &&
1541 // https://github.com/facebook/react/issues/12011
1542 !Object.isSealed(new Proxy({}, {}));
1543
1544 if (isProxySupported) {
1545 /*eslint-disable no-func-assign */
1546 SyntheticEvent = new Proxy(SyntheticEvent, {
1547 construct: function (target, args) {
1548 return this.apply(target, Object.create(target.prototype), args);
1549 },
1550 apply: function (constructor, that, args) {
1551 return new Proxy(constructor.apply(that, args), {
1552 set: function (target, prop, value) {
1553 if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
1554 warning_1(didWarnForAddedNewProperty || target.isPersistent(), "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.');
1555 didWarnForAddedNewProperty = true;
1556 }
1557 target[prop] = value;
1558 return true;
1559 }
1560 });
1561 }
1562 });
1563 /*eslint-enable no-func-assign */
1564 }
1565}
1566
1567addEventPoolingTo(SyntheticEvent);
1568
1569/**
1570 * Helper to nullify syntheticEvent instance properties when destructing
1571 *
1572 * @param {String} propName
1573 * @param {?object} getVal
1574 * @return {object} defineProperty object
1575 */
1576function getPooledWarningPropertyDefinition(propName, getVal) {
1577 var isFunction = typeof getVal === 'function';
1578 return {
1579 configurable: true,
1580 set: set,
1581 get: get
1582 };
1583
1584 function set(val) {
1585 var action = isFunction ? 'setting the method' : 'setting the property';
1586 warn(action, 'This is effectively a no-op');
1587 return val;
1588 }
1589
1590 function get() {
1591 var action = isFunction ? 'accessing the method' : 'accessing the property';
1592 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1593 warn(action, result);
1594 return getVal;
1595 }
1596
1597 function warn(action, result) {
1598 var warningCondition = false;
1599 warning_1(warningCondition, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result);
1600 }
1601}
1602
1603function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1604 var EventConstructor = this;
1605 if (EventConstructor.eventPool.length) {
1606 var instance = EventConstructor.eventPool.pop();
1607 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1608 return instance;
1609 }
1610 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1611}
1612
1613function releasePooledEvent(event) {
1614 var EventConstructor = this;
1615 !(event instanceof EventConstructor) ? invariant_1(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1616 event.destructor();
1617 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1618 EventConstructor.eventPool.push(event);
1619 }
1620}
1621
1622function addEventPoolingTo(EventConstructor) {
1623 EventConstructor.eventPool = [];
1624 EventConstructor.getPooled = getPooledEvent;
1625 EventConstructor.release = releasePooledEvent;
1626}
1627
1628var SyntheticEvent$1 = SyntheticEvent;
1629
1630/**
1631 * @interface Event
1632 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1633 */
1634var SyntheticCompositionEvent = SyntheticEvent$1.extend({
1635 data: null
1636});
1637
1638/**
1639 * @interface Event
1640 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1641 * /#events-inputevents
1642 */
1643var SyntheticInputEvent = SyntheticEvent$1.extend({
1644 data: null
1645});
1646
1647var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1648var START_KEYCODE = 229;
1649
1650var canUseCompositionEvent = ExecutionEnvironment_1.canUseDOM && 'CompositionEvent' in window;
1651
1652var documentMode = null;
1653if (ExecutionEnvironment_1.canUseDOM && 'documentMode' in document) {
1654 documentMode = document.documentMode;
1655}
1656
1657// Webkit offers a very useful `textInput` event that can be used to
1658// directly represent `beforeInput`. The IE `textinput` event is not as
1659// useful, so we don't use it.
1660var canUseTextInputEvent = ExecutionEnvironment_1.canUseDOM && 'TextEvent' in window && !documentMode;
1661
1662// In IE9+, we have access to composition events, but the data supplied
1663// by the native compositionend event may be incorrect. Japanese ideographic
1664// spaces, for instance (\u3000) are not recorded correctly.
1665var useFallbackCompositionData = ExecutionEnvironment_1.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1666
1667var SPACEBAR_CODE = 32;
1668var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1669
1670// Events and their corresponding property names.
1671var eventTypes = {
1672 beforeInput: {
1673 phasedRegistrationNames: {
1674 bubbled: 'onBeforeInput',
1675 captured: 'onBeforeInputCapture'
1676 },
1677 dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste']
1678 },
1679 compositionEnd: {
1680 phasedRegistrationNames: {
1681 bubbled: 'onCompositionEnd',
1682 captured: 'onCompositionEndCapture'
1683 },
1684 dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1685 },
1686 compositionStart: {
1687 phasedRegistrationNames: {
1688 bubbled: 'onCompositionStart',
1689 captured: 'onCompositionStartCapture'
1690 },
1691 dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1692 },
1693 compositionUpdate: {
1694 phasedRegistrationNames: {
1695 bubbled: 'onCompositionUpdate',
1696 captured: 'onCompositionUpdateCapture'
1697 },
1698 dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1699 }
1700};
1701
1702// Track whether we've ever handled a keypress on the space key.
1703var hasSpaceKeypress = false;
1704
1705/**
1706 * Return whether a native keypress event is assumed to be a command.
1707 * This is required because Firefox fires `keypress` events for key commands
1708 * (cut, copy, select-all, etc.) even though no character is inserted.
1709 */
1710function isKeypressCommand(nativeEvent) {
1711 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1712 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1713 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1714}
1715
1716/**
1717 * Translate native top level events into event types.
1718 *
1719 * @param {string} topLevelType
1720 * @return {object}
1721 */
1722function getCompositionEventType(topLevelType) {
1723 switch (topLevelType) {
1724 case 'topCompositionStart':
1725 return eventTypes.compositionStart;
1726 case 'topCompositionEnd':
1727 return eventTypes.compositionEnd;
1728 case 'topCompositionUpdate':
1729 return eventTypes.compositionUpdate;
1730 }
1731}
1732
1733/**
1734 * Does our fallback best-guess model think this event signifies that
1735 * composition has begun?
1736 *
1737 * @param {string} topLevelType
1738 * @param {object} nativeEvent
1739 * @return {boolean}
1740 */
1741function isFallbackCompositionStart(topLevelType, nativeEvent) {
1742 return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
1743}
1744
1745/**
1746 * Does our fallback mode think that this event is the end of composition?
1747 *
1748 * @param {string} topLevelType
1749 * @param {object} nativeEvent
1750 * @return {boolean}
1751 */
1752function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1753 switch (topLevelType) {
1754 case 'topKeyUp':
1755 // Command keys insert or clear IME input.
1756 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1757 case 'topKeyDown':
1758 // Expect IME keyCode on each keydown. If we get any other
1759 // code we must have exited earlier.
1760 return nativeEvent.keyCode !== START_KEYCODE;
1761 case 'topKeyPress':
1762 case 'topMouseDown':
1763 case 'topBlur':
1764 // Events are not possible without cancelling IME.
1765 return true;
1766 default:
1767 return false;
1768 }
1769}
1770
1771/**
1772 * Google Input Tools provides composition data via a CustomEvent,
1773 * with the `data` property populated in the `detail` object. If this
1774 * is available on the event object, use it. If not, this is a plain
1775 * composition event and we have nothing special to extract.
1776 *
1777 * @param {object} nativeEvent
1778 * @return {?string}
1779 */
1780function getDataFromCustomEvent(nativeEvent) {
1781 var detail = nativeEvent.detail;
1782 if (typeof detail === 'object' && 'data' in detail) {
1783 return detail.data;
1784 }
1785 return null;
1786}
1787
1788// Track the current IME composition status, if any.
1789var isComposing = false;
1790
1791/**
1792 * @return {?object} A SyntheticCompositionEvent.
1793 */
1794function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1795 var eventType = void 0;
1796 var fallbackData = void 0;
1797
1798 if (canUseCompositionEvent) {
1799 eventType = getCompositionEventType(topLevelType);
1800 } else if (!isComposing) {
1801 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1802 eventType = eventTypes.compositionStart;
1803 }
1804 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1805 eventType = eventTypes.compositionEnd;
1806 }
1807
1808 if (!eventType) {
1809 return null;
1810 }
1811
1812 if (useFallbackCompositionData) {
1813 // The current composition is stored statically and must not be
1814 // overwritten while composition continues.
1815 if (!isComposing && eventType === eventTypes.compositionStart) {
1816 isComposing = initialize(nativeEventTarget);
1817 } else if (eventType === eventTypes.compositionEnd) {
1818 if (isComposing) {
1819 fallbackData = getData();
1820 }
1821 }
1822 }
1823
1824 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1825
1826 if (fallbackData) {
1827 // Inject data generated from fallback path into the synthetic event.
1828 // This matches the property of native CompositionEventInterface.
1829 event.data = fallbackData;
1830 } else {
1831 var customData = getDataFromCustomEvent(nativeEvent);
1832 if (customData !== null) {
1833 event.data = customData;
1834 }
1835 }
1836
1837 accumulateTwoPhaseDispatches(event);
1838 return event;
1839}
1840
1841/**
1842 * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
1843 * @param {object} nativeEvent Native browser event.
1844 * @return {?string} The string corresponding to this `beforeInput` event.
1845 */
1846function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1847 switch (topLevelType) {
1848 case 'topCompositionEnd':
1849 return getDataFromCustomEvent(nativeEvent);
1850 case 'topKeyPress':
1851 /**
1852 * If native `textInput` events are available, our goal is to make
1853 * use of them. However, there is a special case: the spacebar key.
1854 * In Webkit, preventing default on a spacebar `textInput` event
1855 * cancels character insertion, but it *also* causes the browser
1856 * to fall back to its default spacebar behavior of scrolling the
1857 * page.
1858 *
1859 * Tracking at:
1860 * https://code.google.com/p/chromium/issues/detail?id=355103
1861 *
1862 * To avoid this issue, use the keypress event as if no `textInput`
1863 * event is available.
1864 */
1865 var which = nativeEvent.which;
1866 if (which !== SPACEBAR_CODE) {
1867 return null;
1868 }
1869
1870 hasSpaceKeypress = true;
1871 return SPACEBAR_CHAR;
1872
1873 case 'topTextInput':
1874 // Record the characters to be added to the DOM.
1875 var chars = nativeEvent.data;
1876
1877 // If it's a spacebar character, assume that we have already handled
1878 // it at the keypress level and bail immediately. Android Chrome
1879 // doesn't give us keycodes, so we need to blacklist it.
1880 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1881 return null;
1882 }
1883
1884 return chars;
1885
1886 default:
1887 // For other native event types, do nothing.
1888 return null;
1889 }
1890}
1891
1892/**
1893 * For browsers that do not provide the `textInput` event, extract the
1894 * appropriate string to use for SyntheticInputEvent.
1895 *
1896 * @param {string} topLevelType Record from `BrowserEventConstants`.
1897 * @param {object} nativeEvent Native browser event.
1898 * @return {?string} The fallback string for this `beforeInput` event.
1899 */
1900function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1901 // If we are currently composing (IME) and using a fallback to do so,
1902 // try to extract the composed characters from the fallback object.
1903 // If composition event is available, we extract a string only at
1904 // compositionevent, otherwise extract it at fallback events.
1905 if (isComposing) {
1906 if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1907 var chars = getData();
1908 reset();
1909 isComposing = false;
1910 return chars;
1911 }
1912 return null;
1913 }
1914
1915 switch (topLevelType) {
1916 case 'topPaste':
1917 // If a paste event occurs after a keypress, throw out the input
1918 // chars. Paste events should not lead to BeforeInput events.
1919 return null;
1920 case 'topKeyPress':
1921 /**
1922 * As of v27, Firefox may fire keypress events even when no character
1923 * will be inserted. A few possibilities:
1924 *
1925 * - `which` is `0`. Arrow keys, Esc key, etc.
1926 *
1927 * - `which` is the pressed key code, but no char is available.
1928 * Ex: 'AltGr + d` in Polish. There is no modified character for
1929 * this key combination and no character is inserted into the
1930 * document, but FF fires the keypress for char code `100` anyway.
1931 * No `input` event will occur.
1932 *
1933 * - `which` is the pressed key code, but a command combination is
1934 * being used. Ex: `Cmd+C`. No character is inserted, and no
1935 * `input` event will occur.
1936 */
1937 if (!isKeypressCommand(nativeEvent)) {
1938 // IE fires the `keypress` event when a user types an emoji via
1939 // Touch keyboard of Windows. In such a case, the `char` property
1940 // holds an emoji character like `\uD83D\uDE0A`. Because its length
1941 // is 2, the property `which` does not represent an emoji correctly.
1942 // In such a case, we directly return the `char` property instead of
1943 // using `which`.
1944 if (nativeEvent.char && nativeEvent.char.length > 1) {
1945 return nativeEvent.char;
1946 } else if (nativeEvent.which) {
1947 return String.fromCharCode(nativeEvent.which);
1948 }
1949 }
1950 return null;
1951 case 'topCompositionEnd':
1952 return useFallbackCompositionData ? null : nativeEvent.data;
1953 default:
1954 return null;
1955 }
1956}
1957
1958/**
1959 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
1960 * `textInput` or fallback behavior.
1961 *
1962 * @return {?object} A SyntheticInputEvent.
1963 */
1964function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1965 var chars = void 0;
1966
1967 if (canUseTextInputEvent) {
1968 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
1969 } else {
1970 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
1971 }
1972
1973 // If no characters are being inserted, no BeforeInput event should
1974 // be fired.
1975 if (!chars) {
1976 return null;
1977 }
1978
1979 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
1980
1981 event.data = chars;
1982 accumulateTwoPhaseDispatches(event);
1983 return event;
1984}
1985
1986/**
1987 * Create an `onBeforeInput` event to match
1988 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
1989 *
1990 * This event plugin is based on the native `textInput` event
1991 * available in Chrome, Safari, Opera, and IE. This event fires after
1992 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
1993 *
1994 * `beforeInput` is spec'd but not implemented in any browsers, and
1995 * the `input` event does not provide any useful information about what has
1996 * actually been added, contrary to the spec. Thus, `textInput` is the best
1997 * available event to identify the characters that have actually been inserted
1998 * into the target node.
1999 *
2000 * This plugin is also responsible for emitting `composition` events, thus
2001 * allowing us to share composition fallback code for both `beforeInput` and
2002 * `composition` event types.
2003 */
2004var BeforeInputEventPlugin = {
2005 eventTypes: eventTypes,
2006
2007 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2008 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2009
2010 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2011
2012 if (composition === null) {
2013 return beforeInput;
2014 }
2015
2016 if (beforeInput === null) {
2017 return composition;
2018 }
2019
2020 return [composition, beforeInput];
2021 }
2022};
2023
2024// Use to restore controlled state after a change event has fired.
2025
2026var fiberHostComponent = null;
2027
2028var ReactControlledComponentInjection = {
2029 injectFiberControlledHostComponent: function (hostComponentImpl) {
2030 // The fiber implementation doesn't use dynamic dispatch so we need to
2031 // inject the implementation.
2032 fiberHostComponent = hostComponentImpl;
2033 }
2034};
2035
2036var restoreTarget = null;
2037var restoreQueue = null;
2038
2039function restoreStateOfTarget(target) {
2040 // We perform this translation at the end of the event loop so that we
2041 // always receive the correct fiber here
2042 var internalInstance = getInstanceFromNode(target);
2043 if (!internalInstance) {
2044 // Unmounted
2045 return;
2046 }
2047 !(fiberHostComponent && typeof fiberHostComponent.restoreControlledState === 'function') ? invariant_1(false, 'Fiber needs to be injected to handle a fiber target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2048 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2049 fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props);
2050}
2051
2052var injection$2 = ReactControlledComponentInjection;
2053
2054function enqueueStateRestore(target) {
2055 if (restoreTarget) {
2056 if (restoreQueue) {
2057 restoreQueue.push(target);
2058 } else {
2059 restoreQueue = [target];
2060 }
2061 } else {
2062 restoreTarget = target;
2063 }
2064}
2065
2066function needsStateRestore() {
2067 return restoreTarget !== null || restoreQueue !== null;
2068}
2069
2070function restoreStateIfNeeded() {
2071 if (!restoreTarget) {
2072 return;
2073 }
2074 var target = restoreTarget;
2075 var queuedTargets = restoreQueue;
2076 restoreTarget = null;
2077 restoreQueue = null;
2078
2079 restoreStateOfTarget(target);
2080 if (queuedTargets) {
2081 for (var i = 0; i < queuedTargets.length; i++) {
2082 restoreStateOfTarget(queuedTargets[i]);
2083 }
2084 }
2085}
2086
2087var ReactControlledComponent = Object.freeze({
2088 injection: injection$2,
2089 enqueueStateRestore: enqueueStateRestore,
2090 needsStateRestore: needsStateRestore,
2091 restoreStateIfNeeded: restoreStateIfNeeded
2092});
2093
2094// Used as a way to call batchedUpdates when we don't have a reference to
2095// the renderer. Such as when we're dispatching events or if third party
2096// libraries need to call batchedUpdates. Eventually, this API will go away when
2097// everything is batched by default. We'll then have a similar API to opt-out of
2098// scheduled work and instead do synchronous work.
2099
2100// Defaults
2101var _batchedUpdates = function (fn, bookkeeping) {
2102 return fn(bookkeeping);
2103};
2104var _interactiveUpdates = function (fn, a, b) {
2105 return fn(a, b);
2106};
2107var _flushInteractiveUpdates = function () {};
2108
2109var isBatching = false;
2110function batchedUpdates(fn, bookkeeping) {
2111 if (isBatching) {
2112 // If we are currently inside another batch, we need to wait until it
2113 // fully completes before restoring state.
2114 return fn(bookkeeping);
2115 }
2116 isBatching = true;
2117 try {
2118 return _batchedUpdates(fn, bookkeeping);
2119 } finally {
2120 // Here we wait until all updates have propagated, which is important
2121 // when using controlled components within layers:
2122 // https://github.com/facebook/react/issues/1698
2123 // Then we restore state of any controlled component.
2124 isBatching = false;
2125 var controlledComponentsHavePendingUpdates = needsStateRestore();
2126 if (controlledComponentsHavePendingUpdates) {
2127 // If a controlled event was fired, we may need to restore the state of
2128 // the DOM node back to the controlled value. This is necessary when React
2129 // bails out of the update without touching the DOM.
2130 _flushInteractiveUpdates();
2131 restoreStateIfNeeded();
2132 }
2133 }
2134}
2135
2136function interactiveUpdates(fn, a, b) {
2137 return _interactiveUpdates(fn, a, b);
2138}
2139
2140
2141
2142var injection$3 = {
2143 injectRenderer: function (renderer) {
2144 _batchedUpdates = renderer.batchedUpdates;
2145 _interactiveUpdates = renderer.interactiveUpdates;
2146 _flushInteractiveUpdates = renderer.flushInteractiveUpdates;
2147 }
2148};
2149
2150/**
2151 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2152 */
2153var supportedInputTypes = {
2154 color: true,
2155 date: true,
2156 datetime: true,
2157 'datetime-local': true,
2158 email: true,
2159 month: true,
2160 number: true,
2161 password: true,
2162 range: true,
2163 search: true,
2164 tel: true,
2165 text: true,
2166 time: true,
2167 url: true,
2168 week: true
2169};
2170
2171function isTextInputElement(elem) {
2172 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2173
2174 if (nodeName === 'input') {
2175 return !!supportedInputTypes[elem.type];
2176 }
2177
2178 if (nodeName === 'textarea') {
2179 return true;
2180 }
2181
2182 return false;
2183}
2184
2185/**
2186 * HTML nodeType values that represent the type of the node
2187 */
2188
2189var ELEMENT_NODE = 1;
2190var TEXT_NODE = 3;
2191var COMMENT_NODE = 8;
2192var DOCUMENT_NODE = 9;
2193var DOCUMENT_FRAGMENT_NODE = 11;
2194
2195/**
2196 * Gets the target node from a native browser event by accounting for
2197 * inconsistencies in browser DOM APIs.
2198 *
2199 * @param {object} nativeEvent Native browser event.
2200 * @return {DOMEventTarget} Target node.
2201 */
2202function getEventTarget(nativeEvent) {
2203 var target = nativeEvent.target || window;
2204
2205 // Normalize SVG <use> element events #4963
2206 if (target.correspondingUseElement) {
2207 target = target.correspondingUseElement;
2208 }
2209
2210 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2211 // @see http://www.quirksmode.org/js/events_properties.html
2212 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2213}
2214
2215/**
2216 * Checks if an event is supported in the current execution environment.
2217 *
2218 * NOTE: This will not work correctly for non-generic events such as `change`,
2219 * `reset`, `load`, `error`, and `select`.
2220 *
2221 * Borrows from Modernizr.
2222 *
2223 * @param {string} eventNameSuffix Event name, e.g. "click".
2224 * @param {?boolean} capture Check if the capture phase is supported.
2225 * @return {boolean} True if the event is supported.
2226 * @internal
2227 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2228 */
2229function isEventSupported(eventNameSuffix, capture) {
2230 if (!ExecutionEnvironment_1.canUseDOM || capture && !('addEventListener' in document)) {
2231 return false;
2232 }
2233
2234 var eventName = 'on' + eventNameSuffix;
2235 var isSupported = eventName in document;
2236
2237 if (!isSupported) {
2238 var element = document.createElement('div');
2239 element.setAttribute(eventName, 'return;');
2240 isSupported = typeof element[eventName] === 'function';
2241 }
2242
2243 return isSupported;
2244}
2245
2246function isCheckable(elem) {
2247 var type = elem.type;
2248 var nodeName = elem.nodeName;
2249 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2250}
2251
2252function getTracker(node) {
2253 return node._valueTracker;
2254}
2255
2256function detachTracker(node) {
2257 node._valueTracker = null;
2258}
2259
2260function getValueFromNode(node) {
2261 var value = '';
2262 if (!node) {
2263 return value;
2264 }
2265
2266 if (isCheckable(node)) {
2267 value = node.checked ? 'true' : 'false';
2268 } else {
2269 value = node.value;
2270 }
2271
2272 return value;
2273}
2274
2275function trackValueOnNode(node) {
2276 var valueField = isCheckable(node) ? 'checked' : 'value';
2277 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2278
2279 var currentValue = '' + node[valueField];
2280
2281 // if someone has already defined a value or Safari, then bail
2282 // and don't track value will cause over reporting of changes,
2283 // but it's better then a hard failure
2284 // (needed for certain tests that spyOn input values and Safari)
2285 if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2286 return;
2287 }
2288
2289 Object.defineProperty(node, valueField, {
2290 configurable: true,
2291 get: function () {
2292 return descriptor.get.call(this);
2293 },
2294 set: function (value) {
2295 currentValue = '' + value;
2296 descriptor.set.call(this, value);
2297 }
2298 });
2299 // We could've passed this the first time
2300 // but it triggers a bug in IE11 and Edge 14/15.
2301 // Calling defineProperty() again should be equivalent.
2302 // https://github.com/facebook/react/issues/11768
2303 Object.defineProperty(node, valueField, {
2304 enumerable: descriptor.enumerable
2305 });
2306
2307 var tracker = {
2308 getValue: function () {
2309 return currentValue;
2310 },
2311 setValue: function (value) {
2312 currentValue = '' + value;
2313 },
2314 stopTracking: function () {
2315 detachTracker(node);
2316 delete node[valueField];
2317 }
2318 };
2319 return tracker;
2320}
2321
2322function track(node) {
2323 if (getTracker(node)) {
2324 return;
2325 }
2326
2327 // TODO: Once it's just Fiber we can move this to node._wrapperState
2328 node._valueTracker = trackValueOnNode(node);
2329}
2330
2331function updateValueIfChanged(node) {
2332 if (!node) {
2333 return false;
2334 }
2335
2336 var tracker = getTracker(node);
2337 // if there is no tracker at this point it's unlikely
2338 // that trying again will succeed
2339 if (!tracker) {
2340 return true;
2341 }
2342
2343 var lastValue = tracker.getValue();
2344 var nextValue = getValueFromNode(node);
2345 if (nextValue !== lastValue) {
2346 tracker.setValue(nextValue);
2347 return true;
2348 }
2349 return false;
2350}
2351
2352var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2353
2354var ReactCurrentOwner = ReactInternals$1.ReactCurrentOwner;
2355var ReactDebugCurrentFrame = ReactInternals$1.ReactDebugCurrentFrame;
2356
2357var describeComponentFrame = function (name, source, ownerName) {
2358 return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
2359};
2360
2361// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2362// nor polyfill, then a plain number is used for performance.
2363var hasSymbol = typeof Symbol === 'function' && Symbol['for'];
2364
2365var REACT_ELEMENT_TYPE = hasSymbol ? Symbol['for']('react.element') : 0xeac7;
2366var REACT_CALL_TYPE = hasSymbol ? Symbol['for']('react.call') : 0xeac8;
2367var REACT_RETURN_TYPE = hasSymbol ? Symbol['for']('react.return') : 0xeac9;
2368var REACT_PORTAL_TYPE = hasSymbol ? Symbol['for']('react.portal') : 0xeaca;
2369var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb;
2370var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol['for']('react.strict_mode') : 0xeacc;
2371var REACT_PROVIDER_TYPE = hasSymbol ? Symbol['for']('react.provider') : 0xeacd;
2372var REACT_CONTEXT_TYPE = hasSymbol ? Symbol['for']('react.context') : 0xeace;
2373var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol['for']('react.async_mode') : 0xeacf;
2374
2375var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2376var FAUX_ITERATOR_SYMBOL = '@@iterator';
2377
2378function getIteratorFn(maybeIterable) {
2379 if (maybeIterable === null || typeof maybeIterable === 'undefined') {
2380 return null;
2381 }
2382 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2383 if (typeof maybeIterator === 'function') {
2384 return maybeIterator;
2385 }
2386 return null;
2387}
2388
2389function getComponentName(fiber) {
2390 var type = fiber.type;
2391
2392 if (typeof type === 'function') {
2393 return type.displayName || type.name;
2394 }
2395 if (typeof type === 'string') {
2396 return type;
2397 }
2398 switch (type) {
2399 case REACT_FRAGMENT_TYPE:
2400 return 'ReactFragment';
2401 case REACT_PORTAL_TYPE:
2402 return 'ReactPortal';
2403 case REACT_CALL_TYPE:
2404 return 'ReactCall';
2405 case REACT_RETURN_TYPE:
2406 return 'ReactReturn';
2407 }
2408 return null;
2409}
2410
2411function describeFiber(fiber) {
2412 switch (fiber.tag) {
2413 case IndeterminateComponent:
2414 case FunctionalComponent:
2415 case ClassComponent:
2416 case HostComponent:
2417 var owner = fiber._debugOwner;
2418 var source = fiber._debugSource;
2419 var name = getComponentName(fiber);
2420 var ownerName = null;
2421 if (owner) {
2422 ownerName = getComponentName(owner);
2423 }
2424 return describeComponentFrame(name, source, ownerName);
2425 default:
2426 return '';
2427 }
2428}
2429
2430// This function can only be called with a work-in-progress fiber and
2431// only during begin or complete phase. Do not call it under any other
2432// circumstances.
2433function getStackAddendumByWorkInProgressFiber(workInProgress) {
2434 var info = '';
2435 var node = workInProgress;
2436 do {
2437 info += describeFiber(node);
2438 // Otherwise this return pointer might point to the wrong tree:
2439 node = node['return'];
2440 } while (node);
2441 return info;
2442}
2443
2444function getCurrentFiberOwnerName$1() {
2445 {
2446 var fiber = ReactDebugCurrentFiber.current;
2447 if (fiber === null) {
2448 return null;
2449 }
2450 var owner = fiber._debugOwner;
2451 if (owner !== null && typeof owner !== 'undefined') {
2452 return getComponentName(owner);
2453 }
2454 }
2455 return null;
2456}
2457
2458function getCurrentFiberStackAddendum$1() {
2459 {
2460 var fiber = ReactDebugCurrentFiber.current;
2461 if (fiber === null) {
2462 return null;
2463 }
2464 // Safe because if current fiber exists, we are reconciling,
2465 // and it is guaranteed to be the work-in-progress version.
2466 return getStackAddendumByWorkInProgressFiber(fiber);
2467 }
2468 return null;
2469}
2470
2471function resetCurrentFiber() {
2472 ReactDebugCurrentFrame.getCurrentStack = null;
2473 ReactDebugCurrentFiber.current = null;
2474 ReactDebugCurrentFiber.phase = null;
2475}
2476
2477function setCurrentFiber(fiber) {
2478 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1;
2479 ReactDebugCurrentFiber.current = fiber;
2480 ReactDebugCurrentFiber.phase = null;
2481}
2482
2483function setCurrentPhase(phase) {
2484 ReactDebugCurrentFiber.phase = phase;
2485}
2486
2487var ReactDebugCurrentFiber = {
2488 current: null,
2489 phase: null,
2490 resetCurrentFiber: resetCurrentFiber,
2491 setCurrentFiber: setCurrentFiber,
2492 setCurrentPhase: setCurrentPhase,
2493 getCurrentFiberOwnerName: getCurrentFiberOwnerName$1,
2494 getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1
2495};
2496
2497// A reserved attribute.
2498// It is handled by React separately and shouldn't be written to the DOM.
2499var RESERVED = 0;
2500
2501// A simple string attribute.
2502// Attributes that aren't in the whitelist are presumed to have this type.
2503var STRING = 1;
2504
2505// A string attribute that accepts booleans in React. In HTML, these are called
2506// "enumerated" attributes with "true" and "false" as possible values.
2507// When true, it should be set to a "true" string.
2508// When false, it should be set to a "false" string.
2509var BOOLEANISH_STRING = 2;
2510
2511// A real boolean attribute.
2512// When true, it should be present (set either to an empty string or its name).
2513// When false, it should be omitted.
2514var BOOLEAN = 3;
2515
2516// An attribute that can be used as a flag as well as with a value.
2517// When true, it should be present (set either to an empty string or its name).
2518// When false, it should be omitted.
2519// For any other value, should be present with that value.
2520var OVERLOADED_BOOLEAN = 4;
2521
2522// An attribute that must be numeric or parse as a numeric.
2523// When falsy, it should be removed.
2524var NUMERIC = 5;
2525
2526// An attribute that must be positive numeric or parse as a positive numeric.
2527// When falsy, it should be removed.
2528var POSITIVE_NUMERIC = 6;
2529
2530/* eslint-disable max-len */
2531var 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';
2532/* eslint-enable max-len */
2533var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2534
2535
2536var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2537var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2538
2539var illegalAttributeNameCache = {};
2540var validatedAttributeNameCache = {};
2541
2542function isAttributeNameSafe(attributeName) {
2543 if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
2544 return true;
2545 }
2546 if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
2547 return false;
2548 }
2549 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2550 validatedAttributeNameCache[attributeName] = true;
2551 return true;
2552 }
2553 illegalAttributeNameCache[attributeName] = true;
2554 {
2555 warning_1(false, 'Invalid attribute name: `%s`', attributeName);
2556 }
2557 return false;
2558}
2559
2560function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2561 if (propertyInfo !== null) {
2562 return propertyInfo.type === RESERVED;
2563 }
2564 if (isCustomComponentTag) {
2565 return false;
2566 }
2567 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2568 return true;
2569 }
2570 return false;
2571}
2572
2573function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2574 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2575 return false;
2576 }
2577 switch (typeof value) {
2578 case 'function':
2579 // $FlowIssue symbol is perfectly valid here
2580 case 'symbol':
2581 // eslint-disable-line
2582 return true;
2583 case 'boolean':
2584 {
2585 if (isCustomComponentTag) {
2586 return false;
2587 }
2588 if (propertyInfo !== null) {
2589 return !propertyInfo.acceptsBooleans;
2590 } else {
2591 var prefix = name.toLowerCase().slice(0, 5);
2592 return prefix !== 'data-' && prefix !== 'aria-';
2593 }
2594 }
2595 default:
2596 return false;
2597 }
2598}
2599
2600function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2601 if (value === null || typeof value === 'undefined') {
2602 return true;
2603 }
2604 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2605 return true;
2606 }
2607 if (propertyInfo !== null) {
2608 switch (propertyInfo.type) {
2609 case BOOLEAN:
2610 return !value;
2611 case OVERLOADED_BOOLEAN:
2612 return value === false;
2613 case NUMERIC:
2614 return isNaN(value);
2615 case POSITIVE_NUMERIC:
2616 return isNaN(value) || value < 1;
2617 }
2618 }
2619 return false;
2620}
2621
2622function getPropertyInfo(name) {
2623 return properties.hasOwnProperty(name) ? properties[name] : null;
2624}
2625
2626function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2627 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2628 this.attributeName = attributeName;
2629 this.attributeNamespace = attributeNamespace;
2630 this.mustUseProperty = mustUseProperty;
2631 this.propertyName = name;
2632 this.type = type;
2633}
2634
2635// When adding attributes to this list, be sure to also add them to
2636// the `possibleStandardNames` module to ensure casing and incorrect
2637// name warnings.
2638var properties = {};
2639
2640// These props are reserved by React. They shouldn't be written to the DOM.
2641['children', 'dangerouslySetInnerHTML',
2642// TODO: This prevents the assignment of defaultValue to regular
2643// elements (not just inputs). Now that ReactDOMInput assigns to the
2644// defaultValue property -- do we need this?
2645'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2646 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2647 name, // attributeName
2648 null);
2649});
2650
2651// A few React string attributes have a different name.
2652// This is a mapping from React prop names to the attribute names.
2653new Map([['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']]).forEach(function (attributeName, name) {
2654 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2655 attributeName, // attributeName
2656 null);
2657});
2658
2659// These are "enumerated" HTML attributes that accept "true" and "false".
2660// In React, we let users pass `true` and `false` even though technically
2661// these aren't boolean attributes (they are coerced to strings).
2662['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2663 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2664 name.toLowerCase(), // attributeName
2665 null);
2666});
2667
2668// These are "enumerated" SVG attributes that accept "true" and "false".
2669// In React, we let users pass `true` and `false` even though technically
2670// these aren't boolean attributes (they are coerced to strings).
2671// Since these are SVG attributes, their attribute names are case-sensitive.
2672['autoReverse', 'externalResourcesRequired', 'preserveAlpha'].forEach(function (name) {
2673 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2674 name, // attributeName
2675 null);
2676});
2677
2678// These are HTML boolean attributes.
2679['allowFullScreen', 'async',
2680// Note: there is a special case that prevents it from being written to the DOM
2681// on the client side because the browsers are inconsistent. Instead we call focus().
2682'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2683// Microdata
2684'itemScope'].forEach(function (name) {
2685 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2686 name.toLowerCase(), // attributeName
2687 null);
2688});
2689
2690// These are the few React props that we set as DOM properties
2691// rather than attributes. These are all booleans.
2692['checked',
2693// Note: `option.selected` is not updated if `select.multiple` is
2694// disabled with `removeAttribute`. We have special logic for handling this.
2695'multiple', 'muted', 'selected'].forEach(function (name) {
2696 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2697 name.toLowerCase(), // attributeName
2698 null);
2699});
2700
2701// These are HTML attributes that are "overloaded booleans": they behave like
2702// booleans, but can also accept a string value.
2703['capture', 'download'].forEach(function (name) {
2704 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2705 name.toLowerCase(), // attributeName
2706 null);
2707});
2708
2709// These are HTML attributes that must be positive numbers.
2710['cols', 'rows', 'size', 'span'].forEach(function (name) {
2711 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2712 name.toLowerCase(), // attributeName
2713 null);
2714});
2715
2716// These are HTML attributes that must be numbers.
2717['rowSpan', 'start'].forEach(function (name) {
2718 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2719 name.toLowerCase(), // attributeName
2720 null);
2721});
2722
2723var CAMELIZE = /[\-\:]([a-z])/g;
2724var capitalize = function (token) {
2725 return token[1].toUpperCase();
2726};
2727
2728// This is a list of all SVG attributes that need special casing, namespacing,
2729// or boolean value assignment. Regular attributes that just accept strings
2730// and have the same names are omitted, just like in the HTML whitelist.
2731// Some of these attributes can be hard to find. This list was created by
2732// scrapping the MDN documentation.
2733['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'].forEach(function (attributeName) {
2734 var name = attributeName.replace(CAMELIZE, capitalize);
2735 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2736 attributeName, null);
2737});
2738
2739// String SVG attributes with the xlink namespace.
2740['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2741 var name = attributeName.replace(CAMELIZE, capitalize);
2742 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2743 attributeName, 'http://www.w3.org/1999/xlink');
2744});
2745
2746// String SVG attributes with the xml namespace.
2747['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2748 var name = attributeName.replace(CAMELIZE, capitalize);
2749 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2750 attributeName, 'http://www.w3.org/XML/1998/namespace');
2751});
2752
2753// Special case: this attribute exists both in HTML and SVG.
2754// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2755// its React `tabIndex` name, like we do for attributes that exist only in HTML.
2756properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2757'tabindex', // attributeName
2758null);
2759
2760/**
2761 * Get the value for a property on a node. Only used in DEV for SSR validation.
2762 * The "expected" argument is used as a hint of what the expected value is.
2763 * Some properties have multiple equivalent values.
2764 */
2765function getValueForProperty(node, name, expected, propertyInfo) {
2766 {
2767 if (propertyInfo.mustUseProperty) {
2768 var propertyName = propertyInfo.propertyName;
2769
2770 return node[propertyName];
2771 } else {
2772 var attributeName = propertyInfo.attributeName;
2773
2774 var stringValue = null;
2775
2776 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2777 if (node.hasAttribute(attributeName)) {
2778 var value = node.getAttribute(attributeName);
2779 if (value === '') {
2780 return true;
2781 }
2782 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2783 return value;
2784 }
2785 if (value === '' + expected) {
2786 return expected;
2787 }
2788 return value;
2789 }
2790 } else if (node.hasAttribute(attributeName)) {
2791 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2792 // We had an attribute but shouldn't have had one, so read it
2793 // for the error message.
2794 return node.getAttribute(attributeName);
2795 }
2796 if (propertyInfo.type === BOOLEAN) {
2797 // If this was a boolean, it doesn't matter what the value is
2798 // the fact that we have it is the same as the expected.
2799 return expected;
2800 }
2801 // Even if this property uses a namespace we use getAttribute
2802 // because we assume its namespaced name is the same as our config.
2803 // To use getAttributeNS we need the local name which we don't have
2804 // in our config atm.
2805 stringValue = node.getAttribute(attributeName);
2806 }
2807
2808 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2809 return stringValue === null ? expected : stringValue;
2810 } else if (stringValue === '' + expected) {
2811 return expected;
2812 } else {
2813 return stringValue;
2814 }
2815 }
2816 }
2817}
2818
2819/**
2820 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2821 * The third argument is used as a hint of what the expected value is. Some
2822 * attributes have multiple equivalent values.
2823 */
2824function getValueForAttribute(node, name, expected) {
2825 {
2826 if (!isAttributeNameSafe(name)) {
2827 return;
2828 }
2829 if (!node.hasAttribute(name)) {
2830 return expected === undefined ? undefined : null;
2831 }
2832 var value = node.getAttribute(name);
2833 if (value === '' + expected) {
2834 return expected;
2835 }
2836 return value;
2837 }
2838}
2839
2840/**
2841 * Sets the value for a property on a node.
2842 *
2843 * @param {DOMElement} node
2844 * @param {string} name
2845 * @param {*} value
2846 */
2847function setValueForProperty(node, name, value, isCustomComponentTag) {
2848 var propertyInfo = getPropertyInfo(name);
2849 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2850 return;
2851 }
2852 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2853 value = null;
2854 }
2855 // If the prop isn't in the special list, treat it as a simple attribute.
2856 if (isCustomComponentTag || propertyInfo === null) {
2857 if (isAttributeNameSafe(name)) {
2858 var _attributeName = name;
2859 if (value === null) {
2860 node.removeAttribute(_attributeName);
2861 } else {
2862 node.setAttribute(_attributeName, '' + value);
2863 }
2864 }
2865 return;
2866 }
2867 var mustUseProperty = propertyInfo.mustUseProperty;
2868
2869 if (mustUseProperty) {
2870 var propertyName = propertyInfo.propertyName;
2871
2872 if (value === null) {
2873 var type = propertyInfo.type;
2874
2875 node[propertyName] = type === BOOLEAN ? false : '';
2876 } else {
2877 // Contrary to `setAttribute`, object properties are properly
2878 // `toString`ed by IE8/9.
2879 node[propertyName] = value;
2880 }
2881 return;
2882 }
2883 // The rest are treated as attributes with special cases.
2884 var attributeName = propertyInfo.attributeName,
2885 attributeNamespace = propertyInfo.attributeNamespace;
2886
2887 if (value === null) {
2888 node.removeAttribute(attributeName);
2889 } else {
2890 var _type = propertyInfo.type;
2891
2892 var attributeValue = void 0;
2893 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
2894 attributeValue = '';
2895 } else {
2896 // `setAttribute` with objects becomes only `[object]` in IE8/9,
2897 // ('' + value) makes it output the correct toString()-value.
2898 attributeValue = '' + value;
2899 }
2900 if (attributeNamespace) {
2901 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
2902 } else {
2903 node.setAttribute(attributeName, attributeValue);
2904 }
2905 }
2906}
2907
2908/**
2909 * Copyright (c) 2013-present, Facebook, Inc.
2910 *
2911 * This source code is licensed under the MIT license found in the
2912 * LICENSE file in the root directory of this source tree.
2913 */
2914
2915
2916
2917var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
2918
2919var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
2920
2921/**
2922 * Copyright (c) 2013-present, Facebook, Inc.
2923 *
2924 * This source code is licensed under the MIT license found in the
2925 * LICENSE file in the root directory of this source tree.
2926 */
2927
2928
2929
2930{
2931 var invariant$2 = invariant_1;
2932 var warning$2 = warning_1;
2933 var ReactPropTypesSecret = ReactPropTypesSecret_1;
2934 var loggedTypeFailures = {};
2935}
2936
2937/**
2938 * Assert that the values match with the type specs.
2939 * Error messages are memorized and will only be shown once.
2940 *
2941 * @param {object} typeSpecs Map of name to a ReactPropType
2942 * @param {object} values Runtime values that need to be type-checked
2943 * @param {string} location e.g. "prop", "context", "child context"
2944 * @param {string} componentName Name of the component for error messages.
2945 * @param {?Function} getStack Returns the component stack.
2946 * @private
2947 */
2948function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
2949 {
2950 for (var typeSpecName in typeSpecs) {
2951 if (typeSpecs.hasOwnProperty(typeSpecName)) {
2952 var error;
2953 // Prop type validation may throw. In case they do, we don't want to
2954 // fail the render phase where it didn't fail before. So we log it.
2955 // After these have been cleaned up, we'll let them throw.
2956 try {
2957 // This is intentionally an invariant that gets caught. It's the same
2958 // behavior as without this statement except with a better message.
2959 invariant$2(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'the `prop-types` package, but received `%s`.', componentName || 'React class', location, typeSpecName, typeof typeSpecs[typeSpecName]);
2960 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
2961 } catch (ex) {
2962 error = ex;
2963 }
2964 warning$2(!error || error instanceof 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);
2965 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
2966 // Only monitor this failure once because there tends to be a lot of the
2967 // same error.
2968 loggedTypeFailures[error.message] = true;
2969
2970 var stack = getStack ? getStack() : '';
2971
2972 warning$2(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
2973 }
2974 }
2975 }
2976 }
2977}
2978
2979var checkPropTypes_1 = checkPropTypes;
2980
2981var ReactControlledValuePropTypes = {
2982 checkPropTypes: null
2983};
2984
2985{
2986 var hasReadOnlyValue = {
2987 button: true,
2988 checkbox: true,
2989 image: true,
2990 hidden: true,
2991 radio: true,
2992 reset: true,
2993 submit: true
2994 };
2995
2996 var propTypes = {
2997 value: function (props, propName, componentName) {
2998 if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
2999 return null;
3000 }
3001 return new 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`.');
3002 },
3003 checked: function (props, propName, componentName) {
3004 if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
3005 return null;
3006 }
3007 return new 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`.');
3008 }
3009 };
3010
3011 /**
3012 * Provide a linked `value` attribute for controlled forms. You should not use
3013 * this outside of the ReactDOM controlled form components.
3014 */
3015 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) {
3016 checkPropTypes_1(propTypes, props, 'prop', tagName, getStack);
3017 };
3018}
3019
3020// TODO: direct imports like some-package/src/* are bad. Fix me.
3021var getCurrentFiberOwnerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
3022var getCurrentFiberStackAddendum = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
3023
3024var didWarnValueDefaultValue = false;
3025var didWarnCheckedDefaultChecked = false;
3026var didWarnControlledToUncontrolled = false;
3027var didWarnUncontrolledToControlled = false;
3028
3029function isControlled(props) {
3030 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3031 return usesChecked ? props.checked != null : props.value != null;
3032}
3033
3034/**
3035 * Implements an <input> host component that allows setting these optional
3036 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3037 *
3038 * If `checked` or `value` are not supplied (or null/undefined), user actions
3039 * that affect the checked state or value will trigger updates to the element.
3040 *
3041 * If they are supplied (and not null/undefined), the rendered element will not
3042 * trigger updates to the element. Instead, the props must change in order for
3043 * the rendered element to be updated.
3044 *
3045 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3046 * with an empty value (or `defaultValue`).
3047 *
3048 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3049 */
3050
3051function getHostProps(element, props) {
3052 var node = element;
3053 var checked = props.checked;
3054
3055 var hostProps = _assign({}, props, {
3056 defaultChecked: undefined,
3057 defaultValue: undefined,
3058 value: undefined,
3059 checked: checked != null ? checked : node._wrapperState.initialChecked
3060 });
3061
3062 return hostProps;
3063}
3064
3065function initWrapperState(element, props) {
3066 {
3067 ReactControlledValuePropTypes.checkPropTypes('input', props, getCurrentFiberStackAddendum);
3068
3069 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3070 warning_1(false, '%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://fb.me/react-controlled-components', getCurrentFiberOwnerName() || 'A component', props.type);
3071 didWarnCheckedDefaultChecked = true;
3072 }
3073 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3074 warning_1(false, '%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://fb.me/react-controlled-components', getCurrentFiberOwnerName() || 'A component', props.type);
3075 didWarnValueDefaultValue = true;
3076 }
3077 }
3078
3079 var node = element;
3080 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3081
3082 node._wrapperState = {
3083 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3084 initialValue: getSafeValue(props.value != null ? props.value : defaultValue),
3085 controlled: isControlled(props)
3086 };
3087}
3088
3089function updateChecked(element, props) {
3090 var node = element;
3091 var checked = props.checked;
3092 if (checked != null) {
3093 setValueForProperty(node, 'checked', checked, false);
3094 }
3095}
3096
3097function updateWrapper(element, props) {
3098 var node = element;
3099 {
3100 var _controlled = isControlled(props);
3101
3102 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3103 warning_1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum());
3104 didWarnUncontrolledToControlled = true;
3105 }
3106 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3107 warning_1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum());
3108 didWarnControlledToUncontrolled = true;
3109 }
3110 }
3111
3112 updateChecked(element, props);
3113
3114 var value = getSafeValue(props.value);
3115
3116 if (value != null) {
3117 if (props.type === 'number') {
3118 if (value === 0 && node.value === '' ||
3119 // eslint-disable-next-line
3120 node.value != value) {
3121 node.value = '' + value;
3122 }
3123 } else if (node.value !== '' + value) {
3124 node.value = '' + value;
3125 }
3126 }
3127
3128 if (props.hasOwnProperty('value')) {
3129 setDefaultValue(node, props.type, value);
3130 } else if (props.hasOwnProperty('defaultValue')) {
3131 setDefaultValue(node, props.type, getSafeValue(props.defaultValue));
3132 }
3133
3134 if (props.checked == null && props.defaultChecked != null) {
3135 node.defaultChecked = !!props.defaultChecked;
3136 }
3137}
3138
3139function postMountWrapper(element, props) {
3140 var node = element;
3141
3142 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3143 // Do not assign value if it is already set. This prevents user text input
3144 // from being lost during SSR hydration.
3145 if (node.value === '') {
3146 node.value = '' + node._wrapperState.initialValue;
3147 }
3148
3149 // value must be assigned before defaultValue. This fixes an issue where the
3150 // visually displayed value of date inputs disappears on mobile Safari and Chrome:
3151 // https://github.com/facebook/react/issues/7233
3152 node.defaultValue = '' + node._wrapperState.initialValue;
3153 }
3154
3155 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3156 // this is needed to work around a chrome bug where setting defaultChecked
3157 // will sometimes influence the value of checked (even after detachment).
3158 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3159 // We need to temporarily unset name to avoid disrupting radio button groups.
3160 var name = node.name;
3161 if (name !== '') {
3162 node.name = '';
3163 }
3164 node.defaultChecked = !node.defaultChecked;
3165 node.defaultChecked = !node.defaultChecked;
3166 if (name !== '') {
3167 node.name = name;
3168 }
3169}
3170
3171function restoreControlledState(element, props) {
3172 var node = element;
3173 updateWrapper(node, props);
3174 updateNamedCousins(node, props);
3175}
3176
3177function updateNamedCousins(rootNode, props) {
3178 var name = props.name;
3179 if (props.type === 'radio' && name != null) {
3180 var queryRoot = rootNode;
3181
3182 while (queryRoot.parentNode) {
3183 queryRoot = queryRoot.parentNode;
3184 }
3185
3186 // If `rootNode.form` was non-null, then we could try `form.elements`,
3187 // but that sometimes behaves strangely in IE8. We could also try using
3188 // `form.getElementsByName`, but that will only return direct children
3189 // and won't include inputs that use the HTML5 `form=` attribute. Since
3190 // the input might not even be in a form. It might not even be in the
3191 // document. Let's just use the local `querySelectorAll` to ensure we don't
3192 // miss anything.
3193 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3194
3195 for (var i = 0; i < group.length; i++) {
3196 var otherNode = group[i];
3197 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3198 continue;
3199 }
3200 // This will throw if radio buttons rendered by different copies of React
3201 // and the same name are rendered into the same form (same as #1939).
3202 // That's probably okay; we don't support it just as we don't support
3203 // mixing React radio buttons with non-React ones.
3204 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3205 !otherProps ? invariant_1(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3206
3207 // We need update the tracked value on the named cousin since the value
3208 // was changed but the input saw no event or value set
3209 updateValueIfChanged(otherNode);
3210
3211 // If this is a controlled radio button group, forcing the input that
3212 // was previously checked to update will cause it to be come re-checked
3213 // as appropriate.
3214 updateWrapper(otherNode, otherProps);
3215 }
3216 }
3217}
3218
3219// In Chrome, assigning defaultValue to certain input types triggers input validation.
3220// For number inputs, the display value loses trailing decimal points. For email inputs,
3221// Chrome raises "The specified value <x> is not a valid email address".
3222//
3223// Here we check to see if the defaultValue has actually changed, avoiding these problems
3224// when the user is inputting text
3225//
3226// https://github.com/facebook/react/issues/7253
3227function setDefaultValue(node, type, value) {
3228 if (
3229 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3230 type !== 'number' || node.ownerDocument.activeElement !== node) {
3231 if (value == null) {
3232 node.defaultValue = '' + node._wrapperState.initialValue;
3233 } else if (node.defaultValue !== '' + value) {
3234 node.defaultValue = '' + value;
3235 }
3236 }
3237}
3238
3239function getSafeValue(value) {
3240 switch (typeof value) {
3241 case 'boolean':
3242 case 'number':
3243 case 'object':
3244 case 'string':
3245 case 'undefined':
3246 return value;
3247 default:
3248 // function, symbol are assigned as empty strings
3249 return '';
3250 }
3251}
3252
3253var eventTypes$1 = {
3254 change: {
3255 phasedRegistrationNames: {
3256 bubbled: 'onChange',
3257 captured: 'onChangeCapture'
3258 },
3259 dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange']
3260 }
3261};
3262
3263function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3264 var event = SyntheticEvent$1.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3265 event.type = 'change';
3266 // Flag this event loop as needing state restore.
3267 enqueueStateRestore(target);
3268 accumulateTwoPhaseDispatches(event);
3269 return event;
3270}
3271/**
3272 * For IE shims
3273 */
3274var activeElement = null;
3275var activeElementInst = null;
3276
3277/**
3278 * SECTION: handle `change` event
3279 */
3280function shouldUseChangeEvent(elem) {
3281 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3282 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3283}
3284
3285function manualDispatchChangeEvent(nativeEvent) {
3286 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3287
3288 // If change and propertychange bubbled, we'd just bind to it like all the
3289 // other events and have it go through ReactBrowserEventEmitter. Since it
3290 // doesn't, we manually listen for the events and so we have to enqueue and
3291 // process the abstract event manually.
3292 //
3293 // Batching is necessary here in order to ensure that all event handlers run
3294 // before the next rerender (including event handlers attached to ancestor
3295 // elements instead of directly on the input). Without this, controlled
3296 // components don't work properly in conjunction with event bubbling because
3297 // the component is rerendered and the value reverted before all the event
3298 // handlers can run. See https://github.com/facebook/react/issues/708.
3299 batchedUpdates(runEventInBatch, event);
3300}
3301
3302function runEventInBatch(event) {
3303 runEventsInBatch(event, false);
3304}
3305
3306function getInstIfValueChanged(targetInst) {
3307 var targetNode = getNodeFromInstance$1(targetInst);
3308 if (updateValueIfChanged(targetNode)) {
3309 return targetInst;
3310 }
3311}
3312
3313function getTargetInstForChangeEvent(topLevelType, targetInst) {
3314 if (topLevelType === 'topChange') {
3315 return targetInst;
3316 }
3317}
3318
3319/**
3320 * SECTION: handle `input` event
3321 */
3322var isInputEventSupported = false;
3323if (ExecutionEnvironment_1.canUseDOM) {
3324 // IE9 claims to support the input event but fails to trigger it when
3325 // deleting text, so we ignore its input events.
3326 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3327}
3328
3329/**
3330 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3331 * and override the value property so that we can distinguish user events from
3332 * value changes in JS.
3333 */
3334function startWatchingForValueChange(target, targetInst) {
3335 activeElement = target;
3336 activeElementInst = targetInst;
3337 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3338}
3339
3340/**
3341 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3342 * if any exists.
3343 */
3344function stopWatchingForValueChange() {
3345 if (!activeElement) {
3346 return;
3347 }
3348 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3349 activeElement = null;
3350 activeElementInst = null;
3351}
3352
3353/**
3354 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3355 * the value of the active element has changed.
3356 */
3357function handlePropertyChange(nativeEvent) {
3358 if (nativeEvent.propertyName !== 'value') {
3359 return;
3360 }
3361 if (getInstIfValueChanged(activeElementInst)) {
3362 manualDispatchChangeEvent(nativeEvent);
3363 }
3364}
3365
3366function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3367 if (topLevelType === 'topFocus') {
3368 // In IE9, propertychange fires for most input events but is buggy and
3369 // doesn't fire when text is deleted, but conveniently, selectionchange
3370 // appears to fire in all of the remaining cases so we catch those and
3371 // forward the event if the value has changed
3372 // In either case, we don't want to call the event handler if the value
3373 // is changed from JS so we redefine a setter for `.value` that updates
3374 // our activeElementValue variable, allowing us to ignore those changes
3375 //
3376 // stopWatching() should be a noop here but we call it just in case we
3377 // missed a blur event somehow.
3378 stopWatchingForValueChange();
3379 startWatchingForValueChange(target, targetInst);
3380 } else if (topLevelType === 'topBlur') {
3381 stopWatchingForValueChange();
3382 }
3383}
3384
3385// For IE8 and IE9.
3386function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3387 if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') {
3388 // On the selectionchange event, the target is just document which isn't
3389 // helpful for us so just check activeElement instead.
3390 //
3391 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3392 // propertychange on the first input event after setting `value` from a
3393 // script and fires only keydown, keypress, keyup. Catching keyup usually
3394 // gets it and catching keydown lets us fire an event for the first
3395 // keystroke if user does a key repeat (it'll be a little delayed: right
3396 // before the second keystroke). Other input methods (e.g., paste) seem to
3397 // fire selectionchange normally.
3398 return getInstIfValueChanged(activeElementInst);
3399 }
3400}
3401
3402/**
3403 * SECTION: handle `click` event
3404 */
3405function shouldUseClickEvent(elem) {
3406 // Use the `click` event to detect changes to checkbox and radio inputs.
3407 // This approach works across all browsers, whereas `change` does not fire
3408 // until `blur` in IE8.
3409 var nodeName = elem.nodeName;
3410 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3411}
3412
3413function getTargetInstForClickEvent(topLevelType, targetInst) {
3414 if (topLevelType === 'topClick') {
3415 return getInstIfValueChanged(targetInst);
3416 }
3417}
3418
3419function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3420 if (topLevelType === 'topInput' || topLevelType === 'topChange') {
3421 return getInstIfValueChanged(targetInst);
3422 }
3423}
3424
3425function handleControlledInputBlur(inst, node) {
3426 // TODO: In IE, inst is occasionally null. Why?
3427 if (inst == null) {
3428 return;
3429 }
3430
3431 // Fiber and ReactDOM keep wrapper state in separate places
3432 var state = inst._wrapperState || node._wrapperState;
3433
3434 if (!state || !state.controlled || node.type !== 'number') {
3435 return;
3436 }
3437
3438 // If controlled, assign the value attribute to the current value on blur
3439 setDefaultValue(node, 'number', node.value);
3440}
3441
3442/**
3443 * This plugin creates an `onChange` event that normalizes change events
3444 * across form elements. This event fires at a time when it's possible to
3445 * change the element's value without seeing a flicker.
3446 *
3447 * Supported elements are:
3448 * - input (see `isTextInputElement`)
3449 * - textarea
3450 * - select
3451 */
3452var ChangeEventPlugin = {
3453 eventTypes: eventTypes$1,
3454
3455 _isInputEventSupported: isInputEventSupported,
3456
3457 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3458 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3459
3460 var getTargetInstFunc = void 0,
3461 handleEventFunc = void 0;
3462 if (shouldUseChangeEvent(targetNode)) {
3463 getTargetInstFunc = getTargetInstForChangeEvent;
3464 } else if (isTextInputElement(targetNode)) {
3465 if (isInputEventSupported) {
3466 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3467 } else {
3468 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3469 handleEventFunc = handleEventsForInputEventPolyfill;
3470 }
3471 } else if (shouldUseClickEvent(targetNode)) {
3472 getTargetInstFunc = getTargetInstForClickEvent;
3473 }
3474
3475 if (getTargetInstFunc) {
3476 var inst = getTargetInstFunc(topLevelType, targetInst);
3477 if (inst) {
3478 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3479 return event;
3480 }
3481 }
3482
3483 if (handleEventFunc) {
3484 handleEventFunc(topLevelType, targetNode, targetInst);
3485 }
3486
3487 // When blurring, set the value attribute for number inputs
3488 if (topLevelType === 'topBlur') {
3489 handleControlledInputBlur(targetInst, targetNode);
3490 }
3491 }
3492};
3493
3494/**
3495 * Module that is injectable into `EventPluginHub`, that specifies a
3496 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3497 * plugins, without having to package every one of them. This is better than
3498 * having plugins be ordered in the same order that they are injected because
3499 * that ordering would be influenced by the packaging order.
3500 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3501 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3502 */
3503var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3504
3505var SyntheticUIEvent = SyntheticEvent$1.extend({
3506 view: null,
3507 detail: null
3508});
3509
3510/**
3511 * Translation from modifier key to the associated property in the event.
3512 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3513 */
3514
3515var modifierKeyToProp = {
3516 Alt: 'altKey',
3517 Control: 'ctrlKey',
3518 Meta: 'metaKey',
3519 Shift: 'shiftKey'
3520};
3521
3522// IE8 does not implement getModifierState so we simply map it to the only
3523// modifier keys exposed by the event itself, does not support Lock-keys.
3524// Currently, all major browsers except Chrome seems to support Lock-keys.
3525function modifierStateGetter(keyArg) {
3526 var syntheticEvent = this;
3527 var nativeEvent = syntheticEvent.nativeEvent;
3528 if (nativeEvent.getModifierState) {
3529 return nativeEvent.getModifierState(keyArg);
3530 }
3531 var keyProp = modifierKeyToProp[keyArg];
3532 return keyProp ? !!nativeEvent[keyProp] : false;
3533}
3534
3535function getEventModifierState(nativeEvent) {
3536 return modifierStateGetter;
3537}
3538
3539/**
3540 * @interface MouseEvent
3541 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3542 */
3543var SyntheticMouseEvent = SyntheticUIEvent.extend({
3544 screenX: null,
3545 screenY: null,
3546 clientX: null,
3547 clientY: null,
3548 pageX: null,
3549 pageY: null,
3550 ctrlKey: null,
3551 shiftKey: null,
3552 altKey: null,
3553 metaKey: null,
3554 getModifierState: getEventModifierState,
3555 button: null,
3556 buttons: null,
3557 relatedTarget: function (event) {
3558 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3559 }
3560});
3561
3562var eventTypes$2 = {
3563 mouseEnter: {
3564 registrationName: 'onMouseEnter',
3565 dependencies: ['topMouseOut', 'topMouseOver']
3566 },
3567 mouseLeave: {
3568 registrationName: 'onMouseLeave',
3569 dependencies: ['topMouseOut', 'topMouseOver']
3570 }
3571};
3572
3573var EnterLeaveEventPlugin = {
3574 eventTypes: eventTypes$2,
3575
3576 /**
3577 * For almost every interaction we care about, there will be both a top-level
3578 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3579 * we do not extract duplicate events. However, moving the mouse into the
3580 * browser from outside will not fire a `mouseout` event. In this case, we use
3581 * the `mouseover` top-level event.
3582 */
3583 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3584 if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3585 return null;
3586 }
3587 if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') {
3588 // Must not be a mouse in or mouse out - ignoring.
3589 return null;
3590 }
3591
3592 var win = void 0;
3593 if (nativeEventTarget.window === nativeEventTarget) {
3594 // `nativeEventTarget` is probably a window object.
3595 win = nativeEventTarget;
3596 } else {
3597 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3598 var doc = nativeEventTarget.ownerDocument;
3599 if (doc) {
3600 win = doc.defaultView || doc.parentWindow;
3601 } else {
3602 win = window;
3603 }
3604 }
3605
3606 var from = void 0;
3607 var to = void 0;
3608 if (topLevelType === 'topMouseOut') {
3609 from = targetInst;
3610 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
3611 to = related ? getClosestInstanceFromNode(related) : null;
3612 } else {
3613 // Moving to a node from outside the window.
3614 from = null;
3615 to = targetInst;
3616 }
3617
3618 if (from === to) {
3619 // Nothing pertains to our managed components.
3620 return null;
3621 }
3622
3623 var fromNode = from == null ? win : getNodeFromInstance$1(from);
3624 var toNode = to == null ? win : getNodeFromInstance$1(to);
3625
3626 var leave = SyntheticMouseEvent.getPooled(eventTypes$2.mouseLeave, from, nativeEvent, nativeEventTarget);
3627 leave.type = 'mouseleave';
3628 leave.target = fromNode;
3629 leave.relatedTarget = toNode;
3630
3631 var enter = SyntheticMouseEvent.getPooled(eventTypes$2.mouseEnter, to, nativeEvent, nativeEventTarget);
3632 enter.type = 'mouseenter';
3633 enter.target = toNode;
3634 enter.relatedTarget = fromNode;
3635
3636 accumulateEnterLeaveDispatches(leave, enter, from, to);
3637
3638 return [leave, enter];
3639 }
3640};
3641
3642/**
3643 * Copyright (c) 2013-present, Facebook, Inc.
3644 *
3645 * This source code is licensed under the MIT license found in the
3646 * LICENSE file in the root directory of this source tree.
3647 *
3648 * @typechecks
3649 */
3650
3651/* eslint-disable fb-www/typeof-undefined */
3652
3653/**
3654 * Same as document.activeElement but wraps in a try-catch block. In IE it is
3655 * not safe to call document.activeElement if there is nothing focused.
3656 *
3657 * The activeElement will be null only if the document or document body is not
3658 * yet defined.
3659 *
3660 * @param {?DOMDocument} doc Defaults to current document.
3661 * @return {?DOMElement}
3662 */
3663function getActiveElement(doc) /*?DOMElement*/{
3664 doc = doc || (typeof document !== 'undefined' ? document : undefined);
3665 if (typeof doc === 'undefined') {
3666 return null;
3667 }
3668 try {
3669 return doc.activeElement || doc.body;
3670 } catch (e) {
3671 return doc.body;
3672 }
3673}
3674
3675var getActiveElement_1 = getActiveElement;
3676
3677/**
3678 * Copyright (c) 2013-present, Facebook, Inc.
3679 *
3680 * This source code is licensed under the MIT license found in the
3681 * LICENSE file in the root directory of this source tree.
3682 *
3683 * @typechecks
3684 *
3685 */
3686
3687/*eslint-disable no-self-compare */
3688
3689
3690
3691var hasOwnProperty = Object.prototype.hasOwnProperty;
3692
3693/**
3694 * inlined Object.is polyfill to avoid requiring consumers ship their own
3695 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3696 */
3697function is(x, y) {
3698 // SameValue algorithm
3699 if (x === y) {
3700 // Steps 1-5, 7-10
3701 // Steps 6.b-6.e: +0 != -0
3702 // Added the nonzero y check to make Flow happy, but it is redundant
3703 return x !== 0 || y !== 0 || 1 / x === 1 / y;
3704 } else {
3705 // Step 6.a: NaN == NaN
3706 return x !== x && y !== y;
3707 }
3708}
3709
3710/**
3711 * Performs equality by iterating through keys on an object and returning false
3712 * when any key has values which are not strictly equal between the arguments.
3713 * Returns true when the values of all keys are strictly equal.
3714 */
3715function shallowEqual(objA, objB) {
3716 if (is(objA, objB)) {
3717 return true;
3718 }
3719
3720 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3721 return false;
3722 }
3723
3724 var keysA = Object.keys(objA);
3725 var keysB = Object.keys(objB);
3726
3727 if (keysA.length !== keysB.length) {
3728 return false;
3729 }
3730
3731 // Test for A's keys different from B.
3732 for (var i = 0; i < keysA.length; i++) {
3733 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3734 return false;
3735 }
3736 }
3737
3738 return true;
3739}
3740
3741var shallowEqual_1 = shallowEqual;
3742
3743/**
3744 * `ReactInstanceMap` maintains a mapping from a public facing stateful
3745 * instance (key) and the internal representation (value). This allows public
3746 * methods to accept the user facing instance as an argument and map them back
3747 * to internal methods.
3748 *
3749 * Note that this module is currently shared and assumed to be stateless.
3750 * If this becomes an actual Map, that will break.
3751 */
3752
3753/**
3754 * This API should be called `delete` but we'd have to make sure to always
3755 * transform these to strings for IE support. When this transform is fully
3756 * supported we can rename it.
3757 */
3758
3759
3760function get(key) {
3761 return key._reactInternalFiber;
3762}
3763
3764function has(key) {
3765 return key._reactInternalFiber !== undefined;
3766}
3767
3768function set(key, value) {
3769 key._reactInternalFiber = value;
3770}
3771
3772// Don't change these two values. They're used by React Dev Tools.
3773var NoEffect = /* */0;
3774var PerformedWork = /* */1;
3775
3776// You can change the rest (and add more).
3777var Placement = /* */2;
3778var Update = /* */4;
3779var PlacementAndUpdate = /* */6;
3780var Deletion = /* */8;
3781var ContentReset = /* */16;
3782var Callback = /* */32;
3783var DidCapture = /* */64;
3784var Ref = /* */128;
3785var ErrLog = /* */256;
3786
3787// Union of all host effects
3788var HostEffectMask = /* */511;
3789
3790var Incomplete = /* */512;
3791var ShouldCapture = /* */1024;
3792
3793var MOUNTING = 1;
3794var MOUNTED = 2;
3795var UNMOUNTED = 3;
3796
3797function isFiberMountedImpl(fiber) {
3798 var node = fiber;
3799 if (!fiber.alternate) {
3800 // If there is no alternate, this might be a new tree that isn't inserted
3801 // yet. If it is, then it will have a pending insertion effect on it.
3802 if ((node.effectTag & Placement) !== NoEffect) {
3803 return MOUNTING;
3804 }
3805 while (node['return']) {
3806 node = node['return'];
3807 if ((node.effectTag & Placement) !== NoEffect) {
3808 return MOUNTING;
3809 }
3810 }
3811 } else {
3812 while (node['return']) {
3813 node = node['return'];
3814 }
3815 }
3816 if (node.tag === HostRoot) {
3817 // TODO: Check if this was a nested HostRoot when used with
3818 // renderContainerIntoSubtree.
3819 return MOUNTED;
3820 }
3821 // If we didn't hit the root, that means that we're in an disconnected tree
3822 // that has been unmounted.
3823 return UNMOUNTED;
3824}
3825
3826function isFiberMounted(fiber) {
3827 return isFiberMountedImpl(fiber) === MOUNTED;
3828}
3829
3830function isMounted(component) {
3831 {
3832 var owner = ReactCurrentOwner.current;
3833 if (owner !== null && owner.tag === ClassComponent) {
3834 var ownerFiber = owner;
3835 var instance = ownerFiber.stateNode;
3836 warning_1(instance._warnedAboutRefsInRender, '%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) || 'A component');
3837 instance._warnedAboutRefsInRender = true;
3838 }
3839 }
3840
3841 var fiber = get(component);
3842 if (!fiber) {
3843 return false;
3844 }
3845 return isFiberMountedImpl(fiber) === MOUNTED;
3846}
3847
3848function assertIsMounted(fiber) {
3849 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3850}
3851
3852function findCurrentFiberUsingSlowPath(fiber) {
3853 var alternate = fiber.alternate;
3854 if (!alternate) {
3855 // If there is no alternate, then we only need to check if it is mounted.
3856 var state = isFiberMountedImpl(fiber);
3857 !(state !== UNMOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3858 if (state === MOUNTING) {
3859 return null;
3860 }
3861 return fiber;
3862 }
3863 // If we have two possible branches, we'll walk backwards up to the root
3864 // to see what path the root points to. On the way we may hit one of the
3865 // special cases and we'll deal with them.
3866 var a = fiber;
3867 var b = alternate;
3868 while (true) {
3869 var parentA = a['return'];
3870 var parentB = parentA ? parentA.alternate : null;
3871 if (!parentA || !parentB) {
3872 // We're at the root.
3873 break;
3874 }
3875
3876 // If both copies of the parent fiber point to the same child, we can
3877 // assume that the child is current. This happens when we bailout on low
3878 // priority: the bailed out fiber's child reuses the current child.
3879 if (parentA.child === parentB.child) {
3880 var child = parentA.child;
3881 while (child) {
3882 if (child === a) {
3883 // We've determined that A is the current branch.
3884 assertIsMounted(parentA);
3885 return fiber;
3886 }
3887 if (child === b) {
3888 // We've determined that B is the current branch.
3889 assertIsMounted(parentA);
3890 return alternate;
3891 }
3892 child = child.sibling;
3893 }
3894 // We should never have an alternate for any mounting node. So the only
3895 // way this could possibly happen is if this was unmounted, if at all.
3896 invariant_1(false, 'Unable to find node on an unmounted component.');
3897 }
3898
3899 if (a['return'] !== b['return']) {
3900 // The return pointer of A and the return pointer of B point to different
3901 // fibers. We assume that return pointers never criss-cross, so A must
3902 // belong to the child set of A.return, and B must belong to the child
3903 // set of B.return.
3904 a = parentA;
3905 b = parentB;
3906 } else {
3907 // The return pointers point to the same fiber. We'll have to use the
3908 // default, slow path: scan the child sets of each parent alternate to see
3909 // which child belongs to which set.
3910 //
3911 // Search parent A's child set
3912 var didFindChild = false;
3913 var _child = parentA.child;
3914 while (_child) {
3915 if (_child === a) {
3916 didFindChild = true;
3917 a = parentA;
3918 b = parentB;
3919 break;
3920 }
3921 if (_child === b) {
3922 didFindChild = true;
3923 b = parentA;
3924 a = parentB;
3925 break;
3926 }
3927 _child = _child.sibling;
3928 }
3929 if (!didFindChild) {
3930 // Search parent B's child set
3931 _child = parentB.child;
3932 while (_child) {
3933 if (_child === a) {
3934 didFindChild = true;
3935 a = parentB;
3936 b = parentA;
3937 break;
3938 }
3939 if (_child === b) {
3940 didFindChild = true;
3941 b = parentB;
3942 a = parentA;
3943 break;
3944 }
3945 _child = _child.sibling;
3946 }
3947 !didFindChild ? invariant_1(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
3948 }
3949 }
3950
3951 !(a.alternate === b) ? invariant_1(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
3952 }
3953 // If the root is not a host container, we're in a disconnected tree. I.e.
3954 // unmounted.
3955 !(a.tag === HostRoot) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3956 if (a.stateNode.current === a) {
3957 // We've determined that A is the current branch.
3958 return fiber;
3959 }
3960 // Otherwise B has to be current branch.
3961 return alternate;
3962}
3963
3964function findCurrentHostFiber(parent) {
3965 var currentParent = findCurrentFiberUsingSlowPath(parent);
3966 if (!currentParent) {
3967 return null;
3968 }
3969
3970 // Next we'll drill down this component to find the first HostComponent/Text.
3971 var node = currentParent;
3972 while (true) {
3973 if (node.tag === HostComponent || node.tag === HostText) {
3974 return node;
3975 } else if (node.child) {
3976 node.child['return'] = node;
3977 node = node.child;
3978 continue;
3979 }
3980 if (node === currentParent) {
3981 return null;
3982 }
3983 while (!node.sibling) {
3984 if (!node['return'] || node['return'] === currentParent) {
3985 return null;
3986 }
3987 node = node['return'];
3988 }
3989 node.sibling['return'] = node['return'];
3990 node = node.sibling;
3991 }
3992 // Flow needs the return null here, but ESLint complains about it.
3993 // eslint-disable-next-line no-unreachable
3994 return null;
3995}
3996
3997function findCurrentHostFiberWithNoPortals(parent) {
3998 var currentParent = findCurrentFiberUsingSlowPath(parent);
3999 if (!currentParent) {
4000 return null;
4001 }
4002
4003 // Next we'll drill down this component to find the first HostComponent/Text.
4004 var node = currentParent;
4005 while (true) {
4006 if (node.tag === HostComponent || node.tag === HostText) {
4007 return node;
4008 } else if (node.child && node.tag !== HostPortal) {
4009 node.child['return'] = node;
4010 node = node.child;
4011 continue;
4012 }
4013 if (node === currentParent) {
4014 return null;
4015 }
4016 while (!node.sibling) {
4017 if (!node['return'] || node['return'] === currentParent) {
4018 return null;
4019 }
4020 node = node['return'];
4021 }
4022 node.sibling['return'] = node['return'];
4023 node = node.sibling;
4024 }
4025 // Flow needs the return null here, but ESLint complains about it.
4026 // eslint-disable-next-line no-unreachable
4027 return null;
4028}
4029
4030function addEventBubbleListener(element, eventType, listener) {
4031 element.addEventListener(eventType, listener, false);
4032}
4033
4034function addEventCaptureListener(element, eventType, listener) {
4035 element.addEventListener(eventType, listener, true);
4036}
4037
4038/**
4039 * @interface Event
4040 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4041 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4042 */
4043var SyntheticAnimationEvent = SyntheticEvent$1.extend({
4044 animationName: null,
4045 elapsedTime: null,
4046 pseudoElement: null
4047});
4048
4049/**
4050 * @interface Event
4051 * @see http://www.w3.org/TR/clipboard-apis/
4052 */
4053var SyntheticClipboardEvent = SyntheticEvent$1.extend({
4054 clipboardData: function (event) {
4055 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4056 }
4057});
4058
4059/**
4060 * @interface FocusEvent
4061 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4062 */
4063var SyntheticFocusEvent = SyntheticUIEvent.extend({
4064 relatedTarget: null
4065});
4066
4067/**
4068 * `charCode` represents the actual "character code" and is safe to use with
4069 * `String.fromCharCode`. As such, only keys that correspond to printable
4070 * characters produce a valid `charCode`, the only exception to this is Enter.
4071 * The Tab-key is considered non-printable and does not have a `charCode`,
4072 * presumably because it does not produce a tab-character in browsers.
4073 *
4074 * @param {object} nativeEvent Native browser event.
4075 * @return {number} Normalized `charCode` property.
4076 */
4077function getEventCharCode(nativeEvent) {
4078 var charCode = void 0;
4079 var keyCode = nativeEvent.keyCode;
4080
4081 if ('charCode' in nativeEvent) {
4082 charCode = nativeEvent.charCode;
4083
4084 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4085 if (charCode === 0 && keyCode === 13) {
4086 charCode = 13;
4087 }
4088 } else {
4089 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4090 charCode = keyCode;
4091 }
4092
4093 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4094 // report Enter as charCode 10 when ctrl is pressed.
4095 if (charCode === 10) {
4096 charCode = 13;
4097 }
4098
4099 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4100 // Must not discard the (non-)printable Enter-key.
4101 if (charCode >= 32 || charCode === 13) {
4102 return charCode;
4103 }
4104
4105 return 0;
4106}
4107
4108/**
4109 * Normalization of deprecated HTML5 `key` values
4110 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4111 */
4112var normalizeKey = {
4113 Esc: 'Escape',
4114 Spacebar: ' ',
4115 Left: 'ArrowLeft',
4116 Up: 'ArrowUp',
4117 Right: 'ArrowRight',
4118 Down: 'ArrowDown',
4119 Del: 'Delete',
4120 Win: 'OS',
4121 Menu: 'ContextMenu',
4122 Apps: 'ContextMenu',
4123 Scroll: 'ScrollLock',
4124 MozPrintableKey: 'Unidentified'
4125};
4126
4127/**
4128 * Translation from legacy `keyCode` to HTML5 `key`
4129 * Only special keys supported, all others depend on keyboard layout or browser
4130 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4131 */
4132var translateToKey = {
4133 '8': 'Backspace',
4134 '9': 'Tab',
4135 '12': 'Clear',
4136 '13': 'Enter',
4137 '16': 'Shift',
4138 '17': 'Control',
4139 '18': 'Alt',
4140 '19': 'Pause',
4141 '20': 'CapsLock',
4142 '27': 'Escape',
4143 '32': ' ',
4144 '33': 'PageUp',
4145 '34': 'PageDown',
4146 '35': 'End',
4147 '36': 'Home',
4148 '37': 'ArrowLeft',
4149 '38': 'ArrowUp',
4150 '39': 'ArrowRight',
4151 '40': 'ArrowDown',
4152 '45': 'Insert',
4153 '46': 'Delete',
4154 '112': 'F1',
4155 '113': 'F2',
4156 '114': 'F3',
4157 '115': 'F4',
4158 '116': 'F5',
4159 '117': 'F6',
4160 '118': 'F7',
4161 '119': 'F8',
4162 '120': 'F9',
4163 '121': 'F10',
4164 '122': 'F11',
4165 '123': 'F12',
4166 '144': 'NumLock',
4167 '145': 'ScrollLock',
4168 '224': 'Meta'
4169};
4170
4171/**
4172 * @param {object} nativeEvent Native browser event.
4173 * @return {string} Normalized `key` property.
4174 */
4175function getEventKey(nativeEvent) {
4176 if (nativeEvent.key) {
4177 // Normalize inconsistent values reported by browsers due to
4178 // implementations of a working draft specification.
4179
4180 // FireFox implements `key` but returns `MozPrintableKey` for all
4181 // printable characters (normalized to `Unidentified`), ignore it.
4182 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4183 if (key !== 'Unidentified') {
4184 return key;
4185 }
4186 }
4187
4188 // Browser does not implement `key`, polyfill as much of it as we can.
4189 if (nativeEvent.type === 'keypress') {
4190 var charCode = getEventCharCode(nativeEvent);
4191
4192 // The enter-key is technically both printable and non-printable and can
4193 // thus be captured by `keypress`, no other non-printable key should.
4194 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4195 }
4196 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4197 // While user keyboard layout determines the actual meaning of each
4198 // `keyCode` value, almost all function keys have a universal value.
4199 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4200 }
4201 return '';
4202}
4203
4204/**
4205 * @interface KeyboardEvent
4206 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4207 */
4208var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4209 key: getEventKey,
4210 location: null,
4211 ctrlKey: null,
4212 shiftKey: null,
4213 altKey: null,
4214 metaKey: null,
4215 repeat: null,
4216 locale: null,
4217 getModifierState: getEventModifierState,
4218 // Legacy Interface
4219 charCode: function (event) {
4220 // `charCode` is the result of a KeyPress event and represents the value of
4221 // the actual printable character.
4222
4223 // KeyPress is deprecated, but its replacement is not yet final and not
4224 // implemented in any major browser. Only KeyPress has charCode.
4225 if (event.type === 'keypress') {
4226 return getEventCharCode(event);
4227 }
4228 return 0;
4229 },
4230 keyCode: function (event) {
4231 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4232 // physical keyboard key.
4233
4234 // The actual meaning of the value depends on the users' keyboard layout
4235 // which cannot be detected. Assuming that it is a US keyboard layout
4236 // provides a surprisingly accurate mapping for US and European users.
4237 // Due to this, it is left to the user to implement at this time.
4238 if (event.type === 'keydown' || event.type === 'keyup') {
4239 return event.keyCode;
4240 }
4241 return 0;
4242 },
4243 which: function (event) {
4244 // `which` is an alias for either `keyCode` or `charCode` depending on the
4245 // type of the event.
4246 if (event.type === 'keypress') {
4247 return getEventCharCode(event);
4248 }
4249 if (event.type === 'keydown' || event.type === 'keyup') {
4250 return event.keyCode;
4251 }
4252 return 0;
4253 }
4254});
4255
4256/**
4257 * @interface DragEvent
4258 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4259 */
4260var SyntheticDragEvent = SyntheticMouseEvent.extend({
4261 dataTransfer: null
4262});
4263
4264/**
4265 * @interface TouchEvent
4266 * @see http://www.w3.org/TR/touch-events/
4267 */
4268var SyntheticTouchEvent = SyntheticUIEvent.extend({
4269 touches: null,
4270 targetTouches: null,
4271 changedTouches: null,
4272 altKey: null,
4273 metaKey: null,
4274 ctrlKey: null,
4275 shiftKey: null,
4276 getModifierState: getEventModifierState
4277});
4278
4279/**
4280 * @interface Event
4281 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4282 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4283 */
4284var SyntheticTransitionEvent = SyntheticEvent$1.extend({
4285 propertyName: null,
4286 elapsedTime: null,
4287 pseudoElement: null
4288});
4289
4290/**
4291 * @interface WheelEvent
4292 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4293 */
4294var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4295 deltaX: function (event) {
4296 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4297 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4298 },
4299 deltaY: function (event) {
4300 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4301 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4302 'wheelDelta' in event ? -event.wheelDelta : 0;
4303 },
4304
4305 deltaZ: null,
4306
4307 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4308 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4309 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4310 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4311 deltaMode: null
4312});
4313
4314/**
4315 * Turns
4316 * ['abort', ...]
4317 * into
4318 * eventTypes = {
4319 * 'abort': {
4320 * phasedRegistrationNames: {
4321 * bubbled: 'onAbort',
4322 * captured: 'onAbortCapture',
4323 * },
4324 * dependencies: ['topAbort'],
4325 * },
4326 * ...
4327 * };
4328 * topLevelEventsToDispatchConfig = {
4329 * 'topAbort': { sameConfig }
4330 * };
4331 */
4332var interactiveEventTypeNames = ['blur', 'cancel', 'click', 'close', 'contextMenu', 'copy', 'cut', 'doubleClick', 'dragEnd', 'dragStart', 'drop', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'mouseDown', 'mouseUp', 'paste', 'pause', 'play', 'rateChange', 'reset', 'seeked', 'submit', 'touchCancel', 'touchEnd', 'touchStart', 'volumeChange'];
4333var nonInteractiveEventTypeNames = ['abort', 'animationEnd', 'animationIteration', 'animationStart', 'canPlay', 'canPlayThrough', 'drag', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseMove', 'mouseOut', 'mouseOver', 'playing', 'progress', 'scroll', 'seeking', 'stalled', 'suspend', 'timeUpdate', 'toggle', 'touchMove', 'transitionEnd', 'waiting', 'wheel'];
4334
4335var eventTypes$4 = {};
4336var topLevelEventsToDispatchConfig = {};
4337
4338function addEventTypeNameToConfig(event, isInteractive) {
4339 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4340 var onEvent = 'on' + capitalizedEvent;
4341 var topEvent = 'top' + capitalizedEvent;
4342
4343 var type = {
4344 phasedRegistrationNames: {
4345 bubbled: onEvent,
4346 captured: onEvent + 'Capture'
4347 },
4348 dependencies: [topEvent],
4349 isInteractive: isInteractive
4350 };
4351 eventTypes$4[event] = type;
4352 topLevelEventsToDispatchConfig[topEvent] = type;
4353}
4354
4355interactiveEventTypeNames.forEach(function (eventTypeName) {
4356 addEventTypeNameToConfig(eventTypeName, true);
4357});
4358nonInteractiveEventTypeNames.forEach(function (eventTypeName) {
4359 addEventTypeNameToConfig(eventTypeName, false);
4360});
4361
4362// Only used in DEV for exhaustiveness validation.
4363var knownHTMLTopLevelTypes = ['topAbort', 'topCancel', 'topCanPlay', 'topCanPlayThrough', 'topClose', 'topDurationChange', 'topEmptied', 'topEncrypted', 'topEnded', 'topError', 'topInput', 'topInvalid', 'topLoad', 'topLoadedData', 'topLoadedMetadata', 'topLoadStart', 'topPause', 'topPlay', 'topPlaying', 'topProgress', 'topRateChange', 'topReset', 'topSeeked', 'topSeeking', 'topStalled', 'topSubmit', 'topSuspend', 'topTimeUpdate', 'topToggle', 'topVolumeChange', 'topWaiting'];
4364
4365var SimpleEventPlugin = {
4366 eventTypes: eventTypes$4,
4367
4368 isInteractiveTopLevelEventType: function (topLevelType) {
4369 var config = topLevelEventsToDispatchConfig[topLevelType];
4370 return config !== undefined && config.isInteractive === true;
4371 },
4372
4373
4374 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4375 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4376 if (!dispatchConfig) {
4377 return null;
4378 }
4379 var EventConstructor = void 0;
4380 switch (topLevelType) {
4381 case 'topKeyPress':
4382 // Firefox creates a keypress event for function keys too. This removes
4383 // the unwanted keypress events. Enter is however both printable and
4384 // non-printable. One would expect Tab to be as well (but it isn't).
4385 if (getEventCharCode(nativeEvent) === 0) {
4386 return null;
4387 }
4388 /* falls through */
4389 case 'topKeyDown':
4390 case 'topKeyUp':
4391 EventConstructor = SyntheticKeyboardEvent;
4392 break;
4393 case 'topBlur':
4394 case 'topFocus':
4395 EventConstructor = SyntheticFocusEvent;
4396 break;
4397 case 'topClick':
4398 // Firefox creates a click event on right mouse clicks. This removes the
4399 // unwanted click events.
4400 if (nativeEvent.button === 2) {
4401 return null;
4402 }
4403 /* falls through */
4404 case 'topDoubleClick':
4405 case 'topMouseDown':
4406 case 'topMouseMove':
4407 case 'topMouseUp':
4408 // TODO: Disabled elements should not respond to mouse events
4409 /* falls through */
4410 case 'topMouseOut':
4411 case 'topMouseOver':
4412 case 'topContextMenu':
4413 EventConstructor = SyntheticMouseEvent;
4414 break;
4415 case 'topDrag':
4416 case 'topDragEnd':
4417 case 'topDragEnter':
4418 case 'topDragExit':
4419 case 'topDragLeave':
4420 case 'topDragOver':
4421 case 'topDragStart':
4422 case 'topDrop':
4423 EventConstructor = SyntheticDragEvent;
4424 break;
4425 case 'topTouchCancel':
4426 case 'topTouchEnd':
4427 case 'topTouchMove':
4428 case 'topTouchStart':
4429 EventConstructor = SyntheticTouchEvent;
4430 break;
4431 case 'topAnimationEnd':
4432 case 'topAnimationIteration':
4433 case 'topAnimationStart':
4434 EventConstructor = SyntheticAnimationEvent;
4435 break;
4436 case 'topTransitionEnd':
4437 EventConstructor = SyntheticTransitionEvent;
4438 break;
4439 case 'topScroll':
4440 EventConstructor = SyntheticUIEvent;
4441 break;
4442 case 'topWheel':
4443 EventConstructor = SyntheticWheelEvent;
4444 break;
4445 case 'topCopy':
4446 case 'topCut':
4447 case 'topPaste':
4448 EventConstructor = SyntheticClipboardEvent;
4449 break;
4450 default:
4451 {
4452 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4453 warning_1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4454 }
4455 }
4456 // HTML Events
4457 // @see http://www.w3.org/TR/html5/index.html#events-0
4458 EventConstructor = SyntheticEvent$1;
4459 break;
4460 }
4461 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4462 accumulateTwoPhaseDispatches(event);
4463 return event;
4464 }
4465};
4466
4467var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4468
4469
4470var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4471var callbackBookkeepingPool = [];
4472
4473/**
4474 * Find the deepest React component completely containing the root of the
4475 * passed-in instance (for use when entire React trees are nested within each
4476 * other). If React trees are not nested, returns null.
4477 */
4478function findRootContainerNode(inst) {
4479 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4480 // traversal, but caching is difficult to do correctly without using a
4481 // mutation observer to listen for all DOM changes.
4482 while (inst['return']) {
4483 inst = inst['return'];
4484 }
4485 if (inst.tag !== HostRoot) {
4486 // This can happen if we're in a detached tree.
4487 return null;
4488 }
4489 return inst.stateNode.containerInfo;
4490}
4491
4492// Used to store ancestor hierarchy in top level callback
4493function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4494 if (callbackBookkeepingPool.length) {
4495 var instance = callbackBookkeepingPool.pop();
4496 instance.topLevelType = topLevelType;
4497 instance.nativeEvent = nativeEvent;
4498 instance.targetInst = targetInst;
4499 return instance;
4500 }
4501 return {
4502 topLevelType: topLevelType,
4503 nativeEvent: nativeEvent,
4504 targetInst: targetInst,
4505 ancestors: []
4506 };
4507}
4508
4509function releaseTopLevelCallbackBookKeeping(instance) {
4510 instance.topLevelType = null;
4511 instance.nativeEvent = null;
4512 instance.targetInst = null;
4513 instance.ancestors.length = 0;
4514 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4515 callbackBookkeepingPool.push(instance);
4516 }
4517}
4518
4519function handleTopLevel(bookKeeping) {
4520 var targetInst = bookKeeping.targetInst;
4521
4522 // Loop through the hierarchy, in case there's any nested components.
4523 // It's important that we build the array of ancestors before calling any
4524 // event handlers, because event handlers can modify the DOM, leading to
4525 // inconsistencies with ReactMount's node cache. See #1105.
4526 var ancestor = targetInst;
4527 do {
4528 if (!ancestor) {
4529 bookKeeping.ancestors.push(ancestor);
4530 break;
4531 }
4532 var root = findRootContainerNode(ancestor);
4533 if (!root) {
4534 break;
4535 }
4536 bookKeeping.ancestors.push(ancestor);
4537 ancestor = getClosestInstanceFromNode(root);
4538 } while (ancestor);
4539
4540 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4541 targetInst = bookKeeping.ancestors[i];
4542 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4543 }
4544}
4545
4546// TODO: can we stop exporting these?
4547var _enabled = true;
4548
4549function setEnabled(enabled) {
4550 _enabled = !!enabled;
4551}
4552
4553function isEnabled() {
4554 return _enabled;
4555}
4556
4557/**
4558 * Traps top-level events by using event bubbling.
4559 *
4560 * @param {string} topLevelType Record from `BrowserEventConstants`.
4561 * @param {string} handlerBaseName Event name (e.g. "click").
4562 * @param {object} element Element on which to attach listener.
4563 * @return {?object} An object with a remove function which will forcefully
4564 * remove the listener.
4565 * @internal
4566 */
4567function trapBubbledEvent(topLevelType, handlerBaseName, element) {
4568 if (!element) {
4569 return null;
4570 }
4571 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4572
4573 addEventBubbleListener(element, handlerBaseName,
4574 // Check if interactive and wrap in interactiveUpdates
4575 dispatch.bind(null, topLevelType));
4576}
4577
4578/**
4579 * Traps a top-level event by using event capturing.
4580 *
4581 * @param {string} topLevelType Record from `BrowserEventConstants`.
4582 * @param {string} handlerBaseName Event name (e.g. "click").
4583 * @param {object} element Element on which to attach listener.
4584 * @return {?object} An object with a remove function which will forcefully
4585 * remove the listener.
4586 * @internal
4587 */
4588function trapCapturedEvent(topLevelType, handlerBaseName, element) {
4589 if (!element) {
4590 return null;
4591 }
4592 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4593
4594 addEventCaptureListener(element, handlerBaseName,
4595 // Check if interactive and wrap in interactiveUpdates
4596 dispatch.bind(null, topLevelType));
4597}
4598
4599function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4600 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4601}
4602
4603function dispatchEvent(topLevelType, nativeEvent) {
4604 if (!_enabled) {
4605 return;
4606 }
4607
4608 var nativeEventTarget = getEventTarget(nativeEvent);
4609 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4610 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4611 // If we get an event (ex: img onload) before committing that
4612 // component's mount, ignore it for now (that is, treat it as if it was an
4613 // event on a non-React tree). We might also consider queueing events and
4614 // dispatching them after the mount.
4615 targetInst = null;
4616 }
4617
4618 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4619
4620 try {
4621 // Event queue being processed in the same cycle allows
4622 // `preventDefault`.
4623 batchedUpdates(handleTopLevel, bookKeeping);
4624 } finally {
4625 releaseTopLevelCallbackBookKeeping(bookKeeping);
4626 }
4627}
4628
4629var ReactDOMEventListener = Object.freeze({
4630 get _enabled () { return _enabled; },
4631 setEnabled: setEnabled,
4632 isEnabled: isEnabled,
4633 trapBubbledEvent: trapBubbledEvent,
4634 trapCapturedEvent: trapCapturedEvent,
4635 dispatchEvent: dispatchEvent
4636});
4637
4638/**
4639 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4640 *
4641 * @param {string} styleProp
4642 * @param {string} eventName
4643 * @returns {object}
4644 */
4645function makePrefixMap(styleProp, eventName) {
4646 var prefixes = {};
4647
4648 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4649 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4650 prefixes['Moz' + styleProp] = 'moz' + eventName;
4651 prefixes['ms' + styleProp] = 'MS' + eventName;
4652 prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
4653
4654 return prefixes;
4655}
4656
4657/**
4658 * A list of event names to a configurable list of vendor prefixes.
4659 */
4660var vendorPrefixes = {
4661 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4662 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4663 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4664 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4665};
4666
4667/**
4668 * Event names that have already been detected and prefixed (if applicable).
4669 */
4670var prefixedEventNames = {};
4671
4672/**
4673 * Element to check for prefixes on.
4674 */
4675var style = {};
4676
4677/**
4678 * Bootstrap if a DOM exists.
4679 */
4680if (ExecutionEnvironment_1.canUseDOM) {
4681 style = document.createElement('div').style;
4682
4683 // On some platforms, in particular some releases of Android 4.x,
4684 // the un-prefixed "animation" and "transition" properties are defined on the
4685 // style object but the events that fire will still be prefixed, so we need
4686 // to check if the un-prefixed events are usable, and if not remove them from the map.
4687 if (!('AnimationEvent' in window)) {
4688 delete vendorPrefixes.animationend.animation;
4689 delete vendorPrefixes.animationiteration.animation;
4690 delete vendorPrefixes.animationstart.animation;
4691 }
4692
4693 // Same as above
4694 if (!('TransitionEvent' in window)) {
4695 delete vendorPrefixes.transitionend.transition;
4696 }
4697}
4698
4699/**
4700 * Attempts to determine the correct vendor prefixed event name.
4701 *
4702 * @param {string} eventName
4703 * @returns {string}
4704 */
4705function getVendorPrefixedEventName(eventName) {
4706 if (prefixedEventNames[eventName]) {
4707 return prefixedEventNames[eventName];
4708 } else if (!vendorPrefixes[eventName]) {
4709 return eventName;
4710 }
4711
4712 var prefixMap = vendorPrefixes[eventName];
4713
4714 for (var styleProp in prefixMap) {
4715 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
4716 return prefixedEventNames[eventName] = prefixMap[styleProp];
4717 }
4718 }
4719
4720 return eventName;
4721}
4722
4723/**
4724 * Types of raw signals from the browser caught at the top level.
4725 *
4726 * For events like 'submit' or audio/video events which don't consistently
4727 * bubble (which we trap at a lower node than `document`), binding
4728 * at `document` would cause duplicate events so we don't include them here.
4729 */
4730var topLevelTypes = {
4731 topAnimationEnd: getVendorPrefixedEventName('animationend'),
4732 topAnimationIteration: getVendorPrefixedEventName('animationiteration'),
4733 topAnimationStart: getVendorPrefixedEventName('animationstart'),
4734 topBlur: 'blur',
4735 topCancel: 'cancel',
4736 topChange: 'change',
4737 topClick: 'click',
4738 topClose: 'close',
4739 topCompositionEnd: 'compositionend',
4740 topCompositionStart: 'compositionstart',
4741 topCompositionUpdate: 'compositionupdate',
4742 topContextMenu: 'contextmenu',
4743 topCopy: 'copy',
4744 topCut: 'cut',
4745 topDoubleClick: 'dblclick',
4746 topDrag: 'drag',
4747 topDragEnd: 'dragend',
4748 topDragEnter: 'dragenter',
4749 topDragExit: 'dragexit',
4750 topDragLeave: 'dragleave',
4751 topDragOver: 'dragover',
4752 topDragStart: 'dragstart',
4753 topDrop: 'drop',
4754 topFocus: 'focus',
4755 topInput: 'input',
4756 topKeyDown: 'keydown',
4757 topKeyPress: 'keypress',
4758 topKeyUp: 'keyup',
4759 topLoad: 'load',
4760 topLoadStart: 'loadstart',
4761 topMouseDown: 'mousedown',
4762 topMouseMove: 'mousemove',
4763 topMouseOut: 'mouseout',
4764 topMouseOver: 'mouseover',
4765 topMouseUp: 'mouseup',
4766 topPaste: 'paste',
4767 topScroll: 'scroll',
4768 topSelectionChange: 'selectionchange',
4769 topTextInput: 'textInput',
4770 topToggle: 'toggle',
4771 topTouchCancel: 'touchcancel',
4772 topTouchEnd: 'touchend',
4773 topTouchMove: 'touchmove',
4774 topTouchStart: 'touchstart',
4775 topTransitionEnd: getVendorPrefixedEventName('transitionend'),
4776 topWheel: 'wheel'
4777};
4778
4779// There are so many media events, it makes sense to just
4780// maintain a list of them. Note these aren't technically
4781// "top-level" since they don't bubble. We should come up
4782// with a better naming convention if we come to refactoring
4783// the event system.
4784var mediaEventTypes = {
4785 topAbort: 'abort',
4786 topCanPlay: 'canplay',
4787 topCanPlayThrough: 'canplaythrough',
4788 topDurationChange: 'durationchange',
4789 topEmptied: 'emptied',
4790 topEncrypted: 'encrypted',
4791 topEnded: 'ended',
4792 topError: 'error',
4793 topLoadedData: 'loadeddata',
4794 topLoadedMetadata: 'loadedmetadata',
4795 topLoadStart: 'loadstart',
4796 topPause: 'pause',
4797 topPlay: 'play',
4798 topPlaying: 'playing',
4799 topProgress: 'progress',
4800 topRateChange: 'ratechange',
4801 topSeeked: 'seeked',
4802 topSeeking: 'seeking',
4803 topStalled: 'stalled',
4804 topSuspend: 'suspend',
4805 topTimeUpdate: 'timeupdate',
4806 topVolumeChange: 'volumechange',
4807 topWaiting: 'waiting'
4808};
4809
4810/**
4811 * Summary of `ReactBrowserEventEmitter` event handling:
4812 *
4813 * - Top-level delegation is used to trap most native browser events. This
4814 * may only occur in the main thread and is the responsibility of
4815 * ReactDOMEventListener, which is injected and can therefore support
4816 * pluggable event sources. This is the only work that occurs in the main
4817 * thread.
4818 *
4819 * - We normalize and de-duplicate events to account for browser quirks. This
4820 * may be done in the worker thread.
4821 *
4822 * - Forward these native events (with the associated top-level type used to
4823 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4824 * to extract any synthetic events.
4825 *
4826 * - The `EventPluginHub` will then process each event by annotating them with
4827 * "dispatches", a sequence of listeners and IDs that care about that event.
4828 *
4829 * - The `EventPluginHub` then dispatches the events.
4830 *
4831 * Overview of React and the event system:
4832 *
4833 * +------------+ .
4834 * | DOM | .
4835 * +------------+ .
4836 * | .
4837 * v .
4838 * +------------+ .
4839 * | ReactEvent | .
4840 * | Listener | .
4841 * +------------+ . +-----------+
4842 * | . +--------+|SimpleEvent|
4843 * | . | |Plugin |
4844 * +-----|------+ . v +-----------+
4845 * | | | . +--------------+ +------------+
4846 * | +-----------.--->|EventPluginHub| | Event |
4847 * | | . | | +-----------+ | Propagators|
4848 * | ReactEvent | . | | |TapEvent | |------------|
4849 * | Emitter | . | |<---+|Plugin | |other plugin|
4850 * | | . | | +-----------+ | utilities |
4851 * | +-----------.--->| | +------------+
4852 * | | | . +--------------+
4853 * +-----|------+ . ^ +-----------+
4854 * | . | |Enter/Leave|
4855 * + . +-------+|Plugin |
4856 * +-------------+ . +-----------+
4857 * | application | .
4858 * |-------------| .
4859 * | | .
4860 * | | .
4861 * +-------------+ .
4862 * .
4863 * React Core . General Purpose Event Plugin System
4864 */
4865
4866var alreadyListeningTo = {};
4867var reactTopListenersCounter = 0;
4868
4869/**
4870 * To ensure no conflicts with other potential React instances on the page
4871 */
4872var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4873
4874function getListeningForDocument(mountAt) {
4875 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4876 // directly.
4877 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4878 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4879 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4880 }
4881 return alreadyListeningTo[mountAt[topListenersIDKey]];
4882}
4883
4884/**
4885 * We listen for bubbled touch events on the document object.
4886 *
4887 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4888 * mounting `onmousemove` events at some node that was not the document
4889 * element. The symptoms were that if your mouse is not moving over something
4890 * contained within that mount point (for example on the background) the
4891 * top-level listeners for `onmousemove` won't be called. However, if you
4892 * register the `mousemove` on the document object, then it will of course
4893 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4894 * top-level listeners to the document object only, at least for these
4895 * movement types of events and possibly all events.
4896 *
4897 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4898 *
4899 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
4900 * they bubble to document.
4901 *
4902 * @param {string} registrationName Name of listener (e.g. `onClick`).
4903 * @param {object} contentDocumentHandle Document which owns the container
4904 */
4905function listenTo(registrationName, contentDocumentHandle) {
4906 var mountAt = contentDocumentHandle;
4907 var isListening = getListeningForDocument(mountAt);
4908 var dependencies = registrationNameDependencies[registrationName];
4909
4910 for (var i = 0; i < dependencies.length; i++) {
4911 var dependency = dependencies[i];
4912 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4913 if (dependency === 'topScroll') {
4914 trapCapturedEvent('topScroll', 'scroll', mountAt);
4915 } else if (dependency === 'topFocus' || dependency === 'topBlur') {
4916 trapCapturedEvent('topFocus', 'focus', mountAt);
4917 trapCapturedEvent('topBlur', 'blur', mountAt);
4918
4919 // to make sure blur and focus event listeners are only attached once
4920 isListening.topBlur = true;
4921 isListening.topFocus = true;
4922 } else if (dependency === 'topCancel') {
4923 if (isEventSupported('cancel', true)) {
4924 trapCapturedEvent('topCancel', 'cancel', mountAt);
4925 }
4926 isListening.topCancel = true;
4927 } else if (dependency === 'topClose') {
4928 if (isEventSupported('close', true)) {
4929 trapCapturedEvent('topClose', 'close', mountAt);
4930 }
4931 isListening.topClose = true;
4932 } else if (topLevelTypes.hasOwnProperty(dependency)) {
4933 trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
4934 }
4935
4936 isListening[dependency] = true;
4937 }
4938 }
4939}
4940
4941function isListeningToAllDependencies(registrationName, mountAt) {
4942 var isListening = getListeningForDocument(mountAt);
4943 var dependencies = registrationNameDependencies[registrationName];
4944 for (var i = 0; i < dependencies.length; i++) {
4945 var dependency = dependencies[i];
4946 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4947 return false;
4948 }
4949 }
4950 return true;
4951}
4952
4953/**
4954 * Copyright (c) 2013-present, Facebook, Inc.
4955 *
4956 * This source code is licensed under the MIT license found in the
4957 * LICENSE file in the root directory of this source tree.
4958 *
4959 * @typechecks
4960 */
4961
4962/**
4963 * @param {*} object The object to check.
4964 * @return {boolean} Whether or not the object is a DOM node.
4965 */
4966function isNode(object) {
4967 var doc = object ? object.ownerDocument || object : document;
4968 var defaultView = doc.defaultView || window;
4969 return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
4970}
4971
4972var isNode_1 = isNode;
4973
4974/**
4975 * Copyright (c) 2013-present, Facebook, Inc.
4976 *
4977 * This source code is licensed under the MIT license found in the
4978 * LICENSE file in the root directory of this source tree.
4979 *
4980 * @typechecks
4981 */
4982
4983
4984
4985/**
4986 * @param {*} object The object to check.
4987 * @return {boolean} Whether or not the object is a DOM text node.
4988 */
4989function isTextNode(object) {
4990 return isNode_1(object) && object.nodeType == 3;
4991}
4992
4993var isTextNode_1 = isTextNode;
4994
4995/**
4996 * Copyright (c) 2013-present, Facebook, Inc.
4997 *
4998 * This source code is licensed under the MIT license found in the
4999 * LICENSE file in the root directory of this source tree.
5000 *
5001 *
5002 */
5003
5004
5005
5006/*eslint-disable no-bitwise */
5007
5008/**
5009 * Checks if a given DOM node contains or is another DOM node.
5010 */
5011function containsNode(outerNode, innerNode) {
5012 if (!outerNode || !innerNode) {
5013 return false;
5014 } else if (outerNode === innerNode) {
5015 return true;
5016 } else if (isTextNode_1(outerNode)) {
5017 return false;
5018 } else if (isTextNode_1(innerNode)) {
5019 return containsNode(outerNode, innerNode.parentNode);
5020 } else if ('contains' in outerNode) {
5021 return outerNode.contains(innerNode);
5022 } else if (outerNode.compareDocumentPosition) {
5023 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5024 } else {
5025 return false;
5026 }
5027}
5028
5029var containsNode_1 = containsNode;
5030
5031/**
5032 * Given any node return the first leaf node without children.
5033 *
5034 * @param {DOMElement|DOMTextNode} node
5035 * @return {DOMElement|DOMTextNode}
5036 */
5037function getLeafNode(node) {
5038 while (node && node.firstChild) {
5039 node = node.firstChild;
5040 }
5041 return node;
5042}
5043
5044/**
5045 * Get the next sibling within a container. This will walk up the
5046 * DOM if a node's siblings have been exhausted.
5047 *
5048 * @param {DOMElement|DOMTextNode} node
5049 * @return {?DOMElement|DOMTextNode}
5050 */
5051function getSiblingNode(node) {
5052 while (node) {
5053 if (node.nextSibling) {
5054 return node.nextSibling;
5055 }
5056 node = node.parentNode;
5057 }
5058}
5059
5060/**
5061 * Get object describing the nodes which contain characters at offset.
5062 *
5063 * @param {DOMElement|DOMTextNode} root
5064 * @param {number} offset
5065 * @return {?object}
5066 */
5067function getNodeForCharacterOffset(root, offset) {
5068 var node = getLeafNode(root);
5069 var nodeStart = 0;
5070 var nodeEnd = 0;
5071
5072 while (node) {
5073 if (node.nodeType === TEXT_NODE) {
5074 nodeEnd = nodeStart + node.textContent.length;
5075
5076 if (nodeStart <= offset && nodeEnd >= offset) {
5077 return {
5078 node: node,
5079 offset: offset - nodeStart
5080 };
5081 }
5082
5083 nodeStart = nodeEnd;
5084 }
5085
5086 node = getLeafNode(getSiblingNode(node));
5087 }
5088}
5089
5090/**
5091 * @param {DOMElement} outerNode
5092 * @return {?object}
5093 */
5094function getOffsets(outerNode) {
5095 var selection = window.getSelection && window.getSelection();
5096
5097 if (!selection || selection.rangeCount === 0) {
5098 return null;
5099 }
5100
5101 var anchorNode = selection.anchorNode,
5102 anchorOffset = selection.anchorOffset,
5103 focusNode = selection.focusNode,
5104 focusOffset = selection.focusOffset;
5105
5106 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5107 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5108 // expose properties, triggering a "Permission denied error" if any of its
5109 // properties are accessed. The only seemingly possible way to avoid erroring
5110 // is to access a property that typically works for non-anonymous divs and
5111 // catch any error that may otherwise arise. See
5112 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5113
5114 try {
5115 /* eslint-disable no-unused-expressions */
5116 anchorNode.nodeType;
5117 focusNode.nodeType;
5118 /* eslint-enable no-unused-expressions */
5119 } catch (e) {
5120 return null;
5121 }
5122
5123 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5124}
5125
5126/**
5127 * Returns {start, end} where `start` is the character/codepoint index of
5128 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5129 * `end` is the index of (focusNode, focusOffset).
5130 *
5131 * Returns null if you pass in garbage input but we should probably just crash.
5132 *
5133 * Exported only for testing.
5134 */
5135function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5136 var length = 0;
5137 var start = -1;
5138 var end = -1;
5139 var indexWithinAnchor = 0;
5140 var indexWithinFocus = 0;
5141 var node = outerNode;
5142 var parentNode = null;
5143
5144 outer: while (true) {
5145 var next = null;
5146
5147 while (true) {
5148 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5149 start = length + anchorOffset;
5150 }
5151 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5152 end = length + focusOffset;
5153 }
5154
5155 if (node.nodeType === TEXT_NODE) {
5156 length += node.nodeValue.length;
5157 }
5158
5159 if ((next = node.firstChild) === null) {
5160 break;
5161 }
5162 // Moving from `node` to its first child `next`.
5163 parentNode = node;
5164 node = next;
5165 }
5166
5167 while (true) {
5168 if (node === outerNode) {
5169 // If `outerNode` has children, this is always the second time visiting
5170 // it. If it has no children, this is still the first loop, and the only
5171 // valid selection is anchorNode and focusNode both equal to this node
5172 // and both offsets 0, in which case we will have handled above.
5173 break outer;
5174 }
5175 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5176 start = length;
5177 }
5178 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5179 end = length;
5180 }
5181 if ((next = node.nextSibling) !== null) {
5182 break;
5183 }
5184 node = parentNode;
5185 parentNode = node.parentNode;
5186 }
5187
5188 // Moving from `node` to its next sibling `next`.
5189 node = next;
5190 }
5191
5192 if (start === -1 || end === -1) {
5193 // This should never happen. (Would happen if the anchor/focus nodes aren't
5194 // actually inside the passed-in node.)
5195 return null;
5196 }
5197
5198 return {
5199 start: start,
5200 end: end
5201 };
5202}
5203
5204/**
5205 * In modern non-IE browsers, we can support both forward and backward
5206 * selections.
5207 *
5208 * Note: IE10+ supports the Selection object, but it does not support
5209 * the `extend` method, which means that even in modern IE, it's not possible
5210 * to programmatically create a backward selection. Thus, for all IE
5211 * versions, we use the old IE API to create our selections.
5212 *
5213 * @param {DOMElement|DOMTextNode} node
5214 * @param {object} offsets
5215 */
5216function setOffsets(node, offsets) {
5217 if (!window.getSelection) {
5218 return;
5219 }
5220
5221 var selection = window.getSelection();
5222 var length = node[getTextContentAccessor()].length;
5223 var start = Math.min(offsets.start, length);
5224 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5225
5226 // IE 11 uses modern selection, but doesn't support the extend method.
5227 // Flip backward selections, so we can set with a single range.
5228 if (!selection.extend && start > end) {
5229 var temp = end;
5230 end = start;
5231 start = temp;
5232 }
5233
5234 var startMarker = getNodeForCharacterOffset(node, start);
5235 var endMarker = getNodeForCharacterOffset(node, end);
5236
5237 if (startMarker && endMarker) {
5238 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5239 return;
5240 }
5241 var range = document.createRange();
5242 range.setStart(startMarker.node, startMarker.offset);
5243 selection.removeAllRanges();
5244
5245 if (start > end) {
5246 selection.addRange(range);
5247 selection.extend(endMarker.node, endMarker.offset);
5248 } else {
5249 range.setEnd(endMarker.node, endMarker.offset);
5250 selection.addRange(range);
5251 }
5252 }
5253}
5254
5255function isInDocument(node) {
5256 return containsNode_1(document.documentElement, node);
5257}
5258
5259/**
5260 * @ReactInputSelection: React input selection module. Based on Selection.js,
5261 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5262 * assume buttons have range selections allowed).
5263 * Input selection module for React.
5264 */
5265
5266function hasSelectionCapabilities(elem) {
5267 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5268 return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
5269}
5270
5271function getSelectionInformation() {
5272 var focusedElem = getActiveElement_1();
5273 return {
5274 focusedElem: focusedElem,
5275 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5276 };
5277}
5278
5279/**
5280 * @restoreSelection: If any selection information was potentially lost,
5281 * restore it. This is useful when performing operations that could remove dom
5282 * nodes and place them back in, resulting in focus being lost.
5283 */
5284function restoreSelection(priorSelectionInformation) {
5285 var curFocusedElem = getActiveElement_1();
5286 var priorFocusedElem = priorSelectionInformation.focusedElem;
5287 var priorSelectionRange = priorSelectionInformation.selectionRange;
5288 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5289 if (hasSelectionCapabilities(priorFocusedElem)) {
5290 setSelection(priorFocusedElem, priorSelectionRange);
5291 }
5292
5293 // Focusing a node can change the scroll position, which is undesirable
5294 var ancestors = [];
5295 var ancestor = priorFocusedElem;
5296 while (ancestor = ancestor.parentNode) {
5297 if (ancestor.nodeType === ELEMENT_NODE) {
5298 ancestors.push({
5299 element: ancestor,
5300 left: ancestor.scrollLeft,
5301 top: ancestor.scrollTop
5302 });
5303 }
5304 }
5305
5306 priorFocusedElem.focus();
5307
5308 for (var i = 0; i < ancestors.length; i++) {
5309 var info = ancestors[i];
5310 info.element.scrollLeft = info.left;
5311 info.element.scrollTop = info.top;
5312 }
5313 }
5314}
5315
5316/**
5317 * @getSelection: Gets the selection bounds of a focused textarea, input or
5318 * contentEditable node.
5319 * -@input: Look up selection bounds of this input
5320 * -@return {start: selectionStart, end: selectionEnd}
5321 */
5322function getSelection$1(input) {
5323 var selection = void 0;
5324
5325 if ('selectionStart' in input) {
5326 // Modern browser with input or textarea.
5327 selection = {
5328 start: input.selectionStart,
5329 end: input.selectionEnd
5330 };
5331 } else {
5332 // Content editable or old IE textarea.
5333 selection = getOffsets(input);
5334 }
5335
5336 return selection || { start: 0, end: 0 };
5337}
5338
5339/**
5340 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5341 * the input.
5342 * -@input Set selection bounds of this input or textarea
5343 * -@offsets Object of same form that is returned from get*
5344 */
5345function setSelection(input, offsets) {
5346 var start = offsets.start,
5347 end = offsets.end;
5348
5349 if (end === undefined) {
5350 end = start;
5351 }
5352
5353 if ('selectionStart' in input) {
5354 input.selectionStart = start;
5355 input.selectionEnd = Math.min(end, input.value.length);
5356 } else {
5357 setOffsets(input, offsets);
5358 }
5359}
5360
5361var skipSelectionChangeEvent = ExecutionEnvironment_1.canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5362
5363var eventTypes$3 = {
5364 select: {
5365 phasedRegistrationNames: {
5366 bubbled: 'onSelect',
5367 captured: 'onSelectCapture'
5368 },
5369 dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange']
5370 }
5371};
5372
5373var activeElement$1 = null;
5374var activeElementInst$1 = null;
5375var lastSelection = null;
5376var mouseDown = false;
5377
5378/**
5379 * Get an object which is a unique representation of the current selection.
5380 *
5381 * The return value will not be consistent across nodes or browsers, but
5382 * two identical selections on the same node will return identical objects.
5383 *
5384 * @param {DOMElement} node
5385 * @return {object}
5386 */
5387function getSelection(node) {
5388 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5389 return {
5390 start: node.selectionStart,
5391 end: node.selectionEnd
5392 };
5393 } else if (window.getSelection) {
5394 var selection = window.getSelection();
5395 return {
5396 anchorNode: selection.anchorNode,
5397 anchorOffset: selection.anchorOffset,
5398 focusNode: selection.focusNode,
5399 focusOffset: selection.focusOffset
5400 };
5401 }
5402}
5403
5404/**
5405 * Poll selection to see whether it's changed.
5406 *
5407 * @param {object} nativeEvent
5408 * @return {?SyntheticEvent}
5409 */
5410function constructSelectEvent(nativeEvent, nativeEventTarget) {
5411 // Ensure we have the right element, and that the user is not dragging a
5412 // selection (this matches native `select` event behavior). In HTML5, select
5413 // fires only on input and textarea thus if there's no focused element we
5414 // won't dispatch.
5415 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement_1()) {
5416 return null;
5417 }
5418
5419 // Only fire when selection has actually changed.
5420 var currentSelection = getSelection(activeElement$1);
5421 if (!lastSelection || !shallowEqual_1(lastSelection, currentSelection)) {
5422 lastSelection = currentSelection;
5423
5424 var syntheticEvent = SyntheticEvent$1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5425
5426 syntheticEvent.type = 'select';
5427 syntheticEvent.target = activeElement$1;
5428
5429 accumulateTwoPhaseDispatches(syntheticEvent);
5430
5431 return syntheticEvent;
5432 }
5433
5434 return null;
5435}
5436
5437/**
5438 * This plugin creates an `onSelect` event that normalizes select events
5439 * across form elements.
5440 *
5441 * Supported elements are:
5442 * - input (see `isTextInputElement`)
5443 * - textarea
5444 * - contentEditable
5445 *
5446 * This differs from native browser implementations in the following ways:
5447 * - Fires on contentEditable fields as well as inputs.
5448 * - Fires for collapsed selection.
5449 * - Fires after user input.
5450 */
5451var SelectEventPlugin = {
5452 eventTypes: eventTypes$3,
5453
5454 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5455 var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE ? nativeEventTarget : nativeEventTarget.ownerDocument;
5456 // Track whether all listeners exists for this plugin. If none exist, we do
5457 // not extract events. See #3639.
5458 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5459 return null;
5460 }
5461
5462 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5463
5464 switch (topLevelType) {
5465 // Track the input node that has focus.
5466 case 'topFocus':
5467 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5468 activeElement$1 = targetNode;
5469 activeElementInst$1 = targetInst;
5470 lastSelection = null;
5471 }
5472 break;
5473 case 'topBlur':
5474 activeElement$1 = null;
5475 activeElementInst$1 = null;
5476 lastSelection = null;
5477 break;
5478 // Don't fire the event while the user is dragging. This matches the
5479 // semantics of the native select event.
5480 case 'topMouseDown':
5481 mouseDown = true;
5482 break;
5483 case 'topContextMenu':
5484 case 'topMouseUp':
5485 mouseDown = false;
5486 return constructSelectEvent(nativeEvent, nativeEventTarget);
5487 // Chrome and IE fire non-standard event when selection is changed (and
5488 // sometimes when it hasn't). IE's event fires out of order with respect
5489 // to key and input events on deletion, so we discard it.
5490 //
5491 // Firefox doesn't support selectionchange, so check selection status
5492 // after each key entry. The selection changes after keydown and before
5493 // keyup, but we check on keydown as well in the case of holding down a
5494 // key, when multiple keydown events are fired but only one keyup is.
5495 // This is also our approach for IE handling, for the reason above.
5496 case 'topSelectionChange':
5497 if (skipSelectionChangeEvent) {
5498 break;
5499 }
5500 // falls through
5501 case 'topKeyDown':
5502 case 'topKeyUp':
5503 return constructSelectEvent(nativeEvent, nativeEventTarget);
5504 }
5505
5506 return null;
5507 }
5508};
5509
5510/**
5511 * Inject modules for resolving DOM hierarchy and plugin ordering.
5512 */
5513injection.injectEventPluginOrder(DOMEventPluginOrder);
5514injection$1.injectComponentTree(ReactDOMComponentTree);
5515
5516/**
5517 * Some important event plugins included by default (without having to require
5518 * them).
5519 */
5520injection.injectEventPluginsByName({
5521 SimpleEventPlugin: SimpleEventPlugin,
5522 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5523 ChangeEventPlugin: ChangeEventPlugin,
5524 SelectEventPlugin: SelectEventPlugin,
5525 BeforeInputEventPlugin: BeforeInputEventPlugin
5526});
5527
5528/**
5529 * Copyright (c) 2013-present, Facebook, Inc.
5530 *
5531 * This source code is licensed under the MIT license found in the
5532 * LICENSE file in the root directory of this source tree.
5533 *
5534 */
5535
5536
5537
5538var emptyObject = {};
5539
5540{
5541 Object.freeze(emptyObject);
5542}
5543
5544var emptyObject_1 = emptyObject;
5545
5546var valueStack = [];
5547
5548var fiberStack = void 0;
5549
5550{
5551 fiberStack = [];
5552}
5553
5554var index = -1;
5555
5556function createCursor(defaultValue) {
5557 return {
5558 current: defaultValue
5559 };
5560}
5561
5562
5563
5564function pop(cursor, fiber) {
5565 if (index < 0) {
5566 {
5567 warning_1(false, 'Unexpected pop.');
5568 }
5569 return;
5570 }
5571
5572 {
5573 if (fiber !== fiberStack[index]) {
5574 warning_1(false, 'Unexpected Fiber popped.');
5575 }
5576 }
5577
5578 cursor.current = valueStack[index];
5579
5580 valueStack[index] = null;
5581
5582 {
5583 fiberStack[index] = null;
5584 }
5585
5586 index--;
5587}
5588
5589function push(cursor, value, fiber) {
5590 index++;
5591
5592 valueStack[index] = cursor.current;
5593
5594 {
5595 fiberStack[index] = fiber;
5596 }
5597
5598 cursor.current = value;
5599}
5600
5601function reset$1() {
5602 while (index > -1) {
5603 valueStack[index] = null;
5604
5605 {
5606 fiberStack[index] = null;
5607 }
5608
5609 index--;
5610 }
5611}
5612
5613// Exports ReactDOM.createRoot
5614var enableCreateRoot = true;
5615var enableUserTimingAPI = true;
5616
5617// Mutating mode (React DOM, React ART, React Native):
5618var enableMutatingReconciler = true;
5619// Experimental noop mode (currently unused):
5620var enableNoopReconciler = false;
5621// Experimental persistent mode (Fabric):
5622var enablePersistentReconciler = false;
5623// Experimental error-boundary API that can recover from errors within a single
5624// render phase
5625var enableGetDerivedStateFromCatch = false;
5626// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
5627var debugRenderPhaseSideEffects = false;
5628
5629// In some cases, StrictMode should also double-render lifecycles.
5630// This can be confusing for tests though,
5631// And it can be bad for performance in production.
5632// This feature flag can be used to control the behavior:
5633var debugRenderPhaseSideEffectsForStrictMode = true;
5634
5635// To preserve the "Pause on caught exceptions" behavior of the debugger, we
5636// replay the begin phase of a failed component inside invokeGuardedCallback.
5637var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
5638
5639// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
5640var warnAboutDeprecatedLifecycles = false;
5641
5642// Only used in www builds.
5643
5644// Prefix measurements so that it's possible to filter them.
5645// Longer prefixes are hard to read in DevTools.
5646var reactEmoji = '\u269B';
5647var warningEmoji = '\u26D4';
5648var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
5649
5650// Keep track of current fiber so that we know the path to unwind on pause.
5651// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5652var currentFiber = null;
5653// If we're in the middle of user code, which fiber and method is it?
5654// Reusing `currentFiber` would be confusing for this because user code fiber
5655// can change during commit phase too, but we don't need to unwind it (since
5656// lifecycles in the commit phase don't resemble a tree).
5657var currentPhase = null;
5658var currentPhaseFiber = null;
5659// Did lifecycle hook schedule an update? This is often a performance problem,
5660// so we will keep track of it, and include it in the report.
5661// Track commits caused by cascading updates.
5662var isCommitting = false;
5663var hasScheduledUpdateInCurrentCommit = false;
5664var hasScheduledUpdateInCurrentPhase = false;
5665var commitCountInCurrentWorkLoop = 0;
5666var effectCountInCurrentCommit = 0;
5667var isWaitingForCallback = false;
5668// During commits, we only show a measurement once per method name
5669// to avoid stretch the commit phase with measurement overhead.
5670var labelsInCurrentCommit = new Set();
5671
5672var formatMarkName = function (markName) {
5673 return reactEmoji + ' ' + markName;
5674};
5675
5676var formatLabel = function (label, warning) {
5677 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
5678 var suffix = warning ? ' Warning: ' + warning : '';
5679 return '' + prefix + label + suffix;
5680};
5681
5682var beginMark = function (markName) {
5683 performance.mark(formatMarkName(markName));
5684};
5685
5686var clearMark = function (markName) {
5687 performance.clearMarks(formatMarkName(markName));
5688};
5689
5690var endMark = function (label, markName, warning) {
5691 var formattedMarkName = formatMarkName(markName);
5692 var formattedLabel = formatLabel(label, warning);
5693 try {
5694 performance.measure(formattedLabel, formattedMarkName);
5695 } catch (err) {}
5696 // If previous mark was missing for some reason, this will throw.
5697 // This could only happen if React crashed in an unexpected place earlier.
5698 // Don't pile on with more errors.
5699
5700 // Clear marks immediately to avoid growing buffer.
5701 performance.clearMarks(formattedMarkName);
5702 performance.clearMeasures(formattedLabel);
5703};
5704
5705var getFiberMarkName = function (label, debugID) {
5706 return label + ' (#' + debugID + ')';
5707};
5708
5709var getFiberLabel = function (componentName, isMounted, phase) {
5710 if (phase === null) {
5711 // These are composite component total time measurements.
5712 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
5713 } else {
5714 // Composite component methods.
5715 return componentName + '.' + phase;
5716 }
5717};
5718
5719var beginFiberMark = function (fiber, phase) {
5720 var componentName = getComponentName(fiber) || 'Unknown';
5721 var debugID = fiber._debugID;
5722 var isMounted = fiber.alternate !== null;
5723 var label = getFiberLabel(componentName, isMounted, phase);
5724
5725 if (isCommitting && labelsInCurrentCommit.has(label)) {
5726 // During the commit phase, we don't show duplicate labels because
5727 // there is a fixed overhead for every measurement, and we don't
5728 // want to stretch the commit phase beyond necessary.
5729 return false;
5730 }
5731 labelsInCurrentCommit.add(label);
5732
5733 var markName = getFiberMarkName(label, debugID);
5734 beginMark(markName);
5735 return true;
5736};
5737
5738var clearFiberMark = function (fiber, phase) {
5739 var componentName = getComponentName(fiber) || 'Unknown';
5740 var debugID = fiber._debugID;
5741 var isMounted = fiber.alternate !== null;
5742 var label = getFiberLabel(componentName, isMounted, phase);
5743 var markName = getFiberMarkName(label, debugID);
5744 clearMark(markName);
5745};
5746
5747var endFiberMark = function (fiber, phase, warning) {
5748 var componentName = getComponentName(fiber) || 'Unknown';
5749 var debugID = fiber._debugID;
5750 var isMounted = fiber.alternate !== null;
5751 var label = getFiberLabel(componentName, isMounted, phase);
5752 var markName = getFiberMarkName(label, debugID);
5753 endMark(label, markName, warning);
5754};
5755
5756var shouldIgnoreFiber = function (fiber) {
5757 // Host components should be skipped in the timeline.
5758 // We could check typeof fiber.type, but does this work with RN?
5759 switch (fiber.tag) {
5760 case HostRoot:
5761 case HostComponent:
5762 case HostText:
5763 case HostPortal:
5764 case CallComponent:
5765 case ReturnComponent:
5766 case Fragment:
5767 case ContextProvider:
5768 case ContextConsumer:
5769 return true;
5770 default:
5771 return false;
5772 }
5773};
5774
5775var clearPendingPhaseMeasurement = function () {
5776 if (currentPhase !== null && currentPhaseFiber !== null) {
5777 clearFiberMark(currentPhaseFiber, currentPhase);
5778 }
5779 currentPhaseFiber = null;
5780 currentPhase = null;
5781 hasScheduledUpdateInCurrentPhase = false;
5782};
5783
5784var pauseTimers = function () {
5785 // Stops all currently active measurements so that they can be resumed
5786 // if we continue in a later deferred loop from the same unit of work.
5787 var fiber = currentFiber;
5788 while (fiber) {
5789 if (fiber._debugIsCurrentlyTiming) {
5790 endFiberMark(fiber, null, null);
5791 }
5792 fiber = fiber['return'];
5793 }
5794};
5795
5796var resumeTimersRecursively = function (fiber) {
5797 if (fiber['return'] !== null) {
5798 resumeTimersRecursively(fiber['return']);
5799 }
5800 if (fiber._debugIsCurrentlyTiming) {
5801 beginFiberMark(fiber, null);
5802 }
5803};
5804
5805var resumeTimers = function () {
5806 // Resumes all measurements that were active during the last deferred loop.
5807 if (currentFiber !== null) {
5808 resumeTimersRecursively(currentFiber);
5809 }
5810};
5811
5812function recordEffect() {
5813 if (enableUserTimingAPI) {
5814 effectCountInCurrentCommit++;
5815 }
5816}
5817
5818function recordScheduleUpdate() {
5819 if (enableUserTimingAPI) {
5820 if (isCommitting) {
5821 hasScheduledUpdateInCurrentCommit = true;
5822 }
5823 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
5824 hasScheduledUpdateInCurrentPhase = true;
5825 }
5826 }
5827}
5828
5829function startRequestCallbackTimer() {
5830 if (enableUserTimingAPI) {
5831 if (supportsUserTiming && !isWaitingForCallback) {
5832 isWaitingForCallback = true;
5833 beginMark('(Waiting for async callback...)');
5834 }
5835 }
5836}
5837
5838function stopRequestCallbackTimer(didExpire) {
5839 if (enableUserTimingAPI) {
5840 if (supportsUserTiming) {
5841 isWaitingForCallback = false;
5842 var warning = didExpire ? 'React was blocked by main thread' : null;
5843 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
5844 }
5845 }
5846}
5847
5848function startWorkTimer(fiber) {
5849 if (enableUserTimingAPI) {
5850 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5851 return;
5852 }
5853 // If we pause, this is the fiber to unwind from.
5854 currentFiber = fiber;
5855 if (!beginFiberMark(fiber, null)) {
5856 return;
5857 }
5858 fiber._debugIsCurrentlyTiming = true;
5859 }
5860}
5861
5862function cancelWorkTimer(fiber) {
5863 if (enableUserTimingAPI) {
5864 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5865 return;
5866 }
5867 // Remember we shouldn't complete measurement for this fiber.
5868 // Otherwise flamechart will be deep even for small updates.
5869 fiber._debugIsCurrentlyTiming = false;
5870 clearFiberMark(fiber, null);
5871 }
5872}
5873
5874function stopWorkTimer(fiber) {
5875 if (enableUserTimingAPI) {
5876 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5877 return;
5878 }
5879 // If we pause, its parent is the fiber to unwind from.
5880 currentFiber = fiber['return'];
5881 if (!fiber._debugIsCurrentlyTiming) {
5882 return;
5883 }
5884 fiber._debugIsCurrentlyTiming = false;
5885 endFiberMark(fiber, null, null);
5886 }
5887}
5888
5889function stopFailedWorkTimer(fiber) {
5890 if (enableUserTimingAPI) {
5891 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5892 return;
5893 }
5894 // If we pause, its parent is the fiber to unwind from.
5895 currentFiber = fiber['return'];
5896 if (!fiber._debugIsCurrentlyTiming) {
5897 return;
5898 }
5899 fiber._debugIsCurrentlyTiming = false;
5900 var warning = 'An error was thrown inside this error boundary';
5901 endFiberMark(fiber, null, warning);
5902 }
5903}
5904
5905function startPhaseTimer(fiber, phase) {
5906 if (enableUserTimingAPI) {
5907 if (!supportsUserTiming) {
5908 return;
5909 }
5910 clearPendingPhaseMeasurement();
5911 if (!beginFiberMark(fiber, phase)) {
5912 return;
5913 }
5914 currentPhaseFiber = fiber;
5915 currentPhase = phase;
5916 }
5917}
5918
5919function stopPhaseTimer() {
5920 if (enableUserTimingAPI) {
5921 if (!supportsUserTiming) {
5922 return;
5923 }
5924 if (currentPhase !== null && currentPhaseFiber !== null) {
5925 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
5926 endFiberMark(currentPhaseFiber, currentPhase, warning);
5927 }
5928 currentPhase = null;
5929 currentPhaseFiber = null;
5930 }
5931}
5932
5933function startWorkLoopTimer(nextUnitOfWork) {
5934 if (enableUserTimingAPI) {
5935 currentFiber = nextUnitOfWork;
5936 if (!supportsUserTiming) {
5937 return;
5938 }
5939 commitCountInCurrentWorkLoop = 0;
5940 // This is top level call.
5941 // Any other measurements are performed within.
5942 beginMark('(React Tree Reconciliation)');
5943 // Resume any measurements that were in progress during the last loop.
5944 resumeTimers();
5945 }
5946}
5947
5948function stopWorkLoopTimer(interruptedBy) {
5949 if (enableUserTimingAPI) {
5950 if (!supportsUserTiming) {
5951 return;
5952 }
5953 var warning = null;
5954 if (interruptedBy !== null) {
5955 if (interruptedBy.tag === HostRoot) {
5956 warning = 'A top-level update interrupted the previous render';
5957 } else {
5958 var componentName = getComponentName(interruptedBy) || 'Unknown';
5959 warning = 'An update to ' + componentName + ' interrupted the previous render';
5960 }
5961 } else if (commitCountInCurrentWorkLoop > 1) {
5962 warning = 'There were cascading updates';
5963 }
5964 commitCountInCurrentWorkLoop = 0;
5965 // Pause any measurements until the next loop.
5966 pauseTimers();
5967 endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning);
5968 }
5969}
5970
5971function startCommitTimer() {
5972 if (enableUserTimingAPI) {
5973 if (!supportsUserTiming) {
5974 return;
5975 }
5976 isCommitting = true;
5977 hasScheduledUpdateInCurrentCommit = false;
5978 labelsInCurrentCommit.clear();
5979 beginMark('(Committing Changes)');
5980 }
5981}
5982
5983function stopCommitTimer() {
5984 if (enableUserTimingAPI) {
5985 if (!supportsUserTiming) {
5986 return;
5987 }
5988
5989 var warning = null;
5990 if (hasScheduledUpdateInCurrentCommit) {
5991 warning = 'Lifecycle hook scheduled a cascading update';
5992 } else if (commitCountInCurrentWorkLoop > 0) {
5993 warning = 'Caused by a cascading update in earlier commit';
5994 }
5995 hasScheduledUpdateInCurrentCommit = false;
5996 commitCountInCurrentWorkLoop++;
5997 isCommitting = false;
5998 labelsInCurrentCommit.clear();
5999
6000 endMark('(Committing Changes)', '(Committing Changes)', warning);
6001 }
6002}
6003
6004function startCommitHostEffectsTimer() {
6005 if (enableUserTimingAPI) {
6006 if (!supportsUserTiming) {
6007 return;
6008 }
6009 effectCountInCurrentCommit = 0;
6010 beginMark('(Committing Host Effects)');
6011 }
6012}
6013
6014function stopCommitHostEffectsTimer() {
6015 if (enableUserTimingAPI) {
6016 if (!supportsUserTiming) {
6017 return;
6018 }
6019 var count = effectCountInCurrentCommit;
6020 effectCountInCurrentCommit = 0;
6021 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
6022 }
6023}
6024
6025function startCommitLifeCyclesTimer() {
6026 if (enableUserTimingAPI) {
6027 if (!supportsUserTiming) {
6028 return;
6029 }
6030 effectCountInCurrentCommit = 0;
6031 beginMark('(Calling Lifecycle Methods)');
6032 }
6033}
6034
6035function stopCommitLifeCyclesTimer() {
6036 if (enableUserTimingAPI) {
6037 if (!supportsUserTiming) {
6038 return;
6039 }
6040 var count = effectCountInCurrentCommit;
6041 effectCountInCurrentCommit = 0;
6042 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
6043 }
6044}
6045
6046var warnedAboutMissingGetChildContext = void 0;
6047
6048{
6049 warnedAboutMissingGetChildContext = {};
6050}
6051
6052// A cursor to the current merged context object on the stack.
6053var contextStackCursor = createCursor(emptyObject_1);
6054// A cursor to a boolean indicating whether the context has changed.
6055var didPerformWorkStackCursor = createCursor(false);
6056// Keep track of the previous context object that was on the stack.
6057// We use this to get access to the parent context after we have already
6058// pushed the next context provider, and now need to merge their contexts.
6059var previousContext = emptyObject_1;
6060
6061function getUnmaskedContext(workInProgress) {
6062 var hasOwnContext = isContextProvider(workInProgress);
6063 if (hasOwnContext) {
6064 // If the fiber is a context provider itself, when we read its context
6065 // we have already pushed its own child context on the stack. A context
6066 // provider should not "see" its own child context. Therefore we read the
6067 // previous (parent) context instead for a context provider.
6068 return previousContext;
6069 }
6070 return contextStackCursor.current;
6071}
6072
6073function cacheContext(workInProgress, unmaskedContext, maskedContext) {
6074 var instance = workInProgress.stateNode;
6075 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
6076 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
6077}
6078
6079function getMaskedContext(workInProgress, unmaskedContext) {
6080 var type = workInProgress.type;
6081 var contextTypes = type.contextTypes;
6082 if (!contextTypes) {
6083 return emptyObject_1;
6084 }
6085
6086 // Avoid recreating masked context unless unmasked context has changed.
6087 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
6088 // This may trigger infinite loops if componentWillReceiveProps calls setState.
6089 var instance = workInProgress.stateNode;
6090 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
6091 return instance.__reactInternalMemoizedMaskedChildContext;
6092 }
6093
6094 var context = {};
6095 for (var key in contextTypes) {
6096 context[key] = unmaskedContext[key];
6097 }
6098
6099 {
6100 var name = getComponentName(workInProgress) || 'Unknown';
6101 checkPropTypes_1(contextTypes, context, 'context', name, ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6102 }
6103
6104 // Cache unmasked context so we can avoid recreating masked context unless necessary.
6105 // Context is created before the class component is instantiated so check for instance.
6106 if (instance) {
6107 cacheContext(workInProgress, unmaskedContext, context);
6108 }
6109
6110 return context;
6111}
6112
6113function hasContextChanged() {
6114 return didPerformWorkStackCursor.current;
6115}
6116
6117function isContextConsumer(fiber) {
6118 return fiber.tag === ClassComponent && fiber.type.contextTypes != null;
6119}
6120
6121function isContextProvider(fiber) {
6122 return fiber.tag === ClassComponent && fiber.type.childContextTypes != null;
6123}
6124
6125function popContextProvider(fiber) {
6126 if (!isContextProvider(fiber)) {
6127 return;
6128 }
6129
6130 pop(didPerformWorkStackCursor, fiber);
6131 pop(contextStackCursor, fiber);
6132}
6133
6134function popTopLevelContextObject(fiber) {
6135 pop(didPerformWorkStackCursor, fiber);
6136 pop(contextStackCursor, fiber);
6137}
6138
6139function pushTopLevelContextObject(fiber, context, didChange) {
6140 !(contextStackCursor.cursor == null) ? invariant_1(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6141
6142 push(contextStackCursor, context, fiber);
6143 push(didPerformWorkStackCursor, didChange, fiber);
6144}
6145
6146function processChildContext(fiber, parentContext) {
6147 var instance = fiber.stateNode;
6148 var childContextTypes = fiber.type.childContextTypes;
6149
6150 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
6151 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
6152 if (typeof instance.getChildContext !== 'function') {
6153 {
6154 var componentName = getComponentName(fiber) || 'Unknown';
6155
6156 if (!warnedAboutMissingGetChildContext[componentName]) {
6157 warnedAboutMissingGetChildContext[componentName] = true;
6158 warning_1(false, '%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);
6159 }
6160 }
6161 return parentContext;
6162 }
6163
6164 var childContext = void 0;
6165 {
6166 ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
6167 }
6168 startPhaseTimer(fiber, 'getChildContext');
6169 childContext = instance.getChildContext();
6170 stopPhaseTimer();
6171 {
6172 ReactDebugCurrentFiber.setCurrentPhase(null);
6173 }
6174 for (var contextKey in childContext) {
6175 !(contextKey in childContextTypes) ? invariant_1(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(fiber) || 'Unknown', contextKey) : void 0;
6176 }
6177 {
6178 var name = getComponentName(fiber) || 'Unknown';
6179 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
6180 // In practice, there is one case in which we won't get a stack. It's when
6181 // somebody calls unstable_renderSubtreeIntoContainer() and we process
6182 // context from the parent component instance. The stack will be missing
6183 // because it's outside of the reconciliation, and so the pointer has not
6184 // been set. This is rare and doesn't matter. We'll also remove that API.
6185 ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6186 }
6187
6188 return _assign({}, parentContext, childContext);
6189}
6190
6191function pushContextProvider(workInProgress) {
6192 if (!isContextProvider(workInProgress)) {
6193 return false;
6194 }
6195
6196 var instance = workInProgress.stateNode;
6197 // We push the context as early as possible to ensure stack integrity.
6198 // If the instance does not exist yet, we will push null at first,
6199 // and replace it on the stack later when invalidating the context.
6200 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject_1;
6201
6202 // Remember the parent context so we can merge with it later.
6203 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
6204 previousContext = contextStackCursor.current;
6205 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
6206 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
6207
6208 return true;
6209}
6210
6211function invalidateContextProvider(workInProgress, didChange) {
6212 var instance = workInProgress.stateNode;
6213 !instance ? invariant_1(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6214
6215 if (didChange) {
6216 // Merge parent and own context.
6217 // Skip this if we're not updating due to sCU.
6218 // This avoids unnecessarily recomputing memoized values.
6219 var mergedContext = processChildContext(workInProgress, previousContext);
6220 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
6221
6222 // Replace the old (or empty) context with the new one.
6223 // It is important to unwind the context in the reverse order.
6224 pop(didPerformWorkStackCursor, workInProgress);
6225 pop(contextStackCursor, workInProgress);
6226 // Now push the new context and mark that it has changed.
6227 push(contextStackCursor, mergedContext, workInProgress);
6228 push(didPerformWorkStackCursor, didChange, workInProgress);
6229 } else {
6230 pop(didPerformWorkStackCursor, workInProgress);
6231 push(didPerformWorkStackCursor, didChange, workInProgress);
6232 }
6233}
6234
6235function resetContext() {
6236 previousContext = emptyObject_1;
6237 contextStackCursor.current = emptyObject_1;
6238 didPerformWorkStackCursor.current = false;
6239}
6240
6241function findCurrentUnmaskedContext(fiber) {
6242 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
6243 // makes sense elsewhere
6244 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? invariant_1(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6245
6246 var node = fiber;
6247 while (node.tag !== HostRoot) {
6248 if (isContextProvider(node)) {
6249 return node.stateNode.__reactInternalMemoizedMergedChildContext;
6250 }
6251 var parent = node['return'];
6252 !parent ? invariant_1(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6253 node = parent;
6254 }
6255 return node.stateNode.context;
6256}
6257
6258// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
6259// Math.pow(2, 30) - 1
6260// 0b111111111111111111111111111111
6261var MAX_SIGNED_31_BIT_INT = 1073741823;
6262
6263// TODO: Use an opaque type once ESLint et al support the syntax
6264
6265
6266var NoWork = 0;
6267var Sync = 1;
6268var Never = MAX_SIGNED_31_BIT_INT;
6269
6270var UNIT_SIZE = 10;
6271var MAGIC_NUMBER_OFFSET = 2;
6272
6273// 1 unit of expiration time represents 10ms.
6274function msToExpirationTime(ms) {
6275 // Always add an offset so that we don't clash with the magic number for NoWork.
6276 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET;
6277}
6278
6279function expirationTimeToMs(expirationTime) {
6280 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE;
6281}
6282
6283function ceiling(num, precision) {
6284 return ((num / precision | 0) + 1) * precision;
6285}
6286
6287function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6288 return ceiling(currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
6289}
6290
6291var NoContext = 0;
6292var AsyncMode = 1;
6293var StrictMode = 2;
6294
6295var hasBadMapPolyfill = void 0;
6296
6297{
6298 hasBadMapPolyfill = false;
6299 try {
6300 var nonExtensibleObject = Object.preventExtensions({});
6301 var testMap = new Map([[nonExtensibleObject, null]]);
6302 var testSet = new Set([nonExtensibleObject]);
6303 // This is necessary for Rollup to not consider these unused.
6304 // https://github.com/rollup/rollup/issues/1771
6305 // TODO: we can remove these if Rollup fixes the bug.
6306 testMap.set(0, 0);
6307 testSet.add(0);
6308 } catch (e) {
6309 // TODO: Consider warning about bad polyfills
6310 hasBadMapPolyfill = true;
6311 }
6312}
6313
6314// A Fiber is work on a Component that needs to be done or was done. There can
6315// be more than one per component.
6316
6317
6318var debugCounter = void 0;
6319
6320{
6321 debugCounter = 1;
6322}
6323
6324function FiberNode(tag, pendingProps, key, mode) {
6325 // Instance
6326 this.tag = tag;
6327 this.key = key;
6328 this.type = null;
6329 this.stateNode = null;
6330
6331 // Fiber
6332 this['return'] = null;
6333 this.child = null;
6334 this.sibling = null;
6335 this.index = 0;
6336
6337 this.ref = null;
6338
6339 this.pendingProps = pendingProps;
6340 this.memoizedProps = null;
6341 this.updateQueue = null;
6342 this.memoizedState = null;
6343
6344 this.mode = mode;
6345
6346 // Effects
6347 this.effectTag = NoEffect;
6348 this.nextEffect = null;
6349
6350 this.firstEffect = null;
6351 this.lastEffect = null;
6352
6353 this.expirationTime = NoWork;
6354
6355 this.alternate = null;
6356
6357 {
6358 this._debugID = debugCounter++;
6359 this._debugSource = null;
6360 this._debugOwner = null;
6361 this._debugIsCurrentlyTiming = false;
6362 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
6363 Object.preventExtensions(this);
6364 }
6365 }
6366}
6367
6368// This is a constructor function, rather than a POJO constructor, still
6369// please ensure we do the following:
6370// 1) Nobody should add any instance methods on this. Instance methods can be
6371// more difficult to predict when they get optimized and they are almost
6372// never inlined properly in static compilers.
6373// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
6374// always know when it is a fiber.
6375// 3) We might want to experiment with using numeric keys since they are easier
6376// to optimize in a non-JIT environment.
6377// 4) We can easily go from a constructor to a createFiber object literal if that
6378// is faster.
6379// 5) It should be easy to port this to a C struct and keep a C implementation
6380// compatible.
6381var createFiber = function (tag, pendingProps, key, mode) {
6382 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
6383 return new FiberNode(tag, pendingProps, key, mode);
6384};
6385
6386function shouldConstruct(Component) {
6387 return !!(Component.prototype && Component.prototype.isReactComponent);
6388}
6389
6390// This is used to create an alternate fiber to do work on.
6391function createWorkInProgress(current, pendingProps, expirationTime) {
6392 var workInProgress = current.alternate;
6393 if (workInProgress === null) {
6394 // We use a double buffering pooling technique because we know that we'll
6395 // only ever need at most two versions of a tree. We pool the "other" unused
6396 // node that we're free to reuse. This is lazily created to avoid allocating
6397 // extra objects for things that are never updated. It also allow us to
6398 // reclaim the extra memory if needed.
6399 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
6400 workInProgress.type = current.type;
6401 workInProgress.stateNode = current.stateNode;
6402
6403 {
6404 // DEV-only fields
6405 workInProgress._debugID = current._debugID;
6406 workInProgress._debugSource = current._debugSource;
6407 workInProgress._debugOwner = current._debugOwner;
6408 }
6409
6410 workInProgress.alternate = current;
6411 current.alternate = workInProgress;
6412 } else {
6413 workInProgress.pendingProps = pendingProps;
6414
6415 // We already have an alternate.
6416 // Reset the effect tag.
6417 workInProgress.effectTag = NoEffect;
6418
6419 // The effect list is no longer valid.
6420 workInProgress.nextEffect = null;
6421 workInProgress.firstEffect = null;
6422 workInProgress.lastEffect = null;
6423 }
6424
6425 workInProgress.expirationTime = expirationTime;
6426
6427 workInProgress.child = current.child;
6428 workInProgress.memoizedProps = current.memoizedProps;
6429 workInProgress.memoizedState = current.memoizedState;
6430 workInProgress.updateQueue = current.updateQueue;
6431
6432 // These will be overridden during the parent's reconciliation
6433 workInProgress.sibling = current.sibling;
6434 workInProgress.index = current.index;
6435 workInProgress.ref = current.ref;
6436
6437 return workInProgress;
6438}
6439
6440function createHostRootFiber(isAsync) {
6441 var mode = isAsync ? AsyncMode | StrictMode : NoContext;
6442 return createFiber(HostRoot, null, null, mode);
6443}
6444
6445function createFiberFromElement(element, mode, expirationTime) {
6446 var owner = null;
6447 {
6448 owner = element._owner;
6449 }
6450
6451 var fiber = void 0;
6452 var type = element.type;
6453 var key = element.key;
6454 var pendingProps = element.props;
6455
6456 var fiberTag = void 0;
6457 if (typeof type === 'function') {
6458 fiberTag = shouldConstruct(type) ? ClassComponent : IndeterminateComponent;
6459 } else if (typeof type === 'string') {
6460 fiberTag = HostComponent;
6461 } else {
6462 switch (type) {
6463 case REACT_FRAGMENT_TYPE:
6464 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
6465 case REACT_ASYNC_MODE_TYPE:
6466 fiberTag = Mode;
6467 mode |= AsyncMode | StrictMode;
6468 break;
6469 case REACT_STRICT_MODE_TYPE:
6470 fiberTag = Mode;
6471 mode |= StrictMode;
6472 break;
6473 case REACT_CALL_TYPE:
6474 fiberTag = CallComponent;
6475 break;
6476 case REACT_RETURN_TYPE:
6477 fiberTag = ReturnComponent;
6478 break;
6479 default:
6480 {
6481 if (typeof type === 'object' && type !== null) {
6482 switch (type.$$typeof) {
6483 case REACT_PROVIDER_TYPE:
6484 fiberTag = ContextProvider;
6485 break;
6486 case REACT_CONTEXT_TYPE:
6487 // This is a consumer
6488 fiberTag = ContextConsumer;
6489 break;
6490 default:
6491 if (typeof type.tag === 'number') {
6492 // Currently assumed to be a continuation and therefore is a
6493 // fiber already.
6494 // TODO: The yield system is currently broken for updates in
6495 // some cases. The reified yield stores a fiber, but we don't
6496 // know which fiber that is; the current or a workInProgress?
6497 // When the continuation gets rendered here we don't know if we
6498 // can reuse that fiber or if we need to clone it. There is
6499 // probably a clever way to restructure this.
6500 fiber = type;
6501 fiber.pendingProps = pendingProps;
6502 fiber.expirationTime = expirationTime;
6503 return fiber;
6504 } else {
6505 throwOnInvalidElementType(type, owner);
6506 }
6507 break;
6508 }
6509 } else {
6510 throwOnInvalidElementType(type, owner);
6511 }
6512 }
6513 }
6514 }
6515
6516 fiber = createFiber(fiberTag, pendingProps, key, mode);
6517 fiber.type = type;
6518 fiber.expirationTime = expirationTime;
6519
6520 {
6521 fiber._debugSource = element._source;
6522 fiber._debugOwner = element._owner;
6523 }
6524
6525 return fiber;
6526}
6527
6528function throwOnInvalidElementType(type, owner) {
6529 var info = '';
6530 {
6531 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
6532 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.';
6533 }
6534 var ownerName = owner ? getComponentName(owner) : null;
6535 if (ownerName) {
6536 info += '\n\nCheck the render method of `' + ownerName + '`.';
6537 }
6538 }
6539 invariant_1(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info);
6540}
6541
6542function createFiberFromFragment(elements, mode, expirationTime, key) {
6543 var fiber = createFiber(Fragment, elements, key, mode);
6544 fiber.expirationTime = expirationTime;
6545 return fiber;
6546}
6547
6548function createFiberFromText(content, mode, expirationTime) {
6549 var fiber = createFiber(HostText, content, null, mode);
6550 fiber.expirationTime = expirationTime;
6551 return fiber;
6552}
6553
6554function createFiberFromHostInstanceForDeletion() {
6555 var fiber = createFiber(HostComponent, null, null, NoContext);
6556 fiber.type = 'DELETED';
6557 return fiber;
6558}
6559
6560function createFiberFromPortal(portal, mode, expirationTime) {
6561 var pendingProps = portal.children !== null ? portal.children : [];
6562 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
6563 fiber.expirationTime = expirationTime;
6564 fiber.stateNode = {
6565 containerInfo: portal.containerInfo,
6566 pendingChildren: null, // Used by persistent updates
6567 implementation: portal.implementation
6568 };
6569 return fiber;
6570}
6571
6572// TODO: This should be lifted into the renderer.
6573
6574
6575function createFiberRoot(containerInfo, isAsync, hydrate) {
6576 // Cyclic construction. This cheats the type system right now because
6577 // stateNode is any.
6578 var uninitializedFiber = createHostRootFiber(isAsync);
6579 var root = {
6580 current: uninitializedFiber,
6581 containerInfo: containerInfo,
6582 pendingChildren: null,
6583 pendingCommitExpirationTime: NoWork,
6584 finishedWork: null,
6585 context: null,
6586 pendingContext: null,
6587 hydrate: hydrate,
6588 remainingExpirationTime: NoWork,
6589 firstBatch: null,
6590 nextScheduledRoot: null
6591 };
6592 uninitializedFiber.stateNode = root;
6593 return root;
6594}
6595
6596var onCommitFiberRoot = null;
6597var onCommitFiberUnmount = null;
6598var hasLoggedError = false;
6599
6600function catchErrors(fn) {
6601 return function (arg) {
6602 try {
6603 return fn(arg);
6604 } catch (err) {
6605 if (true && !hasLoggedError) {
6606 hasLoggedError = true;
6607 warning_1(false, 'React DevTools encountered an error: %s', err);
6608 }
6609 }
6610 };
6611}
6612
6613function injectInternals(internals) {
6614 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
6615 // No DevTools
6616 return false;
6617 }
6618 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
6619 if (hook.isDisabled) {
6620 // This isn't a real property on the hook, but it can be set to opt out
6621 // of DevTools integration and associated warnings and logs.
6622 // https://github.com/facebook/react/issues/3877
6623 return true;
6624 }
6625 if (!hook.supportsFiber) {
6626 {
6627 warning_1(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
6628 }
6629 // DevTools exists, even though it doesn't support Fiber.
6630 return true;
6631 }
6632 try {
6633 var rendererID = hook.inject(internals);
6634 // We have successfully injected, so now it is safe to set up hooks.
6635 onCommitFiberRoot = catchErrors(function (root) {
6636 return hook.onCommitFiberRoot(rendererID, root);
6637 });
6638 onCommitFiberUnmount = catchErrors(function (fiber) {
6639 return hook.onCommitFiberUnmount(rendererID, fiber);
6640 });
6641 } catch (err) {
6642 // Catch all errors because it is unsafe to throw during initialization.
6643 {
6644 warning_1(false, 'React DevTools encountered an error: %s.', err);
6645 }
6646 }
6647 // DevTools exists
6648 return true;
6649}
6650
6651function onCommitRoot(root) {
6652 if (typeof onCommitFiberRoot === 'function') {
6653 onCommitFiberRoot(root);
6654 }
6655}
6656
6657function onCommitUnmount(fiber) {
6658 if (typeof onCommitFiberUnmount === 'function') {
6659 onCommitFiberUnmount(fiber);
6660 }
6661}
6662
6663/**
6664 * Forked from fbjs/warning:
6665 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
6666 *
6667 * Only change is we use console.warn instead of console.error,
6668 * and do nothing when 'console' is not supported.
6669 * This really simplifies the code.
6670 * ---
6671 * Similar to invariant but only logs a warning if the condition is not met.
6672 * This can be used to log issues in development environments in critical
6673 * paths. Removing the logging code for production environments will keep the
6674 * same logic and follow the same code paths.
6675 */
6676
6677var lowPriorityWarning = function () {};
6678
6679{
6680 var printWarning$1 = function (format) {
6681 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6682 args[_key - 1] = arguments[_key];
6683 }
6684
6685 var argIndex = 0;
6686 var message = 'Warning: ' + format.replace(/%s/g, function () {
6687 return args[argIndex++];
6688 });
6689 if (typeof console !== 'undefined') {
6690 console.warn(message);
6691 }
6692 try {
6693 // --- Welcome to debugging React ---
6694 // This error was thrown as a convenience so that you can use this stack
6695 // to find the callsite that caused this warning to fire.
6696 throw new Error(message);
6697 } catch (x) {}
6698 };
6699
6700 lowPriorityWarning = function (condition, format) {
6701 if (format === undefined) {
6702 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
6703 }
6704 if (!condition) {
6705 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
6706 args[_key2 - 2] = arguments[_key2];
6707 }
6708
6709 printWarning$1.apply(undefined, [format].concat(args));
6710 }
6711 };
6712}
6713
6714var lowPriorityWarning$1 = lowPriorityWarning;
6715
6716var ReactStrictModeWarnings = {
6717 discardPendingWarnings: function () {},
6718 flushPendingDeprecationWarnings: function () {},
6719 flushPendingUnsafeLifecycleWarnings: function () {},
6720 recordDeprecationWarnings: function (fiber, instance) {},
6721 recordUnsafeLifecycleWarnings: function (fiber, instance) {}
6722};
6723
6724{
6725 var LIFECYCLE_SUGGESTIONS = {
6726 UNSAFE_componentWillMount: 'componentDidMount',
6727 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
6728 UNSAFE_componentWillUpdate: 'componentDidUpdate'
6729 };
6730
6731 var pendingComponentWillMountWarnings = [];
6732 var pendingComponentWillReceivePropsWarnings = [];
6733 var pendingComponentWillUpdateWarnings = [];
6734 var pendingUnsafeLifecycleWarnings = new Map();
6735
6736 // Tracks components we have already warned about.
6737 var didWarnAboutDeprecatedLifecycles = new Set();
6738 var didWarnAboutUnsafeLifecycles = new Set();
6739
6740 ReactStrictModeWarnings.discardPendingWarnings = function () {
6741 pendingComponentWillMountWarnings = [];
6742 pendingComponentWillReceivePropsWarnings = [];
6743 pendingComponentWillUpdateWarnings = [];
6744 pendingUnsafeLifecycleWarnings = new Map();
6745 };
6746
6747 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
6748 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
6749 var lifecyclesWarningMesages = [];
6750
6751 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
6752 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
6753 if (lifecycleWarnings.length > 0) {
6754 var componentNames = new Set();
6755 lifecycleWarnings.forEach(function (fiber) {
6756 componentNames.add(getComponentName(fiber) || 'Component');
6757 didWarnAboutUnsafeLifecycles.add(fiber.type);
6758 });
6759
6760 var formatted = lifecycle.replace('UNSAFE_', '');
6761 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
6762 var sortedComponentNames = Array.from(componentNames).sort().join(', ');
6763
6764 lifecyclesWarningMesages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
6765 }
6766 });
6767
6768 if (lifecyclesWarningMesages.length > 0) {
6769 var strictRootComponentStack = getStackAddendumByWorkInProgressFiber(strictRoot);
6770
6771 warning_1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMesages.join('\n\n'));
6772 }
6773 });
6774
6775 pendingUnsafeLifecycleWarnings = new Map();
6776 };
6777
6778 var getStrictRoot = function (fiber) {
6779 var maybeStrictRoot = null;
6780
6781 while (fiber !== null) {
6782 if (fiber.mode & StrictMode) {
6783 maybeStrictRoot = fiber;
6784 }
6785
6786 fiber = fiber['return'];
6787 }
6788
6789 return maybeStrictRoot;
6790 };
6791
6792 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
6793 if (pendingComponentWillMountWarnings.length > 0) {
6794 var uniqueNames = new Set();
6795 pendingComponentWillMountWarnings.forEach(function (fiber) {
6796 uniqueNames.add(getComponentName(fiber) || 'Component');
6797 didWarnAboutDeprecatedLifecycles.add(fiber.type);
6798 });
6799
6800 var sortedNames = Array.from(uniqueNames).sort().join(', ');
6801
6802 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames);
6803
6804 pendingComponentWillMountWarnings = [];
6805 }
6806
6807 if (pendingComponentWillReceivePropsWarnings.length > 0) {
6808 var _uniqueNames = new Set();
6809 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
6810 _uniqueNames.add(getComponentName(fiber) || 'Component');
6811 didWarnAboutDeprecatedLifecycles.add(fiber.type);
6812 });
6813
6814 var _sortedNames = Array.from(_uniqueNames).sort().join(', ');
6815
6816 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames);
6817
6818 pendingComponentWillReceivePropsWarnings = [];
6819 }
6820
6821 if (pendingComponentWillUpdateWarnings.length > 0) {
6822 var _uniqueNames2 = new Set();
6823 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
6824 _uniqueNames2.add(getComponentName(fiber) || 'Component');
6825 didWarnAboutDeprecatedLifecycles.add(fiber.type);
6826 });
6827
6828 var _sortedNames2 = Array.from(_uniqueNames2).sort().join(', ');
6829
6830 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2);
6831
6832 pendingComponentWillUpdateWarnings = [];
6833 }
6834 };
6835
6836 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
6837 // Dedup strategy: Warn once per component.
6838 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
6839 return;
6840 }
6841
6842 // Don't warn about react-lifecycles-compat polyfilled components.
6843 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
6844 pendingComponentWillMountWarnings.push(fiber);
6845 }
6846 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
6847 pendingComponentWillReceivePropsWarnings.push(fiber);
6848 }
6849 if (typeof instance.componentWillUpdate === 'function') {
6850 pendingComponentWillUpdateWarnings.push(fiber);
6851 }
6852 };
6853
6854 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
6855 var strictRoot = getStrictRoot(fiber);
6856
6857 // Dedup strategy: Warn once per component.
6858 // This is difficult to track any other way since component names
6859 // are often vague and are likely to collide between 3rd party libraries.
6860 // An expand property is probably okay to use here since it's DEV-only,
6861 // and will only be set in the event of serious warnings.
6862 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
6863 return;
6864 }
6865
6866 // Don't warn about react-lifecycles-compat polyfilled components.
6867 // Note that it is sufficient to check for the presence of a
6868 // single lifecycle, componentWillMount, with the polyfill flag.
6869 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning === true) {
6870 return;
6871 }
6872
6873 var warningsForRoot = void 0;
6874 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
6875 warningsForRoot = {
6876 UNSAFE_componentWillMount: [],
6877 UNSAFE_componentWillReceiveProps: [],
6878 UNSAFE_componentWillUpdate: []
6879 };
6880
6881 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
6882 } else {
6883 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
6884 }
6885
6886 var unsafeLifecycles = [];
6887 if (typeof instance.componentWillMount === 'function' || typeof instance.UNSAFE_componentWillMount === 'function') {
6888 unsafeLifecycles.push('UNSAFE_componentWillMount');
6889 }
6890 if (typeof instance.componentWillReceiveProps === 'function' || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
6891 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
6892 }
6893 if (typeof instance.componentWillUpdate === 'function' || typeof instance.UNSAFE_componentWillUpdate === 'function') {
6894 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
6895 }
6896
6897 if (unsafeLifecycles.length > 0) {
6898 unsafeLifecycles.forEach(function (lifecycle) {
6899 warningsForRoot[lifecycle].push(fiber);
6900 });
6901 }
6902 };
6903}
6904
6905var didWarnUpdateInsideUpdate = void 0;
6906
6907{
6908 didWarnUpdateInsideUpdate = false;
6909}
6910
6911// Callbacks are not validated until invocation
6912
6913
6914// Singly linked-list of updates. When an update is scheduled, it is added to
6915// the queue of the current fiber and the work-in-progress fiber. The two queues
6916// are separate but they share a persistent structure.
6917//
6918// During reconciliation, updates are removed from the work-in-progress fiber,
6919// but they remain on the current fiber. That ensures that if a work-in-progress
6920// is aborted, the aborted updates are recovered by cloning from current.
6921//
6922// The work-in-progress queue is always a subset of the current queue.
6923//
6924// When the tree is committed, the work-in-progress becomes the current.
6925
6926
6927function createUpdateQueue(baseState) {
6928 var queue = {
6929 baseState: baseState,
6930 expirationTime: NoWork,
6931 first: null,
6932 last: null,
6933 callbackList: null,
6934 hasForceUpdate: false,
6935 isInitialized: false,
6936 capturedValues: null
6937 };
6938 {
6939 queue.isProcessing = false;
6940 }
6941 return queue;
6942}
6943
6944function insertUpdateIntoQueue(queue, update) {
6945 // Append the update to the end of the list.
6946 if (queue.last === null) {
6947 // Queue is empty
6948 queue.first = queue.last = update;
6949 } else {
6950 queue.last.next = update;
6951 queue.last = update;
6952 }
6953 if (queue.expirationTime === NoWork || queue.expirationTime > update.expirationTime) {
6954 queue.expirationTime = update.expirationTime;
6955 }
6956}
6957
6958var q1 = void 0;
6959var q2 = void 0;
6960function ensureUpdateQueues(fiber) {
6961 q1 = q2 = null;
6962 // We'll have at least one and at most two distinct update queues.
6963 var alternateFiber = fiber.alternate;
6964 var queue1 = fiber.updateQueue;
6965 if (queue1 === null) {
6966 // TODO: We don't know what the base state will be until we begin work.
6967 // It depends on which fiber is the next current. Initialize with an empty
6968 // base state, then set to the memoizedState when rendering. Not super
6969 // happy with this approach.
6970 queue1 = fiber.updateQueue = createUpdateQueue(null);
6971 }
6972
6973 var queue2 = void 0;
6974 if (alternateFiber !== null) {
6975 queue2 = alternateFiber.updateQueue;
6976 if (queue2 === null) {
6977 queue2 = alternateFiber.updateQueue = createUpdateQueue(null);
6978 }
6979 } else {
6980 queue2 = null;
6981 }
6982 queue2 = queue2 !== queue1 ? queue2 : null;
6983
6984 // Use module variables instead of returning a tuple
6985 q1 = queue1;
6986 q2 = queue2;
6987}
6988
6989function insertUpdateIntoFiber(fiber, update) {
6990 ensureUpdateQueues(fiber);
6991 var queue1 = q1;
6992 var queue2 = q2;
6993
6994 // Warn if an update is scheduled from inside an updater function.
6995 {
6996 if ((queue1.isProcessing || queue2 !== null && queue2.isProcessing) && !didWarnUpdateInsideUpdate) {
6997 warning_1(false, '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.');
6998 didWarnUpdateInsideUpdate = true;
6999 }
7000 }
7001
7002 // If there's only one queue, add the update to that queue and exit.
7003 if (queue2 === null) {
7004 insertUpdateIntoQueue(queue1, update);
7005 return;
7006 }
7007
7008 // If either queue is empty, we need to add to both queues.
7009 if (queue1.last === null || queue2.last === null) {
7010 insertUpdateIntoQueue(queue1, update);
7011 insertUpdateIntoQueue(queue2, update);
7012 return;
7013 }
7014
7015 // If both lists are not empty, the last update is the same for both lists
7016 // because of structural sharing. So, we should only append to one of
7017 // the lists.
7018 insertUpdateIntoQueue(queue1, update);
7019 // But we still need to update the `last` pointer of queue2.
7020 queue2.last = update;
7021}
7022
7023function getUpdateExpirationTime(fiber) {
7024 switch (fiber.tag) {
7025 case HostRoot:
7026 case ClassComponent:
7027 var updateQueue = fiber.updateQueue;
7028 if (updateQueue === null) {
7029 return NoWork;
7030 }
7031 return updateQueue.expirationTime;
7032 default:
7033 return NoWork;
7034 }
7035}
7036
7037function getStateFromUpdate(update, instance, prevState, props) {
7038 var partialState = update.partialState;
7039 if (typeof partialState === 'function') {
7040 return partialState.call(instance, prevState, props);
7041 } else {
7042 return partialState;
7043 }
7044}
7045
7046function processUpdateQueue(current, workInProgress, queue, instance, props, renderExpirationTime) {
7047 if (current !== null && current.updateQueue === queue) {
7048 // We need to create a work-in-progress queue, by cloning the current queue.
7049 var currentQueue = queue;
7050 queue = workInProgress.updateQueue = {
7051 baseState: currentQueue.baseState,
7052 expirationTime: currentQueue.expirationTime,
7053 first: currentQueue.first,
7054 last: currentQueue.last,
7055 isInitialized: currentQueue.isInitialized,
7056 capturedValues: currentQueue.capturedValues,
7057 // These fields are no longer valid because they were already committed.
7058 // Reset them.
7059 callbackList: null,
7060 hasForceUpdate: false
7061 };
7062 }
7063
7064 {
7065 // Set this flag so we can warn if setState is called inside the update
7066 // function of another setState.
7067 queue.isProcessing = true;
7068 }
7069
7070 // Reset the remaining expiration time. If we skip over any updates, we'll
7071 // increase this accordingly.
7072 queue.expirationTime = NoWork;
7073
7074 // TODO: We don't know what the base state will be until we begin work.
7075 // It depends on which fiber is the next current. Initialize with an empty
7076 // base state, then set to the memoizedState when rendering. Not super
7077 // happy with this approach.
7078 var state = void 0;
7079 if (queue.isInitialized) {
7080 state = queue.baseState;
7081 } else {
7082 state = queue.baseState = workInProgress.memoizedState;
7083 queue.isInitialized = true;
7084 }
7085 var dontMutatePrevState = true;
7086 var update = queue.first;
7087 var didSkip = false;
7088 while (update !== null) {
7089 var updateExpirationTime = update.expirationTime;
7090 if (updateExpirationTime > renderExpirationTime) {
7091 // This update does not have sufficient priority. Skip it.
7092 var remainingExpirationTime = queue.expirationTime;
7093 if (remainingExpirationTime === NoWork || remainingExpirationTime > updateExpirationTime) {
7094 // Update the remaining expiration time.
7095 queue.expirationTime = updateExpirationTime;
7096 }
7097 if (!didSkip) {
7098 didSkip = true;
7099 queue.baseState = state;
7100 }
7101 // Continue to the next update.
7102 update = update.next;
7103 continue;
7104 }
7105
7106 // This update does have sufficient priority.
7107
7108 // If no previous updates were skipped, drop this update from the queue by
7109 // advancing the head of the list.
7110 if (!didSkip) {
7111 queue.first = update.next;
7112 if (queue.first === null) {
7113 queue.last = null;
7114 }
7115 }
7116
7117 // Invoke setState callback an extra time to help detect side-effects.
7118 // Ignore the return value in this case.
7119 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7120 getStateFromUpdate(update, instance, state, props);
7121 }
7122
7123 // Process the update
7124 var _partialState = void 0;
7125 if (update.isReplace) {
7126 state = getStateFromUpdate(update, instance, state, props);
7127 dontMutatePrevState = true;
7128 } else {
7129 _partialState = getStateFromUpdate(update, instance, state, props);
7130 if (_partialState) {
7131 if (dontMutatePrevState) {
7132 // $FlowFixMe: Idk how to type this properly.
7133 state = _assign({}, state, _partialState);
7134 } else {
7135 state = _assign(state, _partialState);
7136 }
7137 dontMutatePrevState = false;
7138 }
7139 }
7140 if (update.isForced) {
7141 queue.hasForceUpdate = true;
7142 }
7143 if (update.callback !== null) {
7144 // Append to list of callbacks.
7145 var _callbackList = queue.callbackList;
7146 if (_callbackList === null) {
7147 _callbackList = queue.callbackList = [];
7148 }
7149 _callbackList.push(update);
7150 }
7151 if (update.capturedValue !== null) {
7152 var _capturedValues = queue.capturedValues;
7153 if (_capturedValues === null) {
7154 queue.capturedValues = [update.capturedValue];
7155 } else {
7156 _capturedValues.push(update.capturedValue);
7157 }
7158 }
7159 update = update.next;
7160 }
7161
7162 if (queue.callbackList !== null) {
7163 workInProgress.effectTag |= Callback;
7164 } else if (queue.first === null && !queue.hasForceUpdate && queue.capturedValues === null) {
7165 // The queue is empty. We can reset it.
7166 workInProgress.updateQueue = null;
7167 }
7168
7169 if (!didSkip) {
7170 didSkip = true;
7171 queue.baseState = state;
7172 }
7173
7174 {
7175 // No longer processing.
7176 queue.isProcessing = false;
7177 }
7178
7179 return state;
7180}
7181
7182function commitCallbacks(queue, context) {
7183 var callbackList = queue.callbackList;
7184 if (callbackList === null) {
7185 return;
7186 }
7187 // Set the list to null to make sure they don't get called more than once.
7188 queue.callbackList = null;
7189 for (var i = 0; i < callbackList.length; i++) {
7190 var update = callbackList[i];
7191 var _callback = update.callback;
7192 // This update might be processed again. Clear the callback so it's only
7193 // called once.
7194 update.callback = null;
7195 !(typeof _callback === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0;
7196 _callback.call(context);
7197 }
7198}
7199
7200var fakeInternalInstance = {};
7201var isArray = Array.isArray;
7202
7203var didWarnAboutStateAssignmentForComponent = void 0;
7204var didWarnAboutUndefinedDerivedState = void 0;
7205var didWarnAboutUninitializedState = void 0;
7206var didWarnAboutWillReceivePropsAndDerivedState = void 0;
7207var warnOnInvalidCallback$1 = void 0;
7208
7209{
7210 didWarnAboutStateAssignmentForComponent = {};
7211 didWarnAboutUndefinedDerivedState = {};
7212 didWarnAboutUninitializedState = {};
7213 didWarnAboutWillReceivePropsAndDerivedState = {};
7214
7215 var didWarnOnInvalidCallback = {};
7216
7217 warnOnInvalidCallback$1 = function (callback, callerName) {
7218 if (callback === null || typeof callback === 'function') {
7219 return;
7220 }
7221 var key = callerName + '_' + callback;
7222 if (!didWarnOnInvalidCallback[key]) {
7223 warning_1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
7224 didWarnOnInvalidCallback[key] = true;
7225 }
7226 };
7227
7228 // This is so gross but it's at least non-critical and can be removed if
7229 // it causes problems. This is meant to give a nicer error message for
7230 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
7231 // ...)) which otherwise throws a "_processChildContext is not a function"
7232 // exception.
7233 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
7234 enumerable: false,
7235 value: function () {
7236 invariant_1(false, '_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).');
7237 }
7238 });
7239 Object.freeze(fakeInternalInstance);
7240}
7241function callGetDerivedStateFromCatch(ctor, capturedValues) {
7242 var resultState = {};
7243 for (var i = 0; i < capturedValues.length; i++) {
7244 var capturedValue = capturedValues[i];
7245 var error = capturedValue.value;
7246 var partialState = ctor.getDerivedStateFromCatch.call(null, error);
7247 if (partialState !== null && partialState !== undefined) {
7248 _assign(resultState, partialState);
7249 }
7250 }
7251 return resultState;
7252}
7253
7254var ReactFiberClassComponent = function (scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState) {
7255 // Class component state updater
7256 var updater = {
7257 isMounted: isMounted,
7258 enqueueSetState: function (instance, partialState, callback) {
7259 var fiber = get(instance);
7260 callback = callback === undefined ? null : callback;
7261 {
7262 warnOnInvalidCallback$1(callback, 'setState');
7263 }
7264 var expirationTime = computeExpirationForFiber(fiber);
7265 var update = {
7266 expirationTime: expirationTime,
7267 partialState: partialState,
7268 callback: callback,
7269 isReplace: false,
7270 isForced: false,
7271 capturedValue: null,
7272 next: null
7273 };
7274 insertUpdateIntoFiber(fiber, update);
7275 scheduleWork(fiber, expirationTime);
7276 },
7277 enqueueReplaceState: function (instance, state, callback) {
7278 var fiber = get(instance);
7279 callback = callback === undefined ? null : callback;
7280 {
7281 warnOnInvalidCallback$1(callback, 'replaceState');
7282 }
7283 var expirationTime = computeExpirationForFiber(fiber);
7284 var update = {
7285 expirationTime: expirationTime,
7286 partialState: state,
7287 callback: callback,
7288 isReplace: true,
7289 isForced: false,
7290 capturedValue: null,
7291 next: null
7292 };
7293 insertUpdateIntoFiber(fiber, update);
7294 scheduleWork(fiber, expirationTime);
7295 },
7296 enqueueForceUpdate: function (instance, callback) {
7297 var fiber = get(instance);
7298 callback = callback === undefined ? null : callback;
7299 {
7300 warnOnInvalidCallback$1(callback, 'forceUpdate');
7301 }
7302 var expirationTime = computeExpirationForFiber(fiber);
7303 var update = {
7304 expirationTime: expirationTime,
7305 partialState: null,
7306 callback: callback,
7307 isReplace: false,
7308 isForced: true,
7309 capturedValue: null,
7310 next: null
7311 };
7312 insertUpdateIntoFiber(fiber, update);
7313 scheduleWork(fiber, expirationTime);
7314 }
7315 };
7316
7317 function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
7318 if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) {
7319 // If the workInProgress already has an Update effect, return true
7320 return true;
7321 }
7322
7323 var instance = workInProgress.stateNode;
7324 var ctor = workInProgress.type;
7325 if (typeof instance.shouldComponentUpdate === 'function') {
7326 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
7327 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext);
7328 stopPhaseTimer();
7329
7330 {
7331 warning_1(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(workInProgress) || 'Unknown');
7332 }
7333
7334 return shouldUpdate;
7335 }
7336
7337 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
7338 return !shallowEqual_1(oldProps, newProps) || !shallowEqual_1(oldState, newState);
7339 }
7340
7341 return true;
7342 }
7343
7344 function checkClassInstance(workInProgress) {
7345 var instance = workInProgress.stateNode;
7346 var type = workInProgress.type;
7347 {
7348 var name = getComponentName(workInProgress);
7349 var renderPresent = instance.render;
7350
7351 if (!renderPresent) {
7352 if (type.prototype && typeof type.prototype.render === 'function') {
7353 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
7354 } else {
7355 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
7356 }
7357 }
7358
7359 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
7360 warning_1(noGetInitialStateOnES6, '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);
7361 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
7362 warning_1(noGetDefaultPropsOnES6, '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);
7363 var noInstancePropTypes = !instance.propTypes;
7364 warning_1(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
7365 var noInstanceContextTypes = !instance.contextTypes;
7366 warning_1(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
7367 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
7368 warning_1(noComponentShouldUpdate, '%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);
7369 if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
7370 warning_1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(workInProgress) || 'A pure component');
7371 }
7372 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
7373 warning_1(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
7374 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
7375 warning_1(noComponentDidReceiveProps, '%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);
7376 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
7377 warning_1(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
7378 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
7379 warning_1(noUnsafeComponentWillRecieveProps, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
7380 var hasMutatedProps = instance.props !== workInProgress.pendingProps;
7381 warning_1(instance.props === undefined || !hasMutatedProps, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
7382 var noInstanceDefaultProps = !instance.defaultProps;
7383 warning_1(noInstanceDefaultProps, '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);
7384 }
7385
7386 var state = instance.state;
7387 if (state && (typeof state !== 'object' || isArray(state))) {
7388 warning_1(false, '%s.state: must be set to an object or null', getComponentName(workInProgress));
7389 }
7390 if (typeof instance.getChildContext === 'function') {
7391 warning_1(typeof type.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', getComponentName(workInProgress));
7392 }
7393 }
7394
7395 function resetInputPointers(workInProgress, instance) {
7396 instance.props = workInProgress.memoizedProps;
7397 instance.state = workInProgress.memoizedState;
7398 }
7399
7400 function adoptClassInstance(workInProgress, instance) {
7401 instance.updater = updater;
7402 workInProgress.stateNode = instance;
7403 // The instance needs access to the fiber so that it can schedule updates
7404 set(instance, workInProgress);
7405 {
7406 instance._reactInternalInstance = fakeInternalInstance;
7407 }
7408 }
7409
7410 function constructClassInstance(workInProgress, props) {
7411 var ctor = workInProgress.type;
7412 var unmaskedContext = getUnmaskedContext(workInProgress);
7413 var needsContext = isContextConsumer(workInProgress);
7414 var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject_1;
7415
7416 // Instantiate twice to help detect side-effects.
7417 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7418 new ctor(props, context); // eslint-disable-line no-new
7419 }
7420
7421 var instance = new ctor(props, context);
7422 var state = instance.state !== null && instance.state !== undefined ? instance.state : null;
7423 adoptClassInstance(workInProgress, instance);
7424
7425 {
7426 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
7427 var componentName = getComponentName(workInProgress) || 'Unknown';
7428 if (!didWarnAboutUninitializedState[componentName]) {
7429 warning_1(false, '%s: Did not properly initialize state during construction. ' + 'Expected state to be an object, but it was %s.', componentName, instance.state === null ? 'null' : 'undefined');
7430 didWarnAboutUninitializedState[componentName] = true;
7431 }
7432 }
7433 }
7434
7435 workInProgress.memoizedState = state;
7436
7437 var partialState = callGetDerivedStateFromProps(workInProgress, instance, props);
7438
7439 if (partialState !== null && partialState !== undefined) {
7440 // Render-phase updates (like this) should not be added to the update queue,
7441 // So that multiple render passes do not enqueue multiple updates.
7442 // Instead, just synchronously merge the returned state into the instance.
7443 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
7444 }
7445
7446 // Cache unmasked context so we can avoid recreating masked context unless necessary.
7447 // ReactFiberContext usually updates this cache but can't for newly-created instances.
7448 if (needsContext) {
7449 cacheContext(workInProgress, unmaskedContext, context);
7450 }
7451
7452 return instance;
7453 }
7454
7455 function callComponentWillMount(workInProgress, instance) {
7456 startPhaseTimer(workInProgress, 'componentWillMount');
7457 var oldState = instance.state;
7458
7459 if (typeof instance.componentWillMount === 'function') {
7460 instance.componentWillMount();
7461 }
7462 if (typeof instance.UNSAFE_componentWillMount === 'function') {
7463 instance.UNSAFE_componentWillMount();
7464 }
7465
7466 stopPhaseTimer();
7467
7468 if (oldState !== instance.state) {
7469 {
7470 warning_1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress));
7471 }
7472 updater.enqueueReplaceState(instance, instance.state, null);
7473 }
7474 }
7475
7476 function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) {
7477 var oldState = instance.state;
7478 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7479 if (typeof instance.componentWillReceiveProps === 'function') {
7480 instance.componentWillReceiveProps(newProps, newContext);
7481 }
7482 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
7483 instance.UNSAFE_componentWillReceiveProps(newProps, newContext);
7484 }
7485 stopPhaseTimer();
7486
7487 if (instance.state !== oldState) {
7488 {
7489 var componentName = getComponentName(workInProgress) || 'Component';
7490 if (!didWarnAboutStateAssignmentForComponent[componentName]) {
7491 warning_1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
7492 didWarnAboutStateAssignmentForComponent[componentName] = true;
7493 }
7494 }
7495 updater.enqueueReplaceState(instance, instance.state, null);
7496 }
7497 }
7498
7499 function callGetDerivedStateFromProps(workInProgress, instance, props) {
7500 var type = workInProgress.type;
7501
7502
7503 if (typeof type.getDerivedStateFromProps === 'function') {
7504 {
7505 // Don't warn about react-lifecycles-compat polyfilled components
7506 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
7507 var componentName = getComponentName(workInProgress) || 'Unknown';
7508 if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) {
7509 warning_1(false, '%s: Defines both componentWillReceiveProps() and static ' + 'getDerivedStateFromProps() methods. We recommend using ' + 'only getDerivedStateFromProps().', componentName);
7510 didWarnAboutWillReceivePropsAndDerivedState[componentName] = true;
7511 }
7512 }
7513 }
7514
7515 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7516 // Invoke method an extra time to help detect side-effects.
7517 type.getDerivedStateFromProps.call(null, props, workInProgress.memoizedState);
7518 }
7519
7520 var partialState = type.getDerivedStateFromProps.call(null, props, workInProgress.memoizedState);
7521
7522 {
7523 if (partialState === undefined) {
7524 var _componentName = getComponentName(workInProgress) || 'Unknown';
7525 if (!didWarnAboutUndefinedDerivedState[_componentName]) {
7526 warning_1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', _componentName);
7527 didWarnAboutUndefinedDerivedState[_componentName] = _componentName;
7528 }
7529 }
7530 }
7531
7532 return partialState;
7533 }
7534 }
7535
7536 // Invokes the mount life-cycles on a previously never rendered instance.
7537 function mountClassInstance(workInProgress, renderExpirationTime) {
7538 var ctor = workInProgress.type;
7539 var current = workInProgress.alternate;
7540
7541 {
7542 checkClassInstance(workInProgress);
7543 }
7544
7545 var instance = workInProgress.stateNode;
7546 var props = workInProgress.pendingProps;
7547 var unmaskedContext = getUnmaskedContext(workInProgress);
7548
7549 instance.props = props;
7550 instance.state = workInProgress.memoizedState;
7551 instance.refs = emptyObject_1;
7552 instance.context = getMaskedContext(workInProgress, unmaskedContext);
7553
7554 {
7555 if (workInProgress.mode & StrictMode) {
7556 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
7557 }
7558
7559 if (warnAboutDeprecatedLifecycles) {
7560 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
7561 }
7562 }
7563
7564 // In order to support react-lifecycles-compat polyfilled components,
7565 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7566 if ((typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function') && typeof ctor.getDerivedStateFromProps !== 'function') {
7567 callComponentWillMount(workInProgress, instance);
7568 // If we had additional state updates during this life-cycle, let's
7569 // process them now.
7570 var updateQueue = workInProgress.updateQueue;
7571 if (updateQueue !== null) {
7572 instance.state = processUpdateQueue(current, workInProgress, updateQueue, instance, props, renderExpirationTime);
7573 }
7574 }
7575 if (typeof instance.componentDidMount === 'function') {
7576 workInProgress.effectTag |= Update;
7577 }
7578 }
7579
7580 function resumeMountClassInstance(workInProgress, renderExpirationTime) {
7581 var ctor = workInProgress.type;
7582 var instance = workInProgress.stateNode;
7583 resetInputPointers(workInProgress, instance);
7584
7585 var oldProps = workInProgress.memoizedProps;
7586 var newProps = workInProgress.pendingProps;
7587 var oldContext = instance.context;
7588 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7589 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7590
7591 // Note: During these life-cycles, instance.props/instance.state are what
7592 // ever the previously attempted to render - not the "current". However,
7593 // during componentDidUpdate we pass the "current" props.
7594
7595 // In order to support react-lifecycles-compat polyfilled components,
7596 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7597 if ((typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function') && typeof ctor.getDerivedStateFromProps !== 'function') {
7598 if (oldProps !== newProps || oldContext !== newContext) {
7599 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7600 }
7601 }
7602
7603 var derivedStateFromProps = void 0;
7604 if (oldProps !== newProps) {
7605 derivedStateFromProps = callGetDerivedStateFromProps(workInProgress, instance, newProps);
7606 }
7607
7608 // Compute the next state using the memoized state and the update queue.
7609 var oldState = workInProgress.memoizedState;
7610 // TODO: Previous state can be null.
7611 var newState = void 0;
7612 var derivedStateFromCatch = void 0;
7613 if (workInProgress.updateQueue !== null) {
7614 newState = processUpdateQueue(null, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7615
7616 var updateQueue = workInProgress.updateQueue;
7617 if (updateQueue !== null && updateQueue.capturedValues !== null && enableGetDerivedStateFromCatch && typeof ctor.getDerivedStateFromCatch === 'function') {
7618 var capturedValues = updateQueue.capturedValues;
7619 // Don't remove these from the update queue yet. We need them in
7620 // finishClassComponent. Do the reset there.
7621 // TODO: This is awkward. Refactor class components.
7622 // updateQueue.capturedValues = null;
7623 derivedStateFromCatch = callGetDerivedStateFromCatch(ctor, capturedValues);
7624 }
7625 } else {
7626 newState = oldState;
7627 }
7628
7629 if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) {
7630 // Render-phase updates (like this) should not be added to the update queue,
7631 // So that multiple render passes do not enqueue multiple updates.
7632 // Instead, just synchronously merge the returned state into the instance.
7633 newState = newState === null || newState === undefined ? derivedStateFromProps : _assign({}, newState, derivedStateFromProps);
7634 }
7635 if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) {
7636 // Render-phase updates (like this) should not be added to the update queue,
7637 // So that multiple render passes do not enqueue multiple updates.
7638 // Instead, just synchronously merge the returned state into the instance.
7639 newState = newState === null || newState === undefined ? derivedStateFromCatch : _assign({}, newState, derivedStateFromCatch);
7640 }
7641
7642 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7643 // If an update was already in progress, we should schedule an Update
7644 // effect even though we're bailing out, so that cWU/cDU are called.
7645 if (typeof instance.componentDidMount === 'function') {
7646 workInProgress.effectTag |= Update;
7647 }
7648 return false;
7649 }
7650
7651 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7652
7653 if (shouldUpdate) {
7654 // In order to support react-lifecycles-compat polyfilled components,
7655 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7656 if ((typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function') && typeof ctor.getDerivedStateFromProps !== 'function') {
7657 startPhaseTimer(workInProgress, 'componentWillUpdate');
7658 if (typeof instance.componentWillUpdate === 'function') {
7659 instance.componentWillUpdate(newProps, newState, newContext);
7660 }
7661 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
7662 instance.UNSAFE_componentWillUpdate(newProps, newState, newContext);
7663 }
7664 stopPhaseTimer();
7665 }
7666 if (typeof instance.componentDidUpdate === 'function') {
7667 workInProgress.effectTag |= Update;
7668 }
7669 } else {
7670 // If an update was already in progress, we should schedule an Update
7671 // effect even though we're bailing out, so that cWU/cDU are called.
7672 if (typeof instance.componentDidMount === 'function') {
7673 workInProgress.effectTag |= Update;
7674 }
7675
7676 // If shouldComponentUpdate returned false, we should still update the
7677 // memoized props/state to indicate that this work can be reused.
7678 memoizeProps(workInProgress, newProps);
7679 memoizeState(workInProgress, newState);
7680 }
7681
7682 // Update the existing instance's state, props, and context pointers even
7683 // if shouldComponentUpdate returns false.
7684 instance.props = newProps;
7685 instance.state = newState;
7686 instance.context = newContext;
7687
7688 return shouldUpdate;
7689 }
7690
7691 // Invokes the update life-cycles and returns false if it shouldn't rerender.
7692 function updateClassInstance(current, workInProgress, renderExpirationTime) {
7693 var ctor = workInProgress.type;
7694 var instance = workInProgress.stateNode;
7695 resetInputPointers(workInProgress, instance);
7696
7697 var oldProps = workInProgress.memoizedProps;
7698 var newProps = workInProgress.pendingProps;
7699 var oldContext = instance.context;
7700 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7701 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7702
7703 // Note: During these life-cycles, instance.props/instance.state are what
7704 // ever the previously attempted to render - not the "current". However,
7705 // during componentDidUpdate we pass the "current" props.
7706
7707 // In order to support react-lifecycles-compat polyfilled components,
7708 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7709 if ((typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function') && typeof ctor.getDerivedStateFromProps !== 'function') {
7710 if (oldProps !== newProps || oldContext !== newContext) {
7711 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7712 }
7713 }
7714
7715 var derivedStateFromProps = void 0;
7716 if (oldProps !== newProps) {
7717 derivedStateFromProps = callGetDerivedStateFromProps(workInProgress, instance, newProps);
7718 }
7719
7720 // Compute the next state using the memoized state and the update queue.
7721 var oldState = workInProgress.memoizedState;
7722 // TODO: Previous state can be null.
7723 var newState = void 0;
7724 var derivedStateFromCatch = void 0;
7725 if (workInProgress.updateQueue !== null) {
7726 newState = processUpdateQueue(current, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7727
7728 var updateQueue = workInProgress.updateQueue;
7729 if (updateQueue !== null && updateQueue.capturedValues !== null && enableGetDerivedStateFromCatch && typeof ctor.getDerivedStateFromCatch === 'function') {
7730 var capturedValues = updateQueue.capturedValues;
7731 // Don't remove these from the update queue yet. We need them in
7732 // finishClassComponent. Do the reset there.
7733 // TODO: This is awkward. Refactor class components.
7734 // updateQueue.capturedValues = null;
7735 derivedStateFromCatch = callGetDerivedStateFromCatch(ctor, capturedValues);
7736 }
7737 } else {
7738 newState = oldState;
7739 }
7740
7741 if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) {
7742 // Render-phase updates (like this) should not be added to the update queue,
7743 // So that multiple render passes do not enqueue multiple updates.
7744 // Instead, just synchronously merge the returned state into the instance.
7745 newState = newState === null || newState === undefined ? derivedStateFromProps : _assign({}, newState, derivedStateFromProps);
7746 }
7747 if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) {
7748 // Render-phase updates (like this) should not be added to the update queue,
7749 // So that multiple render passes do not enqueue multiple updates.
7750 // Instead, just synchronously merge the returned state into the instance.
7751 newState = newState === null || newState === undefined ? derivedStateFromCatch : _assign({}, newState, derivedStateFromCatch);
7752 }
7753
7754 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7755 // If an update was already in progress, we should schedule an Update
7756 // effect even though we're bailing out, so that cWU/cDU are called.
7757 if (typeof instance.componentDidUpdate === 'function') {
7758 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7759 workInProgress.effectTag |= Update;
7760 }
7761 }
7762 return false;
7763 }
7764
7765 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7766
7767 if (shouldUpdate) {
7768 // In order to support react-lifecycles-compat polyfilled components,
7769 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7770 if ((typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function') && typeof ctor.getDerivedStateFromProps !== 'function') {
7771 startPhaseTimer(workInProgress, 'componentWillUpdate');
7772 if (typeof instance.componentWillUpdate === 'function') {
7773 instance.componentWillUpdate(newProps, newState, newContext);
7774 }
7775 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
7776 instance.UNSAFE_componentWillUpdate(newProps, newState, newContext);
7777 }
7778 stopPhaseTimer();
7779 }
7780 if (typeof instance.componentDidUpdate === 'function') {
7781 workInProgress.effectTag |= Update;
7782 }
7783 } else {
7784 // If an update was already in progress, we should schedule an Update
7785 // effect even though we're bailing out, so that cWU/cDU are called.
7786 if (typeof instance.componentDidUpdate === 'function') {
7787 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7788 workInProgress.effectTag |= Update;
7789 }
7790 }
7791
7792 // If shouldComponentUpdate returned false, we should still update the
7793 // memoized props/state to indicate that this work can be reused.
7794 memoizeProps(workInProgress, newProps);
7795 memoizeState(workInProgress, newState);
7796 }
7797
7798 // Update the existing instance's state, props, and context pointers even
7799 // if shouldComponentUpdate returns false.
7800 instance.props = newProps;
7801 instance.state = newState;
7802 instance.context = newContext;
7803
7804 return shouldUpdate;
7805 }
7806
7807 return {
7808 adoptClassInstance: adoptClassInstance,
7809 callGetDerivedStateFromProps: callGetDerivedStateFromProps,
7810 constructClassInstance: constructClassInstance,
7811 mountClassInstance: mountClassInstance,
7812 resumeMountClassInstance: resumeMountClassInstance,
7813 updateClassInstance: updateClassInstance
7814 };
7815};
7816
7817var getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
7818
7819
7820var didWarnAboutMaps = void 0;
7821var didWarnAboutStringRefInStrictMode = void 0;
7822var ownerHasKeyUseWarning = void 0;
7823var ownerHasFunctionTypeWarning = void 0;
7824var warnForMissingKey = function (child) {};
7825
7826{
7827 didWarnAboutMaps = false;
7828 didWarnAboutStringRefInStrictMode = {};
7829
7830 /**
7831 * Warn if there's no key explicitly set on dynamic arrays of children or
7832 * object keys are not valid. This allows us to keep track of children between
7833 * updates.
7834 */
7835 ownerHasKeyUseWarning = {};
7836 ownerHasFunctionTypeWarning = {};
7837
7838 warnForMissingKey = function (child) {
7839 if (child === null || typeof child !== 'object') {
7840 return;
7841 }
7842 if (!child._store || child._store.validated || child.key != null) {
7843 return;
7844 }
7845 !(typeof child._store === 'object') ? invariant_1(false, 'React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.') : void 0;
7846 child._store.validated = true;
7847
7848 var currentComponentErrorInfo = 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + (getCurrentFiberStackAddendum$2() || '');
7849 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
7850 return;
7851 }
7852 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
7853
7854 warning_1(false, 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.%s', getCurrentFiberStackAddendum$2());
7855 };
7856}
7857
7858var isArray$1 = Array.isArray;
7859
7860function coerceRef(returnFiber, current, element) {
7861 var mixedRef = element.ref;
7862 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
7863 {
7864 if (returnFiber.mode & StrictMode) {
7865 var componentName = getComponentName(returnFiber) || 'Component';
7866 if (!didWarnAboutStringRefInStrictMode[componentName]) {
7867 warning_1(false, '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 createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackAddendumByWorkInProgressFiber(returnFiber));
7868 didWarnAboutStringRefInStrictMode[componentName] = true;
7869 }
7870 }
7871 }
7872
7873 if (element._owner) {
7874 var owner = element._owner;
7875 var inst = void 0;
7876 if (owner) {
7877 var ownerFiber = owner;
7878 !(ownerFiber.tag === ClassComponent) ? invariant_1(false, 'Stateless function components cannot have refs.') : void 0;
7879 inst = ownerFiber.stateNode;
7880 }
7881 !inst ? invariant_1(false, 'Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.', mixedRef) : void 0;
7882 var stringRef = '' + mixedRef;
7883 // Check if previous string ref matches new string ref
7884 if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
7885 return current.ref;
7886 }
7887 var ref = function (value) {
7888 var refs = inst.refs === emptyObject_1 ? inst.refs = {} : inst.refs;
7889 if (value === null) {
7890 delete refs[stringRef];
7891 } else {
7892 refs[stringRef] = value;
7893 }
7894 };
7895 ref._stringRef = stringRef;
7896 return ref;
7897 } else {
7898 !(typeof mixedRef === 'string') ? invariant_1(false, 'Expected ref to be a function or a string.') : void 0;
7899 !element._owner ? invariant_1(false, 'Element ref was specified as a string (%s) but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a functional 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://fb.me/react-refs-must-have-owner for more information.', mixedRef) : void 0;
7900 }
7901 }
7902 return mixedRef;
7903}
7904
7905function throwOnInvalidObjectType(returnFiber, newChild) {
7906 if (returnFiber.type !== 'textarea') {
7907 var addendum = '';
7908 {
7909 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$2() || '');
7910 }
7911 invariant_1(false, 'Objects are not valid as a React child (found: %s).%s', Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild, addendum);
7912 }
7913}
7914
7915function warnOnFunctionType() {
7916 var currentComponentErrorInfo = '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.' + (getCurrentFiberStackAddendum$2() || '');
7917
7918 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
7919 return;
7920 }
7921 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
7922
7923 warning_1(false, '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.%s', getCurrentFiberStackAddendum$2() || '');
7924}
7925
7926// This wrapper function exists because I expect to clone the code in each path
7927// to be able to optimize each path individually by branching early. This needs
7928// a compiler or we can do it manually. Helpers that don't need this branching
7929// live outside of this function.
7930function ChildReconciler(shouldTrackSideEffects) {
7931 function deleteChild(returnFiber, childToDelete) {
7932 if (!shouldTrackSideEffects) {
7933 // Noop.
7934 return;
7935 }
7936 // Deletions are added in reversed order so we add it to the front.
7937 // At this point, the return fiber's effect list is empty except for
7938 // deletions, so we can just append the deletion to the list. The remaining
7939 // effects aren't added until the complete phase. Once we implement
7940 // resuming, this may not be true.
7941 var last = returnFiber.lastEffect;
7942 if (last !== null) {
7943 last.nextEffect = childToDelete;
7944 returnFiber.lastEffect = childToDelete;
7945 } else {
7946 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7947 }
7948 childToDelete.nextEffect = null;
7949 childToDelete.effectTag = Deletion;
7950 }
7951
7952 function deleteRemainingChildren(returnFiber, currentFirstChild) {
7953 if (!shouldTrackSideEffects) {
7954 // Noop.
7955 return null;
7956 }
7957
7958 // TODO: For the shouldClone case, this could be micro-optimized a bit by
7959 // assuming that after the first child we've already added everything.
7960 var childToDelete = currentFirstChild;
7961 while (childToDelete !== null) {
7962 deleteChild(returnFiber, childToDelete);
7963 childToDelete = childToDelete.sibling;
7964 }
7965 return null;
7966 }
7967
7968 function mapRemainingChildren(returnFiber, currentFirstChild) {
7969 // Add the remaining children to a temporary map so that we can find them by
7970 // keys quickly. Implicit (null) keys get added to this set with their index
7971 var existingChildren = new Map();
7972
7973 var existingChild = currentFirstChild;
7974 while (existingChild !== null) {
7975 if (existingChild.key !== null) {
7976 existingChildren.set(existingChild.key, existingChild);
7977 } else {
7978 existingChildren.set(existingChild.index, existingChild);
7979 }
7980 existingChild = existingChild.sibling;
7981 }
7982 return existingChildren;
7983 }
7984
7985 function useFiber(fiber, pendingProps, expirationTime) {
7986 // We currently set sibling to null and index to 0 here because it is easy
7987 // to forget to do before returning it. E.g. for the single child case.
7988 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
7989 clone.index = 0;
7990 clone.sibling = null;
7991 return clone;
7992 }
7993
7994 function placeChild(newFiber, lastPlacedIndex, newIndex) {
7995 newFiber.index = newIndex;
7996 if (!shouldTrackSideEffects) {
7997 // Noop.
7998 return lastPlacedIndex;
7999 }
8000 var current = newFiber.alternate;
8001 if (current !== null) {
8002 var oldIndex = current.index;
8003 if (oldIndex < lastPlacedIndex) {
8004 // This is a move.
8005 newFiber.effectTag = Placement;
8006 return lastPlacedIndex;
8007 } else {
8008 // This item can stay in place.
8009 return oldIndex;
8010 }
8011 } else {
8012 // This is an insertion.
8013 newFiber.effectTag = Placement;
8014 return lastPlacedIndex;
8015 }
8016 }
8017
8018 function placeSingleChild(newFiber) {
8019 // This is simpler for the single child case. We only need to do a
8020 // placement for inserting new children.
8021 if (shouldTrackSideEffects && newFiber.alternate === null) {
8022 newFiber.effectTag = Placement;
8023 }
8024 return newFiber;
8025 }
8026
8027 function updateTextNode(returnFiber, current, textContent, expirationTime) {
8028 if (current === null || current.tag !== HostText) {
8029 // Insert
8030 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
8031 created['return'] = returnFiber;
8032 return created;
8033 } else {
8034 // Update
8035 var existing = useFiber(current, textContent, expirationTime);
8036 existing['return'] = returnFiber;
8037 return existing;
8038 }
8039 }
8040
8041 function updateElement(returnFiber, current, element, expirationTime) {
8042 if (current !== null && current.type === element.type) {
8043 // Move based on index
8044 var existing = useFiber(current, element.props, expirationTime);
8045 existing.ref = coerceRef(returnFiber, current, element);
8046 existing['return'] = returnFiber;
8047 {
8048 existing._debugSource = element._source;
8049 existing._debugOwner = element._owner;
8050 }
8051 return existing;
8052 } else {
8053 // Insert
8054 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
8055 created.ref = coerceRef(returnFiber, current, element);
8056 created['return'] = returnFiber;
8057 return created;
8058 }
8059 }
8060
8061 function updatePortal(returnFiber, current, portal, expirationTime) {
8062 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
8063 // Insert
8064 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
8065 created['return'] = returnFiber;
8066 return created;
8067 } else {
8068 // Update
8069 var existing = useFiber(current, portal.children || [], expirationTime);
8070 existing['return'] = returnFiber;
8071 return existing;
8072 }
8073 }
8074
8075 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
8076 if (current === null || current.tag !== Fragment) {
8077 // Insert
8078 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
8079 created['return'] = returnFiber;
8080 return created;
8081 } else {
8082 // Update
8083 var existing = useFiber(current, fragment, expirationTime);
8084 existing['return'] = returnFiber;
8085 return existing;
8086 }
8087 }
8088
8089 function createChild(returnFiber, newChild, expirationTime) {
8090 if (typeof newChild === 'string' || typeof newChild === 'number') {
8091 // Text nodes don't have keys. If the previous node is implicitly keyed
8092 // we can continue to replace it without aborting even if it is not a text
8093 // node.
8094 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
8095 created['return'] = returnFiber;
8096 return created;
8097 }
8098
8099 if (typeof newChild === 'object' && newChild !== null) {
8100 switch (newChild.$$typeof) {
8101 case REACT_ELEMENT_TYPE:
8102 {
8103 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
8104 _created.ref = coerceRef(returnFiber, null, newChild);
8105 _created['return'] = returnFiber;
8106 return _created;
8107 }
8108 case REACT_PORTAL_TYPE:
8109 {
8110 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
8111 _created2['return'] = returnFiber;
8112 return _created2;
8113 }
8114 }
8115
8116 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8117 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
8118 _created3['return'] = returnFiber;
8119 return _created3;
8120 }
8121
8122 throwOnInvalidObjectType(returnFiber, newChild);
8123 }
8124
8125 {
8126 if (typeof newChild === 'function') {
8127 warnOnFunctionType();
8128 }
8129 }
8130
8131 return null;
8132 }
8133
8134 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
8135 // Update the fiber if the keys match, otherwise return null.
8136
8137 var key = oldFiber !== null ? oldFiber.key : null;
8138
8139 if (typeof newChild === 'string' || typeof newChild === 'number') {
8140 // Text nodes don't have keys. If the previous node is implicitly keyed
8141 // we can continue to replace it without aborting even if it is not a text
8142 // node.
8143 if (key !== null) {
8144 return null;
8145 }
8146 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
8147 }
8148
8149 if (typeof newChild === 'object' && newChild !== null) {
8150 switch (newChild.$$typeof) {
8151 case REACT_ELEMENT_TYPE:
8152 {
8153 if (newChild.key === key) {
8154 if (newChild.type === REACT_FRAGMENT_TYPE) {
8155 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
8156 }
8157 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
8158 } else {
8159 return null;
8160 }
8161 }
8162 case REACT_PORTAL_TYPE:
8163 {
8164 if (newChild.key === key) {
8165 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
8166 } else {
8167 return null;
8168 }
8169 }
8170 }
8171
8172 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8173 if (key !== null) {
8174 return null;
8175 }
8176
8177 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
8178 }
8179
8180 throwOnInvalidObjectType(returnFiber, newChild);
8181 }
8182
8183 {
8184 if (typeof newChild === 'function') {
8185 warnOnFunctionType();
8186 }
8187 }
8188
8189 return null;
8190 }
8191
8192 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
8193 if (typeof newChild === 'string' || typeof newChild === 'number') {
8194 // Text nodes don't have keys, so we neither have to check the old nor
8195 // new node for the key. If both are text nodes, they match.
8196 var matchedFiber = existingChildren.get(newIdx) || null;
8197 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
8198 }
8199
8200 if (typeof newChild === 'object' && newChild !== null) {
8201 switch (newChild.$$typeof) {
8202 case REACT_ELEMENT_TYPE:
8203 {
8204 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
8205 if (newChild.type === REACT_FRAGMENT_TYPE) {
8206 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
8207 }
8208 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
8209 }
8210 case REACT_PORTAL_TYPE:
8211 {
8212 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
8213 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
8214 }
8215 }
8216
8217 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8218 var _matchedFiber3 = existingChildren.get(newIdx) || null;
8219 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
8220 }
8221
8222 throwOnInvalidObjectType(returnFiber, newChild);
8223 }
8224
8225 {
8226 if (typeof newChild === 'function') {
8227 warnOnFunctionType();
8228 }
8229 }
8230
8231 return null;
8232 }
8233
8234 /**
8235 * Warns if there is a duplicate or missing key
8236 */
8237 function warnOnInvalidKey(child, knownKeys) {
8238 {
8239 if (typeof child !== 'object' || child === null) {
8240 return knownKeys;
8241 }
8242 switch (child.$$typeof) {
8243 case REACT_ELEMENT_TYPE:
8244 case REACT_PORTAL_TYPE:
8245 warnForMissingKey(child);
8246 var key = child.key;
8247 if (typeof key !== 'string') {
8248 break;
8249 }
8250 if (knownKeys === null) {
8251 knownKeys = new Set();
8252 knownKeys.add(key);
8253 break;
8254 }
8255 if (!knownKeys.has(key)) {
8256 knownKeys.add(key);
8257 break;
8258 }
8259 warning_1(false, '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.%s', key, getCurrentFiberStackAddendum$2());
8260 break;
8261 default:
8262 break;
8263 }
8264 }
8265 return knownKeys;
8266 }
8267
8268 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
8269 // This algorithm can't optimize by searching from boths ends since we
8270 // don't have backpointers on fibers. I'm trying to see how far we can get
8271 // with that model. If it ends up not being worth the tradeoffs, we can
8272 // add it later.
8273
8274 // Even with a two ended optimization, we'd want to optimize for the case
8275 // where there are few changes and brute force the comparison instead of
8276 // going for the Map. It'd like to explore hitting that path first in
8277 // forward-only mode and only go for the Map once we notice that we need
8278 // lots of look ahead. This doesn't handle reversal as well as two ended
8279 // search but that's unusual. Besides, for the two ended optimization to
8280 // work on Iterables, we'd need to copy the whole set.
8281
8282 // In this first iteration, we'll just live with hitting the bad case
8283 // (adding everything to a Map) in for every insert/move.
8284
8285 // If you change this code, also update reconcileChildrenIterator() which
8286 // uses the same algorithm.
8287
8288 {
8289 // First, validate keys.
8290 var knownKeys = null;
8291 for (var i = 0; i < newChildren.length; i++) {
8292 var child = newChildren[i];
8293 knownKeys = warnOnInvalidKey(child, knownKeys);
8294 }
8295 }
8296
8297 var resultingFirstChild = null;
8298 var previousNewFiber = null;
8299
8300 var oldFiber = currentFirstChild;
8301 var lastPlacedIndex = 0;
8302 var newIdx = 0;
8303 var nextOldFiber = null;
8304 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
8305 if (oldFiber.index > newIdx) {
8306 nextOldFiber = oldFiber;
8307 oldFiber = null;
8308 } else {
8309 nextOldFiber = oldFiber.sibling;
8310 }
8311 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
8312 if (newFiber === null) {
8313 // TODO: This breaks on empty slots like null children. That's
8314 // unfortunate because it triggers the slow path all the time. We need
8315 // a better way to communicate whether this was a miss or null,
8316 // boolean, undefined, etc.
8317 if (oldFiber === null) {
8318 oldFiber = nextOldFiber;
8319 }
8320 break;
8321 }
8322 if (shouldTrackSideEffects) {
8323 if (oldFiber && newFiber.alternate === null) {
8324 // We matched the slot, but we didn't reuse the existing fiber, so we
8325 // need to delete the existing child.
8326 deleteChild(returnFiber, oldFiber);
8327 }
8328 }
8329 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8330 if (previousNewFiber === null) {
8331 // TODO: Move out of the loop. This only happens for the first run.
8332 resultingFirstChild = newFiber;
8333 } else {
8334 // TODO: Defer siblings if we're not at the right index for this slot.
8335 // I.e. if we had null values before, then we want to defer this
8336 // for each null value. However, we also don't want to call updateSlot
8337 // with the previous one.
8338 previousNewFiber.sibling = newFiber;
8339 }
8340 previousNewFiber = newFiber;
8341 oldFiber = nextOldFiber;
8342 }
8343
8344 if (newIdx === newChildren.length) {
8345 // We've reached the end of the new children. We can delete the rest.
8346 deleteRemainingChildren(returnFiber, oldFiber);
8347 return resultingFirstChild;
8348 }
8349
8350 if (oldFiber === null) {
8351 // If we don't have any more existing children we can choose a fast path
8352 // since the rest will all be insertions.
8353 for (; newIdx < newChildren.length; newIdx++) {
8354 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
8355 if (!_newFiber) {
8356 continue;
8357 }
8358 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
8359 if (previousNewFiber === null) {
8360 // TODO: Move out of the loop. This only happens for the first run.
8361 resultingFirstChild = _newFiber;
8362 } else {
8363 previousNewFiber.sibling = _newFiber;
8364 }
8365 previousNewFiber = _newFiber;
8366 }
8367 return resultingFirstChild;
8368 }
8369
8370 // Add all children to a key map for quick lookups.
8371 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8372
8373 // Keep scanning and use the map to restore deleted items as moves.
8374 for (; newIdx < newChildren.length; newIdx++) {
8375 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
8376 if (_newFiber2) {
8377 if (shouldTrackSideEffects) {
8378 if (_newFiber2.alternate !== null) {
8379 // The new fiber is a work in progress, but if there exists a
8380 // current, that means that we reused the fiber. We need to delete
8381 // it from the child list so that we don't add it to the deletion
8382 // list.
8383 existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key);
8384 }
8385 }
8386 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
8387 if (previousNewFiber === null) {
8388 resultingFirstChild = _newFiber2;
8389 } else {
8390 previousNewFiber.sibling = _newFiber2;
8391 }
8392 previousNewFiber = _newFiber2;
8393 }
8394 }
8395
8396 if (shouldTrackSideEffects) {
8397 // Any existing children that weren't consumed above were deleted. We need
8398 // to add them to the deletion list.
8399 existingChildren.forEach(function (child) {
8400 return deleteChild(returnFiber, child);
8401 });
8402 }
8403
8404 return resultingFirstChild;
8405 }
8406
8407 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
8408 // This is the same implementation as reconcileChildrenArray(),
8409 // but using the iterator instead.
8410
8411 var iteratorFn = getIteratorFn(newChildrenIterable);
8412 !(typeof iteratorFn === 'function') ? invariant_1(false, 'An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.') : void 0;
8413
8414 {
8415 // Warn about using Maps as children
8416 if (typeof newChildrenIterable.entries === 'function') {
8417 var possibleMap = newChildrenIterable;
8418 if (possibleMap.entries === iteratorFn) {
8419 warning_1(didWarnAboutMaps, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.%s', getCurrentFiberStackAddendum$2());
8420 didWarnAboutMaps = true;
8421 }
8422 }
8423
8424 // First, validate keys.
8425 // We'll get a different iterator later for the main pass.
8426 var _newChildren = iteratorFn.call(newChildrenIterable);
8427 if (_newChildren) {
8428 var knownKeys = null;
8429 var _step = _newChildren.next();
8430 for (; !_step.done; _step = _newChildren.next()) {
8431 var child = _step.value;
8432 knownKeys = warnOnInvalidKey(child, knownKeys);
8433 }
8434 }
8435 }
8436
8437 var newChildren = iteratorFn.call(newChildrenIterable);
8438 !(newChildren != null) ? invariant_1(false, 'An iterable object provided no iterator.') : void 0;
8439
8440 var resultingFirstChild = null;
8441 var previousNewFiber = null;
8442
8443 var oldFiber = currentFirstChild;
8444 var lastPlacedIndex = 0;
8445 var newIdx = 0;
8446 var nextOldFiber = null;
8447
8448 var step = newChildren.next();
8449 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
8450 if (oldFiber.index > newIdx) {
8451 nextOldFiber = oldFiber;
8452 oldFiber = null;
8453 } else {
8454 nextOldFiber = oldFiber.sibling;
8455 }
8456 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
8457 if (newFiber === null) {
8458 // TODO: This breaks on empty slots like null children. That's
8459 // unfortunate because it triggers the slow path all the time. We need
8460 // a better way to communicate whether this was a miss or null,
8461 // boolean, undefined, etc.
8462 if (!oldFiber) {
8463 oldFiber = nextOldFiber;
8464 }
8465 break;
8466 }
8467 if (shouldTrackSideEffects) {
8468 if (oldFiber && newFiber.alternate === null) {
8469 // We matched the slot, but we didn't reuse the existing fiber, so we
8470 // need to delete the existing child.
8471 deleteChild(returnFiber, oldFiber);
8472 }
8473 }
8474 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8475 if (previousNewFiber === null) {
8476 // TODO: Move out of the loop. This only happens for the first run.
8477 resultingFirstChild = newFiber;
8478 } else {
8479 // TODO: Defer siblings if we're not at the right index for this slot.
8480 // I.e. if we had null values before, then we want to defer this
8481 // for each null value. However, we also don't want to call updateSlot
8482 // with the previous one.
8483 previousNewFiber.sibling = newFiber;
8484 }
8485 previousNewFiber = newFiber;
8486 oldFiber = nextOldFiber;
8487 }
8488
8489 if (step.done) {
8490 // We've reached the end of the new children. We can delete the rest.
8491 deleteRemainingChildren(returnFiber, oldFiber);
8492 return resultingFirstChild;
8493 }
8494
8495 if (oldFiber === null) {
8496 // If we don't have any more existing children we can choose a fast path
8497 // since the rest will all be insertions.
8498 for (; !step.done; newIdx++, step = newChildren.next()) {
8499 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
8500 if (_newFiber3 === null) {
8501 continue;
8502 }
8503 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
8504 if (previousNewFiber === null) {
8505 // TODO: Move out of the loop. This only happens for the first run.
8506 resultingFirstChild = _newFiber3;
8507 } else {
8508 previousNewFiber.sibling = _newFiber3;
8509 }
8510 previousNewFiber = _newFiber3;
8511 }
8512 return resultingFirstChild;
8513 }
8514
8515 // Add all children to a key map for quick lookups.
8516 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8517
8518 // Keep scanning and use the map to restore deleted items as moves.
8519 for (; !step.done; newIdx++, step = newChildren.next()) {
8520 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
8521 if (_newFiber4 !== null) {
8522 if (shouldTrackSideEffects) {
8523 if (_newFiber4.alternate !== null) {
8524 // The new fiber is a work in progress, but if there exists a
8525 // current, that means that we reused the fiber. We need to delete
8526 // it from the child list so that we don't add it to the deletion
8527 // list.
8528 existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key);
8529 }
8530 }
8531 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
8532 if (previousNewFiber === null) {
8533 resultingFirstChild = _newFiber4;
8534 } else {
8535 previousNewFiber.sibling = _newFiber4;
8536 }
8537 previousNewFiber = _newFiber4;
8538 }
8539 }
8540
8541 if (shouldTrackSideEffects) {
8542 // Any existing children that weren't consumed above were deleted. We need
8543 // to add them to the deletion list.
8544 existingChildren.forEach(function (child) {
8545 return deleteChild(returnFiber, child);
8546 });
8547 }
8548
8549 return resultingFirstChild;
8550 }
8551
8552 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
8553 // There's no need to check for keys on text nodes since we don't have a
8554 // way to define them.
8555 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
8556 // We already have an existing node so let's just update it and delete
8557 // the rest.
8558 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
8559 var existing = useFiber(currentFirstChild, textContent, expirationTime);
8560 existing['return'] = returnFiber;
8561 return existing;
8562 }
8563 // The existing first child is not a text node so we need to create one
8564 // and delete the existing ones.
8565 deleteRemainingChildren(returnFiber, currentFirstChild);
8566 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
8567 created['return'] = returnFiber;
8568 return created;
8569 }
8570
8571 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
8572 var key = element.key;
8573 var child = currentFirstChild;
8574 while (child !== null) {
8575 // TODO: If key === null and child.key === null, then this only applies to
8576 // the first item in the list.
8577 if (child.key === key) {
8578 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) {
8579 deleteRemainingChildren(returnFiber, child.sibling);
8580 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
8581 existing.ref = coerceRef(returnFiber, child, element);
8582 existing['return'] = returnFiber;
8583 {
8584 existing._debugSource = element._source;
8585 existing._debugOwner = element._owner;
8586 }
8587 return existing;
8588 } else {
8589 deleteRemainingChildren(returnFiber, child);
8590 break;
8591 }
8592 } else {
8593 deleteChild(returnFiber, child);
8594 }
8595 child = child.sibling;
8596 }
8597
8598 if (element.type === REACT_FRAGMENT_TYPE) {
8599 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
8600 created['return'] = returnFiber;
8601 return created;
8602 } else {
8603 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
8604 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
8605 _created4['return'] = returnFiber;
8606 return _created4;
8607 }
8608 }
8609
8610 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
8611 var key = portal.key;
8612 var child = currentFirstChild;
8613 while (child !== null) {
8614 // TODO: If key === null and child.key === null, then this only applies to
8615 // the first item in the list.
8616 if (child.key === key) {
8617 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
8618 deleteRemainingChildren(returnFiber, child.sibling);
8619 var existing = useFiber(child, portal.children || [], expirationTime);
8620 existing['return'] = returnFiber;
8621 return existing;
8622 } else {
8623 deleteRemainingChildren(returnFiber, child);
8624 break;
8625 }
8626 } else {
8627 deleteChild(returnFiber, child);
8628 }
8629 child = child.sibling;
8630 }
8631
8632 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
8633 created['return'] = returnFiber;
8634 return created;
8635 }
8636
8637 // This API will tag the children with the side-effect of the reconciliation
8638 // itself. They will be added to the side-effect list as we pass through the
8639 // children and the parent.
8640 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
8641 // This function is not recursive.
8642 // If the top level item is an array, we treat it as a set of children,
8643 // not as a fragment. Nested arrays on the other hand will be treated as
8644 // fragment nodes. Recursion happens at the normal flow.
8645
8646 // Handle top level unkeyed fragments as if they were arrays.
8647 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
8648 // We treat the ambiguous cases above the same.
8649 if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
8650 newChild = newChild.props.children;
8651 }
8652
8653 // Handle object types
8654 var isObject = typeof newChild === 'object' && newChild !== null;
8655
8656 if (isObject) {
8657 switch (newChild.$$typeof) {
8658 case REACT_ELEMENT_TYPE:
8659 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
8660 case REACT_PORTAL_TYPE:
8661 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
8662 }
8663 }
8664
8665 if (typeof newChild === 'string' || typeof newChild === 'number') {
8666 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
8667 }
8668
8669 if (isArray$1(newChild)) {
8670 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
8671 }
8672
8673 if (getIteratorFn(newChild)) {
8674 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
8675 }
8676
8677 if (isObject) {
8678 throwOnInvalidObjectType(returnFiber, newChild);
8679 }
8680
8681 {
8682 if (typeof newChild === 'function') {
8683 warnOnFunctionType();
8684 }
8685 }
8686 if (typeof newChild === 'undefined') {
8687 // If the new child is undefined, and the return fiber is a composite
8688 // component, throw an error. If Fiber return types are disabled,
8689 // we already threw above.
8690 switch (returnFiber.tag) {
8691 case ClassComponent:
8692 {
8693 {
8694 var instance = returnFiber.stateNode;
8695 if (instance.render._isMockFunction) {
8696 // We allow auto-mocks to proceed as if they're returning null.
8697 break;
8698 }
8699 }
8700 }
8701 // Intentionally fall through to the next case, which handles both
8702 // functions and classes
8703 // eslint-disable-next-lined no-fallthrough
8704 case FunctionalComponent:
8705 {
8706 var Component = returnFiber.type;
8707 invariant_1(false, '%s(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.', Component.displayName || Component.name || 'Component');
8708 }
8709 }
8710 }
8711
8712 // Remaining cases are all treated as empty.
8713 return deleteRemainingChildren(returnFiber, currentFirstChild);
8714 }
8715
8716 return reconcileChildFibers;
8717}
8718
8719var reconcileChildFibers = ChildReconciler(true);
8720var mountChildFibers = ChildReconciler(false);
8721
8722function cloneChildFibers(current, workInProgress) {
8723 !(current === null || workInProgress.child === current.child) ? invariant_1(false, 'Resuming work not yet implemented.') : void 0;
8724
8725 if (workInProgress.child === null) {
8726 return;
8727 }
8728
8729 var currentChild = workInProgress.child;
8730 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8731 workInProgress.child = newChild;
8732
8733 newChild['return'] = workInProgress;
8734 while (currentChild.sibling !== null) {
8735 currentChild = currentChild.sibling;
8736 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8737 newChild['return'] = workInProgress;
8738 }
8739 newChild.sibling = null;
8740}
8741
8742var changedBitsStack = [];
8743var currentValueStack = [];
8744var stack = [];
8745var index$1 = -1;
8746
8747var rendererSigil = void 0;
8748{
8749 // Use this to detect multiple renderers using the same context
8750 rendererSigil = {};
8751}
8752
8753function pushProvider(providerFiber) {
8754 var context = providerFiber.type.context;
8755 index$1 += 1;
8756 changedBitsStack[index$1] = context.changedBits;
8757 currentValueStack[index$1] = context.currentValue;
8758 stack[index$1] = providerFiber;
8759 context.currentValue = providerFiber.pendingProps.value;
8760 context.changedBits = providerFiber.stateNode;
8761
8762 {
8763 warning_1(context._currentRenderer === null || context._currentRenderer === rendererSigil, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
8764 context._currentRenderer = rendererSigil;
8765 }
8766}
8767
8768function popProvider(providerFiber) {
8769 {
8770 warning_1(index$1 > -1 && providerFiber === stack[index$1], 'Unexpected pop.');
8771 }
8772 var changedBits = changedBitsStack[index$1];
8773 var currentValue = currentValueStack[index$1];
8774 changedBitsStack[index$1] = null;
8775 currentValueStack[index$1] = null;
8776 stack[index$1] = null;
8777 index$1 -= 1;
8778 var context = providerFiber.type.context;
8779 context.currentValue = currentValue;
8780 context.changedBits = changedBits;
8781}
8782
8783function resetProviderStack() {
8784 for (var i = index$1; i > -1; i--) {
8785 var providerFiber = stack[i];
8786 var context = providerFiber.type.context;
8787 context.currentValue = context.defaultValue;
8788 context.changedBits = 0;
8789 changedBitsStack[i] = null;
8790 currentValueStack[i] = null;
8791 stack[i] = null;
8792 {
8793 context._currentRenderer = null;
8794 }
8795 }
8796 index$1 = -1;
8797}
8798
8799var didWarnAboutBadClass = void 0;
8800var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0;
8801var didWarnAboutStatelessRefs = void 0;
8802
8803{
8804 didWarnAboutBadClass = {};
8805 didWarnAboutGetDerivedStateOnFunctionalComponent = {};
8806 didWarnAboutStatelessRefs = {};
8807}
8808
8809var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber) {
8810 var shouldSetTextContent = config.shouldSetTextContent,
8811 shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree;
8812 var pushHostContext = hostContext.pushHostContext,
8813 pushHostContainer = hostContext.pushHostContainer;
8814 var enterHydrationState = hydrationContext.enterHydrationState,
8815 resetHydrationState = hydrationContext.resetHydrationState,
8816 tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance;
8817
8818 var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState),
8819 adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance,
8820 callGetDerivedStateFromProps = _ReactFiberClassCompo.callGetDerivedStateFromProps,
8821 constructClassInstance = _ReactFiberClassCompo.constructClassInstance,
8822 mountClassInstance = _ReactFiberClassCompo.mountClassInstance,
8823 resumeMountClassInstance = _ReactFiberClassCompo.resumeMountClassInstance,
8824 updateClassInstance = _ReactFiberClassCompo.updateClassInstance;
8825
8826 // TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
8827
8828
8829 function reconcileChildren(current, workInProgress, nextChildren) {
8830 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, workInProgress.expirationTime);
8831 }
8832
8833 function reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime) {
8834 if (current === null) {
8835 // If this is a fresh new component that hasn't been rendered yet, we
8836 // won't update its child set by applying minimal side-effects. Instead,
8837 // we will add them all to the child before it gets rendered. That means
8838 // we can optimize this reconciliation pass by not tracking side-effects.
8839 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8840 } else {
8841 // If the current child is the same as the work in progress, it means that
8842 // we haven't yet started any work on these children. Therefore, we use
8843 // the clone algorithm to create a copy of all the current children.
8844
8845 // If we had any progressed work already, that is invalid at this point so
8846 // let's throw it out.
8847 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8848 }
8849 }
8850
8851 function updateFragment(current, workInProgress) {
8852 var nextChildren = workInProgress.pendingProps;
8853 if (hasContextChanged()) {
8854 // Normally we can bail out on props equality but if context has changed
8855 // we don't do the bailout and we have to reuse existing props instead.
8856 } else if (workInProgress.memoizedProps === nextChildren) {
8857 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8858 }
8859 reconcileChildren(current, workInProgress, nextChildren);
8860 memoizeProps(workInProgress, nextChildren);
8861 return workInProgress.child;
8862 }
8863
8864 function updateMode(current, workInProgress) {
8865 var nextChildren = workInProgress.pendingProps.children;
8866 if (hasContextChanged()) {
8867 // Normally we can bail out on props equality but if context has changed
8868 // we don't do the bailout and we have to reuse existing props instead.
8869 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
8870 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8871 }
8872 reconcileChildren(current, workInProgress, nextChildren);
8873 memoizeProps(workInProgress, nextChildren);
8874 return workInProgress.child;
8875 }
8876
8877 function markRef(current, workInProgress) {
8878 var ref = workInProgress.ref;
8879 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8880 // Schedule a Ref effect
8881 workInProgress.effectTag |= Ref;
8882 }
8883 }
8884
8885 function updateFunctionalComponent(current, workInProgress) {
8886 var fn = workInProgress.type;
8887 var nextProps = workInProgress.pendingProps;
8888
8889 if (hasContextChanged()) {
8890 // Normally we can bail out on props equality but if context has changed
8891 // we don't do the bailout and we have to reuse existing props instead.
8892 } else {
8893 if (workInProgress.memoizedProps === nextProps) {
8894 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8895 }
8896 // TODO: consider bringing fn.shouldComponentUpdate() back.
8897 // It used to be here.
8898 }
8899
8900 var unmaskedContext = getUnmaskedContext(workInProgress);
8901 var context = getMaskedContext(workInProgress, unmaskedContext);
8902
8903 var nextChildren = void 0;
8904
8905 {
8906 ReactCurrentOwner.current = workInProgress;
8907 ReactDebugCurrentFiber.setCurrentPhase('render');
8908 nextChildren = fn(nextProps, context);
8909 ReactDebugCurrentFiber.setCurrentPhase(null);
8910 }
8911 // React DevTools reads this flag.
8912 workInProgress.effectTag |= PerformedWork;
8913 reconcileChildren(current, workInProgress, nextChildren);
8914 memoizeProps(workInProgress, nextProps);
8915 return workInProgress.child;
8916 }
8917
8918 function updateClassComponent(current, workInProgress, renderExpirationTime) {
8919 // Push context providers early to prevent context stack mismatches.
8920 // During mounting we don't know the child context yet as the instance doesn't exist.
8921 // We will invalidate the child context in finishClassComponent() right after rendering.
8922 var hasContext = pushContextProvider(workInProgress);
8923 var shouldUpdate = void 0;
8924 if (current === null) {
8925 if (workInProgress.stateNode === null) {
8926 // In the initial pass we might need to construct the instance.
8927 constructClassInstance(workInProgress, workInProgress.pendingProps);
8928 mountClassInstance(workInProgress, renderExpirationTime);
8929
8930 shouldUpdate = true;
8931 } else {
8932 // In a resume, we'll already have an instance we can reuse.
8933 shouldUpdate = resumeMountClassInstance(workInProgress, renderExpirationTime);
8934 }
8935 } else {
8936 shouldUpdate = updateClassInstance(current, workInProgress, renderExpirationTime);
8937 }
8938
8939 // We processed the update queue inside updateClassInstance. It may have
8940 // included some errors that were dispatched during the commit phase.
8941 // TODO: Refactor class components so this is less awkward.
8942 var didCaptureError = false;
8943 var updateQueue = workInProgress.updateQueue;
8944 if (updateQueue !== null && updateQueue.capturedValues !== null) {
8945 shouldUpdate = true;
8946 didCaptureError = true;
8947 }
8948 return finishClassComponent(current, workInProgress, shouldUpdate, hasContext, didCaptureError, renderExpirationTime);
8949 }
8950
8951 function finishClassComponent(current, workInProgress, shouldUpdate, hasContext, didCaptureError, renderExpirationTime) {
8952 // Refs should update even if shouldComponentUpdate returns false
8953 markRef(current, workInProgress);
8954
8955 if (!shouldUpdate && !didCaptureError) {
8956 // Context providers should defer to sCU for rendering
8957 if (hasContext) {
8958 invalidateContextProvider(workInProgress, false);
8959 }
8960
8961 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8962 }
8963
8964 var ctor = workInProgress.type;
8965 var instance = workInProgress.stateNode;
8966
8967 // Rerender
8968 ReactCurrentOwner.current = workInProgress;
8969 var nextChildren = void 0;
8970 if (didCaptureError && (!enableGetDerivedStateFromCatch || typeof ctor.getDerivedStateFromCatch !== 'function')) {
8971 // If we captured an error, but getDerivedStateFrom catch is not defined,
8972 // unmount all the children. componentDidCatch will schedule an update to
8973 // re-render a fallback. This is temporary until we migrate everyone to
8974 // the new API.
8975 // TODO: Warn in a future release.
8976 nextChildren = null;
8977 } else {
8978 {
8979 ReactDebugCurrentFiber.setCurrentPhase('render');
8980 nextChildren = instance.render();
8981 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8982 instance.render();
8983 }
8984 ReactDebugCurrentFiber.setCurrentPhase(null);
8985 }
8986 }
8987
8988 // React DevTools reads this flag.
8989 workInProgress.effectTag |= PerformedWork;
8990 if (didCaptureError) {
8991 // If we're recovering from an error, reconcile twice: first to delete
8992 // all the existing children.
8993 reconcileChildrenAtExpirationTime(current, workInProgress, null, renderExpirationTime);
8994 workInProgress.child = null;
8995 // Now we can continue reconciling like normal. This has the effect of
8996 // remounting all children regardless of whether their their
8997 // identity matches.
8998 }
8999 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime);
9000 // Memoize props and state using the values we just used to render.
9001 // TODO: Restructure so we never read values from the instance.
9002 memoizeState(workInProgress, instance.state);
9003 memoizeProps(workInProgress, instance.props);
9004
9005 // The context might have changed so we need to recalculate it.
9006 if (hasContext) {
9007 invalidateContextProvider(workInProgress, true);
9008 }
9009
9010 return workInProgress.child;
9011 }
9012
9013 function pushHostRootContext(workInProgress) {
9014 var root = workInProgress.stateNode;
9015 if (root.pendingContext) {
9016 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
9017 } else if (root.context) {
9018 // Should always be set
9019 pushTopLevelContextObject(workInProgress, root.context, false);
9020 }
9021 pushHostContainer(workInProgress, root.containerInfo);
9022 }
9023
9024 function updateHostRoot(current, workInProgress, renderExpirationTime) {
9025 pushHostRootContext(workInProgress);
9026 var updateQueue = workInProgress.updateQueue;
9027 if (updateQueue !== null) {
9028 var prevState = workInProgress.memoizedState;
9029 var state = processUpdateQueue(current, workInProgress, updateQueue, null, null, renderExpirationTime);
9030 memoizeState(workInProgress, state);
9031 updateQueue = workInProgress.updateQueue;
9032
9033 var element = void 0;
9034 if (updateQueue !== null && updateQueue.capturedValues !== null) {
9035 // There's an uncaught error. Unmount the whole root.
9036 element = null;
9037 } else if (prevState === state) {
9038 // If the state is the same as before, that's a bailout because we had
9039 // no work that expires at this time.
9040 resetHydrationState();
9041 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9042 } else {
9043 element = state.element;
9044 }
9045 var root = workInProgress.stateNode;
9046 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
9047 // If we don't have any current children this might be the first pass.
9048 // We always try to hydrate. If this isn't a hydration pass there won't
9049 // be any children to hydrate which is effectively the same thing as
9050 // not hydrating.
9051
9052 // This is a bit of a hack. We track the host root as a placement to
9053 // know that we're currently in a mounting state. That way isMounted
9054 // works as expected. We must reset this before committing.
9055 // TODO: Delete this when we delete isMounted and findDOMNode.
9056 workInProgress.effectTag |= Placement;
9057
9058 // Ensure that children mount into this root without tracking
9059 // side-effects. This ensures that we don't store Placement effects on
9060 // nodes that will be hydrated.
9061 workInProgress.child = mountChildFibers(workInProgress, null, element, renderExpirationTime);
9062 } else {
9063 // Otherwise reset hydration state in case we aborted and resumed another
9064 // root.
9065 resetHydrationState();
9066 reconcileChildren(current, workInProgress, element);
9067 }
9068 memoizeState(workInProgress, state);
9069 return workInProgress.child;
9070 }
9071 resetHydrationState();
9072 // If there is no update queue, that's a bailout because the root has no props.
9073 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9074 }
9075
9076 function updateHostComponent(current, workInProgress, renderExpirationTime) {
9077 pushHostContext(workInProgress);
9078
9079 if (current === null) {
9080 tryToClaimNextHydratableInstance(workInProgress);
9081 }
9082
9083 var type = workInProgress.type;
9084 var memoizedProps = workInProgress.memoizedProps;
9085 var nextProps = workInProgress.pendingProps;
9086 var prevProps = current !== null ? current.memoizedProps : null;
9087
9088 if (hasContextChanged()) {
9089 // Normally we can bail out on props equality but if context has changed
9090 // we don't do the bailout and we have to reuse existing props instead.
9091 } else if (memoizedProps === nextProps) {
9092 var isHidden = workInProgress.mode & AsyncMode && shouldDeprioritizeSubtree(type, nextProps);
9093 if (isHidden) {
9094 // Before bailing out, make sure we've deprioritized a hidden component.
9095 workInProgress.expirationTime = Never;
9096 }
9097 if (!isHidden || renderExpirationTime !== Never) {
9098 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9099 }
9100 // If we're rendering a hidden node at hidden priority, don't bailout. The
9101 // parent is complete, but the children may not be.
9102 }
9103
9104 var nextChildren = nextProps.children;
9105 var isDirectTextChild = shouldSetTextContent(type, nextProps);
9106
9107 if (isDirectTextChild) {
9108 // We special case a direct text child of a host node. This is a common
9109 // case. We won't handle it as a reified child. We will instead handle
9110 // this in the host environment that also have access to this prop. That
9111 // avoids allocating another HostText fiber and traversing it.
9112 nextChildren = null;
9113 } else if (prevProps && shouldSetTextContent(type, prevProps)) {
9114 // If we're switching from a direct text child to a normal child, or to
9115 // empty, we need to schedule the text content to be reset.
9116 workInProgress.effectTag |= ContentReset;
9117 }
9118
9119 markRef(current, workInProgress);
9120
9121 // Check the host config to see if the children are offscreen/hidden.
9122 if (renderExpirationTime !== Never && workInProgress.mode & AsyncMode && shouldDeprioritizeSubtree(type, nextProps)) {
9123 // Down-prioritize the children.
9124 workInProgress.expirationTime = Never;
9125 // Bailout and come back to this fiber later.
9126 workInProgress.memoizedProps = nextProps;
9127 return null;
9128 }
9129
9130 reconcileChildren(current, workInProgress, nextChildren);
9131 memoizeProps(workInProgress, nextProps);
9132 return workInProgress.child;
9133 }
9134
9135 function updateHostText(current, workInProgress) {
9136 if (current === null) {
9137 tryToClaimNextHydratableInstance(workInProgress);
9138 }
9139 var nextProps = workInProgress.pendingProps;
9140 memoizeProps(workInProgress, nextProps);
9141 // Nothing to do here. This is terminal. We'll do the completion step
9142 // immediately after.
9143 return null;
9144 }
9145
9146 function mountIndeterminateComponent(current, workInProgress, renderExpirationTime) {
9147 !(current === null) ? invariant_1(false, 'An indeterminate component should never have mounted. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9148 var fn = workInProgress.type;
9149 var props = workInProgress.pendingProps;
9150 var unmaskedContext = getUnmaskedContext(workInProgress);
9151 var context = getMaskedContext(workInProgress, unmaskedContext);
9152
9153 var value = void 0;
9154
9155 {
9156 if (fn.prototype && typeof fn.prototype.render === 'function') {
9157 var componentName = getComponentName(workInProgress) || 'Unknown';
9158
9159 if (!didWarnAboutBadClass[componentName]) {
9160 warning_1(false, "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);
9161 didWarnAboutBadClass[componentName] = true;
9162 }
9163 }
9164 ReactCurrentOwner.current = workInProgress;
9165 value = fn(props, context);
9166 }
9167 // React DevTools reads this flag.
9168 workInProgress.effectTag |= PerformedWork;
9169
9170 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9171 var Component = workInProgress.type;
9172
9173 // Proceed under the assumption that this is a class instance
9174 workInProgress.tag = ClassComponent;
9175
9176 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
9177
9178 if (typeof Component.getDerivedStateFromProps === 'function') {
9179 var partialState = callGetDerivedStateFromProps(workInProgress, value, props);
9180
9181 if (partialState !== null && partialState !== undefined) {
9182 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
9183 }
9184 }
9185
9186 // Push context providers early to prevent context stack mismatches.
9187 // During mounting we don't know the child context yet as the instance doesn't exist.
9188 // We will invalidate the child context in finishClassComponent() right after rendering.
9189 var hasContext = pushContextProvider(workInProgress);
9190 adoptClassInstance(workInProgress, value);
9191 mountClassInstance(workInProgress, renderExpirationTime);
9192 return finishClassComponent(current, workInProgress, true, hasContext, false, renderExpirationTime);
9193 } else {
9194 // Proceed under the assumption that this is a functional component
9195 workInProgress.tag = FunctionalComponent;
9196 {
9197 var _Component = workInProgress.type;
9198
9199 if (_Component) {
9200 warning_1(!_Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', _Component.displayName || _Component.name || 'Component');
9201 }
9202 if (workInProgress.ref !== null) {
9203 var info = '';
9204 var ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
9205 if (ownerName) {
9206 info += '\n\nCheck the render method of `' + ownerName + '`.';
9207 }
9208
9209 var warningKey = ownerName || workInProgress._debugID || '';
9210 var debugSource = workInProgress._debugSource;
9211 if (debugSource) {
9212 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
9213 }
9214 if (!didWarnAboutStatelessRefs[warningKey]) {
9215 didWarnAboutStatelessRefs[warningKey] = true;
9216 warning_1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber.getCurrentFiberStackAddendum());
9217 }
9218 }
9219
9220 if (typeof fn.getDerivedStateFromProps === 'function') {
9221 var _componentName = getComponentName(workInProgress) || 'Unknown';
9222
9223 if (!didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName]) {
9224 warning_1(false, '%s: Stateless functional components do not support getDerivedStateFromProps.', _componentName);
9225 didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName] = true;
9226 }
9227 }
9228 }
9229 reconcileChildren(current, workInProgress, value);
9230 memoizeProps(workInProgress, props);
9231 return workInProgress.child;
9232 }
9233 }
9234
9235 function updateCallComponent(current, workInProgress, renderExpirationTime) {
9236 var nextProps = workInProgress.pendingProps;
9237 if (hasContextChanged()) {
9238 // Normally we can bail out on props equality but if context has changed
9239 // we don't do the bailout and we have to reuse existing props instead.
9240 } else if (workInProgress.memoizedProps === nextProps) {
9241 nextProps = workInProgress.memoizedProps;
9242 // TODO: When bailing out, we might need to return the stateNode instead
9243 // of the child. To check it for work.
9244 // return bailoutOnAlreadyFinishedWork(current, workInProgress);
9245 }
9246
9247 var nextChildren = nextProps.children;
9248
9249 // The following is a fork of reconcileChildrenAtExpirationTime but using
9250 // stateNode to store the child.
9251 if (current === null) {
9252 workInProgress.stateNode = mountChildFibers(workInProgress, workInProgress.stateNode, nextChildren, renderExpirationTime);
9253 } else {
9254 workInProgress.stateNode = reconcileChildFibers(workInProgress, current.stateNode, nextChildren, renderExpirationTime);
9255 }
9256
9257 memoizeProps(workInProgress, nextProps);
9258 // This doesn't take arbitrary time so we could synchronously just begin
9259 // eagerly do the work of workInProgress.child as an optimization.
9260 return workInProgress.stateNode;
9261 }
9262
9263 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
9264 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9265 var nextChildren = workInProgress.pendingProps;
9266 if (hasContextChanged()) {
9267 // Normally we can bail out on props equality but if context has changed
9268 // we don't do the bailout and we have to reuse existing props instead.
9269 } else if (workInProgress.memoizedProps === nextChildren) {
9270 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9271 }
9272
9273 if (current === null) {
9274 // Portals are special because we don't append the children during mount
9275 // but at commit. Therefore we need to track insertions which the normal
9276 // flow doesn't do during mount. This doesn't happen at the root because
9277 // the root always starts with a "current" with a null child.
9278 // TODO: Consider unifying this with how the root works.
9279 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9280 memoizeProps(workInProgress, nextChildren);
9281 } else {
9282 reconcileChildren(current, workInProgress, nextChildren);
9283 memoizeProps(workInProgress, nextChildren);
9284 }
9285 return workInProgress.child;
9286 }
9287
9288 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
9289 var fiber = workInProgress.child;
9290 while (fiber !== null) {
9291 var nextFiber = void 0;
9292 // Visit this fiber.
9293 switch (fiber.tag) {
9294 case ContextConsumer:
9295 // Check if the context matches.
9296 var observedBits = fiber.stateNode | 0;
9297 if (fiber.type === context && (observedBits & changedBits) !== 0) {
9298 // Update the expiration time of all the ancestors, including
9299 // the alternates.
9300 var node = fiber;
9301 while (node !== null) {
9302 var alternate = node.alternate;
9303 if (node.expirationTime === NoWork || node.expirationTime > renderExpirationTime) {
9304 node.expirationTime = renderExpirationTime;
9305 if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > renderExpirationTime)) {
9306 alternate.expirationTime = renderExpirationTime;
9307 }
9308 } else if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > renderExpirationTime)) {
9309 alternate.expirationTime = renderExpirationTime;
9310 } else {
9311 // Neither alternate was updated, which means the rest of the
9312 // ancestor path already has sufficient priority.
9313 break;
9314 }
9315 node = node['return'];
9316 }
9317 // Don't scan deeper than a matching consumer. When we render the
9318 // consumer, we'll continue scanning from that point. This way the
9319 // scanning work is time-sliced.
9320 nextFiber = null;
9321 } else {
9322 // Traverse down.
9323 nextFiber = fiber.child;
9324 }
9325 break;
9326 case ContextProvider:
9327 // Don't scan deeper if this is a matching provider
9328 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
9329 break;
9330 default:
9331 // Traverse down.
9332 nextFiber = fiber.child;
9333 break;
9334 }
9335 if (nextFiber !== null) {
9336 // Set the return pointer of the child to the work-in-progress fiber.
9337 nextFiber['return'] = fiber;
9338 } else {
9339 // No child. Traverse to next sibling.
9340 nextFiber = fiber;
9341 while (nextFiber !== null) {
9342 if (nextFiber === workInProgress) {
9343 // We're back to the root of this subtree. Exit.
9344 nextFiber = null;
9345 break;
9346 }
9347 var sibling = nextFiber.sibling;
9348 if (sibling !== null) {
9349 nextFiber = sibling;
9350 break;
9351 }
9352 // No more siblings. Traverse up.
9353 nextFiber = nextFiber['return'];
9354 }
9355 }
9356 fiber = nextFiber;
9357 }
9358 }
9359
9360 function updateContextProvider(current, workInProgress, renderExpirationTime) {
9361 var providerType = workInProgress.type;
9362 var context = providerType.context;
9363
9364 var newProps = workInProgress.pendingProps;
9365 var oldProps = workInProgress.memoizedProps;
9366
9367 if (hasContextChanged()) {
9368 // Normally we can bail out on props equality but if context has changed
9369 // we don't do the bailout and we have to reuse existing props instead.
9370 } else if (oldProps === newProps) {
9371 workInProgress.stateNode = 0;
9372 pushProvider(workInProgress);
9373 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9374 }
9375 workInProgress.memoizedProps = newProps;
9376
9377 var newValue = newProps.value;
9378
9379 var changedBits = void 0;
9380 if (oldProps === null) {
9381 // Initial render
9382 changedBits = MAX_SIGNED_31_BIT_INT;
9383 } else {
9384 var oldValue = oldProps.value;
9385 // Use Object.is to compare the new context value to the old value.
9386 // Inlined Object.is polyfill.
9387 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9388 if (oldValue === newValue && (oldValue !== 0 || 1 / oldValue === 1 / newValue) || oldValue !== oldValue && newValue !== newValue // eslint-disable-line no-self-compare
9389 ) {
9390 // No change.
9391 changedBits = 0;
9392 } else {
9393 changedBits = typeof context.calculateChangedBits === 'function' ? context.calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
9394 {
9395 warning_1((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
9396 }
9397 changedBits |= 0;
9398
9399 if (changedBits !== 0) {
9400 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9401 }
9402 }
9403 }
9404
9405 workInProgress.stateNode = changedBits;
9406 pushProvider(workInProgress);
9407
9408 if (oldProps !== null && oldProps.children === newProps.children) {
9409 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9410 }
9411 var newChildren = newProps.children;
9412 reconcileChildren(current, workInProgress, newChildren);
9413 return workInProgress.child;
9414 }
9415
9416 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
9417 var context = workInProgress.type;
9418 var newProps = workInProgress.pendingProps;
9419
9420 var newValue = context.currentValue;
9421 var changedBits = context.changedBits;
9422
9423 if (changedBits !== 0) {
9424 // Context change propagation stops at matching consumers, for time-
9425 // slicing. Continue the propagation here.
9426 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9427 }
9428
9429 // Store the observedBits on the fiber's stateNode for quick access.
9430 var observedBits = newProps.observedBits;
9431 if (observedBits === undefined || observedBits === null) {
9432 // Subscribe to all changes by default
9433 observedBits = MAX_SIGNED_31_BIT_INT;
9434 }
9435 workInProgress.stateNode = observedBits;
9436
9437 var render = newProps.children;
9438
9439 if (typeof render !== 'function') {
9440 invariant_1(false, '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.');
9441 }
9442
9443 var newChildren = render(newValue);
9444 reconcileChildren(current, workInProgress, newChildren);
9445 return workInProgress.child;
9446 }
9447
9448 /*
9449 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
9450 let child = firstChild;
9451 do {
9452 // Ensure that the first and last effect of the parent corresponds
9453 // to the children's first and last effect.
9454 if (!returnFiber.firstEffect) {
9455 returnFiber.firstEffect = child.firstEffect;
9456 }
9457 if (child.lastEffect) {
9458 if (returnFiber.lastEffect) {
9459 returnFiber.lastEffect.nextEffect = child.firstEffect;
9460 }
9461 returnFiber.lastEffect = child.lastEffect;
9462 }
9463 } while (child = child.sibling);
9464 }
9465 */
9466
9467 function bailoutOnAlreadyFinishedWork(current, workInProgress) {
9468 cancelWorkTimer(workInProgress);
9469
9470 // TODO: We should ideally be able to bail out early if the children have no
9471 // more work to do. However, since we don't have a separation of this
9472 // Fiber's priority and its children yet - we don't know without doing lots
9473 // of the same work we do anyway. Once we have that separation we can just
9474 // bail out here if the children has no more work at this priority level.
9475 // if (workInProgress.priorityOfChildren <= priorityLevel) {
9476 // // If there are side-effects in these children that have not yet been
9477 // // committed we need to ensure that they get properly transferred up.
9478 // if (current && current.child !== workInProgress.child) {
9479 // reuseChildrenEffects(workInProgress, child);
9480 // }
9481 // return null;
9482 // }
9483
9484 cloneChildFibers(current, workInProgress);
9485 return workInProgress.child;
9486 }
9487
9488 function bailoutOnLowPriority(current, workInProgress) {
9489 cancelWorkTimer(workInProgress);
9490
9491 // TODO: Handle HostComponent tags here as well and call pushHostContext()?
9492 // See PR 8590 discussion for context
9493 switch (workInProgress.tag) {
9494 case HostRoot:
9495 pushHostRootContext(workInProgress);
9496 break;
9497 case ClassComponent:
9498 pushContextProvider(workInProgress);
9499 break;
9500 case HostPortal:
9501 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9502 break;
9503 case ContextProvider:
9504 pushProvider(workInProgress);
9505 break;
9506 }
9507 // TODO: What if this is currently in progress?
9508 // How can that happen? How is this not being cloned?
9509 return null;
9510 }
9511
9512 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead
9513 function memoizeProps(workInProgress, nextProps) {
9514 workInProgress.memoizedProps = nextProps;
9515 }
9516
9517 function memoizeState(workInProgress, nextState) {
9518 workInProgress.memoizedState = nextState;
9519 // Don't reset the updateQueue, in case there are pending updates. Resetting
9520 // is handled by processUpdateQueue.
9521 }
9522
9523 function beginWork(current, workInProgress, renderExpirationTime) {
9524 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
9525 return bailoutOnLowPriority(current, workInProgress);
9526 }
9527
9528 switch (workInProgress.tag) {
9529 case IndeterminateComponent:
9530 return mountIndeterminateComponent(current, workInProgress, renderExpirationTime);
9531 case FunctionalComponent:
9532 return updateFunctionalComponent(current, workInProgress);
9533 case ClassComponent:
9534 return updateClassComponent(current, workInProgress, renderExpirationTime);
9535 case HostRoot:
9536 return updateHostRoot(current, workInProgress, renderExpirationTime);
9537 case HostComponent:
9538 return updateHostComponent(current, workInProgress, renderExpirationTime);
9539 case HostText:
9540 return updateHostText(current, workInProgress);
9541 case CallHandlerPhase:
9542 // This is a restart. Reset the tag to the initial phase.
9543 workInProgress.tag = CallComponent;
9544 // Intentionally fall through since this is now the same.
9545 case CallComponent:
9546 return updateCallComponent(current, workInProgress, renderExpirationTime);
9547 case ReturnComponent:
9548 // A return component is just a placeholder, we can just run through the
9549 // next one immediately.
9550 return null;
9551 case HostPortal:
9552 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9553 case Fragment:
9554 return updateFragment(current, workInProgress);
9555 case Mode:
9556 return updateMode(current, workInProgress);
9557 case ContextProvider:
9558 return updateContextProvider(current, workInProgress, renderExpirationTime);
9559 case ContextConsumer:
9560 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9561 default:
9562 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9563 }
9564 }
9565
9566 return {
9567 beginWork: beginWork
9568 };
9569};
9570
9571var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) {
9572 var createInstance = config.createInstance,
9573 createTextInstance = config.createTextInstance,
9574 appendInitialChild = config.appendInitialChild,
9575 finalizeInitialChildren = config.finalizeInitialChildren,
9576 prepareUpdate = config.prepareUpdate,
9577 mutation = config.mutation,
9578 persistence = config.persistence;
9579 var getRootHostContainer = hostContext.getRootHostContainer,
9580 popHostContext = hostContext.popHostContext,
9581 getHostContext = hostContext.getHostContext,
9582 popHostContainer = hostContext.popHostContainer;
9583 var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance,
9584 prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance,
9585 popHydrationState = hydrationContext.popHydrationState;
9586
9587
9588 function markUpdate(workInProgress) {
9589 // Tag the fiber with an update effect. This turns a Placement into
9590 // an UpdateAndPlacement.
9591 workInProgress.effectTag |= Update;
9592 }
9593
9594 function markRef(workInProgress) {
9595 workInProgress.effectTag |= Ref;
9596 }
9597
9598 function appendAllReturns(returns, workInProgress) {
9599 var node = workInProgress.stateNode;
9600 if (node) {
9601 node['return'] = workInProgress;
9602 }
9603 while (node !== null) {
9604 if (node.tag === HostComponent || node.tag === HostText || node.tag === HostPortal) {
9605 invariant_1(false, 'A call cannot have host component children.');
9606 } else if (node.tag === ReturnComponent) {
9607 returns.push(node.pendingProps.value);
9608 } else if (node.child !== null) {
9609 node.child['return'] = node;
9610 node = node.child;
9611 continue;
9612 }
9613 while (node.sibling === null) {
9614 if (node['return'] === null || node['return'] === workInProgress) {
9615 return;
9616 }
9617 node = node['return'];
9618 }
9619 node.sibling['return'] = node['return'];
9620 node = node.sibling;
9621 }
9622 }
9623
9624 function moveCallToHandlerPhase(current, workInProgress, renderExpirationTime) {
9625 var props = workInProgress.memoizedProps;
9626 !props ? invariant_1(false, 'Should be resolved by now. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9627
9628 // First step of the call has completed. Now we need to do the second.
9629 // TODO: It would be nice to have a multi stage call represented by a
9630 // single component, or at least tail call optimize nested ones. Currently
9631 // that requires additional fields that we don't want to add to the fiber.
9632 // So this requires nested handlers.
9633 // Note: This doesn't mutate the alternate node. I don't think it needs to
9634 // since this stage is reset for every pass.
9635 workInProgress.tag = CallHandlerPhase;
9636
9637 // Build up the returns.
9638 // TODO: Compare this to a generator or opaque helpers like Children.
9639 var returns = [];
9640 appendAllReturns(returns, workInProgress);
9641 var fn = props.handler;
9642 var childProps = props.props;
9643 var nextChildren = fn(childProps, returns);
9644
9645 var currentFirstChild = current !== null ? current.child : null;
9646 workInProgress.child = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, renderExpirationTime);
9647 return workInProgress.child;
9648 }
9649
9650 function appendAllChildren(parent, workInProgress) {
9651 // We only have the top Fiber that was created but we need recurse down its
9652 // children to find all the terminal nodes.
9653 var node = workInProgress.child;
9654 while (node !== null) {
9655 if (node.tag === HostComponent || node.tag === HostText) {
9656 appendInitialChild(parent, node.stateNode);
9657 } else if (node.tag === HostPortal) {
9658 // If we have a portal child, then we don't want to traverse
9659 // down its children. Instead, we'll get insertions from each child in
9660 // the portal directly.
9661 } else if (node.child !== null) {
9662 node.child['return'] = node;
9663 node = node.child;
9664 continue;
9665 }
9666 if (node === workInProgress) {
9667 return;
9668 }
9669 while (node.sibling === null) {
9670 if (node['return'] === null || node['return'] === workInProgress) {
9671 return;
9672 }
9673 node = node['return'];
9674 }
9675 node.sibling['return'] = node['return'];
9676 node = node.sibling;
9677 }
9678 }
9679
9680 var updateHostContainer = void 0;
9681 var updateHostComponent = void 0;
9682 var updateHostText = void 0;
9683 if (mutation) {
9684 if (enableMutatingReconciler) {
9685 // Mutation mode
9686 updateHostContainer = function (workInProgress) {
9687 // Noop
9688 };
9689 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9690 // TODO: Type this specific to this type of component.
9691 workInProgress.updateQueue = updatePayload;
9692 // If the update payload indicates that there is a change or if there
9693 // is a new ref we mark this as an update. All the work is done in commitWork.
9694 if (updatePayload) {
9695 markUpdate(workInProgress);
9696 }
9697 };
9698 updateHostText = function (current, workInProgress, oldText, newText) {
9699 // If the text differs, mark it as an update. All the work in done in commitWork.
9700 if (oldText !== newText) {
9701 markUpdate(workInProgress);
9702 }
9703 };
9704 } else {
9705 invariant_1(false, 'Mutating reconciler is disabled.');
9706 }
9707 } else if (persistence) {
9708 if (enablePersistentReconciler) {
9709 // Persistent host tree mode
9710 var cloneInstance = persistence.cloneInstance,
9711 createContainerChildSet = persistence.createContainerChildSet,
9712 appendChildToContainerChildSet = persistence.appendChildToContainerChildSet,
9713 finalizeContainerChildren = persistence.finalizeContainerChildren;
9714
9715 // An unfortunate fork of appendAllChildren because we have two different parent types.
9716
9717 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) {
9718 // We only have the top Fiber that was created but we need recurse down its
9719 // children to find all the terminal nodes.
9720 var node = workInProgress.child;
9721 while (node !== null) {
9722 if (node.tag === HostComponent || node.tag === HostText) {
9723 appendChildToContainerChildSet(containerChildSet, node.stateNode);
9724 } else if (node.tag === HostPortal) {
9725 // If we have a portal child, then we don't want to traverse
9726 // down its children. Instead, we'll get insertions from each child in
9727 // the portal directly.
9728 } else if (node.child !== null) {
9729 node.child['return'] = node;
9730 node = node.child;
9731 continue;
9732 }
9733 if (node === workInProgress) {
9734 return;
9735 }
9736 while (node.sibling === null) {
9737 if (node['return'] === null || node['return'] === workInProgress) {
9738 return;
9739 }
9740 node = node['return'];
9741 }
9742 node.sibling['return'] = node['return'];
9743 node = node.sibling;
9744 }
9745 };
9746 updateHostContainer = function (workInProgress) {
9747 var portalOrRoot = workInProgress.stateNode;
9748 var childrenUnchanged = workInProgress.firstEffect === null;
9749 if (childrenUnchanged) {
9750 // No changes, just reuse the existing instance.
9751 } else {
9752 var container = portalOrRoot.containerInfo;
9753 var newChildSet = createContainerChildSet(container);
9754 // If children might have changed, we have to add them all to the set.
9755 appendAllChildrenToContainer(newChildSet, workInProgress);
9756 portalOrRoot.pendingChildren = newChildSet;
9757 // Schedule an update on the container to swap out the container.
9758 markUpdate(workInProgress);
9759 finalizeContainerChildren(container, newChildSet);
9760 }
9761 };
9762 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9763 // If there are no effects associated with this node, then none of our children had any updates.
9764 // This guarantees that we can reuse all of them.
9765 var childrenUnchanged = workInProgress.firstEffect === null;
9766 var currentInstance = current.stateNode;
9767 if (childrenUnchanged && updatePayload === null) {
9768 // No changes, just reuse the existing instance.
9769 // Note that this might release a previous clone.
9770 workInProgress.stateNode = currentInstance;
9771 } else {
9772 var recyclableInstance = workInProgress.stateNode;
9773 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9774 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9775 markUpdate(workInProgress);
9776 }
9777 workInProgress.stateNode = newInstance;
9778 if (childrenUnchanged) {
9779 // If there are no other effects in this tree, we need to flag this node as having one.
9780 // Even though we're not going to use it for anything.
9781 // Otherwise parents won't know that there are new children to propagate upwards.
9782 markUpdate(workInProgress);
9783 } else {
9784 // If children might have changed, we have to add them all to the set.
9785 appendAllChildren(newInstance, workInProgress);
9786 }
9787 }
9788 };
9789 updateHostText = function (current, workInProgress, oldText, newText) {
9790 if (oldText !== newText) {
9791 // If the text content differs, we'll create a new text instance for it.
9792 var rootContainerInstance = getRootHostContainer();
9793 var currentHostContext = getHostContext();
9794 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9795 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9796 // This lets the parents know that at least one of their children has changed.
9797 markUpdate(workInProgress);
9798 }
9799 };
9800 } else {
9801 invariant_1(false, 'Persistent reconciler is disabled.');
9802 }
9803 } else {
9804 if (enableNoopReconciler) {
9805 // No host operations
9806 updateHostContainer = function (workInProgress) {
9807 // Noop
9808 };
9809 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9810 // Noop
9811 };
9812 updateHostText = function (current, workInProgress, oldText, newText) {
9813 // Noop
9814 };
9815 } else {
9816 invariant_1(false, 'Noop reconciler is disabled.');
9817 }
9818 }
9819
9820 function completeWork(current, workInProgress, renderExpirationTime) {
9821 var newProps = workInProgress.pendingProps;
9822 switch (workInProgress.tag) {
9823 case FunctionalComponent:
9824 return null;
9825 case ClassComponent:
9826 {
9827 // We are leaving this subtree, so pop context if any.
9828 popContextProvider(workInProgress);
9829
9830 // If this component caught an error, schedule an error log effect.
9831 var instance = workInProgress.stateNode;
9832 var updateQueue = workInProgress.updateQueue;
9833 if (updateQueue !== null && updateQueue.capturedValues !== null) {
9834 workInProgress.effectTag &= ~DidCapture;
9835 if (typeof instance.componentDidCatch === 'function') {
9836 workInProgress.effectTag |= ErrLog;
9837 } else {
9838 // Normally we clear this in the commit phase, but since we did not
9839 // schedule an effect, we need to reset it here.
9840 updateQueue.capturedValues = null;
9841 }
9842 }
9843 return null;
9844 }
9845 case HostRoot:
9846 {
9847 popHostContainer(workInProgress);
9848 popTopLevelContextObject(workInProgress);
9849 var fiberRoot = workInProgress.stateNode;
9850 if (fiberRoot.pendingContext) {
9851 fiberRoot.context = fiberRoot.pendingContext;
9852 fiberRoot.pendingContext = null;
9853 }
9854 if (current === null || current.child === null) {
9855 // If we hydrated, pop so that we can delete any remaining children
9856 // that weren't hydrated.
9857 popHydrationState(workInProgress);
9858 // This resets the hacky state to fix isMounted before committing.
9859 // TODO: Delete this when we delete isMounted and findDOMNode.
9860 workInProgress.effectTag &= ~Placement;
9861 }
9862 updateHostContainer(workInProgress);
9863
9864 var _updateQueue = workInProgress.updateQueue;
9865 if (_updateQueue !== null && _updateQueue.capturedValues !== null) {
9866 workInProgress.effectTag |= ErrLog;
9867 }
9868 return null;
9869 }
9870 case HostComponent:
9871 {
9872 popHostContext(workInProgress);
9873 var rootContainerInstance = getRootHostContainer();
9874 var type = workInProgress.type;
9875 if (current !== null && workInProgress.stateNode != null) {
9876 // If we have an alternate, that means this is an update and we need to
9877 // schedule a side-effect to do the updates.
9878 var oldProps = current.memoizedProps;
9879 // If we get updated because one of our children updated, we don't
9880 // have newProps so we'll have to reuse them.
9881 // TODO: Split the update API as separate for the props vs. children.
9882 // Even better would be if children weren't special cased at all tho.
9883 var _instance = workInProgress.stateNode;
9884 var currentHostContext = getHostContext();
9885 // TODO: Experiencing an error where oldProps is null. Suggests a host
9886 // component is hitting the resume path. Figure out why. Possibly
9887 // related to `hidden`.
9888 var updatePayload = prepareUpdate(_instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9889
9890 updateHostComponent(current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9891
9892 if (current.ref !== workInProgress.ref) {
9893 markRef(workInProgress);
9894 }
9895 } else {
9896 if (!newProps) {
9897 !(workInProgress.stateNode !== null) ? invariant_1(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9898 // This can happen when we abort work.
9899 return null;
9900 }
9901
9902 var _currentHostContext = getHostContext();
9903 // TODO: Move createInstance to beginWork and keep it on a context
9904 // "stack" as the parent. Then append children as we go in beginWork
9905 // or completeWork depending on we want to add then top->down or
9906 // bottom->up. Top->down is faster in IE11.
9907 var wasHydrated = popHydrationState(workInProgress);
9908 if (wasHydrated) {
9909 // TODO: Move this and createInstance step into the beginPhase
9910 // to consolidate.
9911 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) {
9912 // If changes to the hydrated node needs to be applied at the
9913 // commit-phase we mark this as such.
9914 markUpdate(workInProgress);
9915 }
9916 } else {
9917 var _instance2 = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress);
9918
9919 appendAllChildren(_instance2, workInProgress);
9920
9921 // Certain renderers require commit-time effects for initial mount.
9922 // (eg DOM renderer supports auto-focus for certain elements).
9923 // Make sure such renderers get scheduled for later work.
9924 if (finalizeInitialChildren(_instance2, type, newProps, rootContainerInstance, _currentHostContext)) {
9925 markUpdate(workInProgress);
9926 }
9927 workInProgress.stateNode = _instance2;
9928 }
9929
9930 if (workInProgress.ref !== null) {
9931 // If there is a ref on a host node we need to schedule a callback
9932 markRef(workInProgress);
9933 }
9934 }
9935 return null;
9936 }
9937 case HostText:
9938 {
9939 var newText = newProps;
9940 if (current && workInProgress.stateNode != null) {
9941 var oldText = current.memoizedProps;
9942 // If we have an alternate, that means this is an update and we need
9943 // to schedule a side-effect to do the updates.
9944 updateHostText(current, workInProgress, oldText, newText);
9945 } else {
9946 if (typeof newText !== 'string') {
9947 !(workInProgress.stateNode !== null) ? invariant_1(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9948 // This can happen when we abort work.
9949 return null;
9950 }
9951 var _rootContainerInstance = getRootHostContainer();
9952 var _currentHostContext2 = getHostContext();
9953 var _wasHydrated = popHydrationState(workInProgress);
9954 if (_wasHydrated) {
9955 if (prepareToHydrateHostTextInstance(workInProgress)) {
9956 markUpdate(workInProgress);
9957 }
9958 } else {
9959 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress);
9960 }
9961 }
9962 return null;
9963 }
9964 case CallComponent:
9965 return moveCallToHandlerPhase(current, workInProgress, renderExpirationTime);
9966 case CallHandlerPhase:
9967 // Reset the tag to now be a first phase call.
9968 workInProgress.tag = CallComponent;
9969 return null;
9970 case ReturnComponent:
9971 // Does nothing.
9972 return null;
9973 case Fragment:
9974 return null;
9975 case Mode:
9976 return null;
9977 case HostPortal:
9978 popHostContainer(workInProgress);
9979 updateHostContainer(workInProgress);
9980 return null;
9981 case ContextProvider:
9982 // Pop provider fiber
9983 popProvider(workInProgress);
9984 return null;
9985 case ContextConsumer:
9986 return null;
9987 // Error cases
9988 case IndeterminateComponent:
9989 invariant_1(false, 'An indeterminate component should have become determinate before completing. This error is likely caused by a bug in React. Please file an issue.');
9990 // eslint-disable-next-line no-fallthrough
9991 default:
9992 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9993 }
9994 }
9995
9996 return {
9997 completeWork: completeWork
9998 };
9999};
10000
10001function createCapturedValue(value, source) {
10002 // If the value is an error, call this function immediately after it is thrown
10003 // so the stack is accurate.
10004 return {
10005 value: value,
10006 source: source,
10007 stack: getStackAddendumByWorkInProgressFiber(source)
10008 };
10009}
10010
10011var ReactFiberUnwindWork = function (hostContext, scheduleWork, isAlreadyFailedLegacyErrorBoundary) {
10012 var popHostContainer = hostContext.popHostContainer,
10013 popHostContext = hostContext.popHostContext;
10014
10015
10016 function throwException(returnFiber, sourceFiber, rawValue) {
10017 // The source fiber did not complete.
10018 sourceFiber.effectTag |= Incomplete;
10019 // Its effect list is no longer valid.
10020 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10021
10022 var value = createCapturedValue(rawValue, sourceFiber);
10023
10024 var workInProgress = returnFiber;
10025 do {
10026 switch (workInProgress.tag) {
10027 case HostRoot:
10028 {
10029 // Uncaught error
10030 var errorInfo = value;
10031 ensureUpdateQueues(workInProgress);
10032 var updateQueue = workInProgress.updateQueue;
10033 updateQueue.capturedValues = [errorInfo];
10034 workInProgress.effectTag |= ShouldCapture;
10035 return;
10036 }
10037 case ClassComponent:
10038 // Capture and retry
10039 var ctor = workInProgress.type;
10040 var _instance = workInProgress.stateNode;
10041 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromCatch === 'function' && enableGetDerivedStateFromCatch || _instance !== null && typeof _instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(_instance))) {
10042 ensureUpdateQueues(workInProgress);
10043 var _updateQueue = workInProgress.updateQueue;
10044 var capturedValues = _updateQueue.capturedValues;
10045 if (capturedValues === null) {
10046 _updateQueue.capturedValues = [value];
10047 } else {
10048 capturedValues.push(value);
10049 }
10050 workInProgress.effectTag |= ShouldCapture;
10051 return;
10052 }
10053 break;
10054 default:
10055 break;
10056 }
10057 workInProgress = workInProgress['return'];
10058 } while (workInProgress !== null);
10059 }
10060
10061 function unwindWork(workInProgress) {
10062 switch (workInProgress.tag) {
10063 case ClassComponent:
10064 {
10065 popContextProvider(workInProgress);
10066 var effectTag = workInProgress.effectTag;
10067 if (effectTag & ShouldCapture) {
10068 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10069 return workInProgress;
10070 }
10071 return null;
10072 }
10073 case HostRoot:
10074 {
10075 popHostContainer(workInProgress);
10076 popTopLevelContextObject(workInProgress);
10077 var _effectTag = workInProgress.effectTag;
10078 if (_effectTag & ShouldCapture) {
10079 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10080 return workInProgress;
10081 }
10082 return null;
10083 }
10084 case HostComponent:
10085 {
10086 popHostContext(workInProgress);
10087 return null;
10088 }
10089 case HostPortal:
10090 popHostContainer(workInProgress);
10091 return null;
10092 case ContextProvider:
10093 popProvider(workInProgress);
10094 return null;
10095 default:
10096 return null;
10097 }
10098 }
10099 return {
10100 throwException: throwException,
10101 unwindWork: unwindWork
10102 };
10103};
10104
10105// This module is forked in different environments.
10106// By default, return `true` to log errors to the console.
10107// Forks can return `false` if this isn't desirable.
10108function showErrorDialog(capturedError) {
10109 return true;
10110}
10111
10112function logCapturedError(capturedError) {
10113 var logError = showErrorDialog(capturedError);
10114
10115 // Allow injected showErrorDialog() to prevent default console.error logging.
10116 // This enables renderers like ReactNative to better manage redbox behavior.
10117 if (logError === false) {
10118 return;
10119 }
10120
10121 var error = capturedError.error;
10122 var suppressLogging = error && error.suppressReactErrorLogging;
10123 if (suppressLogging) {
10124 return;
10125 }
10126
10127 {
10128 var componentName = capturedError.componentName,
10129 componentStack = capturedError.componentStack,
10130 errorBoundaryName = capturedError.errorBoundaryName,
10131 errorBoundaryFound = capturedError.errorBoundaryFound,
10132 willRetry = capturedError.willRetry;
10133
10134
10135 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10136
10137 var errorBoundaryMessage = void 0;
10138 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10139 if (errorBoundaryFound && errorBoundaryName) {
10140 if (willRetry) {
10141 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10142 } else {
10143 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10144 }
10145 } else {
10146 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.';
10147 }
10148 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10149
10150 // In development, we provide our own message with just the component stack.
10151 // We don't include the original error message and JS stack because the browser
10152 // has already printed it. Even if the application swallows the error, it is still
10153 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10154 console.error(combinedMessage);
10155 }
10156}
10157
10158var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback;
10159var hasCaughtError$1 = ReactErrorUtils.hasCaughtError;
10160var clearCaughtError$1 = ReactErrorUtils.clearCaughtError;
10161
10162
10163function logError(boundary, errorInfo) {
10164 var source = errorInfo.source;
10165 var stack = errorInfo.stack;
10166 if (stack === null) {
10167 stack = getStackAddendumByWorkInProgressFiber(source);
10168 }
10169
10170 var capturedError = {
10171 componentName: source !== null ? getComponentName(source) : null,
10172 error: errorInfo.value,
10173 errorBoundary: boundary,
10174 componentStack: stack !== null ? stack : '',
10175 errorBoundaryName: null,
10176 errorBoundaryFound: false,
10177 willRetry: false
10178 };
10179
10180 if (boundary !== null) {
10181 capturedError.errorBoundaryName = getComponentName(boundary);
10182 capturedError.errorBoundaryFound = capturedError.willRetry = boundary.tag === ClassComponent;
10183 } else {
10184 capturedError.errorBoundaryName = null;
10185 capturedError.errorBoundaryFound = capturedError.willRetry = false;
10186 }
10187
10188 try {
10189 logCapturedError(capturedError);
10190 } catch (e) {
10191 // Prevent cycle if logCapturedError() throws.
10192 // A cycle may still occur if logCapturedError renders a component that throws.
10193 var suppressLogging = e && e.suppressReactErrorLogging;
10194 if (!suppressLogging) {
10195 console.error(e);
10196 }
10197 }
10198}
10199
10200var ReactFiberCommitWork = function (config, captureError, scheduleWork, computeExpirationForFiber, markLegacyErrorBoundaryAsFailed, recalculateCurrentTime) {
10201 var getPublicInstance = config.getPublicInstance,
10202 mutation = config.mutation,
10203 persistence = config.persistence;
10204
10205
10206 var callComponentWillUnmountWithTimer = function (current, instance) {
10207 startPhaseTimer(current, 'componentWillUnmount');
10208 instance.props = current.memoizedProps;
10209 instance.state = current.memoizedState;
10210 instance.componentWillUnmount();
10211 stopPhaseTimer();
10212 };
10213
10214 // Capture errors so they don't interrupt unmounting.
10215 function safelyCallComponentWillUnmount(current, instance) {
10216 {
10217 invokeGuardedCallback$3(null, callComponentWillUnmountWithTimer, null, current, instance);
10218 if (hasCaughtError$1()) {
10219 var unmountError = clearCaughtError$1();
10220 captureError(current, unmountError);
10221 }
10222 }
10223 }
10224
10225 function safelyDetachRef(current) {
10226 var ref = current.ref;
10227 if (ref !== null) {
10228 if (typeof ref === 'function') {
10229 {
10230 invokeGuardedCallback$3(null, ref, null, null);
10231 if (hasCaughtError$1()) {
10232 var refError = clearCaughtError$1();
10233 captureError(current, refError);
10234 }
10235 }
10236 } else {
10237 ref.value = null;
10238 }
10239 }
10240 }
10241
10242 function commitLifeCycles(finishedRoot, current, finishedWork, currentTime, committedExpirationTime) {
10243 switch (finishedWork.tag) {
10244 case ClassComponent:
10245 {
10246 var _instance = finishedWork.stateNode;
10247 if (finishedWork.effectTag & Update) {
10248 if (current === null) {
10249 startPhaseTimer(finishedWork, 'componentDidMount');
10250 _instance.props = finishedWork.memoizedProps;
10251 _instance.state = finishedWork.memoizedState;
10252 _instance.componentDidMount();
10253 stopPhaseTimer();
10254 } else {
10255 var prevProps = current.memoizedProps;
10256 var prevState = current.memoizedState;
10257 startPhaseTimer(finishedWork, 'componentDidUpdate');
10258 _instance.props = finishedWork.memoizedProps;
10259 _instance.state = finishedWork.memoizedState;
10260 _instance.componentDidUpdate(prevProps, prevState);
10261 stopPhaseTimer();
10262 }
10263 }
10264 var updateQueue = finishedWork.updateQueue;
10265 if (updateQueue !== null) {
10266 commitCallbacks(updateQueue, _instance);
10267 }
10268 return;
10269 }
10270 case HostRoot:
10271 {
10272 var _updateQueue = finishedWork.updateQueue;
10273 if (_updateQueue !== null) {
10274 var _instance2 = null;
10275 if (finishedWork.child !== null) {
10276 switch (finishedWork.child.tag) {
10277 case HostComponent:
10278 _instance2 = getPublicInstance(finishedWork.child.stateNode);
10279 break;
10280 case ClassComponent:
10281 _instance2 = finishedWork.child.stateNode;
10282 break;
10283 }
10284 }
10285 commitCallbacks(_updateQueue, _instance2);
10286 }
10287 return;
10288 }
10289 case HostComponent:
10290 {
10291 var _instance3 = finishedWork.stateNode;
10292
10293 // Renderers may schedule work to be done after host components are mounted
10294 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10295 // These effects should only be committed when components are first mounted,
10296 // aka when there is no current/alternate.
10297 if (current === null && finishedWork.effectTag & Update) {
10298 var type = finishedWork.type;
10299 var props = finishedWork.memoizedProps;
10300 commitMount(_instance3, type, props, finishedWork);
10301 }
10302
10303 return;
10304 }
10305 case HostText:
10306 {
10307 // We have no life-cycles associated with text.
10308 return;
10309 }
10310 case HostPortal:
10311 {
10312 // We have no life-cycles associated with portals.
10313 return;
10314 }
10315 default:
10316 {
10317 invariant_1(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10318 }
10319 }
10320 }
10321
10322 function commitErrorLogging(finishedWork, onUncaughtError) {
10323 switch (finishedWork.tag) {
10324 case ClassComponent:
10325 {
10326 var ctor = finishedWork.type;
10327 var _instance4 = finishedWork.stateNode;
10328 var updateQueue = finishedWork.updateQueue;
10329 !(updateQueue !== null && updateQueue.capturedValues !== null) ? invariant_1(false, 'An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10330 var capturedErrors = updateQueue.capturedValues;
10331 updateQueue.capturedValues = null;
10332
10333 if (typeof ctor.getDerivedStateFromCatch !== 'function') {
10334 // To preserve the preexisting retry behavior of error boundaries,
10335 // we keep track of which ones already failed during this batch.
10336 // This gets reset before we yield back to the browser.
10337 // TODO: Warn in strict mode if getDerivedStateFromCatch is
10338 // not defined.
10339 markLegacyErrorBoundaryAsFailed(_instance4);
10340 }
10341
10342 _instance4.props = finishedWork.memoizedProps;
10343 _instance4.state = finishedWork.memoizedState;
10344 for (var i = 0; i < capturedErrors.length; i++) {
10345 var errorInfo = capturedErrors[i];
10346 var _error = errorInfo.value;
10347 logError(finishedWork, errorInfo);
10348 _instance4.componentDidCatch(_error);
10349 }
10350 }
10351 break;
10352 case HostRoot:
10353 {
10354 var _updateQueue2 = finishedWork.updateQueue;
10355 !(_updateQueue2 !== null && _updateQueue2.capturedValues !== null) ? invariant_1(false, 'An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10356 var _capturedErrors = _updateQueue2.capturedValues;
10357 _updateQueue2.capturedValues = null;
10358 for (var _i = 0; _i < _capturedErrors.length; _i++) {
10359 var _errorInfo = _capturedErrors[_i];
10360 logError(finishedWork, _errorInfo);
10361 onUncaughtError(_errorInfo.value);
10362 }
10363 break;
10364 }
10365 default:
10366 invariant_1(false, 'This unit of work tag cannot capture errors. This error is likely caused by a bug in React. Please file an issue.');
10367 }
10368 }
10369
10370 function commitAttachRef(finishedWork) {
10371 var ref = finishedWork.ref;
10372 if (ref !== null) {
10373 var _instance5 = finishedWork.stateNode;
10374 var instanceToUse = void 0;
10375 switch (finishedWork.tag) {
10376 case HostComponent:
10377 instanceToUse = getPublicInstance(_instance5);
10378 break;
10379 default:
10380 instanceToUse = _instance5;
10381 }
10382 if (typeof ref === 'function') {
10383 ref(instanceToUse);
10384 } else {
10385 ref.value = instanceToUse;
10386 }
10387 }
10388 }
10389
10390 function commitDetachRef(current) {
10391 var currentRef = current.ref;
10392 if (currentRef !== null) {
10393 if (typeof currentRef === 'function') {
10394 currentRef(null);
10395 } else {
10396 currentRef.value = null;
10397 }
10398 }
10399 }
10400
10401 // User-originating errors (lifecycles and refs) should not interrupt
10402 // deletion, so don't let them throw. Host-originating errors should
10403 // interrupt deletion, so it's okay
10404 function commitUnmount(current) {
10405 if (typeof onCommitUnmount === 'function') {
10406 onCommitUnmount(current);
10407 }
10408
10409 switch (current.tag) {
10410 case ClassComponent:
10411 {
10412 safelyDetachRef(current);
10413 var _instance6 = current.stateNode;
10414 if (typeof _instance6.componentWillUnmount === 'function') {
10415 safelyCallComponentWillUnmount(current, _instance6);
10416 }
10417 return;
10418 }
10419 case HostComponent:
10420 {
10421 safelyDetachRef(current);
10422 return;
10423 }
10424 case CallComponent:
10425 {
10426 commitNestedUnmounts(current.stateNode);
10427 return;
10428 }
10429 case HostPortal:
10430 {
10431 // TODO: this is recursive.
10432 // We are also not using this parent because
10433 // the portal will get pushed immediately.
10434 if (enableMutatingReconciler && mutation) {
10435 unmountHostComponents(current);
10436 } else if (enablePersistentReconciler && persistence) {
10437 emptyPortalContainer(current);
10438 }
10439 return;
10440 }
10441 }
10442 }
10443
10444 function commitNestedUnmounts(root) {
10445 // While we're inside a removed host node we don't want to call
10446 // removeChild on the inner nodes because they're removed by the top
10447 // call anyway. We also want to call componentWillUnmount on all
10448 // composites before this host node is removed from the tree. Therefore
10449 var node = root;
10450 while (true) {
10451 commitUnmount(node);
10452 // Visit children because they may contain more composite or host nodes.
10453 // Skip portals because commitUnmount() currently visits them recursively.
10454 if (node.child !== null && (
10455 // If we use mutation we drill down into portals using commitUnmount above.
10456 // If we don't use mutation we drill down into portals here instead.
10457 !mutation || node.tag !== HostPortal)) {
10458 node.child['return'] = node;
10459 node = node.child;
10460 continue;
10461 }
10462 if (node === root) {
10463 return;
10464 }
10465 while (node.sibling === null) {
10466 if (node['return'] === null || node['return'] === root) {
10467 return;
10468 }
10469 node = node['return'];
10470 }
10471 node.sibling['return'] = node['return'];
10472 node = node.sibling;
10473 }
10474 }
10475
10476 function detachFiber(current) {
10477 // Cut off the return pointers to disconnect it from the tree. Ideally, we
10478 // should clear the child pointer of the parent alternate to let this
10479 // get GC:ed but we don't know which for sure which parent is the current
10480 // one so we'll settle for GC:ing the subtree of this child. This child
10481 // itself will be GC:ed when the parent updates the next time.
10482 current['return'] = null;
10483 current.child = null;
10484 if (current.alternate) {
10485 current.alternate.child = null;
10486 current.alternate['return'] = null;
10487 }
10488 }
10489
10490 var emptyPortalContainer = void 0;
10491
10492 if (!mutation) {
10493 var commitContainer = void 0;
10494 if (persistence) {
10495 var replaceContainerChildren = persistence.replaceContainerChildren,
10496 createContainerChildSet = persistence.createContainerChildSet;
10497
10498 emptyPortalContainer = function (current) {
10499 var portal = current.stateNode;
10500 var containerInfo = portal.containerInfo;
10501
10502 var emptyChildSet = createContainerChildSet(containerInfo);
10503 replaceContainerChildren(containerInfo, emptyChildSet);
10504 };
10505 commitContainer = function (finishedWork) {
10506 switch (finishedWork.tag) {
10507 case ClassComponent:
10508 {
10509 return;
10510 }
10511 case HostComponent:
10512 {
10513 return;
10514 }
10515 case HostText:
10516 {
10517 return;
10518 }
10519 case HostRoot:
10520 case HostPortal:
10521 {
10522 var portalOrRoot = finishedWork.stateNode;
10523 var containerInfo = portalOrRoot.containerInfo,
10524 _pendingChildren = portalOrRoot.pendingChildren;
10525
10526 replaceContainerChildren(containerInfo, _pendingChildren);
10527 return;
10528 }
10529 default:
10530 {
10531 invariant_1(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10532 }
10533 }
10534 };
10535 } else {
10536 commitContainer = function (finishedWork) {
10537 // Noop
10538 };
10539 }
10540 if (enablePersistentReconciler || enableNoopReconciler) {
10541 return {
10542 commitResetTextContent: function (finishedWork) {},
10543 commitPlacement: function (finishedWork) {},
10544 commitDeletion: function (current) {
10545 // Detach refs and call componentWillUnmount() on the whole subtree.
10546 commitNestedUnmounts(current);
10547 detachFiber(current);
10548 },
10549 commitWork: function (current, finishedWork) {
10550 commitContainer(finishedWork);
10551 },
10552
10553 commitLifeCycles: commitLifeCycles,
10554 commitErrorLogging: commitErrorLogging,
10555 commitAttachRef: commitAttachRef,
10556 commitDetachRef: commitDetachRef
10557 };
10558 } else if (persistence) {
10559 invariant_1(false, 'Persistent reconciler is disabled.');
10560 } else {
10561 invariant_1(false, 'Noop reconciler is disabled.');
10562 }
10563 }
10564 var commitMount = mutation.commitMount,
10565 commitUpdate = mutation.commitUpdate,
10566 resetTextContent = mutation.resetTextContent,
10567 commitTextUpdate = mutation.commitTextUpdate,
10568 appendChild = mutation.appendChild,
10569 appendChildToContainer = mutation.appendChildToContainer,
10570 insertBefore = mutation.insertBefore,
10571 insertInContainerBefore = mutation.insertInContainerBefore,
10572 removeChild = mutation.removeChild,
10573 removeChildFromContainer = mutation.removeChildFromContainer;
10574
10575
10576 function getHostParentFiber(fiber) {
10577 var parent = fiber['return'];
10578 while (parent !== null) {
10579 if (isHostParent(parent)) {
10580 return parent;
10581 }
10582 parent = parent['return'];
10583 }
10584 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
10585 }
10586
10587 function isHostParent(fiber) {
10588 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10589 }
10590
10591 function getHostSibling(fiber) {
10592 // We're going to search forward into the tree until we find a sibling host
10593 // node. Unfortunately, if multiple insertions are done in a row we have to
10594 // search past them. This leads to exponential search for the next sibling.
10595 var node = fiber;
10596 siblings: while (true) {
10597 // If we didn't find anything, let's try the next sibling.
10598 while (node.sibling === null) {
10599 if (node['return'] === null || isHostParent(node['return'])) {
10600 // If we pop out of the root or hit the parent the fiber we are the
10601 // last sibling.
10602 return null;
10603 }
10604 node = node['return'];
10605 }
10606 node.sibling['return'] = node['return'];
10607 node = node.sibling;
10608 while (node.tag !== HostComponent && node.tag !== HostText) {
10609 // If it is not host node and, we might have a host node inside it.
10610 // Try to search down until we find one.
10611 if (node.effectTag & Placement) {
10612 // If we don't have a child, try the siblings instead.
10613 continue siblings;
10614 }
10615 // If we don't have a child, try the siblings instead.
10616 // We also skip portals because they are not part of this host tree.
10617 if (node.child === null || node.tag === HostPortal) {
10618 continue siblings;
10619 } else {
10620 node.child['return'] = node;
10621 node = node.child;
10622 }
10623 }
10624 // Check if this host node is stable or about to be placed.
10625 if (!(node.effectTag & Placement)) {
10626 // Found it!
10627 return node.stateNode;
10628 }
10629 }
10630 }
10631
10632 function commitPlacement(finishedWork) {
10633 // Recursively insert all host nodes into the parent.
10634 var parentFiber = getHostParentFiber(finishedWork);
10635 var parent = void 0;
10636 var isContainer = void 0;
10637 switch (parentFiber.tag) {
10638 case HostComponent:
10639 parent = parentFiber.stateNode;
10640 isContainer = false;
10641 break;
10642 case HostRoot:
10643 parent = parentFiber.stateNode.containerInfo;
10644 isContainer = true;
10645 break;
10646 case HostPortal:
10647 parent = parentFiber.stateNode.containerInfo;
10648 isContainer = true;
10649 break;
10650 default:
10651 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
10652 }
10653 if (parentFiber.effectTag & ContentReset) {
10654 // Reset the text content of the parent before doing any insertions
10655 resetTextContent(parent);
10656 // Clear ContentReset from the effect tag
10657 parentFiber.effectTag &= ~ContentReset;
10658 }
10659
10660 var before = getHostSibling(finishedWork);
10661 // We only have the top Fiber that was inserted but we need recurse down its
10662 // children to find all the terminal nodes.
10663 var node = finishedWork;
10664 while (true) {
10665 if (node.tag === HostComponent || node.tag === HostText) {
10666 if (before) {
10667 if (isContainer) {
10668 insertInContainerBefore(parent, node.stateNode, before);
10669 } else {
10670 insertBefore(parent, node.stateNode, before);
10671 }
10672 } else {
10673 if (isContainer) {
10674 appendChildToContainer(parent, node.stateNode);
10675 } else {
10676 appendChild(parent, node.stateNode);
10677 }
10678 }
10679 } else if (node.tag === HostPortal) {
10680 // If the insertion itself is a portal, then we don't want to traverse
10681 // down its children. Instead, we'll get insertions from each child in
10682 // the portal directly.
10683 } else if (node.child !== null) {
10684 node.child['return'] = node;
10685 node = node.child;
10686 continue;
10687 }
10688 if (node === finishedWork) {
10689 return;
10690 }
10691 while (node.sibling === null) {
10692 if (node['return'] === null || node['return'] === finishedWork) {
10693 return;
10694 }
10695 node = node['return'];
10696 }
10697 node.sibling['return'] = node['return'];
10698 node = node.sibling;
10699 }
10700 }
10701
10702 function unmountHostComponents(current) {
10703 // We only have the top Fiber that was inserted but we need recurse down its
10704 var node = current;
10705
10706 // Each iteration, currentParent is populated with node's host parent if not
10707 // currentParentIsValid.
10708 var currentParentIsValid = false;
10709 var currentParent = void 0;
10710 var currentParentIsContainer = void 0;
10711
10712 while (true) {
10713 if (!currentParentIsValid) {
10714 var parent = node['return'];
10715 findParent: while (true) {
10716 !(parent !== null) ? invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10717 switch (parent.tag) {
10718 case HostComponent:
10719 currentParent = parent.stateNode;
10720 currentParentIsContainer = false;
10721 break findParent;
10722 case HostRoot:
10723 currentParent = parent.stateNode.containerInfo;
10724 currentParentIsContainer = true;
10725 break findParent;
10726 case HostPortal:
10727 currentParent = parent.stateNode.containerInfo;
10728 currentParentIsContainer = true;
10729 break findParent;
10730 }
10731 parent = parent['return'];
10732 }
10733 currentParentIsValid = true;
10734 }
10735
10736 if (node.tag === HostComponent || node.tag === HostText) {
10737 commitNestedUnmounts(node);
10738 // After all the children have unmounted, it is now safe to remove the
10739 // node from the tree.
10740 if (currentParentIsContainer) {
10741 removeChildFromContainer(currentParent, node.stateNode);
10742 } else {
10743 removeChild(currentParent, node.stateNode);
10744 }
10745 // Don't visit children because we already visited them.
10746 } else if (node.tag === HostPortal) {
10747 // When we go into a portal, it becomes the parent to remove from.
10748 // We will reassign it back when we pop the portal on the way up.
10749 currentParent = node.stateNode.containerInfo;
10750 // Visit children because portals might contain host components.
10751 if (node.child !== null) {
10752 node.child['return'] = node;
10753 node = node.child;
10754 continue;
10755 }
10756 } else {
10757 commitUnmount(node);
10758 // Visit children because we may find more host components below.
10759 if (node.child !== null) {
10760 node.child['return'] = node;
10761 node = node.child;
10762 continue;
10763 }
10764 }
10765 if (node === current) {
10766 return;
10767 }
10768 while (node.sibling === null) {
10769 if (node['return'] === null || node['return'] === current) {
10770 return;
10771 }
10772 node = node['return'];
10773 if (node.tag === HostPortal) {
10774 // When we go out of the portal, we need to restore the parent.
10775 // Since we don't keep a stack of them, we will search for it.
10776 currentParentIsValid = false;
10777 }
10778 }
10779 node.sibling['return'] = node['return'];
10780 node = node.sibling;
10781 }
10782 }
10783
10784 function commitDeletion(current) {
10785 // Recursively delete all host nodes from the parent.
10786 // Detach refs and call componentWillUnmount() on the whole subtree.
10787 unmountHostComponents(current);
10788 detachFiber(current);
10789 }
10790
10791 function commitWork(current, finishedWork) {
10792 switch (finishedWork.tag) {
10793 case ClassComponent:
10794 {
10795 return;
10796 }
10797 case HostComponent:
10798 {
10799 var _instance7 = finishedWork.stateNode;
10800 if (_instance7 != null) {
10801 // Commit the work prepared earlier.
10802 var newProps = finishedWork.memoizedProps;
10803 // For hydration we reuse the update path but we treat the oldProps
10804 // as the newProps. The updatePayload will contain the real change in
10805 // this case.
10806 var oldProps = current !== null ? current.memoizedProps : newProps;
10807 var type = finishedWork.type;
10808 // TODO: Type the updateQueue to be specific to host components.
10809 var updatePayload = finishedWork.updateQueue;
10810 finishedWork.updateQueue = null;
10811 if (updatePayload !== null) {
10812 commitUpdate(_instance7, updatePayload, type, oldProps, newProps, finishedWork);
10813 }
10814 }
10815 return;
10816 }
10817 case HostText:
10818 {
10819 !(finishedWork.stateNode !== null) ? invariant_1(false, 'This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10820 var textInstance = finishedWork.stateNode;
10821 var newText = finishedWork.memoizedProps;
10822 // For hydration we reuse the update path but we treat the oldProps
10823 // as the newProps. The updatePayload will contain the real change in
10824 // this case.
10825 var oldText = current !== null ? current.memoizedProps : newText;
10826 commitTextUpdate(textInstance, oldText, newText);
10827 return;
10828 }
10829 case HostRoot:
10830 {
10831 return;
10832 }
10833 default:
10834 {
10835 invariant_1(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10836 }
10837 }
10838 }
10839
10840 function commitResetTextContent(current) {
10841 resetTextContent(current.stateNode);
10842 }
10843
10844 if (enableMutatingReconciler) {
10845 return {
10846 commitResetTextContent: commitResetTextContent,
10847 commitPlacement: commitPlacement,
10848 commitDeletion: commitDeletion,
10849 commitWork: commitWork,
10850 commitLifeCycles: commitLifeCycles,
10851 commitErrorLogging: commitErrorLogging,
10852 commitAttachRef: commitAttachRef,
10853 commitDetachRef: commitDetachRef
10854 };
10855 } else {
10856 invariant_1(false, 'Mutating reconciler is disabled.');
10857 }
10858};
10859
10860var NO_CONTEXT = {};
10861
10862var ReactFiberHostContext = function (config) {
10863 var getChildHostContext = config.getChildHostContext,
10864 getRootHostContext = config.getRootHostContext;
10865
10866
10867 var contextStackCursor = createCursor(NO_CONTEXT);
10868 var contextFiberStackCursor = createCursor(NO_CONTEXT);
10869 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
10870
10871 function requiredContext(c) {
10872 !(c !== NO_CONTEXT) ? invariant_1(false, 'Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10873 return c;
10874 }
10875
10876 function getRootHostContainer() {
10877 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10878 return rootInstance;
10879 }
10880
10881 function pushHostContainer(fiber, nextRootInstance) {
10882 // Push current root instance onto the stack;
10883 // This allows us to reset root when portals are popped.
10884 push(rootInstanceStackCursor, nextRootInstance, fiber);
10885
10886 var nextRootContext = getRootHostContext(nextRootInstance);
10887
10888 // Track the context and the Fiber that provided it.
10889 // This enables us to pop only Fibers that provide unique contexts.
10890 push(contextFiberStackCursor, fiber, fiber);
10891 push(contextStackCursor, nextRootContext, fiber);
10892 }
10893
10894 function popHostContainer(fiber) {
10895 pop(contextStackCursor, fiber);
10896 pop(contextFiberStackCursor, fiber);
10897 pop(rootInstanceStackCursor, fiber);
10898 }
10899
10900 function getHostContext() {
10901 var context = requiredContext(contextStackCursor.current);
10902 return context;
10903 }
10904
10905 function pushHostContext(fiber) {
10906 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10907 var context = requiredContext(contextStackCursor.current);
10908 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
10909
10910 // Don't push this Fiber's context unless it's unique.
10911 if (context === nextContext) {
10912 return;
10913 }
10914
10915 // Track the context and the Fiber that provided it.
10916 // This enables us to pop only Fibers that provide unique contexts.
10917 push(contextFiberStackCursor, fiber, fiber);
10918 push(contextStackCursor, nextContext, fiber);
10919 }
10920
10921 function popHostContext(fiber) {
10922 // Do not pop unless this Fiber provided the current context.
10923 // pushHostContext() only pushes Fibers that provide unique contexts.
10924 if (contextFiberStackCursor.current !== fiber) {
10925 return;
10926 }
10927
10928 pop(contextStackCursor, fiber);
10929 pop(contextFiberStackCursor, fiber);
10930 }
10931
10932 function resetHostContainer() {
10933 contextStackCursor.current = NO_CONTEXT;
10934 rootInstanceStackCursor.current = NO_CONTEXT;
10935 }
10936
10937 return {
10938 getHostContext: getHostContext,
10939 getRootHostContainer: getRootHostContainer,
10940 popHostContainer: popHostContainer,
10941 popHostContext: popHostContext,
10942 pushHostContainer: pushHostContainer,
10943 pushHostContext: pushHostContext,
10944 resetHostContainer: resetHostContainer
10945 };
10946};
10947
10948var ReactFiberHydrationContext = function (config) {
10949 var shouldSetTextContent = config.shouldSetTextContent,
10950 hydration = config.hydration;
10951
10952 // If this doesn't have hydration mode.
10953
10954 if (!hydration) {
10955 return {
10956 enterHydrationState: function () {
10957 return false;
10958 },
10959 resetHydrationState: function () {},
10960 tryToClaimNextHydratableInstance: function () {},
10961 prepareToHydrateHostInstance: function () {
10962 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10963 },
10964 prepareToHydrateHostTextInstance: function () {
10965 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10966 },
10967 popHydrationState: function (fiber) {
10968 return false;
10969 }
10970 };
10971 }
10972
10973 var canHydrateInstance = hydration.canHydrateInstance,
10974 canHydrateTextInstance = hydration.canHydrateTextInstance,
10975 getNextHydratableSibling = hydration.getNextHydratableSibling,
10976 getFirstHydratableChild = hydration.getFirstHydratableChild,
10977 hydrateInstance = hydration.hydrateInstance,
10978 hydrateTextInstance = hydration.hydrateTextInstance,
10979 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
10980 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
10981 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
10982 didNotHydrateInstance = hydration.didNotHydrateInstance,
10983 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
10984 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
10985 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
10986 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
10987
10988 // The deepest Fiber on the stack involved in a hydration context.
10989 // This may have been an insertion or a hydration.
10990
10991 var hydrationParentFiber = null;
10992 var nextHydratableInstance = null;
10993 var isHydrating = false;
10994
10995 function enterHydrationState(fiber) {
10996 var parentInstance = fiber.stateNode.containerInfo;
10997 nextHydratableInstance = getFirstHydratableChild(parentInstance);
10998 hydrationParentFiber = fiber;
10999 isHydrating = true;
11000 return true;
11001 }
11002
11003 function deleteHydratableInstance(returnFiber, instance) {
11004 {
11005 switch (returnFiber.tag) {
11006 case HostRoot:
11007 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
11008 break;
11009 case HostComponent:
11010 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
11011 break;
11012 }
11013 }
11014
11015 var childToDelete = createFiberFromHostInstanceForDeletion();
11016 childToDelete.stateNode = instance;
11017 childToDelete['return'] = returnFiber;
11018 childToDelete.effectTag = Deletion;
11019
11020 // This might seem like it belongs on progressedFirstDeletion. However,
11021 // these children are not part of the reconciliation list of children.
11022 // Even if we abort and rereconcile the children, that will try to hydrate
11023 // again and the nodes are still in the host tree so these will be
11024 // recreated.
11025 if (returnFiber.lastEffect !== null) {
11026 returnFiber.lastEffect.nextEffect = childToDelete;
11027 returnFiber.lastEffect = childToDelete;
11028 } else {
11029 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11030 }
11031 }
11032
11033 function insertNonHydratedInstance(returnFiber, fiber) {
11034 fiber.effectTag |= Placement;
11035 {
11036 switch (returnFiber.tag) {
11037 case HostRoot:
11038 {
11039 var parentContainer = returnFiber.stateNode.containerInfo;
11040 switch (fiber.tag) {
11041 case HostComponent:
11042 var type = fiber.type;
11043 var props = fiber.pendingProps;
11044 didNotFindHydratableContainerInstance(parentContainer, type, props);
11045 break;
11046 case HostText:
11047 var text = fiber.pendingProps;
11048 didNotFindHydratableContainerTextInstance(parentContainer, text);
11049 break;
11050 }
11051 break;
11052 }
11053 case HostComponent:
11054 {
11055 var parentType = returnFiber.type;
11056 var parentProps = returnFiber.memoizedProps;
11057 var parentInstance = returnFiber.stateNode;
11058 switch (fiber.tag) {
11059 case HostComponent:
11060 var _type = fiber.type;
11061 var _props = fiber.pendingProps;
11062 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
11063 break;
11064 case HostText:
11065 var _text = fiber.pendingProps;
11066 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
11067 break;
11068 }
11069 break;
11070 }
11071 default:
11072 return;
11073 }
11074 }
11075 }
11076
11077 function tryHydrate(fiber, nextInstance) {
11078 switch (fiber.tag) {
11079 case HostComponent:
11080 {
11081 var type = fiber.type;
11082 var props = fiber.pendingProps;
11083 var instance = canHydrateInstance(nextInstance, type, props);
11084 if (instance !== null) {
11085 fiber.stateNode = instance;
11086 return true;
11087 }
11088 return false;
11089 }
11090 case HostText:
11091 {
11092 var text = fiber.pendingProps;
11093 var textInstance = canHydrateTextInstance(nextInstance, text);
11094 if (textInstance !== null) {
11095 fiber.stateNode = textInstance;
11096 return true;
11097 }
11098 return false;
11099 }
11100 default:
11101 return false;
11102 }
11103 }
11104
11105 function tryToClaimNextHydratableInstance(fiber) {
11106 if (!isHydrating) {
11107 return;
11108 }
11109 var nextInstance = nextHydratableInstance;
11110 if (!nextInstance) {
11111 // Nothing to hydrate. Make it an insertion.
11112 insertNonHydratedInstance(hydrationParentFiber, fiber);
11113 isHydrating = false;
11114 hydrationParentFiber = fiber;
11115 return;
11116 }
11117 if (!tryHydrate(fiber, nextInstance)) {
11118 // If we can't hydrate this instance let's try the next one.
11119 // We use this as a heuristic. It's based on intuition and not data so it
11120 // might be flawed or unnecessary.
11121 nextInstance = getNextHydratableSibling(nextInstance);
11122 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
11123 // Nothing to hydrate. Make it an insertion.
11124 insertNonHydratedInstance(hydrationParentFiber, fiber);
11125 isHydrating = false;
11126 hydrationParentFiber = fiber;
11127 return;
11128 }
11129 // We matched the next one, we'll now assume that the first one was
11130 // superfluous and we'll delete it. Since we can't eagerly delete it
11131 // we'll have to schedule a deletion. To do that, this node needs a dummy
11132 // fiber associated with it.
11133 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
11134 }
11135 hydrationParentFiber = fiber;
11136 nextHydratableInstance = getFirstHydratableChild(nextInstance);
11137 }
11138
11139 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
11140 var instance = fiber.stateNode;
11141 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
11142 // TODO: Type this specific to this type of component.
11143 fiber.updateQueue = updatePayload;
11144 // If the update payload indicates that there is a change or if there
11145 // is a new ref we mark this as an update.
11146 if (updatePayload !== null) {
11147 return true;
11148 }
11149 return false;
11150 }
11151
11152 function prepareToHydrateHostTextInstance(fiber) {
11153 var textInstance = fiber.stateNode;
11154 var textContent = fiber.memoizedProps;
11155 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
11156 {
11157 if (shouldUpdate) {
11158 // We assume that prepareToHydrateHostTextInstance is called in a context where the
11159 // hydration parent is the parent host component of this host text.
11160 var returnFiber = hydrationParentFiber;
11161 if (returnFiber !== null) {
11162 switch (returnFiber.tag) {
11163 case HostRoot:
11164 {
11165 var parentContainer = returnFiber.stateNode.containerInfo;
11166 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
11167 break;
11168 }
11169 case HostComponent:
11170 {
11171 var parentType = returnFiber.type;
11172 var parentProps = returnFiber.memoizedProps;
11173 var parentInstance = returnFiber.stateNode;
11174 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
11175 break;
11176 }
11177 }
11178 }
11179 }
11180 }
11181 return shouldUpdate;
11182 }
11183
11184 function popToNextHostParent(fiber) {
11185 var parent = fiber['return'];
11186 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
11187 parent = parent['return'];
11188 }
11189 hydrationParentFiber = parent;
11190 }
11191
11192 function popHydrationState(fiber) {
11193 if (fiber !== hydrationParentFiber) {
11194 // We're deeper than the current hydration context, inside an inserted
11195 // tree.
11196 return false;
11197 }
11198 if (!isHydrating) {
11199 // If we're not currently hydrating but we're in a hydration context, then
11200 // we were an insertion and now need to pop up reenter hydration of our
11201 // siblings.
11202 popToNextHostParent(fiber);
11203 isHydrating = true;
11204 return false;
11205 }
11206
11207 var type = fiber.type;
11208
11209 // If we have any remaining hydratable nodes, we need to delete them now.
11210 // We only do this deeper than head and body since they tend to have random
11211 // other nodes in them. We also ignore components with pure text content in
11212 // side of them.
11213 // TODO: Better heuristic.
11214 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
11215 var nextInstance = nextHydratableInstance;
11216 while (nextInstance) {
11217 deleteHydratableInstance(fiber, nextInstance);
11218 nextInstance = getNextHydratableSibling(nextInstance);
11219 }
11220 }
11221
11222 popToNextHostParent(fiber);
11223 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
11224 return true;
11225 }
11226
11227 function resetHydrationState() {
11228 hydrationParentFiber = null;
11229 nextHydratableInstance = null;
11230 isHydrating = false;
11231 }
11232
11233 return {
11234 enterHydrationState: enterHydrationState,
11235 resetHydrationState: resetHydrationState,
11236 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
11237 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
11238 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
11239 popHydrationState: popHydrationState
11240 };
11241};
11242
11243// This lets us hook into Fiber to debug what it's doing.
11244// See https://github.com/facebook/react/pull/8033.
11245// This is not part of the public API, not even for React DevTools.
11246// You may only inject a debugTool if you work on React Fiber itself.
11247var ReactFiberInstrumentation = {
11248 debugTool: null
11249};
11250
11251var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
11252
11253var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
11254var hasCaughtError = ReactErrorUtils.hasCaughtError;
11255var clearCaughtError = ReactErrorUtils.clearCaughtError;
11256
11257
11258var didWarnAboutStateTransition = void 0;
11259var didWarnSetStateChildContext = void 0;
11260var warnAboutUpdateOnUnmounted = void 0;
11261var warnAboutInvalidUpdates = void 0;
11262
11263{
11264 didWarnAboutStateTransition = false;
11265 didWarnSetStateChildContext = false;
11266 var didWarnStateUpdateForUnmountedComponent = {};
11267
11268 warnAboutUpdateOnUnmounted = function (fiber) {
11269 var componentName = getComponentName(fiber) || 'ReactClass';
11270 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
11271 return;
11272 }
11273 warning_1(false, 'Can only update a mounted or mounting ' + 'component. This usually means you called setState, replaceState, ' + 'or forceUpdate on an unmounted component. This is a no-op.\n\nPlease ' + 'check the code for the %s component.', componentName);
11274 didWarnStateUpdateForUnmountedComponent[componentName] = true;
11275 };
11276
11277 warnAboutInvalidUpdates = function (instance) {
11278 switch (ReactDebugCurrentFiber.phase) {
11279 case 'getChildContext':
11280 if (didWarnSetStateChildContext) {
11281 return;
11282 }
11283 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
11284 didWarnSetStateChildContext = true;
11285 break;
11286 case 'render':
11287 if (didWarnAboutStateTransition) {
11288 return;
11289 }
11290 warning_1(false, 'Cannot update during an existing state transition (such as within ' + "`render` or another component's constructor). Render methods should " + 'be a pure function of props and state; constructor side-effects are ' + 'an anti-pattern, but can be moved to `componentWillMount`.');
11291 didWarnAboutStateTransition = true;
11292 break;
11293 }
11294 };
11295}
11296
11297var ReactFiberScheduler = function (config) {
11298 var hostContext = ReactFiberHostContext(config);
11299 var popHostContext = hostContext.popHostContext,
11300 popHostContainer = hostContext.popHostContainer;
11301
11302 var hydrationContext = ReactFiberHydrationContext(config);
11303 var resetHostContainer = hostContext.resetHostContainer;
11304
11305 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
11306 beginWork = _ReactFiberBeginWork.beginWork;
11307
11308 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
11309 completeWork = _ReactFiberCompleteWo.completeWork;
11310
11311 var _ReactFiberUnwindWork = ReactFiberUnwindWork(hostContext, scheduleWork, isAlreadyFailedLegacyErrorBoundary),
11312 throwException = _ReactFiberUnwindWork.throwException,
11313 unwindWork = _ReactFiberUnwindWork.unwindWork;
11314
11315 var _ReactFiberCommitWork = ReactFiberCommitWork(config, onCommitPhaseError, scheduleWork, computeExpirationForFiber, markLegacyErrorBoundaryAsFailed, recalculateCurrentTime),
11316 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
11317 commitPlacement = _ReactFiberCommitWork.commitPlacement,
11318 commitDeletion = _ReactFiberCommitWork.commitDeletion,
11319 commitWork = _ReactFiberCommitWork.commitWork,
11320 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
11321 commitErrorLogging = _ReactFiberCommitWork.commitErrorLogging,
11322 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
11323 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
11324
11325 var now = config.now,
11326 scheduleDeferredCallback = config.scheduleDeferredCallback,
11327 cancelDeferredCallback = config.cancelDeferredCallback,
11328 prepareForCommit = config.prepareForCommit,
11329 resetAfterCommit = config.resetAfterCommit;
11330
11331 // Represents the current time in ms.
11332
11333 var originalStartTimeMs = now();
11334 var mostRecentCurrentTime = msToExpirationTime(0);
11335 var mostRecentCurrentTimeMs = originalStartTimeMs;
11336
11337 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
11338 var lastUniqueAsyncExpiration = 0;
11339
11340 // Represents the expiration time that incoming updates should use. (If this
11341 // is NoWork, use the default strategy: async updates in async mode, sync
11342 // updates in sync mode.)
11343 var expirationContext = NoWork;
11344
11345 var isWorking = false;
11346
11347 // The next work in progress fiber that we're currently working on.
11348 var nextUnitOfWork = null;
11349 var nextRoot = null;
11350 // The time at which we're currently rendering work.
11351 var nextRenderExpirationTime = NoWork;
11352
11353 // The next fiber with an effect that we're currently committing.
11354 var nextEffect = null;
11355
11356 var isCommitting = false;
11357
11358 var isRootReadyForCommit = false;
11359
11360 var legacyErrorBoundariesThatAlreadyFailed = null;
11361
11362 // Used for performance tracking.
11363 var interruptedBy = null;
11364
11365 var stashedWorkInProgressProperties = void 0;
11366 var replayUnitOfWork = void 0;
11367 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11368 stashedWorkInProgressProperties = null;
11369 replayUnitOfWork = function (failedUnitOfWork, isAsync) {
11370 // Retore the original state of the work-in-progress
11371 _assign(failedUnitOfWork, stashedWorkInProgressProperties);
11372 switch (failedUnitOfWork.tag) {
11373 case HostRoot:
11374 popHostContainer(failedUnitOfWork);
11375 popTopLevelContextObject(failedUnitOfWork);
11376 break;
11377 case HostComponent:
11378 popHostContext(failedUnitOfWork);
11379 break;
11380 case ClassComponent:
11381 popContextProvider(failedUnitOfWork);
11382 break;
11383 case HostPortal:
11384 popHostContainer(failedUnitOfWork);
11385 break;
11386 case ContextProvider:
11387 popProvider(failedUnitOfWork);
11388 break;
11389 }
11390 // Replay the begin phase.
11391 invokeGuardedCallback$2(null, workLoop, null, isAsync);
11392 if (hasCaughtError()) {
11393 clearCaughtError();
11394 } else {
11395 // This should be unreachable because the render phase is
11396 // idempotent
11397 }
11398 };
11399 }
11400
11401 function resetContextStack() {
11402 // Reset the stack
11403 reset$1();
11404 // Reset the cursors
11405 resetContext();
11406 resetHostContainer();
11407
11408 // TODO: Unify new context implementation with other stacks
11409 resetProviderStack();
11410
11411 {
11412 ReactStrictModeWarnings.discardPendingWarnings();
11413 }
11414
11415 nextRoot = null;
11416 nextRenderExpirationTime = NoWork;
11417 nextUnitOfWork = null;
11418
11419 isRootReadyForCommit = false;
11420 }
11421
11422 function commitAllHostEffects() {
11423 while (nextEffect !== null) {
11424 {
11425 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
11426 }
11427 recordEffect();
11428
11429 var effectTag = nextEffect.effectTag;
11430 if (effectTag & ContentReset) {
11431 commitResetTextContent(nextEffect);
11432 }
11433
11434 if (effectTag & Ref) {
11435 var current = nextEffect.alternate;
11436 if (current !== null) {
11437 commitDetachRef(current);
11438 }
11439 }
11440
11441 // The following switch statement is only concerned about placement,
11442 // updates, and deletions. To avoid needing to add a case for every
11443 // possible bitmap value, we remove the secondary effects from the
11444 // effect tag and switch on that value.
11445 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
11446 switch (primaryEffectTag) {
11447 case Placement:
11448 {
11449 commitPlacement(nextEffect);
11450 // Clear the "placement" from effect tag so that we know that this is inserted, before
11451 // any life-cycles like componentDidMount gets called.
11452 // TODO: findDOMNode doesn't rely on this any more but isMounted
11453 // does and isMounted is deprecated anyway so we should be able
11454 // to kill this.
11455 nextEffect.effectTag &= ~Placement;
11456 break;
11457 }
11458 case PlacementAndUpdate:
11459 {
11460 // Placement
11461 commitPlacement(nextEffect);
11462 // Clear the "placement" from effect tag so that we know that this is inserted, before
11463 // any life-cycles like componentDidMount gets called.
11464 nextEffect.effectTag &= ~Placement;
11465
11466 // Update
11467 var _current = nextEffect.alternate;
11468 commitWork(_current, nextEffect);
11469 break;
11470 }
11471 case Update:
11472 {
11473 var _current2 = nextEffect.alternate;
11474 commitWork(_current2, nextEffect);
11475 break;
11476 }
11477 case Deletion:
11478 {
11479 commitDeletion(nextEffect);
11480 break;
11481 }
11482 }
11483 nextEffect = nextEffect.nextEffect;
11484 }
11485
11486 {
11487 ReactDebugCurrentFiber.resetCurrentFiber();
11488 }
11489 }
11490
11491 function commitAllLifeCycles(finishedRoot, currentTime, committedExpirationTime) {
11492 {
11493 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
11494
11495 if (warnAboutDeprecatedLifecycles) {
11496 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
11497 }
11498 }
11499 while (nextEffect !== null) {
11500 var effectTag = nextEffect.effectTag;
11501
11502 if (effectTag & (Update | Callback)) {
11503 recordEffect();
11504 var current = nextEffect.alternate;
11505 commitLifeCycles(finishedRoot, current, nextEffect, currentTime, committedExpirationTime);
11506 }
11507
11508 if (effectTag & ErrLog) {
11509 commitErrorLogging(nextEffect, onUncaughtError);
11510 }
11511
11512 if (effectTag & Ref) {
11513 recordEffect();
11514 commitAttachRef(nextEffect);
11515 }
11516
11517 var next = nextEffect.nextEffect;
11518 // Ensure that we clean these up so that we don't accidentally keep them.
11519 // I'm not actually sure this matters because we can't reset firstEffect
11520 // and lastEffect since they're on every node, not just the effectful
11521 // ones. So we have to clean everything as we reuse nodes anyway.
11522 nextEffect.nextEffect = null;
11523 // Ensure that we reset the effectTag here so that we can rely on effect
11524 // tags to reason about the current life-cycle.
11525 nextEffect = next;
11526 }
11527 }
11528
11529 function isAlreadyFailedLegacyErrorBoundary(instance) {
11530 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
11531 }
11532
11533 function markLegacyErrorBoundaryAsFailed(instance) {
11534 if (legacyErrorBoundariesThatAlreadyFailed === null) {
11535 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
11536 } else {
11537 legacyErrorBoundariesThatAlreadyFailed.add(instance);
11538 }
11539 }
11540
11541 function commitRoot(finishedWork) {
11542 isWorking = true;
11543 isCommitting = true;
11544 startCommitTimer();
11545
11546 var root = finishedWork.stateNode;
11547 !(root.current !== finishedWork) ? invariant_1(false, 'Cannot commit the same tree as before. This is probably a bug related to the return field. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11548 var committedExpirationTime = root.pendingCommitExpirationTime;
11549 !(committedExpirationTime !== NoWork) ? invariant_1(false, 'Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11550 root.pendingCommitExpirationTime = NoWork;
11551
11552 var currentTime = recalculateCurrentTime();
11553
11554 // Reset this to null before calling lifecycles
11555 ReactCurrentOwner.current = null;
11556
11557 var firstEffect = void 0;
11558 if (finishedWork.effectTag > PerformedWork) {
11559 // A fiber's effect list consists only of its children, not itself. So if
11560 // the root has an effect, we need to add it to the end of the list. The
11561 // resulting list is the set that would belong to the root's parent, if
11562 // it had one; that is, all the effects in the tree including the root.
11563 if (finishedWork.lastEffect !== null) {
11564 finishedWork.lastEffect.nextEffect = finishedWork;
11565 firstEffect = finishedWork.firstEffect;
11566 } else {
11567 firstEffect = finishedWork;
11568 }
11569 } else {
11570 // There is no effect on the root.
11571 firstEffect = finishedWork.firstEffect;
11572 }
11573
11574 prepareForCommit(root.containerInfo);
11575
11576 // Commit all the side-effects within a tree. We'll do this in two passes.
11577 // The first pass performs all the host insertions, updates, deletions and
11578 // ref unmounts.
11579 nextEffect = firstEffect;
11580 startCommitHostEffectsTimer();
11581 while (nextEffect !== null) {
11582 var didError = false;
11583 var error = void 0;
11584 {
11585 invokeGuardedCallback$2(null, commitAllHostEffects, null);
11586 if (hasCaughtError()) {
11587 didError = true;
11588 error = clearCaughtError();
11589 }
11590 }
11591 if (didError) {
11592 !(nextEffect !== null) ? invariant_1(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11593 onCommitPhaseError(nextEffect, error);
11594 // Clean-up
11595 if (nextEffect !== null) {
11596 nextEffect = nextEffect.nextEffect;
11597 }
11598 }
11599 }
11600 stopCommitHostEffectsTimer();
11601
11602 resetAfterCommit(root.containerInfo);
11603
11604 // The work-in-progress tree is now the current tree. This must come after
11605 // the first pass of the commit phase, so that the previous tree is still
11606 // current during componentWillUnmount, but before the second pass, so that
11607 // the finished work is current during componentDidMount/Update.
11608 root.current = finishedWork;
11609
11610 // In the second pass we'll perform all life-cycles and ref callbacks.
11611 // Life-cycles happen as a separate pass so that all placements, updates,
11612 // and deletions in the entire tree have already been invoked.
11613 // This pass also triggers any renderer-specific initial effects.
11614 nextEffect = firstEffect;
11615 startCommitLifeCyclesTimer();
11616 while (nextEffect !== null) {
11617 var _didError = false;
11618 var _error = void 0;
11619 {
11620 invokeGuardedCallback$2(null, commitAllLifeCycles, null, root, currentTime, committedExpirationTime);
11621 if (hasCaughtError()) {
11622 _didError = true;
11623 _error = clearCaughtError();
11624 }
11625 }
11626 if (_didError) {
11627 !(nextEffect !== null) ? invariant_1(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11628 onCommitPhaseError(nextEffect, _error);
11629 if (nextEffect !== null) {
11630 nextEffect = nextEffect.nextEffect;
11631 }
11632 }
11633 }
11634
11635 isCommitting = false;
11636 isWorking = false;
11637 stopCommitLifeCyclesTimer();
11638 stopCommitTimer();
11639 if (typeof onCommitRoot === 'function') {
11640 onCommitRoot(finishedWork.stateNode);
11641 }
11642 if (true && ReactFiberInstrumentation_1.debugTool) {
11643 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11644 }
11645
11646 var remainingTime = root.current.expirationTime;
11647 if (remainingTime === NoWork) {
11648 // If there's no remaining work, we can clear the set of already failed
11649 // error boundaries.
11650 legacyErrorBoundariesThatAlreadyFailed = null;
11651 }
11652 return remainingTime;
11653 }
11654
11655 function resetExpirationTime(workInProgress, renderTime) {
11656 if (renderTime !== Never && workInProgress.expirationTime === Never) {
11657 // The children of this component are hidden. Don't bubble their
11658 // expiration times.
11659 return;
11660 }
11661
11662 // Check for pending updates.
11663 var newExpirationTime = getUpdateExpirationTime(workInProgress);
11664
11665 // TODO: Calls need to visit stateNode
11666
11667 // Bubble up the earliest expiration time.
11668 var child = workInProgress.child;
11669 while (child !== null) {
11670 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
11671 newExpirationTime = child.expirationTime;
11672 }
11673 child = child.sibling;
11674 }
11675 workInProgress.expirationTime = newExpirationTime;
11676 }
11677
11678 function completeUnitOfWork(workInProgress) {
11679 // Attempt to complete the current unit of work, then move to the
11680 // next sibling. If there are no more siblings, return to the
11681 // parent fiber.
11682 while (true) {
11683 // The current, flushed, state of this fiber is the alternate.
11684 // Ideally nothing should rely on this, but relying on it here
11685 // means that we don't need an additional field on the work in
11686 // progress.
11687 var current = workInProgress.alternate;
11688 {
11689 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
11690 }
11691
11692 var returnFiber = workInProgress['return'];
11693 var siblingFiber = workInProgress.sibling;
11694
11695 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11696 // This fiber completed.
11697 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
11698 stopWorkTimer(workInProgress);
11699 resetExpirationTime(workInProgress, nextRenderExpirationTime);
11700 {
11701 ReactDebugCurrentFiber.resetCurrentFiber();
11702 }
11703
11704 if (next !== null) {
11705 stopWorkTimer(workInProgress);
11706 if (true && ReactFiberInstrumentation_1.debugTool) {
11707 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11708 }
11709 // If completing this work spawned new work, do that next. We'll come
11710 // back here again.
11711 return next;
11712 }
11713
11714 if (returnFiber !== null &&
11715 // Do not append effects to parents if a sibling failed to complete
11716 (returnFiber.effectTag & Incomplete) === NoEffect) {
11717 // Append all the effects of the subtree and this fiber onto the effect
11718 // list of the parent. The completion order of the children affects the
11719 // side-effect order.
11720 if (returnFiber.firstEffect === null) {
11721 returnFiber.firstEffect = workInProgress.firstEffect;
11722 }
11723 if (workInProgress.lastEffect !== null) {
11724 if (returnFiber.lastEffect !== null) {
11725 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11726 }
11727 returnFiber.lastEffect = workInProgress.lastEffect;
11728 }
11729
11730 // If this fiber had side-effects, we append it AFTER the children's
11731 // side-effects. We can perform certain side-effects earlier if
11732 // needed, by doing multiple passes over the effect list. We don't want
11733 // to schedule our own side-effect on our own list because if end up
11734 // reusing children we'll schedule this effect onto itself since we're
11735 // at the end.
11736 var effectTag = workInProgress.effectTag;
11737 // Skip both NoWork and PerformedWork tags when creating the effect list.
11738 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11739 if (effectTag > PerformedWork) {
11740 if (returnFiber.lastEffect !== null) {
11741 returnFiber.lastEffect.nextEffect = workInProgress;
11742 } else {
11743 returnFiber.firstEffect = workInProgress;
11744 }
11745 returnFiber.lastEffect = workInProgress;
11746 }
11747 }
11748
11749 if (true && ReactFiberInstrumentation_1.debugTool) {
11750 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11751 }
11752
11753 if (siblingFiber !== null) {
11754 // If there is more work to do in this returnFiber, do that next.
11755 return siblingFiber;
11756 } else if (returnFiber !== null) {
11757 // If there's no more work in this returnFiber. Complete the returnFiber.
11758 workInProgress = returnFiber;
11759 continue;
11760 } else {
11761 // We've reached the root.
11762 isRootReadyForCommit = true;
11763 return null;
11764 }
11765 } else {
11766 // This fiber did not complete because something threw. Pop values off
11767 // the stack without entering the complete phase. If this is a boundary,
11768 // capture values if possible.
11769 var _next = unwindWork(workInProgress);
11770 // Because this fiber did not complete, don't reset its expiration time.
11771 if (workInProgress.effectTag & DidCapture) {
11772 // Restarting an error boundary
11773 stopFailedWorkTimer(workInProgress);
11774 } else {
11775 stopWorkTimer(workInProgress);
11776 }
11777
11778 {
11779 ReactDebugCurrentFiber.resetCurrentFiber();
11780 }
11781
11782 if (_next !== null) {
11783 stopWorkTimer(workInProgress);
11784 if (true && ReactFiberInstrumentation_1.debugTool) {
11785 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11786 }
11787 // If completing this work spawned new work, do that next. We'll come
11788 // back here again.
11789 // Since we're restarting, remove anything that is not a host effect
11790 // from the effect tag.
11791 _next.effectTag &= HostEffectMask;
11792 return _next;
11793 }
11794
11795 if (returnFiber !== null) {
11796 // Mark the parent fiber as incomplete and clear its effect list.
11797 returnFiber.firstEffect = returnFiber.lastEffect = null;
11798 returnFiber.effectTag |= Incomplete;
11799 }
11800
11801 if (true && ReactFiberInstrumentation_1.debugTool) {
11802 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11803 }
11804
11805 if (siblingFiber !== null) {
11806 // If there is more work to do in this returnFiber, do that next.
11807 return siblingFiber;
11808 } else if (returnFiber !== null) {
11809 // If there's no more work in this returnFiber. Complete the returnFiber.
11810 workInProgress = returnFiber;
11811 continue;
11812 } else {
11813 return null;
11814 }
11815 }
11816 }
11817
11818 // Without this explicit null return Flow complains of invalid return type
11819 // TODO Remove the above while(true) loop
11820 // eslint-disable-next-line no-unreachable
11821 return null;
11822 }
11823
11824 function performUnitOfWork(workInProgress) {
11825 // The current, flushed, state of this fiber is the alternate.
11826 // Ideally nothing should rely on this, but relying on it here
11827 // means that we don't need an additional field on the work in
11828 // progress.
11829 var current = workInProgress.alternate;
11830
11831 // See if beginning this work spawns more work.
11832 startWorkTimer(workInProgress);
11833 {
11834 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
11835 }
11836
11837 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11838 stashedWorkInProgressProperties = _assign({}, workInProgress);
11839 }
11840 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
11841
11842 {
11843 ReactDebugCurrentFiber.resetCurrentFiber();
11844 }
11845 if (true && ReactFiberInstrumentation_1.debugTool) {
11846 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11847 }
11848
11849 if (next === null) {
11850 // If this doesn't spawn new work, complete the current work.
11851 next = completeUnitOfWork(workInProgress);
11852 }
11853
11854 ReactCurrentOwner.current = null;
11855
11856 return next;
11857 }
11858
11859 function workLoop(isAsync) {
11860 if (!isAsync) {
11861 // Flush all expired work.
11862 while (nextUnitOfWork !== null) {
11863 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11864 }
11865 } else {
11866 // Flush asynchronous work until the deadline runs out of time.
11867 while (nextUnitOfWork !== null && !shouldYield()) {
11868 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11869 }
11870 }
11871 }
11872
11873 function renderRoot(root, expirationTime, isAsync) {
11874 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11875 isWorking = true;
11876
11877 // Check if we're starting from a fresh stack, or if we're resuming from
11878 // previously yielded work.
11879 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11880 // Reset the stack and start working from the root.
11881 resetContextStack();
11882 nextRoot = root;
11883 nextRenderExpirationTime = expirationTime;
11884 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11885 root.pendingCommitExpirationTime = NoWork;
11886 }
11887
11888 var didFatal = false;
11889
11890 startWorkLoopTimer(nextUnitOfWork);
11891
11892 do {
11893 try {
11894 workLoop(isAsync);
11895 } catch (thrownValue) {
11896 if (nextUnitOfWork === null) {
11897 // This is a fatal error.
11898 didFatal = true;
11899 onUncaughtError(thrownValue);
11900 break;
11901 }
11902
11903 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11904 var failedUnitOfWork = nextUnitOfWork;
11905 replayUnitOfWork(failedUnitOfWork, isAsync);
11906 }
11907
11908 var sourceFiber = nextUnitOfWork;
11909 var returnFiber = sourceFiber['return'];
11910 if (returnFiber === null) {
11911 // This is a fatal error.
11912 didFatal = true;
11913 onUncaughtError(thrownValue);
11914 break;
11915 }
11916 throwException(returnFiber, sourceFiber, thrownValue);
11917 nextUnitOfWork = completeUnitOfWork(sourceFiber);
11918 }
11919 break;
11920 } while (true);
11921
11922 // We're done performing work. Time to clean up.
11923 stopWorkLoopTimer(interruptedBy);
11924 interruptedBy = null;
11925 isWorking = false;
11926
11927 // Yield back to main thread.
11928 if (didFatal) {
11929 // There was a fatal error.
11930 return null;
11931 } else if (nextUnitOfWork === null) {
11932 // We reached the root.
11933 if (isRootReadyForCommit) {
11934 // The root successfully completed. It's ready for commit.
11935 root.pendingCommitExpirationTime = expirationTime;
11936 var finishedWork = root.current.alternate;
11937 return finishedWork;
11938 } else {
11939 // The root did not complete.
11940 invariant_1(false, 'Expired work should have completed. This error is likely caused by a bug in React. Please file an issue.');
11941 }
11942 } else {
11943 // There's more work to do, but we ran out of time. Yield back to
11944 // the renderer.
11945 return null;
11946 }
11947 }
11948
11949 function scheduleCapture(sourceFiber, boundaryFiber, value, expirationTime) {
11950 // TODO: We only support dispatching errors.
11951 var capturedValue = createCapturedValue(value, sourceFiber);
11952 var update = {
11953 expirationTime: expirationTime,
11954 partialState: null,
11955 callback: null,
11956 isReplace: false,
11957 isForced: false,
11958 capturedValue: capturedValue,
11959 next: null
11960 };
11961 insertUpdateIntoFiber(boundaryFiber, update);
11962 scheduleWork(boundaryFiber, expirationTime);
11963 }
11964
11965 function dispatch(sourceFiber, value, expirationTime) {
11966 !(!isWorking || isCommitting) ? invariant_1(false, 'dispatch: Cannot dispatch during the render phase.') : void 0;
11967
11968 // TODO: Handle arrays
11969
11970 var fiber = sourceFiber['return'];
11971 while (fiber !== null) {
11972 switch (fiber.tag) {
11973 case ClassComponent:
11974 var ctor = fiber.type;
11975 var instance = fiber.stateNode;
11976 if (typeof ctor.getDerivedStateFromCatch === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
11977 scheduleCapture(sourceFiber, fiber, value, expirationTime);
11978 return;
11979 }
11980 break;
11981 // TODO: Handle async boundaries
11982 case HostRoot:
11983 scheduleCapture(sourceFiber, fiber, value, expirationTime);
11984 return;
11985 }
11986 fiber = fiber['return'];
11987 }
11988
11989 if (sourceFiber.tag === HostRoot) {
11990 // Error was thrown at the root. There is no parent, so the root
11991 // itself should capture it.
11992 scheduleCapture(sourceFiber, sourceFiber, value, expirationTime);
11993 }
11994 }
11995
11996 function onCommitPhaseError(fiber, error) {
11997 return dispatch(fiber, error, Sync);
11998 }
11999
12000 function computeAsyncExpiration(currentTime) {
12001 // Given the current clock time, returns an expiration time. We use rounding
12002 // to batch like updates together.
12003 // Should complete within ~1000ms. 1200ms max.
12004 var expirationMs = 5000;
12005 var bucketSizeMs = 250;
12006 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
12007 }
12008
12009 function computeInteractiveExpiration(currentTime) {
12010 // Should complete within ~500ms. 600ms max.
12011 var expirationMs = 500;
12012 var bucketSizeMs = 100;
12013 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
12014 }
12015
12016 // Creates a unique async expiration time.
12017 function computeUniqueAsyncExpiration() {
12018 var currentTime = recalculateCurrentTime();
12019 var result = computeAsyncExpiration(currentTime);
12020 if (result <= lastUniqueAsyncExpiration) {
12021 // Since we assume the current time monotonically increases, we only hit
12022 // this branch when computeUniqueAsyncExpiration is fired multiple times
12023 // within a 200ms window (or whatever the async bucket size is).
12024 result = lastUniqueAsyncExpiration + 1;
12025 }
12026 lastUniqueAsyncExpiration = result;
12027 return lastUniqueAsyncExpiration;
12028 }
12029
12030 function computeExpirationForFiber(fiber) {
12031 var expirationTime = void 0;
12032 if (expirationContext !== NoWork) {
12033 // An explicit expiration context was set;
12034 expirationTime = expirationContext;
12035 } else if (isWorking) {
12036 if (isCommitting) {
12037 // Updates that occur during the commit phase should have sync priority
12038 // by default.
12039 expirationTime = Sync;
12040 } else {
12041 // Updates during the render phase should expire at the same time as
12042 // the work that is being rendered.
12043 expirationTime = nextRenderExpirationTime;
12044 }
12045 } else {
12046 // No explicit expiration context was set, and we're not currently
12047 // performing work. Calculate a new expiration time.
12048 if (fiber.mode & AsyncMode) {
12049 if (isBatchingInteractiveUpdates) {
12050 // This is an interactive update
12051 var currentTime = recalculateCurrentTime();
12052 expirationTime = computeInteractiveExpiration(currentTime);
12053 } else {
12054 // This is an async update
12055 var _currentTime = recalculateCurrentTime();
12056 expirationTime = computeAsyncExpiration(_currentTime);
12057 }
12058 } else {
12059 // This is a sync update
12060 expirationTime = Sync;
12061 }
12062 }
12063 if (isBatchingInteractiveUpdates) {
12064 // This is an interactive update. Keep track of the lowest pending
12065 // interactive expiration time. This allows us to synchronously flush
12066 // all interactive updates when needed.
12067 if (lowestPendingInteractiveExpirationTime === NoWork || expirationTime > lowestPendingInteractiveExpirationTime) {
12068 lowestPendingInteractiveExpirationTime = expirationTime;
12069 }
12070 }
12071 return expirationTime;
12072 }
12073
12074 function scheduleWork(fiber, expirationTime) {
12075 return scheduleWorkImpl(fiber, expirationTime, false);
12076 }
12077
12078 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
12079 recordScheduleUpdate();
12080
12081 {
12082 if (!isErrorRecovery && fiber.tag === ClassComponent) {
12083 var instance = fiber.stateNode;
12084 warnAboutInvalidUpdates(instance);
12085 }
12086 }
12087
12088 var node = fiber;
12089 while (node !== null) {
12090 // Walk the parent path to the root and update each node's
12091 // expiration time.
12092 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
12093 node.expirationTime = expirationTime;
12094 }
12095 if (node.alternate !== null) {
12096 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
12097 node.alternate.expirationTime = expirationTime;
12098 }
12099 }
12100 if (node['return'] === null) {
12101 if (node.tag === HostRoot) {
12102 var root = node.stateNode;
12103 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime < nextRenderExpirationTime) {
12104 // This is an interruption. (Used for performance tracking.)
12105 interruptedBy = fiber;
12106 resetContextStack();
12107 }
12108 if (nextRoot !== root || !isWorking) {
12109 requestWork(root, expirationTime);
12110 }
12111 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12112 invariant_1(false, '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.');
12113 }
12114 } else {
12115 {
12116 if (!isErrorRecovery && fiber.tag === ClassComponent) {
12117 warnAboutUpdateOnUnmounted(fiber);
12118 }
12119 }
12120 return;
12121 }
12122 }
12123 node = node['return'];
12124 }
12125 }
12126
12127 function recalculateCurrentTime() {
12128 // Subtract initial time so it fits inside 32bits
12129 mostRecentCurrentTimeMs = now() - originalStartTimeMs;
12130 mostRecentCurrentTime = msToExpirationTime(mostRecentCurrentTimeMs);
12131 return mostRecentCurrentTime;
12132 }
12133
12134 function deferredUpdates(fn) {
12135 var previousExpirationContext = expirationContext;
12136 var currentTime = recalculateCurrentTime();
12137 expirationContext = computeAsyncExpiration(currentTime);
12138 try {
12139 return fn();
12140 } finally {
12141 expirationContext = previousExpirationContext;
12142 }
12143 }
12144 function syncUpdates(fn, a, b, c, d) {
12145 var previousExpirationContext = expirationContext;
12146 expirationContext = Sync;
12147 try {
12148 return fn(a, b, c, d);
12149 } finally {
12150 expirationContext = previousExpirationContext;
12151 }
12152 }
12153
12154 // TODO: Everything below this is written as if it has been lifted to the
12155 // renderers. I'll do this in a follow-up.
12156
12157 // Linked-list of roots
12158 var firstScheduledRoot = null;
12159 var lastScheduledRoot = null;
12160
12161 var callbackExpirationTime = NoWork;
12162 var callbackID = -1;
12163 var isRendering = false;
12164 var nextFlushedRoot = null;
12165 var nextFlushedExpirationTime = NoWork;
12166 var lowestPendingInteractiveExpirationTime = NoWork;
12167 var deadlineDidExpire = false;
12168 var hasUnhandledError = false;
12169 var unhandledError = null;
12170 var deadline = null;
12171
12172 var isBatchingUpdates = false;
12173 var isUnbatchingUpdates = false;
12174 var isBatchingInteractiveUpdates = false;
12175
12176 var completedBatches = null;
12177
12178 // Use these to prevent an infinite loop of nested updates
12179 var NESTED_UPDATE_LIMIT = 1000;
12180 var nestedUpdateCount = 0;
12181
12182 var timeHeuristicForUnitOfWork = 1;
12183
12184 function scheduleCallbackWithExpiration(expirationTime) {
12185 if (callbackExpirationTime !== NoWork) {
12186 // A callback is already scheduled. Check its expiration time (timeout).
12187 if (expirationTime > callbackExpirationTime) {
12188 // Existing callback has sufficient timeout. Exit.
12189 return;
12190 } else {
12191 // Existing callback has insufficient timeout. Cancel and schedule a
12192 // new one.
12193 cancelDeferredCallback(callbackID);
12194 }
12195 // The request callback timer is already running. Don't start a new one.
12196 } else {
12197 startRequestCallbackTimer();
12198 }
12199
12200 // Compute a timeout for the given expiration time.
12201 var currentMs = now() - originalStartTimeMs;
12202 var expirationMs = expirationTimeToMs(expirationTime);
12203 var timeout = expirationMs - currentMs;
12204
12205 callbackExpirationTime = expirationTime;
12206 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
12207 }
12208
12209 // requestWork is called by the scheduler whenever a root receives an update.
12210 // It's up to the renderer to call renderRoot at some point in the future.
12211 function requestWork(root, expirationTime) {
12212 addRootToSchedule(root, expirationTime);
12213
12214 if (isRendering) {
12215 // Prevent reentrancy. Remaining work will be scheduled at the end of
12216 // the currently rendering batch.
12217 return;
12218 }
12219
12220 if (isBatchingUpdates) {
12221 // Flush work at the end of the batch.
12222 if (isUnbatchingUpdates) {
12223 // ...unless we're inside unbatchedUpdates, in which case we should
12224 // flush it now.
12225 nextFlushedRoot = root;
12226 nextFlushedExpirationTime = Sync;
12227 performWorkOnRoot(root, Sync, false);
12228 }
12229 return;
12230 }
12231
12232 // TODO: Get rid of Sync and use current time?
12233 if (expirationTime === Sync) {
12234 performSyncWork();
12235 } else {
12236 scheduleCallbackWithExpiration(expirationTime);
12237 }
12238 }
12239
12240 function addRootToSchedule(root, expirationTime) {
12241 // Add the root to the schedule.
12242 // Check if this root is already part of the schedule.
12243 if (root.nextScheduledRoot === null) {
12244 // This root is not already scheduled. Add it.
12245 root.remainingExpirationTime = expirationTime;
12246 if (lastScheduledRoot === null) {
12247 firstScheduledRoot = lastScheduledRoot = root;
12248 root.nextScheduledRoot = root;
12249 } else {
12250 lastScheduledRoot.nextScheduledRoot = root;
12251 lastScheduledRoot = root;
12252 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12253 }
12254 } else {
12255 // This root is already scheduled, but its priority may have increased.
12256 var remainingExpirationTime = root.remainingExpirationTime;
12257 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
12258 // Update the priority.
12259 root.remainingExpirationTime = expirationTime;
12260 }
12261 }
12262 }
12263
12264 function findHighestPriorityRoot() {
12265 var highestPriorityWork = NoWork;
12266 var highestPriorityRoot = null;
12267 if (lastScheduledRoot !== null) {
12268 var previousScheduledRoot = lastScheduledRoot;
12269 var root = firstScheduledRoot;
12270 while (root !== null) {
12271 var remainingExpirationTime = root.remainingExpirationTime;
12272 if (remainingExpirationTime === NoWork) {
12273 // This root no longer has work. Remove it from the scheduler.
12274
12275 // TODO: This check is redudant, but Flow is confused by the branch
12276 // below where we set lastScheduledRoot to null, even though we break
12277 // from the loop right after.
12278 !(previousScheduledRoot !== null && lastScheduledRoot !== null) ? invariant_1(false, 'Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12279 if (root === root.nextScheduledRoot) {
12280 // This is the only root in the list.
12281 root.nextScheduledRoot = null;
12282 firstScheduledRoot = lastScheduledRoot = null;
12283 break;
12284 } else if (root === firstScheduledRoot) {
12285 // This is the first root in the list.
12286 var next = root.nextScheduledRoot;
12287 firstScheduledRoot = next;
12288 lastScheduledRoot.nextScheduledRoot = next;
12289 root.nextScheduledRoot = null;
12290 } else if (root === lastScheduledRoot) {
12291 // This is the last root in the list.
12292 lastScheduledRoot = previousScheduledRoot;
12293 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12294 root.nextScheduledRoot = null;
12295 break;
12296 } else {
12297 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12298 root.nextScheduledRoot = null;
12299 }
12300 root = previousScheduledRoot.nextScheduledRoot;
12301 } else {
12302 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
12303 // Update the priority, if it's higher
12304 highestPriorityWork = remainingExpirationTime;
12305 highestPriorityRoot = root;
12306 }
12307 if (root === lastScheduledRoot) {
12308 break;
12309 }
12310 previousScheduledRoot = root;
12311 root = root.nextScheduledRoot;
12312 }
12313 }
12314 }
12315
12316 // If the next root is the same as the previous root, this is a nested
12317 // update. To prevent an infinite loop, increment the nested update count.
12318 var previousFlushedRoot = nextFlushedRoot;
12319 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot && highestPriorityWork === Sync) {
12320 nestedUpdateCount++;
12321 } else {
12322 // Reset whenever we switch roots.
12323 nestedUpdateCount = 0;
12324 }
12325 nextFlushedRoot = highestPriorityRoot;
12326 nextFlushedExpirationTime = highestPriorityWork;
12327 }
12328
12329 function performAsyncWork(dl) {
12330 performWork(NoWork, true, dl);
12331 }
12332
12333 function performSyncWork() {
12334 performWork(Sync, false, null);
12335 }
12336
12337 function performWork(minExpirationTime, isAsync, dl) {
12338 deadline = dl;
12339
12340 // Keep working on roots until there's no more work, or until the we reach
12341 // the deadline.
12342 findHighestPriorityRoot();
12343
12344 if (enableUserTimingAPI && deadline !== null) {
12345 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
12346 stopRequestCallbackTimer(didExpire);
12347 }
12348
12349 if (isAsync) {
12350 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime) && (!deadlineDidExpire || recalculateCurrentTime() >= nextFlushedExpirationTime)) {
12351 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, !deadlineDidExpire);
12352 findHighestPriorityRoot();
12353 }
12354 } else {
12355 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime)) {
12356 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12357 findHighestPriorityRoot();
12358 }
12359 }
12360
12361 // We're done flushing work. Either we ran out of time in this callback,
12362 // or there's no more work left with sufficient priority.
12363
12364 // If we're inside a callback, set this to false since we just completed it.
12365 if (deadline !== null) {
12366 callbackExpirationTime = NoWork;
12367 callbackID = -1;
12368 }
12369 // If there's work left over, schedule a new callback.
12370 if (nextFlushedExpirationTime !== NoWork) {
12371 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
12372 }
12373
12374 // Clean-up.
12375 deadline = null;
12376 deadlineDidExpire = false;
12377
12378 finishRendering();
12379 }
12380
12381 function flushRoot(root, expirationTime) {
12382 !!isRendering ? invariant_1(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12383 // Perform work on root as if the given expiration time is the current time.
12384 // This has the effect of synchronously flushing all work up to and
12385 // including the given time.
12386 performWorkOnRoot(root, expirationTime, false);
12387 finishRendering();
12388 }
12389
12390 function finishRendering() {
12391 nestedUpdateCount = 0;
12392
12393 if (completedBatches !== null) {
12394 var batches = completedBatches;
12395 completedBatches = null;
12396 for (var i = 0; i < batches.length; i++) {
12397 var batch = batches[i];
12398 try {
12399 batch._onComplete();
12400 } catch (error) {
12401 if (!hasUnhandledError) {
12402 hasUnhandledError = true;
12403 unhandledError = error;
12404 }
12405 }
12406 }
12407 }
12408
12409 if (hasUnhandledError) {
12410 var error = unhandledError;
12411 unhandledError = null;
12412 hasUnhandledError = false;
12413 throw error;
12414 }
12415 }
12416
12417 function performWorkOnRoot(root, expirationTime, isAsync) {
12418 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12419
12420 isRendering = true;
12421
12422 // Check if this is async work or sync/expired work.
12423 if (!isAsync) {
12424 // Flush sync work.
12425 var finishedWork = root.finishedWork;
12426 if (finishedWork !== null) {
12427 // This root is already complete. We can commit it.
12428 completeRoot(root, finishedWork, expirationTime);
12429 } else {
12430 root.finishedWork = null;
12431 finishedWork = renderRoot(root, expirationTime, false);
12432 if (finishedWork !== null) {
12433 // We've completed the root. Commit it.
12434 completeRoot(root, finishedWork, expirationTime);
12435 }
12436 }
12437 } else {
12438 // Flush async work.
12439 var _finishedWork = root.finishedWork;
12440 if (_finishedWork !== null) {
12441 // This root is already complete. We can commit it.
12442 completeRoot(root, _finishedWork, expirationTime);
12443 } else {
12444 root.finishedWork = null;
12445 _finishedWork = renderRoot(root, expirationTime, true);
12446 if (_finishedWork !== null) {
12447 // We've completed the root. Check the deadline one more time
12448 // before committing.
12449 if (!shouldYield()) {
12450 // Still time left. Commit the root.
12451 completeRoot(root, _finishedWork, expirationTime);
12452 } else {
12453 // There's no time left. Mark this root as complete. We'll come
12454 // back and commit it later.
12455 root.finishedWork = _finishedWork;
12456 }
12457 }
12458 }
12459 }
12460
12461 isRendering = false;
12462 }
12463
12464 function completeRoot(root, finishedWork, expirationTime) {
12465 // Check if there's a batch that matches this expiration time.
12466 var firstBatch = root.firstBatch;
12467 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
12468 if (completedBatches === null) {
12469 completedBatches = [firstBatch];
12470 } else {
12471 completedBatches.push(firstBatch);
12472 }
12473 if (firstBatch._defer) {
12474 // This root is blocked from committing by a batch. Unschedule it until
12475 // we receive another update.
12476 root.finishedWork = finishedWork;
12477 root.remainingExpirationTime = NoWork;
12478 return;
12479 }
12480 }
12481
12482 // Commit the root.
12483 root.finishedWork = null;
12484 root.remainingExpirationTime = commitRoot(finishedWork);
12485 }
12486
12487 // When working on async work, the reconciler asks the renderer if it should
12488 // yield execution. For DOM, we implement this with requestIdleCallback.
12489 function shouldYield() {
12490 if (deadline === null) {
12491 return false;
12492 }
12493 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
12494 // Disregard deadline.didTimeout. Only expired work should be flushed
12495 // during a timeout. This path is only hit for non-expired work.
12496 return false;
12497 }
12498 deadlineDidExpire = true;
12499 return true;
12500 }
12501
12502 function onUncaughtError(error) {
12503 !(nextFlushedRoot !== null) ? invariant_1(false, 'Should be working on a root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12504 // Unschedule this root so we don't work on it again until there's
12505 // another update.
12506 nextFlushedRoot.remainingExpirationTime = NoWork;
12507 if (!hasUnhandledError) {
12508 hasUnhandledError = true;
12509 unhandledError = error;
12510 }
12511 }
12512
12513 // TODO: Batching should be implemented at the renderer level, not inside
12514 // the reconciler.
12515 function batchedUpdates(fn, a) {
12516 var previousIsBatchingUpdates = isBatchingUpdates;
12517 isBatchingUpdates = true;
12518 try {
12519 return fn(a);
12520 } finally {
12521 isBatchingUpdates = previousIsBatchingUpdates;
12522 if (!isBatchingUpdates && !isRendering) {
12523 performSyncWork();
12524 }
12525 }
12526 }
12527
12528 // TODO: Batching should be implemented at the renderer level, not inside
12529 // the reconciler.
12530 function unbatchedUpdates(fn, a) {
12531 if (isBatchingUpdates && !isUnbatchingUpdates) {
12532 isUnbatchingUpdates = true;
12533 try {
12534 return fn(a);
12535 } finally {
12536 isUnbatchingUpdates = false;
12537 }
12538 }
12539 return fn(a);
12540 }
12541
12542 // TODO: Batching should be implemented at the renderer level, not within
12543 // the reconciler.
12544 function flushSync(fn, a) {
12545 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
12546 var previousIsBatchingUpdates = isBatchingUpdates;
12547 isBatchingUpdates = true;
12548 try {
12549 return syncUpdates(fn, a);
12550 } finally {
12551 isBatchingUpdates = previousIsBatchingUpdates;
12552 performSyncWork();
12553 }
12554 }
12555
12556 function interactiveUpdates(fn, a, b) {
12557 if (isBatchingInteractiveUpdates) {
12558 return fn(a, b);
12559 }
12560 // If there are any pending interactive updates, synchronously flush them.
12561 // This needs to happen before we read any handlers, because the effect of
12562 // the previous event may influence which handlers are called during
12563 // this event.
12564 if (!isBatchingUpdates && !isRendering && lowestPendingInteractiveExpirationTime !== NoWork) {
12565 // Synchronously flush pending interactive updates.
12566 performWork(lowestPendingInteractiveExpirationTime, false, null);
12567 lowestPendingInteractiveExpirationTime = NoWork;
12568 }
12569 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
12570 var previousIsBatchingUpdates = isBatchingUpdates;
12571 isBatchingInteractiveUpdates = true;
12572 isBatchingUpdates = true;
12573 try {
12574 return fn(a, b);
12575 } finally {
12576 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
12577 isBatchingUpdates = previousIsBatchingUpdates;
12578 if (!isBatchingUpdates && !isRendering) {
12579 performSyncWork();
12580 }
12581 }
12582 }
12583
12584 function flushInteractiveUpdates() {
12585 if (!isRendering && lowestPendingInteractiveExpirationTime !== NoWork) {
12586 // Synchronously flush pending interactive updates.
12587 performWork(lowestPendingInteractiveExpirationTime, false, null);
12588 lowestPendingInteractiveExpirationTime = NoWork;
12589 }
12590 }
12591
12592 function flushControlled(fn) {
12593 var previousIsBatchingUpdates = isBatchingUpdates;
12594 isBatchingUpdates = true;
12595 try {
12596 syncUpdates(fn);
12597 } finally {
12598 isBatchingUpdates = previousIsBatchingUpdates;
12599 if (!isBatchingUpdates && !isRendering) {
12600 performWork(Sync, false, null);
12601 }
12602 }
12603 }
12604
12605 return {
12606 recalculateCurrentTime: recalculateCurrentTime,
12607 computeExpirationForFiber: computeExpirationForFiber,
12608 scheduleWork: scheduleWork,
12609 requestWork: requestWork,
12610 flushRoot: flushRoot,
12611 batchedUpdates: batchedUpdates,
12612 unbatchedUpdates: unbatchedUpdates,
12613 flushSync: flushSync,
12614 flushControlled: flushControlled,
12615 deferredUpdates: deferredUpdates,
12616 syncUpdates: syncUpdates,
12617 interactiveUpdates: interactiveUpdates,
12618 flushInteractiveUpdates: flushInteractiveUpdates,
12619 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
12620 };
12621};
12622
12623var didWarnAboutNestedUpdates = void 0;
12624
12625{
12626 didWarnAboutNestedUpdates = false;
12627}
12628
12629// 0 is PROD, 1 is DEV.
12630// Might add PROFILE later.
12631
12632
12633function getContextForSubtree(parentComponent) {
12634 if (!parentComponent) {
12635 return emptyObject_1;
12636 }
12637
12638 var fiber = get(parentComponent);
12639 var parentContext = findCurrentUnmaskedContext(fiber);
12640 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
12641}
12642
12643var ReactFiberReconciler$1 = function (config) {
12644 var getPublicInstance = config.getPublicInstance;
12645
12646 var _ReactFiberScheduler = ReactFiberScheduler(config),
12647 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
12648 recalculateCurrentTime = _ReactFiberScheduler.recalculateCurrentTime,
12649 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
12650 scheduleWork = _ReactFiberScheduler.scheduleWork,
12651 requestWork = _ReactFiberScheduler.requestWork,
12652 flushRoot = _ReactFiberScheduler.flushRoot,
12653 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
12654 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
12655 flushSync = _ReactFiberScheduler.flushSync,
12656 flushControlled = _ReactFiberScheduler.flushControlled,
12657 deferredUpdates = _ReactFiberScheduler.deferredUpdates,
12658 syncUpdates = _ReactFiberScheduler.syncUpdates,
12659 interactiveUpdates = _ReactFiberScheduler.interactiveUpdates,
12660 flushInteractiveUpdates = _ReactFiberScheduler.flushInteractiveUpdates;
12661
12662 function scheduleRootUpdate(current, element, currentTime, expirationTime, callback) {
12663 {
12664 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
12665 didWarnAboutNestedUpdates = true;
12666 warning_1(false, '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(ReactDebugCurrentFiber.current) || 'Unknown');
12667 }
12668 }
12669
12670 callback = callback === undefined ? null : callback;
12671 {
12672 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
12673 }
12674
12675 var update = {
12676 expirationTime: expirationTime,
12677 partialState: { element: element },
12678 callback: callback,
12679 isReplace: false,
12680 isForced: false,
12681 capturedValue: null,
12682 next: null
12683 };
12684 insertUpdateIntoFiber(current, update);
12685 scheduleWork(current, expirationTime);
12686
12687 return expirationTime;
12688 }
12689
12690 function updateContainerAtExpirationTime(element, container, parentComponent, currentTime, expirationTime, callback) {
12691 // TODO: If this is a nested container, this won't be the root.
12692 var current = container.current;
12693
12694 {
12695 if (ReactFiberInstrumentation_1.debugTool) {
12696 if (current.alternate === null) {
12697 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12698 } else if (element === null) {
12699 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12700 } else {
12701 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12702 }
12703 }
12704 }
12705
12706 var context = getContextForSubtree(parentComponent);
12707 if (container.context === null) {
12708 container.context = context;
12709 } else {
12710 container.pendingContext = context;
12711 }
12712
12713 return scheduleRootUpdate(current, element, currentTime, expirationTime, callback);
12714 }
12715
12716 function findHostInstance(fiber) {
12717 var hostFiber = findCurrentHostFiber(fiber);
12718 if (hostFiber === null) {
12719 return null;
12720 }
12721 return hostFiber.stateNode;
12722 }
12723
12724 return {
12725 createContainer: function (containerInfo, isAsync, hydrate) {
12726 return createFiberRoot(containerInfo, isAsync, hydrate);
12727 },
12728 updateContainer: function (element, container, parentComponent, callback) {
12729 var current = container.current;
12730 var currentTime = recalculateCurrentTime();
12731 var expirationTime = computeExpirationForFiber(current);
12732 return updateContainerAtExpirationTime(element, container, parentComponent, currentTime, expirationTime, callback);
12733 },
12734 updateContainerAtExpirationTime: function (element, container, parentComponent, expirationTime, callback) {
12735 var currentTime = recalculateCurrentTime();
12736 return updateContainerAtExpirationTime(element, container, parentComponent, currentTime, expirationTime, callback);
12737 },
12738
12739
12740 flushRoot: flushRoot,
12741
12742 requestWork: requestWork,
12743
12744 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
12745
12746 batchedUpdates: batchedUpdates,
12747
12748 unbatchedUpdates: unbatchedUpdates,
12749
12750 deferredUpdates: deferredUpdates,
12751
12752 syncUpdates: syncUpdates,
12753
12754 interactiveUpdates: interactiveUpdates,
12755
12756 flushInteractiveUpdates: flushInteractiveUpdates,
12757
12758 flushControlled: flushControlled,
12759
12760 flushSync: flushSync,
12761
12762 getPublicRootInstance: function (container) {
12763 var containerFiber = container.current;
12764 if (!containerFiber.child) {
12765 return null;
12766 }
12767 switch (containerFiber.child.tag) {
12768 case HostComponent:
12769 return getPublicInstance(containerFiber.child.stateNode);
12770 default:
12771 return containerFiber.child.stateNode;
12772 }
12773 },
12774
12775
12776 findHostInstance: findHostInstance,
12777
12778 findHostInstanceWithNoPortals: function (fiber) {
12779 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
12780 if (hostFiber === null) {
12781 return null;
12782 }
12783 return hostFiber.stateNode;
12784 },
12785 injectIntoDevTools: function (devToolsConfig) {
12786 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12787
12788 return injectInternals(_assign({}, devToolsConfig, {
12789 findHostInstanceByFiber: function (fiber) {
12790 return findHostInstance(fiber);
12791 },
12792 findFiberByHostInstance: function (instance) {
12793 if (!findFiberByHostInstance) {
12794 // Might not be implemented by the renderer.
12795 return null;
12796 }
12797 return findFiberByHostInstance(instance);
12798 }
12799 }));
12800 }
12801 };
12802};
12803
12804var ReactFiberReconciler$2 = Object.freeze({
12805 default: ReactFiberReconciler$1
12806});
12807
12808var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
12809
12810// TODO: bundle Flow types with the package.
12811
12812
12813
12814// TODO: decide on the top-level export form.
12815// This is hacky but makes it work with both Rollup and Jest.
12816var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
12817
12818function createPortal$1(children, containerInfo,
12819// TODO: figure out the API for cross-renderer implementation.
12820implementation) {
12821 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
12822
12823 return {
12824 // This tag allow us to uniquely identify this as a React Portal
12825 $$typeof: REACT_PORTAL_TYPE,
12826 key: key == null ? null : '' + key,
12827 children: children,
12828 containerInfo: containerInfo,
12829 implementation: implementation
12830 };
12831}
12832
12833// TODO: this is special because it gets imported during build.
12834
12835var ReactVersion = '16.3.0-alpha.1';
12836
12837// a requestAnimationFrame, storing the time for the start of the frame, then
12838// scheduling a postMessage which gets scheduled after paint. Within the
12839// postMessage handler do as much work as possible until time + frame rate.
12840// By separating the idle call into a separate event tick we ensure that
12841// layout, paint and other browser work is counted against the available time.
12842// The frame rate is dynamically adjusted.
12843
12844{
12845 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
12846 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
12847 }
12848}
12849
12850var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
12851
12852var now = void 0;
12853if (hasNativePerformanceNow) {
12854 now = function () {
12855 return performance.now();
12856 };
12857} else {
12858 now = function () {
12859 return Date.now();
12860 };
12861}
12862
12863// TODO: There's no way to cancel, because Fiber doesn't atm.
12864var rIC = void 0;
12865var cIC = void 0;
12866
12867if (!ExecutionEnvironment_1.canUseDOM) {
12868 rIC = function (frameCallback) {
12869 return setTimeout(function () {
12870 frameCallback({
12871 timeRemaining: function () {
12872 return Infinity;
12873 }
12874 });
12875 });
12876 };
12877 cIC = function (timeoutID) {
12878 clearTimeout(timeoutID);
12879 };
12880} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
12881 // Polyfill requestIdleCallback and cancelIdleCallback
12882
12883 var scheduledRICCallback = null;
12884 var isIdleScheduled = false;
12885 var timeoutTime = -1;
12886
12887 var isAnimationFrameScheduled = false;
12888
12889 var frameDeadline = 0;
12890 // We start out assuming that we run at 30fps but then the heuristic tracking
12891 // will adjust this value to a faster fps if we get more frequent animation
12892 // frames.
12893 var previousFrameTime = 33;
12894 var activeFrameTime = 33;
12895
12896 var frameDeadlineObject = void 0;
12897 if (hasNativePerformanceNow) {
12898 frameDeadlineObject = {
12899 didTimeout: false,
12900 timeRemaining: function () {
12901 // We assume that if we have a performance timer that the rAF callback
12902 // gets a performance timer value. Not sure if this is always true.
12903 var remaining = frameDeadline - performance.now();
12904 return remaining > 0 ? remaining : 0;
12905 }
12906 };
12907 } else {
12908 frameDeadlineObject = {
12909 didTimeout: false,
12910 timeRemaining: function () {
12911 // Fallback to Date.now()
12912 var remaining = frameDeadline - Date.now();
12913 return remaining > 0 ? remaining : 0;
12914 }
12915 };
12916 }
12917
12918 // We use the postMessage trick to defer idle work until after the repaint.
12919 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12920 var idleTick = function (event) {
12921 if (event.source !== window || event.data !== messageKey) {
12922 return;
12923 }
12924
12925 isIdleScheduled = false;
12926
12927 var currentTime = now();
12928 if (frameDeadline - currentTime <= 0) {
12929 // There's no time left in this idle period. Check if the callback has
12930 // a timeout and whether it's been exceeded.
12931 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12932 // Exceeded the timeout. Invoke the callback even though there's no
12933 // time left.
12934 frameDeadlineObject.didTimeout = true;
12935 } else {
12936 // No timeout.
12937 if (!isAnimationFrameScheduled) {
12938 // Schedule another animation callback so we retry later.
12939 isAnimationFrameScheduled = true;
12940 requestAnimationFrame(animationTick);
12941 }
12942 // Exit without invoking the callback.
12943 return;
12944 }
12945 } else {
12946 // There's still time left in this idle period.
12947 frameDeadlineObject.didTimeout = false;
12948 }
12949
12950 timeoutTime = -1;
12951 var callback = scheduledRICCallback;
12952 scheduledRICCallback = null;
12953 if (callback !== null) {
12954 callback(frameDeadlineObject);
12955 }
12956 };
12957 // Assumes that we have addEventListener in this environment. Might need
12958 // something better for old IE.
12959 window.addEventListener('message', idleTick, false);
12960
12961 var animationTick = function (rafTime) {
12962 isAnimationFrameScheduled = false;
12963 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12964 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12965 if (nextFrameTime < 8) {
12966 // Defensive coding. We don't support higher frame rates than 120hz.
12967 // If we get lower than that, it is probably a bug.
12968 nextFrameTime = 8;
12969 }
12970 // If one frame goes long, then the next one can be short to catch up.
12971 // If two frames are short in a row, then that's an indication that we
12972 // actually have a higher frame rate than what we're currently optimizing.
12973 // We adjust our heuristic dynamically accordingly. For example, if we're
12974 // running on 120hz display or 90hz VR display.
12975 // Take the max of the two in case one of them was an anomaly due to
12976 // missed frame deadlines.
12977 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12978 } else {
12979 previousFrameTime = nextFrameTime;
12980 }
12981 frameDeadline = rafTime + activeFrameTime;
12982 if (!isIdleScheduled) {
12983 isIdleScheduled = true;
12984 window.postMessage(messageKey, '*');
12985 }
12986 };
12987
12988 rIC = function (callback, options) {
12989 // This assumes that we only schedule one callback at a time because that's
12990 // how Fiber uses it.
12991 scheduledRICCallback = callback;
12992 if (options != null && typeof options.timeout === 'number') {
12993 timeoutTime = now() + options.timeout;
12994 }
12995 if (!isAnimationFrameScheduled) {
12996 // If rAF didn't already schedule one, we need to schedule a frame.
12997 // TODO: If this rAF doesn't materialize because the browser throttles, we
12998 // might want to still have setTimeout trigger rIC as a backup to ensure
12999 // that we keep performing work.
13000 isAnimationFrameScheduled = true;
13001 requestAnimationFrame(animationTick);
13002 }
13003 return 0;
13004 };
13005
13006 cIC = function () {
13007 scheduledRICCallback = null;
13008 isIdleScheduled = false;
13009 timeoutTime = -1;
13010 };
13011} else {
13012 rIC = window.requestIdleCallback;
13013 cIC = window.cancelIdleCallback;
13014}
13015
13016var didWarnSelectedSetOnOption = false;
13017
13018function flattenChildren(children) {
13019 var content = '';
13020
13021 // Flatten children and warn if they aren't strings or numbers;
13022 // invalid types are ignored.
13023 // We can silently skip them because invalid DOM nesting warning
13024 // catches these cases in Fiber.
13025 React.Children.forEach(children, function (child) {
13026 if (child == null) {
13027 return;
13028 }
13029 if (typeof child === 'string' || typeof child === 'number') {
13030 content += child;
13031 }
13032 });
13033
13034 return content;
13035}
13036
13037/**
13038 * Implements an <option> host component that warns when `selected` is set.
13039 */
13040
13041function validateProps(element, props) {
13042 // TODO (yungsters): Remove support for `selected` in <option>.
13043 {
13044 if (props.selected != null && !didWarnSelectedSetOnOption) {
13045 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
13046 didWarnSelectedSetOnOption = true;
13047 }
13048 }
13049}
13050
13051function postMountWrapper$1(element, props) {
13052 // value="" should make a value attribute (#6219)
13053 if (props.value != null) {
13054 element.setAttribute('value', props.value);
13055 }
13056}
13057
13058function getHostProps$1(element, props) {
13059 var hostProps = _assign({ children: undefined }, props);
13060 var content = flattenChildren(props.children);
13061
13062 if (content) {
13063 hostProps.children = content;
13064 }
13065
13066 return hostProps;
13067}
13068
13069// TODO: direct imports like some-package/src/* are bad. Fix me.
13070var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
13071var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13072
13073
13074var didWarnValueDefaultValue$1 = void 0;
13075
13076{
13077 didWarnValueDefaultValue$1 = false;
13078}
13079
13080function getDeclarationErrorAddendum() {
13081 var ownerName = getCurrentFiberOwnerName$3();
13082 if (ownerName) {
13083 return '\n\nCheck the render method of `' + ownerName + '`.';
13084 }
13085 return '';
13086}
13087
13088var valuePropNames = ['value', 'defaultValue'];
13089
13090/**
13091 * Validation function for `value` and `defaultValue`.
13092 */
13093function checkSelectPropTypes(props) {
13094 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
13095
13096 for (var i = 0; i < valuePropNames.length; i++) {
13097 var propName = valuePropNames[i];
13098 if (props[propName] == null) {
13099 continue;
13100 }
13101 var isArray = Array.isArray(props[propName]);
13102 if (props.multiple && !isArray) {
13103 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
13104 } else if (!props.multiple && isArray) {
13105 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
13106 }
13107 }
13108}
13109
13110function updateOptions(node, multiple, propValue, setDefaultSelected) {
13111 var options = node.options;
13112
13113 if (multiple) {
13114 var selectedValues = propValue;
13115 var selectedValue = {};
13116 for (var i = 0; i < selectedValues.length; i++) {
13117 // Prefix to avoid chaos with special keys.
13118 selectedValue['$' + selectedValues[i]] = true;
13119 }
13120 for (var _i = 0; _i < options.length; _i++) {
13121 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
13122 if (options[_i].selected !== selected) {
13123 options[_i].selected = selected;
13124 }
13125 if (selected && setDefaultSelected) {
13126 options[_i].defaultSelected = true;
13127 }
13128 }
13129 } else {
13130 // Do not set `select.value` as exact behavior isn't consistent across all
13131 // browsers for all cases.
13132 var _selectedValue = '' + propValue;
13133 var defaultSelected = null;
13134 for (var _i2 = 0; _i2 < options.length; _i2++) {
13135 if (options[_i2].value === _selectedValue) {
13136 options[_i2].selected = true;
13137 if (setDefaultSelected) {
13138 options[_i2].defaultSelected = true;
13139 }
13140 return;
13141 }
13142 if (defaultSelected === null && !options[_i2].disabled) {
13143 defaultSelected = options[_i2];
13144 }
13145 }
13146 if (defaultSelected !== null) {
13147 defaultSelected.selected = true;
13148 }
13149 }
13150}
13151
13152/**
13153 * Implements a <select> host component that allows optionally setting the
13154 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
13155 * stringable. If `multiple` is true, the prop must be an array of stringables.
13156 *
13157 * If `value` is not supplied (or null/undefined), user actions that change the
13158 * selected option will trigger updates to the rendered options.
13159 *
13160 * If it is supplied (and not null/undefined), the rendered options will not
13161 * update in response to user actions. Instead, the `value` prop must change in
13162 * order for the rendered options to update.
13163 *
13164 * If `defaultValue` is provided, any options with the supplied values will be
13165 * selected.
13166 */
13167
13168function getHostProps$2(element, props) {
13169 return _assign({}, props, {
13170 value: undefined
13171 });
13172}
13173
13174function initWrapperState$1(element, props) {
13175 var node = element;
13176 {
13177 checkSelectPropTypes(props);
13178 }
13179
13180 var value = props.value;
13181 node._wrapperState = {
13182 initialValue: value != null ? value : props.defaultValue,
13183 wasMultiple: !!props.multiple
13184 };
13185
13186 {
13187 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
13188 warning_1(false, '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://fb.me/react-controlled-components');
13189 didWarnValueDefaultValue$1 = true;
13190 }
13191 }
13192}
13193
13194function postMountWrapper$2(element, props) {
13195 var node = element;
13196 node.multiple = !!props.multiple;
13197 var value = props.value;
13198 if (value != null) {
13199 updateOptions(node, !!props.multiple, value, false);
13200 } else if (props.defaultValue != null) {
13201 updateOptions(node, !!props.multiple, props.defaultValue, true);
13202 }
13203}
13204
13205function postUpdateWrapper(element, props) {
13206 var node = element;
13207 // After the initial mount, we control selected-ness manually so don't pass
13208 // this value down
13209 node._wrapperState.initialValue = undefined;
13210
13211 var wasMultiple = node._wrapperState.wasMultiple;
13212 node._wrapperState.wasMultiple = !!props.multiple;
13213
13214 var value = props.value;
13215 if (value != null) {
13216 updateOptions(node, !!props.multiple, value, false);
13217 } else if (wasMultiple !== !!props.multiple) {
13218 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
13219 if (props.defaultValue != null) {
13220 updateOptions(node, !!props.multiple, props.defaultValue, true);
13221 } else {
13222 // Revert the select back to its default unselected state.
13223 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
13224 }
13225 }
13226}
13227
13228function restoreControlledState$2(element, props) {
13229 var node = element;
13230 var value = props.value;
13231
13232 if (value != null) {
13233 updateOptions(node, !!props.multiple, value, false);
13234 }
13235}
13236
13237// TODO: direct imports like some-package/src/* are bad. Fix me.
13238var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13239
13240var didWarnValDefaultVal = false;
13241
13242/**
13243 * Implements a <textarea> host component that allows setting `value`, and
13244 * `defaultValue`. This differs from the traditional DOM API because value is
13245 * usually set as PCDATA children.
13246 *
13247 * If `value` is not supplied (or null/undefined), user actions that affect the
13248 * value will trigger updates to the element.
13249 *
13250 * If `value` is supplied (and not null/undefined), the rendered element will
13251 * not trigger updates to the element. Instead, the `value` prop must change in
13252 * order for the rendered element to be updated.
13253 *
13254 * The rendered element will be initialized with an empty value, the prop
13255 * `defaultValue` if specified, or the children content (deprecated).
13256 */
13257
13258function getHostProps$3(element, props) {
13259 var node = element;
13260 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
13261
13262 // Always set children to the same thing. In IE9, the selection range will
13263 // get reset if `textContent` is mutated. We could add a check in setTextContent
13264 // to only set the value if/when the value differs from the node value (which would
13265 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
13266 // solution. The value can be a boolean or object so that's why it's forced
13267 // to be a string.
13268 var hostProps = _assign({}, props, {
13269 value: undefined,
13270 defaultValue: undefined,
13271 children: '' + node._wrapperState.initialValue
13272 });
13273
13274 return hostProps;
13275}
13276
13277function initWrapperState$2(element, props) {
13278 var node = element;
13279 {
13280 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
13281 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
13282 warning_1(false, '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://fb.me/react-controlled-components');
13283 didWarnValDefaultVal = true;
13284 }
13285 }
13286
13287 var initialValue = props.value;
13288
13289 // Only bother fetching default value if we're going to use it
13290 if (initialValue == null) {
13291 var defaultValue = props.defaultValue;
13292 // TODO (yungsters): Remove support for children content in <textarea>.
13293 var children = props.children;
13294 if (children != null) {
13295 {
13296 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
13297 }
13298 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
13299 if (Array.isArray(children)) {
13300 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
13301 children = children[0];
13302 }
13303
13304 defaultValue = '' + children;
13305 }
13306 if (defaultValue == null) {
13307 defaultValue = '';
13308 }
13309 initialValue = defaultValue;
13310 }
13311
13312 node._wrapperState = {
13313 initialValue: '' + initialValue
13314 };
13315}
13316
13317function updateWrapper$1(element, props) {
13318 var node = element;
13319 var value = props.value;
13320 if (value != null) {
13321 // Cast `value` to a string to ensure the value is set correctly. While
13322 // browsers typically do this as necessary, jsdom doesn't.
13323 var newValue = '' + value;
13324
13325 // To avoid side effects (such as losing text selection), only set value if changed
13326 if (newValue !== node.value) {
13327 node.value = newValue;
13328 }
13329 if (props.defaultValue == null) {
13330 node.defaultValue = newValue;
13331 }
13332 }
13333 if (props.defaultValue != null) {
13334 node.defaultValue = props.defaultValue;
13335 }
13336}
13337
13338function postMountWrapper$3(element, props) {
13339 var node = element;
13340 // This is in postMount because we need access to the DOM node, which is not
13341 // available until after the component has mounted.
13342 var textContent = node.textContent;
13343
13344 // Only set node.value if textContent is equal to the expected
13345 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
13346 // will populate textContent as well.
13347 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
13348 if (textContent === node._wrapperState.initialValue) {
13349 node.value = textContent;
13350 }
13351}
13352
13353function restoreControlledState$3(element, props) {
13354 // DOM component is still mounted; update
13355 updateWrapper$1(element, props);
13356}
13357
13358var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
13359var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
13360var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
13361
13362var Namespaces = {
13363 html: HTML_NAMESPACE$1,
13364 mathml: MATH_NAMESPACE,
13365 svg: SVG_NAMESPACE
13366};
13367
13368// Assumes there is no parent namespace.
13369function getIntrinsicNamespace(type) {
13370 switch (type) {
13371 case 'svg':
13372 return SVG_NAMESPACE;
13373 case 'math':
13374 return MATH_NAMESPACE;
13375 default:
13376 return HTML_NAMESPACE$1;
13377 }
13378}
13379
13380function getChildNamespace(parentNamespace, type) {
13381 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
13382 // No (or default) parent namespace: potential entry point.
13383 return getIntrinsicNamespace(type);
13384 }
13385 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
13386 // We're leaving SVG.
13387 return HTML_NAMESPACE$1;
13388 }
13389 // By default, pass namespace below.
13390 return parentNamespace;
13391}
13392
13393/* globals MSApp */
13394
13395/**
13396 * Create a function which has 'unsafe' privileges (required by windows8 apps)
13397 */
13398var createMicrosoftUnsafeLocalFunction = function (func) {
13399 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
13400 return function (arg0, arg1, arg2, arg3) {
13401 MSApp.execUnsafeLocalFunction(function () {
13402 return func(arg0, arg1, arg2, arg3);
13403 });
13404 };
13405 } else {
13406 return func;
13407 }
13408};
13409
13410// SVG temp container for IE lacking innerHTML
13411var reusableSVGContainer = void 0;
13412
13413/**
13414 * Set the innerHTML property of a node
13415 *
13416 * @param {DOMElement} node
13417 * @param {string} html
13418 * @internal
13419 */
13420var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
13421 // IE does not have innerHTML for SVG nodes, so instead we inject the
13422 // new markup in a temp node and then move the child nodes across into
13423 // the target node
13424
13425 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
13426 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
13427 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
13428 var svgNode = reusableSVGContainer.firstChild;
13429 while (node.firstChild) {
13430 node.removeChild(node.firstChild);
13431 }
13432 while (svgNode.firstChild) {
13433 node.appendChild(svgNode.firstChild);
13434 }
13435 } else {
13436 node.innerHTML = html;
13437 }
13438});
13439
13440/**
13441 * Set the textContent property of a node. For text updates, it's faster
13442 * to set the `nodeValue` of the Text node directly instead of using
13443 * `.textContent` which will remove the existing node and create a new one.
13444 *
13445 * @param {DOMElement} node
13446 * @param {string} text
13447 * @internal
13448 */
13449var setTextContent = function (node, text) {
13450 if (text) {
13451 var firstChild = node.firstChild;
13452
13453 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
13454 firstChild.nodeValue = text;
13455 return;
13456 }
13457 }
13458 node.textContent = text;
13459};
13460
13461/**
13462 * CSS properties which accept numbers but are not in units of "px".
13463 */
13464var isUnitlessNumber = {
13465 animationIterationCount: true,
13466 borderImageOutset: true,
13467 borderImageSlice: true,
13468 borderImageWidth: true,
13469 boxFlex: true,
13470 boxFlexGroup: true,
13471 boxOrdinalGroup: true,
13472 columnCount: true,
13473 columns: true,
13474 flex: true,
13475 flexGrow: true,
13476 flexPositive: true,
13477 flexShrink: true,
13478 flexNegative: true,
13479 flexOrder: true,
13480 gridRow: true,
13481 gridRowEnd: true,
13482 gridRowSpan: true,
13483 gridRowStart: true,
13484 gridColumn: true,
13485 gridColumnEnd: true,
13486 gridColumnSpan: true,
13487 gridColumnStart: true,
13488 fontWeight: true,
13489 lineClamp: true,
13490 lineHeight: true,
13491 opacity: true,
13492 order: true,
13493 orphans: true,
13494 tabSize: true,
13495 widows: true,
13496 zIndex: true,
13497 zoom: true,
13498
13499 // SVG-related properties
13500 fillOpacity: true,
13501 floodOpacity: true,
13502 stopOpacity: true,
13503 strokeDasharray: true,
13504 strokeDashoffset: true,
13505 strokeMiterlimit: true,
13506 strokeOpacity: true,
13507 strokeWidth: true
13508};
13509
13510/**
13511 * @param {string} prefix vendor-specific prefix, eg: Webkit
13512 * @param {string} key style name, eg: transitionDuration
13513 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
13514 * WebkitTransitionDuration
13515 */
13516function prefixKey(prefix, key) {
13517 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
13518}
13519
13520/**
13521 * Support style names that may come passed in prefixed by adding permutations
13522 * of vendor prefixes.
13523 */
13524var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
13525
13526// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
13527// infinite loop, because it iterates over the newly added props too.
13528Object.keys(isUnitlessNumber).forEach(function (prop) {
13529 prefixes.forEach(function (prefix) {
13530 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
13531 });
13532});
13533
13534/**
13535 * Convert a value into the proper css writable value. The style name `name`
13536 * should be logical (no hyphens), as specified
13537 * in `CSSProperty.isUnitlessNumber`.
13538 *
13539 * @param {string} name CSS property name such as `topMargin`.
13540 * @param {*} value CSS property value such as `10px`.
13541 * @return {string} Normalized style value with dimensions applied.
13542 */
13543function dangerousStyleValue(name, value, isCustomProperty) {
13544 // Note that we've removed escapeTextForBrowser() calls here since the
13545 // whole string will be escaped when the attribute is injected into
13546 // the markup. If you provide unsafe user data here they can inject
13547 // arbitrary CSS which may be problematic (I couldn't repro this):
13548 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
13549 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
13550 // This is not an XSS hole but instead a potential CSS injection issue
13551 // which has lead to a greater discussion about how we're going to
13552 // trust URLs moving forward. See #2115901
13553
13554 var isEmpty = value == null || typeof value === 'boolean' || value === '';
13555 if (isEmpty) {
13556 return '';
13557 }
13558
13559 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
13560 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
13561 }
13562
13563 return ('' + value).trim();
13564}
13565
13566/**
13567 * Copyright (c) 2013-present, Facebook, Inc.
13568 *
13569 * This source code is licensed under the MIT license found in the
13570 * LICENSE file in the root directory of this source tree.
13571 *
13572 * @typechecks
13573 */
13574
13575var _uppercasePattern = /([A-Z])/g;
13576
13577/**
13578 * Hyphenates a camelcased string, for example:
13579 *
13580 * > hyphenate('backgroundColor')
13581 * < "background-color"
13582 *
13583 * For CSS style names, use `hyphenateStyleName` instead which works properly
13584 * with all vendor prefixes, including `ms`.
13585 *
13586 * @param {string} string
13587 * @return {string}
13588 */
13589function hyphenate(string) {
13590 return string.replace(_uppercasePattern, '-$1').toLowerCase();
13591}
13592
13593var hyphenate_1 = hyphenate;
13594
13595/**
13596 * Copyright (c) 2013-present, Facebook, Inc.
13597 *
13598 * This source code is licensed under the MIT license found in the
13599 * LICENSE file in the root directory of this source tree.
13600 *
13601 * @typechecks
13602 */
13603
13604
13605
13606
13607
13608var msPattern = /^ms-/;
13609
13610/**
13611 * Hyphenates a camelcased CSS property name, for example:
13612 *
13613 * > hyphenateStyleName('backgroundColor')
13614 * < "background-color"
13615 * > hyphenateStyleName('MozTransition')
13616 * < "-moz-transition"
13617 * > hyphenateStyleName('msTransition')
13618 * < "-ms-transition"
13619 *
13620 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
13621 * is converted to `-ms-`.
13622 *
13623 * @param {string} string
13624 * @return {string}
13625 */
13626function hyphenateStyleName(string) {
13627 return hyphenate_1(string).replace(msPattern, '-ms-');
13628}
13629
13630var hyphenateStyleName_1 = hyphenateStyleName;
13631
13632/**
13633 * Copyright (c) 2013-present, Facebook, Inc.
13634 *
13635 * This source code is licensed under the MIT license found in the
13636 * LICENSE file in the root directory of this source tree.
13637 *
13638 * @typechecks
13639 */
13640
13641var _hyphenPattern = /-(.)/g;
13642
13643/**
13644 * Camelcases a hyphenated string, for example:
13645 *
13646 * > camelize('background-color')
13647 * < "backgroundColor"
13648 *
13649 * @param {string} string
13650 * @return {string}
13651 */
13652function camelize(string) {
13653 return string.replace(_hyphenPattern, function (_, character) {
13654 return character.toUpperCase();
13655 });
13656}
13657
13658var camelize_1 = camelize;
13659
13660/**
13661 * Copyright (c) 2013-present, Facebook, Inc.
13662 *
13663 * This source code is licensed under the MIT license found in the
13664 * LICENSE file in the root directory of this source tree.
13665 *
13666 * @typechecks
13667 */
13668
13669
13670
13671
13672
13673var msPattern$1 = /^-ms-/;
13674
13675/**
13676 * Camelcases a hyphenated CSS property name, for example:
13677 *
13678 * > camelizeStyleName('background-color')
13679 * < "backgroundColor"
13680 * > camelizeStyleName('-moz-transition')
13681 * < "MozTransition"
13682 * > camelizeStyleName('-ms-transition')
13683 * < "msTransition"
13684 *
13685 * As Andi Smith suggests
13686 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
13687 * is converted to lowercase `ms`.
13688 *
13689 * @param {string} string
13690 * @return {string}
13691 */
13692function camelizeStyleName(string) {
13693 return camelize_1(string.replace(msPattern$1, 'ms-'));
13694}
13695
13696var camelizeStyleName_1 = camelizeStyleName;
13697
13698var warnValidStyle = emptyFunction_1;
13699
13700{
13701 // 'msTransform' is correct, but the other prefixes should be capitalized
13702 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
13703
13704 // style values shouldn't contain a semicolon
13705 var badStyleValueWithSemicolonPattern = /;\s*$/;
13706
13707 var warnedStyleNames = {};
13708 var warnedStyleValues = {};
13709 var warnedForNaNValue = false;
13710 var warnedForInfinityValue = false;
13711
13712 var warnHyphenatedStyleName = function (name, getStack) {
13713 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
13714 return;
13715 }
13716
13717 warnedStyleNames[name] = true;
13718 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
13719 };
13720
13721 var warnBadVendoredStyleName = function (name, getStack) {
13722 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
13723 return;
13724 }
13725
13726 warnedStyleNames[name] = true;
13727 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
13728 };
13729
13730 var warnStyleValueWithSemicolon = function (name, value, getStack) {
13731 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
13732 return;
13733 }
13734
13735 warnedStyleValues[value] = true;
13736 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
13737 };
13738
13739 var warnStyleValueIsNaN = function (name, value, getStack) {
13740 if (warnedForNaNValue) {
13741 return;
13742 }
13743
13744 warnedForNaNValue = true;
13745 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
13746 };
13747
13748 var warnStyleValueIsInfinity = function (name, value, getStack) {
13749 if (warnedForInfinityValue) {
13750 return;
13751 }
13752
13753 warnedForInfinityValue = true;
13754 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
13755 };
13756
13757 warnValidStyle = function (name, value, getStack) {
13758 if (name.indexOf('-') > -1) {
13759 warnHyphenatedStyleName(name, getStack);
13760 } else if (badVendoredStyleNamePattern.test(name)) {
13761 warnBadVendoredStyleName(name, getStack);
13762 } else if (badStyleValueWithSemicolonPattern.test(value)) {
13763 warnStyleValueWithSemicolon(name, value, getStack);
13764 }
13765
13766 if (typeof value === 'number') {
13767 if (isNaN(value)) {
13768 warnStyleValueIsNaN(name, value, getStack);
13769 } else if (!isFinite(value)) {
13770 warnStyleValueIsInfinity(name, value, getStack);
13771 }
13772 }
13773 };
13774}
13775
13776var warnValidStyle$1 = warnValidStyle;
13777
13778/**
13779 * Operations for dealing with CSS properties.
13780 */
13781
13782/**
13783 * This creates a string that is expected to be equivalent to the style
13784 * attribute generated by server-side rendering. It by-passes warnings and
13785 * security checks so it's not safe to use this value for anything other than
13786 * comparison. It is only used in DEV for SSR validation.
13787 */
13788function createDangerousStringForStyles(styles) {
13789 {
13790 var serialized = '';
13791 var delimiter = '';
13792 for (var styleName in styles) {
13793 if (!styles.hasOwnProperty(styleName)) {
13794 continue;
13795 }
13796 var styleValue = styles[styleName];
13797 if (styleValue != null) {
13798 var isCustomProperty = styleName.indexOf('--') === 0;
13799 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
13800 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
13801
13802 delimiter = ';';
13803 }
13804 }
13805 return serialized || null;
13806 }
13807}
13808
13809/**
13810 * Sets the value for multiple styles on a node. If a value is specified as
13811 * '' (empty string), the corresponding style property will be unset.
13812 *
13813 * @param {DOMElement} node
13814 * @param {object} styles
13815 */
13816function setValueForStyles(node, styles, getStack) {
13817 var style = node.style;
13818 for (var styleName in styles) {
13819 if (!styles.hasOwnProperty(styleName)) {
13820 continue;
13821 }
13822 var isCustomProperty = styleName.indexOf('--') === 0;
13823 {
13824 if (!isCustomProperty) {
13825 warnValidStyle$1(styleName, styles[styleName], getStack);
13826 }
13827 }
13828 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
13829 if (styleName === 'float') {
13830 styleName = 'cssFloat';
13831 }
13832 if (isCustomProperty) {
13833 style.setProperty(styleName, styleValue);
13834 } else {
13835 style[styleName] = styleValue;
13836 }
13837 }
13838}
13839
13840// For HTML, certain tags should omit their close tag. We keep a whitelist for
13841// those special-case tags.
13842
13843var omittedCloseTags = {
13844 area: true,
13845 base: true,
13846 br: true,
13847 col: true,
13848 embed: true,
13849 hr: true,
13850 img: true,
13851 input: true,
13852 keygen: true,
13853 link: true,
13854 meta: true,
13855 param: true,
13856 source: true,
13857 track: true,
13858 wbr: true
13859};
13860
13861// For HTML, certain tags cannot have children. This has the same purpose as
13862// `omittedCloseTags` except that `menuitem` should still have its closing tag.
13863
13864var voidElementTags = _assign({
13865 menuitem: true
13866}, omittedCloseTags);
13867
13868var HTML$1 = '__html';
13869
13870function assertValidProps(tag, props, getStack) {
13871 if (!props) {
13872 return;
13873 }
13874 // Note the use of `==` which checks for null or undefined.
13875 if (voidElementTags[tag]) {
13876 !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant_1(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, getStack()) : void 0;
13877 }
13878 if (props.dangerouslySetInnerHTML != null) {
13879 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
13880 !(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML) ? invariant_1(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : void 0;
13881 }
13882 {
13883 warning_1(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, '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.%s', getStack());
13884 }
13885 !(props.style == null || typeof props.style === 'object') ? invariant_1(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getStack()) : void 0;
13886}
13887
13888function isCustomComponent(tagName, props) {
13889 if (tagName.indexOf('-') === -1) {
13890 return typeof props.is === 'string';
13891 }
13892 switch (tagName) {
13893 // These are reserved SVG and MathML elements.
13894 // We don't mind this whitelist too much because we expect it to never grow.
13895 // The alternative is to track the namespace in a few places which is convoluted.
13896 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
13897 case 'annotation-xml':
13898 case 'color-profile':
13899 case 'font-face':
13900 case 'font-face-src':
13901 case 'font-face-uri':
13902 case 'font-face-format':
13903 case 'font-face-name':
13904 case 'missing-glyph':
13905 return false;
13906 default:
13907 return true;
13908 }
13909}
13910
13911// When adding attributes to the HTML or SVG whitelist, be sure to
13912// also add them to this module to ensure casing and incorrect name
13913// warnings.
13914var possibleStandardNames = {
13915 // HTML
13916 accept: 'accept',
13917 acceptcharset: 'acceptCharset',
13918 'accept-charset': 'acceptCharset',
13919 accesskey: 'accessKey',
13920 action: 'action',
13921 allowfullscreen: 'allowFullScreen',
13922 alt: 'alt',
13923 as: 'as',
13924 async: 'async',
13925 autocapitalize: 'autoCapitalize',
13926 autocomplete: 'autoComplete',
13927 autocorrect: 'autoCorrect',
13928 autofocus: 'autoFocus',
13929 autoplay: 'autoPlay',
13930 autosave: 'autoSave',
13931 capture: 'capture',
13932 cellpadding: 'cellPadding',
13933 cellspacing: 'cellSpacing',
13934 challenge: 'challenge',
13935 charset: 'charSet',
13936 checked: 'checked',
13937 children: 'children',
13938 cite: 'cite',
13939 'class': 'className',
13940 classid: 'classID',
13941 classname: 'className',
13942 cols: 'cols',
13943 colspan: 'colSpan',
13944 content: 'content',
13945 contenteditable: 'contentEditable',
13946 contextmenu: 'contextMenu',
13947 controls: 'controls',
13948 controlslist: 'controlsList',
13949 coords: 'coords',
13950 crossorigin: 'crossOrigin',
13951 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13952 data: 'data',
13953 datetime: 'dateTime',
13954 'default': 'default',
13955 defaultchecked: 'defaultChecked',
13956 defaultvalue: 'defaultValue',
13957 defer: 'defer',
13958 dir: 'dir',
13959 disabled: 'disabled',
13960 download: 'download',
13961 draggable: 'draggable',
13962 enctype: 'encType',
13963 'for': 'htmlFor',
13964 form: 'form',
13965 formmethod: 'formMethod',
13966 formaction: 'formAction',
13967 formenctype: 'formEncType',
13968 formnovalidate: 'formNoValidate',
13969 formtarget: 'formTarget',
13970 frameborder: 'frameBorder',
13971 headers: 'headers',
13972 height: 'height',
13973 hidden: 'hidden',
13974 high: 'high',
13975 href: 'href',
13976 hreflang: 'hrefLang',
13977 htmlfor: 'htmlFor',
13978 httpequiv: 'httpEquiv',
13979 'http-equiv': 'httpEquiv',
13980 icon: 'icon',
13981 id: 'id',
13982 innerhtml: 'innerHTML',
13983 inputmode: 'inputMode',
13984 integrity: 'integrity',
13985 is: 'is',
13986 itemid: 'itemID',
13987 itemprop: 'itemProp',
13988 itemref: 'itemRef',
13989 itemscope: 'itemScope',
13990 itemtype: 'itemType',
13991 keyparams: 'keyParams',
13992 keytype: 'keyType',
13993 kind: 'kind',
13994 label: 'label',
13995 lang: 'lang',
13996 list: 'list',
13997 loop: 'loop',
13998 low: 'low',
13999 manifest: 'manifest',
14000 marginwidth: 'marginWidth',
14001 marginheight: 'marginHeight',
14002 max: 'max',
14003 maxlength: 'maxLength',
14004 media: 'media',
14005 mediagroup: 'mediaGroup',
14006 method: 'method',
14007 min: 'min',
14008 minlength: 'minLength',
14009 multiple: 'multiple',
14010 muted: 'muted',
14011 name: 'name',
14012 nomodule: 'noModule',
14013 nonce: 'nonce',
14014 novalidate: 'noValidate',
14015 open: 'open',
14016 optimum: 'optimum',
14017 pattern: 'pattern',
14018 placeholder: 'placeholder',
14019 playsinline: 'playsInline',
14020 poster: 'poster',
14021 preload: 'preload',
14022 profile: 'profile',
14023 radiogroup: 'radioGroup',
14024 readonly: 'readOnly',
14025 referrerpolicy: 'referrerPolicy',
14026 rel: 'rel',
14027 required: 'required',
14028 reversed: 'reversed',
14029 role: 'role',
14030 rows: 'rows',
14031 rowspan: 'rowSpan',
14032 sandbox: 'sandbox',
14033 scope: 'scope',
14034 scoped: 'scoped',
14035 scrolling: 'scrolling',
14036 seamless: 'seamless',
14037 selected: 'selected',
14038 shape: 'shape',
14039 size: 'size',
14040 sizes: 'sizes',
14041 span: 'span',
14042 spellcheck: 'spellCheck',
14043 src: 'src',
14044 srcdoc: 'srcDoc',
14045 srclang: 'srcLang',
14046 srcset: 'srcSet',
14047 start: 'start',
14048 step: 'step',
14049 style: 'style',
14050 summary: 'summary',
14051 tabindex: 'tabIndex',
14052 target: 'target',
14053 title: 'title',
14054 type: 'type',
14055 usemap: 'useMap',
14056 value: 'value',
14057 width: 'width',
14058 wmode: 'wmode',
14059 wrap: 'wrap',
14060
14061 // SVG
14062 about: 'about',
14063 accentheight: 'accentHeight',
14064 'accent-height': 'accentHeight',
14065 accumulate: 'accumulate',
14066 additive: 'additive',
14067 alignmentbaseline: 'alignmentBaseline',
14068 'alignment-baseline': 'alignmentBaseline',
14069 allowreorder: 'allowReorder',
14070 alphabetic: 'alphabetic',
14071 amplitude: 'amplitude',
14072 arabicform: 'arabicForm',
14073 'arabic-form': 'arabicForm',
14074 ascent: 'ascent',
14075 attributename: 'attributeName',
14076 attributetype: 'attributeType',
14077 autoreverse: 'autoReverse',
14078 azimuth: 'azimuth',
14079 basefrequency: 'baseFrequency',
14080 baselineshift: 'baselineShift',
14081 'baseline-shift': 'baselineShift',
14082 baseprofile: 'baseProfile',
14083 bbox: 'bbox',
14084 begin: 'begin',
14085 bias: 'bias',
14086 by: 'by',
14087 calcmode: 'calcMode',
14088 capheight: 'capHeight',
14089 'cap-height': 'capHeight',
14090 clip: 'clip',
14091 clippath: 'clipPath',
14092 'clip-path': 'clipPath',
14093 clippathunits: 'clipPathUnits',
14094 cliprule: 'clipRule',
14095 'clip-rule': 'clipRule',
14096 color: 'color',
14097 colorinterpolation: 'colorInterpolation',
14098 'color-interpolation': 'colorInterpolation',
14099 colorinterpolationfilters: 'colorInterpolationFilters',
14100 'color-interpolation-filters': 'colorInterpolationFilters',
14101 colorprofile: 'colorProfile',
14102 'color-profile': 'colorProfile',
14103 colorrendering: 'colorRendering',
14104 'color-rendering': 'colorRendering',
14105 contentscripttype: 'contentScriptType',
14106 contentstyletype: 'contentStyleType',
14107 cursor: 'cursor',
14108 cx: 'cx',
14109 cy: 'cy',
14110 d: 'd',
14111 datatype: 'datatype',
14112 decelerate: 'decelerate',
14113 descent: 'descent',
14114 diffuseconstant: 'diffuseConstant',
14115 direction: 'direction',
14116 display: 'display',
14117 divisor: 'divisor',
14118 dominantbaseline: 'dominantBaseline',
14119 'dominant-baseline': 'dominantBaseline',
14120 dur: 'dur',
14121 dx: 'dx',
14122 dy: 'dy',
14123 edgemode: 'edgeMode',
14124 elevation: 'elevation',
14125 enablebackground: 'enableBackground',
14126 'enable-background': 'enableBackground',
14127 end: 'end',
14128 exponent: 'exponent',
14129 externalresourcesrequired: 'externalResourcesRequired',
14130 fill: 'fill',
14131 fillopacity: 'fillOpacity',
14132 'fill-opacity': 'fillOpacity',
14133 fillrule: 'fillRule',
14134 'fill-rule': 'fillRule',
14135 filter: 'filter',
14136 filterres: 'filterRes',
14137 filterunits: 'filterUnits',
14138 floodopacity: 'floodOpacity',
14139 'flood-opacity': 'floodOpacity',
14140 floodcolor: 'floodColor',
14141 'flood-color': 'floodColor',
14142 focusable: 'focusable',
14143 fontfamily: 'fontFamily',
14144 'font-family': 'fontFamily',
14145 fontsize: 'fontSize',
14146 'font-size': 'fontSize',
14147 fontsizeadjust: 'fontSizeAdjust',
14148 'font-size-adjust': 'fontSizeAdjust',
14149 fontstretch: 'fontStretch',
14150 'font-stretch': 'fontStretch',
14151 fontstyle: 'fontStyle',
14152 'font-style': 'fontStyle',
14153 fontvariant: 'fontVariant',
14154 'font-variant': 'fontVariant',
14155 fontweight: 'fontWeight',
14156 'font-weight': 'fontWeight',
14157 format: 'format',
14158 from: 'from',
14159 fx: 'fx',
14160 fy: 'fy',
14161 g1: 'g1',
14162 g2: 'g2',
14163 glyphname: 'glyphName',
14164 'glyph-name': 'glyphName',
14165 glyphorientationhorizontal: 'glyphOrientationHorizontal',
14166 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
14167 glyphorientationvertical: 'glyphOrientationVertical',
14168 'glyph-orientation-vertical': 'glyphOrientationVertical',
14169 glyphref: 'glyphRef',
14170 gradienttransform: 'gradientTransform',
14171 gradientunits: 'gradientUnits',
14172 hanging: 'hanging',
14173 horizadvx: 'horizAdvX',
14174 'horiz-adv-x': 'horizAdvX',
14175 horizoriginx: 'horizOriginX',
14176 'horiz-origin-x': 'horizOriginX',
14177 ideographic: 'ideographic',
14178 imagerendering: 'imageRendering',
14179 'image-rendering': 'imageRendering',
14180 in2: 'in2',
14181 'in': 'in',
14182 inlist: 'inlist',
14183 intercept: 'intercept',
14184 k1: 'k1',
14185 k2: 'k2',
14186 k3: 'k3',
14187 k4: 'k4',
14188 k: 'k',
14189 kernelmatrix: 'kernelMatrix',
14190 kernelunitlength: 'kernelUnitLength',
14191 kerning: 'kerning',
14192 keypoints: 'keyPoints',
14193 keysplines: 'keySplines',
14194 keytimes: 'keyTimes',
14195 lengthadjust: 'lengthAdjust',
14196 letterspacing: 'letterSpacing',
14197 'letter-spacing': 'letterSpacing',
14198 lightingcolor: 'lightingColor',
14199 'lighting-color': 'lightingColor',
14200 limitingconeangle: 'limitingConeAngle',
14201 local: 'local',
14202 markerend: 'markerEnd',
14203 'marker-end': 'markerEnd',
14204 markerheight: 'markerHeight',
14205 markermid: 'markerMid',
14206 'marker-mid': 'markerMid',
14207 markerstart: 'markerStart',
14208 'marker-start': 'markerStart',
14209 markerunits: 'markerUnits',
14210 markerwidth: 'markerWidth',
14211 mask: 'mask',
14212 maskcontentunits: 'maskContentUnits',
14213 maskunits: 'maskUnits',
14214 mathematical: 'mathematical',
14215 mode: 'mode',
14216 numoctaves: 'numOctaves',
14217 offset: 'offset',
14218 opacity: 'opacity',
14219 operator: 'operator',
14220 order: 'order',
14221 orient: 'orient',
14222 orientation: 'orientation',
14223 origin: 'origin',
14224 overflow: 'overflow',
14225 overlineposition: 'overlinePosition',
14226 'overline-position': 'overlinePosition',
14227 overlinethickness: 'overlineThickness',
14228 'overline-thickness': 'overlineThickness',
14229 paintorder: 'paintOrder',
14230 'paint-order': 'paintOrder',
14231 panose1: 'panose1',
14232 'panose-1': 'panose1',
14233 pathlength: 'pathLength',
14234 patterncontentunits: 'patternContentUnits',
14235 patterntransform: 'patternTransform',
14236 patternunits: 'patternUnits',
14237 pointerevents: 'pointerEvents',
14238 'pointer-events': 'pointerEvents',
14239 points: 'points',
14240 pointsatx: 'pointsAtX',
14241 pointsaty: 'pointsAtY',
14242 pointsatz: 'pointsAtZ',
14243 prefix: 'prefix',
14244 preservealpha: 'preserveAlpha',
14245 preserveaspectratio: 'preserveAspectRatio',
14246 primitiveunits: 'primitiveUnits',
14247 property: 'property',
14248 r: 'r',
14249 radius: 'radius',
14250 refx: 'refX',
14251 refy: 'refY',
14252 renderingintent: 'renderingIntent',
14253 'rendering-intent': 'renderingIntent',
14254 repeatcount: 'repeatCount',
14255 repeatdur: 'repeatDur',
14256 requiredextensions: 'requiredExtensions',
14257 requiredfeatures: 'requiredFeatures',
14258 resource: 'resource',
14259 restart: 'restart',
14260 result: 'result',
14261 results: 'results',
14262 rotate: 'rotate',
14263 rx: 'rx',
14264 ry: 'ry',
14265 scale: 'scale',
14266 security: 'security',
14267 seed: 'seed',
14268 shaperendering: 'shapeRendering',
14269 'shape-rendering': 'shapeRendering',
14270 slope: 'slope',
14271 spacing: 'spacing',
14272 specularconstant: 'specularConstant',
14273 specularexponent: 'specularExponent',
14274 speed: 'speed',
14275 spreadmethod: 'spreadMethod',
14276 startoffset: 'startOffset',
14277 stddeviation: 'stdDeviation',
14278 stemh: 'stemh',
14279 stemv: 'stemv',
14280 stitchtiles: 'stitchTiles',
14281 stopcolor: 'stopColor',
14282 'stop-color': 'stopColor',
14283 stopopacity: 'stopOpacity',
14284 'stop-opacity': 'stopOpacity',
14285 strikethroughposition: 'strikethroughPosition',
14286 'strikethrough-position': 'strikethroughPosition',
14287 strikethroughthickness: 'strikethroughThickness',
14288 'strikethrough-thickness': 'strikethroughThickness',
14289 string: 'string',
14290 stroke: 'stroke',
14291 strokedasharray: 'strokeDasharray',
14292 'stroke-dasharray': 'strokeDasharray',
14293 strokedashoffset: 'strokeDashoffset',
14294 'stroke-dashoffset': 'strokeDashoffset',
14295 strokelinecap: 'strokeLinecap',
14296 'stroke-linecap': 'strokeLinecap',
14297 strokelinejoin: 'strokeLinejoin',
14298 'stroke-linejoin': 'strokeLinejoin',
14299 strokemiterlimit: 'strokeMiterlimit',
14300 'stroke-miterlimit': 'strokeMiterlimit',
14301 strokewidth: 'strokeWidth',
14302 'stroke-width': 'strokeWidth',
14303 strokeopacity: 'strokeOpacity',
14304 'stroke-opacity': 'strokeOpacity',
14305 suppresscontenteditablewarning: 'suppressContentEditableWarning',
14306 suppresshydrationwarning: 'suppressHydrationWarning',
14307 surfacescale: 'surfaceScale',
14308 systemlanguage: 'systemLanguage',
14309 tablevalues: 'tableValues',
14310 targetx: 'targetX',
14311 targety: 'targetY',
14312 textanchor: 'textAnchor',
14313 'text-anchor': 'textAnchor',
14314 textdecoration: 'textDecoration',
14315 'text-decoration': 'textDecoration',
14316 textlength: 'textLength',
14317 textrendering: 'textRendering',
14318 'text-rendering': 'textRendering',
14319 to: 'to',
14320 transform: 'transform',
14321 'typeof': 'typeof',
14322 u1: 'u1',
14323 u2: 'u2',
14324 underlineposition: 'underlinePosition',
14325 'underline-position': 'underlinePosition',
14326 underlinethickness: 'underlineThickness',
14327 'underline-thickness': 'underlineThickness',
14328 unicode: 'unicode',
14329 unicodebidi: 'unicodeBidi',
14330 'unicode-bidi': 'unicodeBidi',
14331 unicoderange: 'unicodeRange',
14332 'unicode-range': 'unicodeRange',
14333 unitsperem: 'unitsPerEm',
14334 'units-per-em': 'unitsPerEm',
14335 unselectable: 'unselectable',
14336 valphabetic: 'vAlphabetic',
14337 'v-alphabetic': 'vAlphabetic',
14338 values: 'values',
14339 vectoreffect: 'vectorEffect',
14340 'vector-effect': 'vectorEffect',
14341 version: 'version',
14342 vertadvy: 'vertAdvY',
14343 'vert-adv-y': 'vertAdvY',
14344 vertoriginx: 'vertOriginX',
14345 'vert-origin-x': 'vertOriginX',
14346 vertoriginy: 'vertOriginY',
14347 'vert-origin-y': 'vertOriginY',
14348 vhanging: 'vHanging',
14349 'v-hanging': 'vHanging',
14350 videographic: 'vIdeographic',
14351 'v-ideographic': 'vIdeographic',
14352 viewbox: 'viewBox',
14353 viewtarget: 'viewTarget',
14354 visibility: 'visibility',
14355 vmathematical: 'vMathematical',
14356 'v-mathematical': 'vMathematical',
14357 vocab: 'vocab',
14358 widths: 'widths',
14359 wordspacing: 'wordSpacing',
14360 'word-spacing': 'wordSpacing',
14361 writingmode: 'writingMode',
14362 'writing-mode': 'writingMode',
14363 x1: 'x1',
14364 x2: 'x2',
14365 x: 'x',
14366 xchannelselector: 'xChannelSelector',
14367 xheight: 'xHeight',
14368 'x-height': 'xHeight',
14369 xlinkactuate: 'xlinkActuate',
14370 'xlink:actuate': 'xlinkActuate',
14371 xlinkarcrole: 'xlinkArcrole',
14372 'xlink:arcrole': 'xlinkArcrole',
14373 xlinkhref: 'xlinkHref',
14374 'xlink:href': 'xlinkHref',
14375 xlinkrole: 'xlinkRole',
14376 'xlink:role': 'xlinkRole',
14377 xlinkshow: 'xlinkShow',
14378 'xlink:show': 'xlinkShow',
14379 xlinktitle: 'xlinkTitle',
14380 'xlink:title': 'xlinkTitle',
14381 xlinktype: 'xlinkType',
14382 'xlink:type': 'xlinkType',
14383 xmlbase: 'xmlBase',
14384 'xml:base': 'xmlBase',
14385 xmllang: 'xmlLang',
14386 'xml:lang': 'xmlLang',
14387 xmlns: 'xmlns',
14388 'xml:space': 'xmlSpace',
14389 xmlnsxlink: 'xmlnsXlink',
14390 'xmlns:xlink': 'xmlnsXlink',
14391 xmlspace: 'xmlSpace',
14392 y1: 'y1',
14393 y2: 'y2',
14394 y: 'y',
14395 ychannelselector: 'yChannelSelector',
14396 z: 'z',
14397 zoomandpan: 'zoomAndPan'
14398};
14399
14400var ariaProperties = {
14401 'aria-current': 0, // state
14402 'aria-details': 0,
14403 'aria-disabled': 0, // state
14404 'aria-hidden': 0, // state
14405 'aria-invalid': 0, // state
14406 'aria-keyshortcuts': 0,
14407 'aria-label': 0,
14408 'aria-roledescription': 0,
14409 // Widget Attributes
14410 'aria-autocomplete': 0,
14411 'aria-checked': 0,
14412 'aria-expanded': 0,
14413 'aria-haspopup': 0,
14414 'aria-level': 0,
14415 'aria-modal': 0,
14416 'aria-multiline': 0,
14417 'aria-multiselectable': 0,
14418 'aria-orientation': 0,
14419 'aria-placeholder': 0,
14420 'aria-pressed': 0,
14421 'aria-readonly': 0,
14422 'aria-required': 0,
14423 'aria-selected': 0,
14424 'aria-sort': 0,
14425 'aria-valuemax': 0,
14426 'aria-valuemin': 0,
14427 'aria-valuenow': 0,
14428 'aria-valuetext': 0,
14429 // Live Region Attributes
14430 'aria-atomic': 0,
14431 'aria-busy': 0,
14432 'aria-live': 0,
14433 'aria-relevant': 0,
14434 // Drag-and-Drop Attributes
14435 'aria-dropeffect': 0,
14436 'aria-grabbed': 0,
14437 // Relationship Attributes
14438 'aria-activedescendant': 0,
14439 'aria-colcount': 0,
14440 'aria-colindex': 0,
14441 'aria-colspan': 0,
14442 'aria-controls': 0,
14443 'aria-describedby': 0,
14444 'aria-errormessage': 0,
14445 'aria-flowto': 0,
14446 'aria-labelledby': 0,
14447 'aria-owns': 0,
14448 'aria-posinset': 0,
14449 'aria-rowcount': 0,
14450 'aria-rowindex': 0,
14451 'aria-rowspan': 0,
14452 'aria-setsize': 0
14453};
14454
14455var warnedProperties = {};
14456var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
14457var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
14458
14459var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
14460
14461function getStackAddendum() {
14462 var stack = ReactDebugCurrentFrame.getStackAddendum();
14463 return stack != null ? stack : '';
14464}
14465
14466function validateProperty(tagName, name) {
14467 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
14468 return true;
14469 }
14470
14471 if (rARIACamel.test(name)) {
14472 var ariaName = 'aria-' + name.slice(4).toLowerCase();
14473 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
14474
14475 // If this is an aria-* attribute, but is not listed in the known DOM
14476 // DOM properties, then it is an invalid aria-* attribute.
14477 if (correctName == null) {
14478 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
14479 warnedProperties[name] = true;
14480 return true;
14481 }
14482 // aria-* attributes should be lowercase; suggest the lowercase version.
14483 if (name !== correctName) {
14484 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
14485 warnedProperties[name] = true;
14486 return true;
14487 }
14488 }
14489
14490 if (rARIA.test(name)) {
14491 var lowerCasedName = name.toLowerCase();
14492 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
14493
14494 // If this is an aria-* attribute, but is not listed in the known DOM
14495 // DOM properties, then it is an invalid aria-* attribute.
14496 if (standardName == null) {
14497 warnedProperties[name] = true;
14498 return false;
14499 }
14500 // aria-* attributes should be lowercase; suggest the lowercase version.
14501 if (name !== standardName) {
14502 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
14503 warnedProperties[name] = true;
14504 return true;
14505 }
14506 }
14507
14508 return true;
14509}
14510
14511function warnInvalidARIAProps(type, props) {
14512 var invalidProps = [];
14513
14514 for (var key in props) {
14515 var isValid = validateProperty(type, key);
14516 if (!isValid) {
14517 invalidProps.push(key);
14518 }
14519 }
14520
14521 var unknownPropString = invalidProps.map(function (prop) {
14522 return '`' + prop + '`';
14523 }).join(', ');
14524
14525 if (invalidProps.length === 1) {
14526 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
14527 } else if (invalidProps.length > 1) {
14528 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
14529 }
14530}
14531
14532function validateProperties(type, props) {
14533 if (isCustomComponent(type, props)) {
14534 return;
14535 }
14536 warnInvalidARIAProps(type, props);
14537}
14538
14539var didWarnValueNull = false;
14540
14541function getStackAddendum$1() {
14542 var stack = ReactDebugCurrentFrame.getStackAddendum();
14543 return stack != null ? stack : '';
14544}
14545
14546function validateProperties$1(type, props) {
14547 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
14548 return;
14549 }
14550
14551 if (props != null && props.value === null && !didWarnValueNull) {
14552 didWarnValueNull = true;
14553 if (type === 'select' && props.multiple) {
14554 warning_1(false, '`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.%s', type, getStackAddendum$1());
14555 } else {
14556 warning_1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', type, getStackAddendum$1());
14557 }
14558 }
14559}
14560
14561function getStackAddendum$2() {
14562 var stack = ReactDebugCurrentFrame.getStackAddendum();
14563 return stack != null ? stack : '';
14564}
14565
14566var validateProperty$1 = function () {};
14567
14568{
14569 var warnedProperties$1 = {};
14570 var _hasOwnProperty = Object.prototype.hasOwnProperty;
14571 var EVENT_NAME_REGEX = /^on./;
14572 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
14573 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
14574 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
14575
14576 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
14577 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
14578 return true;
14579 }
14580
14581 var lowerCasedName = name.toLowerCase();
14582 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
14583 warning_1(false, '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.');
14584 warnedProperties$1[name] = true;
14585 return true;
14586 }
14587
14588 // We can't rely on the event system being injected on the server.
14589 if (canUseEventSystem) {
14590 if (registrationNameModules.hasOwnProperty(name)) {
14591 return true;
14592 }
14593 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
14594 if (registrationName != null) {
14595 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
14596 warnedProperties$1[name] = true;
14597 return true;
14598 }
14599 if (EVENT_NAME_REGEX.test(name)) {
14600 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
14601 warnedProperties$1[name] = true;
14602 return true;
14603 }
14604 } else if (EVENT_NAME_REGEX.test(name)) {
14605 // If no event plugins have been injected, we are in a server environment.
14606 // So we can't tell if the event name is correct for sure, but we can filter
14607 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
14608 if (INVALID_EVENT_NAME_REGEX.test(name)) {
14609 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
14610 }
14611 warnedProperties$1[name] = true;
14612 return true;
14613 }
14614
14615 // Let the ARIA attribute hook validate ARIA attributes
14616 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
14617 return true;
14618 }
14619
14620 if (lowerCasedName === 'innerhtml') {
14621 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
14622 warnedProperties$1[name] = true;
14623 return true;
14624 }
14625
14626 if (lowerCasedName === 'aria') {
14627 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
14628 warnedProperties$1[name] = true;
14629 return true;
14630 }
14631
14632 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
14633 warning_1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.%s', typeof value, getStackAddendum$2());
14634 warnedProperties$1[name] = true;
14635 return true;
14636 }
14637
14638 if (typeof value === 'number' && isNaN(value)) {
14639 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
14640 warnedProperties$1[name] = true;
14641 return true;
14642 }
14643
14644 var propertyInfo = getPropertyInfo(name);
14645 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
14646
14647 // Known attributes should match the casing specified in the property config.
14648 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14649 var standardName = possibleStandardNames[lowerCasedName];
14650 if (standardName !== name) {
14651 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
14652 warnedProperties$1[name] = true;
14653 return true;
14654 }
14655 } else if (!isReserved && name !== lowerCasedName) {
14656 // Unknown attributes should have lowercase casing since that's how they
14657 // will be cased anyway with server rendering.
14658 warning_1(false, '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.%s', name, lowerCasedName, getStackAddendum$2());
14659 warnedProperties$1[name] = true;
14660 return true;
14661 }
14662
14663 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
14664 if (value) {
14665 warning_1(false, '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()}.%s', value, name, name, value, name, getStackAddendum$2());
14666 } else {
14667 warning_1(false, '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.%s', value, name, name, value, name, name, name, getStackAddendum$2());
14668 }
14669 warnedProperties$1[name] = true;
14670 return true;
14671 }
14672
14673 // Now that we've validated casing, do not validate
14674 // data types for reserved props
14675 if (isReserved) {
14676 return true;
14677 }
14678
14679 // Warn when a known attribute is a bad type
14680 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
14681 warnedProperties$1[name] = true;
14682 return false;
14683 }
14684
14685 return true;
14686 };
14687}
14688
14689var warnUnknownProperties = function (type, props, canUseEventSystem) {
14690 var unknownProps = [];
14691 for (var key in props) {
14692 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
14693 if (!isValid) {
14694 unknownProps.push(key);
14695 }
14696 }
14697
14698 var unknownPropString = unknownProps.map(function (prop) {
14699 return '`' + prop + '`';
14700 }).join(', ');
14701 if (unknownProps.length === 1) {
14702 warning_1(false, '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://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$2());
14703 } else if (unknownProps.length > 1) {
14704 warning_1(false, '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://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$2());
14705 }
14706};
14707
14708function validateProperties$2(type, props, canUseEventSystem) {
14709 if (isCustomComponent(type, props)) {
14710 return;
14711 }
14712 warnUnknownProperties(type, props, canUseEventSystem);
14713}
14714
14715// TODO: direct imports like some-package/src/* are bad. Fix me.
14716var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
14717var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14718
14719var didWarnInvalidHydration = false;
14720var didWarnShadyDOM = false;
14721
14722var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
14723var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
14724var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
14725var AUTOFOCUS = 'autoFocus';
14726var CHILDREN = 'children';
14727var STYLE = 'style';
14728var HTML = '__html';
14729
14730var HTML_NAMESPACE = Namespaces.html;
14731
14732
14733var getStack = emptyFunction_1.thatReturns('');
14734
14735var warnedUnknownTags = void 0;
14736var suppressHydrationWarning = void 0;
14737
14738var validatePropertiesInDevelopment = void 0;
14739var warnForTextDifference = void 0;
14740var warnForPropDifference = void 0;
14741var warnForExtraAttributes = void 0;
14742var warnForInvalidEventListener = void 0;
14743
14744var normalizeMarkupForTextOrAttribute = void 0;
14745var normalizeHTML = void 0;
14746
14747{
14748 getStack = getCurrentFiberStackAddendum$3;
14749
14750 warnedUnknownTags = {
14751 // Chrome is the only major browser not shipping <time>. But as of July
14752 // 2017 it intends to ship it due to widespread usage. We intentionally
14753 // *don't* warn for <time> even if it's unrecognized by Chrome because
14754 // it soon will be, and many apps have been using it anyway.
14755 time: true,
14756 // There are working polyfills for <dialog>. Let people use it.
14757 dialog: true
14758 };
14759
14760 validatePropertiesInDevelopment = function (type, props) {
14761 validateProperties(type, props);
14762 validateProperties$1(type, props);
14763 validateProperties$2(type, props, /* canUseEventSystem */true);
14764 };
14765
14766 // HTML parsing normalizes CR and CRLF to LF.
14767 // It also can turn \u0000 into \uFFFD inside attributes.
14768 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
14769 // If we have a mismatch, it might be caused by that.
14770 // We will still patch up in this case but not fire the warning.
14771 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
14772 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
14773
14774 normalizeMarkupForTextOrAttribute = function (markup) {
14775 var markupString = typeof markup === 'string' ? markup : '' + markup;
14776 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
14777 };
14778
14779 warnForTextDifference = function (serverText, clientText) {
14780 if (didWarnInvalidHydration) {
14781 return;
14782 }
14783 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
14784 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
14785 if (normalizedServerText === normalizedClientText) {
14786 return;
14787 }
14788 didWarnInvalidHydration = true;
14789 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
14790 };
14791
14792 warnForPropDifference = function (propName, serverValue, clientValue) {
14793 if (didWarnInvalidHydration) {
14794 return;
14795 }
14796 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
14797 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
14798 if (normalizedServerValue === normalizedClientValue) {
14799 return;
14800 }
14801 didWarnInvalidHydration = true;
14802 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
14803 };
14804
14805 warnForExtraAttributes = function (attributeNames) {
14806 if (didWarnInvalidHydration) {
14807 return;
14808 }
14809 didWarnInvalidHydration = true;
14810 var names = [];
14811 attributeNames.forEach(function (name) {
14812 names.push(name);
14813 });
14814 warning_1(false, 'Extra attributes from the server: %s', names);
14815 };
14816
14817 warnForInvalidEventListener = function (registrationName, listener) {
14818 if (listener === false) {
14819 warning_1(false, '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.%s', registrationName, registrationName, registrationName, getCurrentFiberStackAddendum$3());
14820 } else {
14821 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
14822 }
14823 };
14824
14825 // Parse the HTML and read it back to normalize the HTML string so that it
14826 // can be used for comparison.
14827 normalizeHTML = function (parent, html) {
14828 // We could have created a separate document here to avoid
14829 // re-initializing custom elements if they exist. But this breaks
14830 // how <noscript> is being handled. So we use the same document.
14831 // See the discussion in https://github.com/facebook/react/pull/11157.
14832 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
14833 testElement.innerHTML = html;
14834 return testElement.innerHTML;
14835 };
14836}
14837
14838function ensureListeningTo(rootContainerElement, registrationName) {
14839 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
14840 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
14841 listenTo(registrationName, doc);
14842}
14843
14844function getOwnerDocumentFromRootContainer(rootContainerElement) {
14845 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
14846}
14847
14848function trapClickOnNonInteractiveElement(node) {
14849 // Mobile Safari does not fire properly bubble click events on
14850 // non-interactive elements, which means delegated click listeners do not
14851 // fire. The workaround for this bug involves attaching an empty click
14852 // listener on the target node.
14853 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
14854 // Just set it using the onclick property so that we don't have to manage any
14855 // bookkeeping for it. Not sure if we need to clear it when the listener is
14856 // removed.
14857 // TODO: Only do this for the relevant Safaris maybe?
14858 node.onclick = emptyFunction_1;
14859}
14860
14861function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
14862 for (var propKey in nextProps) {
14863 if (!nextProps.hasOwnProperty(propKey)) {
14864 continue;
14865 }
14866 var nextProp = nextProps[propKey];
14867 if (propKey === STYLE) {
14868 {
14869 if (nextProp) {
14870 // Freeze the next style object so that we can assume it won't be
14871 // mutated. We have already warned for this in the past.
14872 Object.freeze(nextProp);
14873 }
14874 }
14875 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14876 setValueForStyles(domElement, nextProp, getStack);
14877 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14878 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14879 if (nextHtml != null) {
14880 setInnerHTML(domElement, nextHtml);
14881 }
14882 } else if (propKey === CHILDREN) {
14883 if (typeof nextProp === 'string') {
14884 // Avoid setting initial textContent when the text is empty. In IE11 setting
14885 // textContent on a <textarea> will cause the placeholder to not
14886 // show within the <textarea> until it has been focused and blurred again.
14887 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
14888 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
14889 if (canSetTextContent) {
14890 setTextContent(domElement, nextProp);
14891 }
14892 } else if (typeof nextProp === 'number') {
14893 setTextContent(domElement, '' + nextProp);
14894 }
14895 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14896 // Noop
14897 } else if (propKey === AUTOFOCUS) {
14898 // We polyfill it separately on the client during commit.
14899 // We blacklist it here rather than in the property list because we emit it in SSR.
14900 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14901 if (nextProp != null) {
14902 if (true && typeof nextProp !== 'function') {
14903 warnForInvalidEventListener(propKey, nextProp);
14904 }
14905 ensureListeningTo(rootContainerElement, propKey);
14906 }
14907 } else if (nextProp != null) {
14908 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14909 }
14910 }
14911}
14912
14913function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14914 // TODO: Handle wasCustomComponentTag
14915 for (var i = 0; i < updatePayload.length; i += 2) {
14916 var propKey = updatePayload[i];
14917 var propValue = updatePayload[i + 1];
14918 if (propKey === STYLE) {
14919 setValueForStyles(domElement, propValue, getStack);
14920 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14921 setInnerHTML(domElement, propValue);
14922 } else if (propKey === CHILDREN) {
14923 setTextContent(domElement, propValue);
14924 } else {
14925 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14926 }
14927 }
14928}
14929
14930function createElement$1(type, props, rootContainerElement, parentNamespace) {
14931 var isCustomComponentTag = void 0;
14932
14933 // We create tags in the namespace of their parent container, except HTML
14934 // tags get no namespace.
14935 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14936 var domElement = void 0;
14937 var namespaceURI = parentNamespace;
14938 if (namespaceURI === HTML_NAMESPACE) {
14939 namespaceURI = getIntrinsicNamespace(type);
14940 }
14941 if (namespaceURI === HTML_NAMESPACE) {
14942 {
14943 isCustomComponentTag = isCustomComponent(type, props);
14944 // Should this check be gated by parent namespace? Not sure we want to
14945 // allow <SVG> or <mATH>.
14946 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14947 }
14948
14949 if (type === 'script') {
14950 // Create the script via .innerHTML so its "parser-inserted" flag is
14951 // set to true and it does not execute
14952 var div = ownerDocument.createElement('div');
14953 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14954 // This is guaranteed to yield a script element.
14955 var firstChild = div.firstChild;
14956 domElement = div.removeChild(firstChild);
14957 } else if (typeof props.is === 'string') {
14958 // $FlowIssue `createElement` should be updated for Web Components
14959 domElement = ownerDocument.createElement(type, { is: props.is });
14960 } else {
14961 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14962 // See discussion in https://github.com/facebook/react/pull/6896
14963 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14964 domElement = ownerDocument.createElement(type);
14965 }
14966 } else {
14967 domElement = ownerDocument.createElementNS(namespaceURI, type);
14968 }
14969
14970 {
14971 if (namespaceURI === HTML_NAMESPACE) {
14972 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14973 warnedUnknownTags[type] = true;
14974 warning_1(false, 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
14975 }
14976 }
14977 }
14978
14979 return domElement;
14980}
14981
14982function createTextNode$1(text, rootContainerElement) {
14983 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14984}
14985
14986function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14987 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14988 {
14989 validatePropertiesInDevelopment(tag, rawProps);
14990 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14991 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14992 didWarnShadyDOM = true;
14993 }
14994 }
14995
14996 // TODO: Make sure that we check isMounted before firing any of these events.
14997 var props = void 0;
14998 switch (tag) {
14999 case 'iframe':
15000 case 'object':
15001 trapBubbledEvent('topLoad', 'load', domElement);
15002 props = rawProps;
15003 break;
15004 case 'video':
15005 case 'audio':
15006 // Create listener for each media event
15007 for (var event in mediaEventTypes) {
15008 if (mediaEventTypes.hasOwnProperty(event)) {
15009 trapBubbledEvent(event, mediaEventTypes[event], domElement);
15010 }
15011 }
15012 props = rawProps;
15013 break;
15014 case 'source':
15015 trapBubbledEvent('topError', 'error', domElement);
15016 props = rawProps;
15017 break;
15018 case 'img':
15019 case 'image':
15020 case 'link':
15021 trapBubbledEvent('topError', 'error', domElement);
15022 trapBubbledEvent('topLoad', 'load', domElement);
15023 props = rawProps;
15024 break;
15025 case 'form':
15026 trapBubbledEvent('topReset', 'reset', domElement);
15027 trapBubbledEvent('topSubmit', 'submit', domElement);
15028 props = rawProps;
15029 break;
15030 case 'details':
15031 trapBubbledEvent('topToggle', 'toggle', domElement);
15032 props = rawProps;
15033 break;
15034 case 'input':
15035 initWrapperState(domElement, rawProps);
15036 props = getHostProps(domElement, rawProps);
15037 trapBubbledEvent('topInvalid', 'invalid', domElement);
15038 // For controlled components we always need to ensure we're listening
15039 // to onChange. Even if there is no listener.
15040 ensureListeningTo(rootContainerElement, 'onChange');
15041 break;
15042 case 'option':
15043 validateProps(domElement, rawProps);
15044 props = getHostProps$1(domElement, rawProps);
15045 break;
15046 case 'select':
15047 initWrapperState$1(domElement, rawProps);
15048 props = getHostProps$2(domElement, rawProps);
15049 trapBubbledEvent('topInvalid', 'invalid', domElement);
15050 // For controlled components we always need to ensure we're listening
15051 // to onChange. Even if there is no listener.
15052 ensureListeningTo(rootContainerElement, 'onChange');
15053 break;
15054 case 'textarea':
15055 initWrapperState$2(domElement, rawProps);
15056 props = getHostProps$3(domElement, rawProps);
15057 trapBubbledEvent('topInvalid', 'invalid', domElement);
15058 // For controlled components we always need to ensure we're listening
15059 // to onChange. Even if there is no listener.
15060 ensureListeningTo(rootContainerElement, 'onChange');
15061 break;
15062 default:
15063 props = rawProps;
15064 }
15065
15066 assertValidProps(tag, props, getStack);
15067
15068 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
15069
15070 switch (tag) {
15071 case 'input':
15072 // TODO: Make sure we check if this is still unmounted or do any clean
15073 // up necessary since we never stop tracking anymore.
15074 track(domElement);
15075 postMountWrapper(domElement, rawProps);
15076 break;
15077 case 'textarea':
15078 // TODO: Make sure we check if this is still unmounted or do any clean
15079 // up necessary since we never stop tracking anymore.
15080 track(domElement);
15081 postMountWrapper$3(domElement, rawProps);
15082 break;
15083 case 'option':
15084 postMountWrapper$1(domElement, rawProps);
15085 break;
15086 case 'select':
15087 postMountWrapper$2(domElement, rawProps);
15088 break;
15089 default:
15090 if (typeof props.onClick === 'function') {
15091 // TODO: This cast may not be sound for SVG, MathML or custom elements.
15092 trapClickOnNonInteractiveElement(domElement);
15093 }
15094 break;
15095 }
15096}
15097
15098// Calculate the diff between the two objects.
15099function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
15100 {
15101 validatePropertiesInDevelopment(tag, nextRawProps);
15102 }
15103
15104 var updatePayload = null;
15105
15106 var lastProps = void 0;
15107 var nextProps = void 0;
15108 switch (tag) {
15109 case 'input':
15110 lastProps = getHostProps(domElement, lastRawProps);
15111 nextProps = getHostProps(domElement, nextRawProps);
15112 updatePayload = [];
15113 break;
15114 case 'option':
15115 lastProps = getHostProps$1(domElement, lastRawProps);
15116 nextProps = getHostProps$1(domElement, nextRawProps);
15117 updatePayload = [];
15118 break;
15119 case 'select':
15120 lastProps = getHostProps$2(domElement, lastRawProps);
15121 nextProps = getHostProps$2(domElement, nextRawProps);
15122 updatePayload = [];
15123 break;
15124 case 'textarea':
15125 lastProps = getHostProps$3(domElement, lastRawProps);
15126 nextProps = getHostProps$3(domElement, nextRawProps);
15127 updatePayload = [];
15128 break;
15129 default:
15130 lastProps = lastRawProps;
15131 nextProps = nextRawProps;
15132 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
15133 // TODO: This cast may not be sound for SVG, MathML or custom elements.
15134 trapClickOnNonInteractiveElement(domElement);
15135 }
15136 break;
15137 }
15138
15139 assertValidProps(tag, nextProps, getStack);
15140
15141 var propKey = void 0;
15142 var styleName = void 0;
15143 var styleUpdates = null;
15144 for (propKey in lastProps) {
15145 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
15146 continue;
15147 }
15148 if (propKey === STYLE) {
15149 var lastStyle = lastProps[propKey];
15150 for (styleName in lastStyle) {
15151 if (lastStyle.hasOwnProperty(styleName)) {
15152 if (!styleUpdates) {
15153 styleUpdates = {};
15154 }
15155 styleUpdates[styleName] = '';
15156 }
15157 }
15158 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
15159 // Noop. This is handled by the clear text mechanism.
15160 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
15161 // Noop
15162 } else if (propKey === AUTOFOCUS) {
15163 // Noop. It doesn't work on updates anyway.
15164 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15165 // This is a special case. If any listener updates we need to ensure
15166 // that the "current" fiber pointer gets updated so we need a commit
15167 // to update this element.
15168 if (!updatePayload) {
15169 updatePayload = [];
15170 }
15171 } else {
15172 // For all other deleted properties we add it to the queue. We use
15173 // the whitelist in the commit phase instead.
15174 (updatePayload = updatePayload || []).push(propKey, null);
15175 }
15176 }
15177 for (propKey in nextProps) {
15178 var nextProp = nextProps[propKey];
15179 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
15180 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
15181 continue;
15182 }
15183 if (propKey === STYLE) {
15184 {
15185 if (nextProp) {
15186 // Freeze the next style object so that we can assume it won't be
15187 // mutated. We have already warned for this in the past.
15188 Object.freeze(nextProp);
15189 }
15190 }
15191 if (lastProp) {
15192 // Unset styles on `lastProp` but not on `nextProp`.
15193 for (styleName in lastProp) {
15194 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
15195 if (!styleUpdates) {
15196 styleUpdates = {};
15197 }
15198 styleUpdates[styleName] = '';
15199 }
15200 }
15201 // Update styles that changed since `lastProp`.
15202 for (styleName in nextProp) {
15203 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
15204 if (!styleUpdates) {
15205 styleUpdates = {};
15206 }
15207 styleUpdates[styleName] = nextProp[styleName];
15208 }
15209 }
15210 } else {
15211 // Relies on `updateStylesByID` not mutating `styleUpdates`.
15212 if (!styleUpdates) {
15213 if (!updatePayload) {
15214 updatePayload = [];
15215 }
15216 updatePayload.push(propKey, styleUpdates);
15217 }
15218 styleUpdates = nextProp;
15219 }
15220 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
15221 var nextHtml = nextProp ? nextProp[HTML] : undefined;
15222 var lastHtml = lastProp ? lastProp[HTML] : undefined;
15223 if (nextHtml != null) {
15224 if (lastHtml !== nextHtml) {
15225 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
15226 }
15227 } else {
15228 // TODO: It might be too late to clear this if we have children
15229 // inserted already.
15230 }
15231 } else if (propKey === CHILDREN) {
15232 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
15233 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
15234 }
15235 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
15236 // Noop
15237 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15238 if (nextProp != null) {
15239 // We eagerly listen to this even though we haven't committed yet.
15240 if (true && typeof nextProp !== 'function') {
15241 warnForInvalidEventListener(propKey, nextProp);
15242 }
15243 ensureListeningTo(rootContainerElement, propKey);
15244 }
15245 if (!updatePayload && lastProp !== nextProp) {
15246 // This is a special case. If any listener updates we need to ensure
15247 // that the "current" props pointer gets updated so we need a commit
15248 // to update this element.
15249 updatePayload = [];
15250 }
15251 } else {
15252 // For any other property we always add it to the queue and then we
15253 // filter it out using the whitelist during the commit.
15254 (updatePayload = updatePayload || []).push(propKey, nextProp);
15255 }
15256 }
15257 if (styleUpdates) {
15258 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
15259 }
15260 return updatePayload;
15261}
15262
15263// Apply the diff.
15264function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
15265 // Update checked *before* name.
15266 // In the middle of an update, it is possible to have multiple checked.
15267 // When a checked radio tries to change name, browser makes another radio's checked false.
15268 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
15269 updateChecked(domElement, nextRawProps);
15270 }
15271
15272 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
15273 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
15274 // Apply the diff.
15275 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
15276
15277 // TODO: Ensure that an update gets scheduled if any of the special props
15278 // changed.
15279 switch (tag) {
15280 case 'input':
15281 // Update the wrapper around inputs *after* updating props. This has to
15282 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
15283 // raise warnings and prevent the new value from being assigned.
15284 updateWrapper(domElement, nextRawProps);
15285 break;
15286 case 'textarea':
15287 updateWrapper$1(domElement, nextRawProps);
15288 break;
15289 case 'select':
15290 // <select> value update needs to occur after <option> children
15291 // reconciliation
15292 postUpdateWrapper(domElement, nextRawProps);
15293 break;
15294 }
15295}
15296
15297function getPossibleStandardName(propName) {
15298 {
15299 var lowerCasedName = propName.toLowerCase();
15300 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
15301 return null;
15302 }
15303 return possibleStandardNames[lowerCasedName] || null;
15304 }
15305 return null;
15306}
15307
15308function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
15309 var isCustomComponentTag = void 0;
15310 var extraAttributeNames = void 0;
15311
15312 {
15313 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
15314 isCustomComponentTag = isCustomComponent(tag, rawProps);
15315 validatePropertiesInDevelopment(tag, rawProps);
15316 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
15317 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
15318 didWarnShadyDOM = true;
15319 }
15320 }
15321
15322 // TODO: Make sure that we check isMounted before firing any of these events.
15323 switch (tag) {
15324 case 'iframe':
15325 case 'object':
15326 trapBubbledEvent('topLoad', 'load', domElement);
15327 break;
15328 case 'video':
15329 case 'audio':
15330 // Create listener for each media event
15331 for (var event in mediaEventTypes) {
15332 if (mediaEventTypes.hasOwnProperty(event)) {
15333 trapBubbledEvent(event, mediaEventTypes[event], domElement);
15334 }
15335 }
15336 break;
15337 case 'source':
15338 trapBubbledEvent('topError', 'error', domElement);
15339 break;
15340 case 'img':
15341 case 'image':
15342 case 'link':
15343 trapBubbledEvent('topError', 'error', domElement);
15344 trapBubbledEvent('topLoad', 'load', domElement);
15345 break;
15346 case 'form':
15347 trapBubbledEvent('topReset', 'reset', domElement);
15348 trapBubbledEvent('topSubmit', 'submit', domElement);
15349 break;
15350 case 'details':
15351 trapBubbledEvent('topToggle', 'toggle', domElement);
15352 break;
15353 case 'input':
15354 initWrapperState(domElement, rawProps);
15355 trapBubbledEvent('topInvalid', 'invalid', domElement);
15356 // For controlled components we always need to ensure we're listening
15357 // to onChange. Even if there is no listener.
15358 ensureListeningTo(rootContainerElement, 'onChange');
15359 break;
15360 case 'option':
15361 validateProps(domElement, rawProps);
15362 break;
15363 case 'select':
15364 initWrapperState$1(domElement, rawProps);
15365 trapBubbledEvent('topInvalid', 'invalid', domElement);
15366 // For controlled components we always need to ensure we're listening
15367 // to onChange. Even if there is no listener.
15368 ensureListeningTo(rootContainerElement, 'onChange');
15369 break;
15370 case 'textarea':
15371 initWrapperState$2(domElement, rawProps);
15372 trapBubbledEvent('topInvalid', 'invalid', domElement);
15373 // For controlled components we always need to ensure we're listening
15374 // to onChange. Even if there is no listener.
15375 ensureListeningTo(rootContainerElement, 'onChange');
15376 break;
15377 }
15378
15379 assertValidProps(tag, rawProps, getStack);
15380
15381 {
15382 extraAttributeNames = new Set();
15383 var attributes = domElement.attributes;
15384 for (var i = 0; i < attributes.length; i++) {
15385 var name = attributes[i].name.toLowerCase();
15386 switch (name) {
15387 // Built-in SSR attribute is whitelisted
15388 case 'data-reactroot':
15389 break;
15390 // Controlled attributes are not validated
15391 // TODO: Only ignore them on controlled tags.
15392 case 'value':
15393 break;
15394 case 'checked':
15395 break;
15396 case 'selected':
15397 break;
15398 default:
15399 // Intentionally use the original name.
15400 // See discussion in https://github.com/facebook/react/pull/10676.
15401 extraAttributeNames.add(attributes[i].name);
15402 }
15403 }
15404 }
15405
15406 var updatePayload = null;
15407 for (var propKey in rawProps) {
15408 if (!rawProps.hasOwnProperty(propKey)) {
15409 continue;
15410 }
15411 var nextProp = rawProps[propKey];
15412 if (propKey === CHILDREN) {
15413 // For text content children we compare against textContent. This
15414 // might match additional HTML that is hidden when we read it using
15415 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
15416 // satisfies our requirement. Our requirement is not to produce perfect
15417 // HTML and attributes. Ideally we should preserve structure but it's
15418 // ok not to if the visible content is still enough to indicate what
15419 // even listeners these nodes might be wired up to.
15420 // TODO: Warn if there is more than a single textNode as a child.
15421 // TODO: Should we use domElement.firstChild.nodeValue to compare?
15422 if (typeof nextProp === 'string') {
15423 if (domElement.textContent !== nextProp) {
15424 if (true && !suppressHydrationWarning) {
15425 warnForTextDifference(domElement.textContent, nextProp);
15426 }
15427 updatePayload = [CHILDREN, nextProp];
15428 }
15429 } else if (typeof nextProp === 'number') {
15430 if (domElement.textContent !== '' + nextProp) {
15431 if (true && !suppressHydrationWarning) {
15432 warnForTextDifference(domElement.textContent, nextProp);
15433 }
15434 updatePayload = [CHILDREN, '' + nextProp];
15435 }
15436 }
15437 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15438 if (nextProp != null) {
15439 if (true && typeof nextProp !== 'function') {
15440 warnForInvalidEventListener(propKey, nextProp);
15441 }
15442 ensureListeningTo(rootContainerElement, propKey);
15443 }
15444 } else if (true &&
15445 // Convince Flow we've calculated it (it's DEV-only in this method.)
15446 typeof isCustomComponentTag === 'boolean') {
15447 // Validate that the properties correspond to their expected values.
15448 var serverValue = void 0;
15449 var propertyInfo = getPropertyInfo(propKey);
15450 if (suppressHydrationWarning) {
15451 // Don't bother comparing. We're ignoring all these warnings.
15452 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
15453 // Controlled attributes are not validated
15454 // TODO: Only ignore them on controlled tags.
15455 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
15456 // Noop
15457 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
15458 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
15459 var serverHTML = domElement.innerHTML;
15460 var expectedHTML = normalizeHTML(domElement, rawHtml);
15461 if (expectedHTML !== serverHTML) {
15462 warnForPropDifference(propKey, serverHTML, expectedHTML);
15463 }
15464 } else if (propKey === STYLE) {
15465 // $FlowFixMe - Should be inferred as not undefined.
15466 extraAttributeNames['delete'](propKey);
15467 var expectedStyle = createDangerousStringForStyles(nextProp);
15468 serverValue = domElement.getAttribute('style');
15469 if (expectedStyle !== serverValue) {
15470 warnForPropDifference(propKey, serverValue, expectedStyle);
15471 }
15472 } else if (isCustomComponentTag) {
15473 // $FlowFixMe - Should be inferred as not undefined.
15474 extraAttributeNames['delete'](propKey.toLowerCase());
15475 serverValue = getValueForAttribute(domElement, propKey, nextProp);
15476
15477 if (nextProp !== serverValue) {
15478 warnForPropDifference(propKey, serverValue, nextProp);
15479 }
15480 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
15481 var isMismatchDueToBadCasing = false;
15482 if (propertyInfo !== null) {
15483 // $FlowFixMe - Should be inferred as not undefined.
15484 extraAttributeNames['delete'](propertyInfo.attributeName);
15485 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
15486 } else {
15487 var ownNamespace = parentNamespace;
15488 if (ownNamespace === HTML_NAMESPACE) {
15489 ownNamespace = getIntrinsicNamespace(tag);
15490 }
15491 if (ownNamespace === HTML_NAMESPACE) {
15492 // $FlowFixMe - Should be inferred as not undefined.
15493 extraAttributeNames['delete'](propKey.toLowerCase());
15494 } else {
15495 var standardName = getPossibleStandardName(propKey);
15496 if (standardName !== null && standardName !== propKey) {
15497 // If an SVG prop is supplied with bad casing, it will
15498 // be successfully parsed from HTML, but will produce a mismatch
15499 // (and would be incorrectly rendered on the client).
15500 // However, we already warn about bad casing elsewhere.
15501 // So we'll skip the misleading extra mismatch warning in this case.
15502 isMismatchDueToBadCasing = true;
15503 // $FlowFixMe - Should be inferred as not undefined.
15504 extraAttributeNames['delete'](standardName);
15505 }
15506 // $FlowFixMe - Should be inferred as not undefined.
15507 extraAttributeNames['delete'](propKey);
15508 }
15509 serverValue = getValueForAttribute(domElement, propKey, nextProp);
15510 }
15511
15512 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
15513 warnForPropDifference(propKey, serverValue, nextProp);
15514 }
15515 }
15516 }
15517 }
15518
15519 {
15520 // $FlowFixMe - Should be inferred as not undefined.
15521 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
15522 // $FlowFixMe - Should be inferred as not undefined.
15523 warnForExtraAttributes(extraAttributeNames);
15524 }
15525 }
15526
15527 switch (tag) {
15528 case 'input':
15529 // TODO: Make sure we check if this is still unmounted or do any clean
15530 // up necessary since we never stop tracking anymore.
15531 track(domElement);
15532 postMountWrapper(domElement, rawProps);
15533 break;
15534 case 'textarea':
15535 // TODO: Make sure we check if this is still unmounted or do any clean
15536 // up necessary since we never stop tracking anymore.
15537 track(domElement);
15538 postMountWrapper$3(domElement, rawProps);
15539 break;
15540 case 'select':
15541 case 'option':
15542 // For input and textarea we current always set the value property at
15543 // post mount to force it to diverge from attributes. However, for
15544 // option and select we don't quite do the same thing and select
15545 // is not resilient to the DOM state changing so we don't do that here.
15546 // TODO: Consider not doing this for input and textarea.
15547 break;
15548 default:
15549 if (typeof rawProps.onClick === 'function') {
15550 // TODO: This cast may not be sound for SVG, MathML or custom elements.
15551 trapClickOnNonInteractiveElement(domElement);
15552 }
15553 break;
15554 }
15555
15556 return updatePayload;
15557}
15558
15559function diffHydratedText$1(textNode, text) {
15560 var isDifferent = textNode.nodeValue !== text;
15561 return isDifferent;
15562}
15563
15564function warnForUnmatchedText$1(textNode, text) {
15565 {
15566 warnForTextDifference(textNode.nodeValue, text);
15567 }
15568}
15569
15570function warnForDeletedHydratableElement$1(parentNode, child) {
15571 {
15572 if (didWarnInvalidHydration) {
15573 return;
15574 }
15575 didWarnInvalidHydration = true;
15576 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
15577 }
15578}
15579
15580function warnForDeletedHydratableText$1(parentNode, child) {
15581 {
15582 if (didWarnInvalidHydration) {
15583 return;
15584 }
15585 didWarnInvalidHydration = true;
15586 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
15587 }
15588}
15589
15590function warnForInsertedHydratedElement$1(parentNode, tag, props) {
15591 {
15592 if (didWarnInvalidHydration) {
15593 return;
15594 }
15595 didWarnInvalidHydration = true;
15596 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
15597 }
15598}
15599
15600function warnForInsertedHydratedText$1(parentNode, text) {
15601 {
15602 if (text === '') {
15603 // We expect to insert empty text nodes since they're not represented in
15604 // the HTML.
15605 // TODO: Remove this special case if we can just avoid inserting empty
15606 // text nodes.
15607 return;
15608 }
15609 if (didWarnInvalidHydration) {
15610 return;
15611 }
15612 didWarnInvalidHydration = true;
15613 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
15614 }
15615}
15616
15617function restoreControlledState$1(domElement, tag, props) {
15618 switch (tag) {
15619 case 'input':
15620 restoreControlledState(domElement, props);
15621 return;
15622 case 'textarea':
15623 restoreControlledState$3(domElement, props);
15624 return;
15625 case 'select':
15626 restoreControlledState$2(domElement, props);
15627 return;
15628 }
15629}
15630
15631var ReactDOMFiberComponent = Object.freeze({
15632 createElement: createElement$1,
15633 createTextNode: createTextNode$1,
15634 setInitialProperties: setInitialProperties$1,
15635 diffProperties: diffProperties$1,
15636 updateProperties: updateProperties$1,
15637 diffHydratedProperties: diffHydratedProperties$1,
15638 diffHydratedText: diffHydratedText$1,
15639 warnForUnmatchedText: warnForUnmatchedText$1,
15640 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
15641 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
15642 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
15643 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
15644 restoreControlledState: restoreControlledState$1
15645});
15646
15647// TODO: direct imports like some-package/src/* are bad. Fix me.
15648var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
15649
15650var validateDOMNesting = emptyFunction_1;
15651
15652{
15653 // This validation code was written based on the HTML5 parsing spec:
15654 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
15655 //
15656 // Note: this does not catch all invalid nesting, nor does it try to (as it's
15657 // not clear what practical benefit doing so provides); instead, we warn only
15658 // for cases where the parser will give a parse tree differing from what React
15659 // intended. For example, <b><div></div></b> is invalid but we don't warn
15660 // because it still parses correctly; we do warn for other cases like nested
15661 // <p> tags where the beginning of the second element implicitly closes the
15662 // first, causing a confusing mess.
15663
15664 // https://html.spec.whatwg.org/multipage/syntax.html#special
15665 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'];
15666
15667 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
15668 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
15669
15670 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
15671 // TODO: Distinguish by namespace here -- for <title>, including it here
15672 // errs on the side of fewer warnings
15673 'foreignObject', 'desc', 'title'];
15674
15675 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
15676 var buttonScopeTags = inScopeTags.concat(['button']);
15677
15678 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
15679 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
15680
15681 var emptyAncestorInfo = {
15682 current: null,
15683
15684 formTag: null,
15685 aTagInScope: null,
15686 buttonTagInScope: null,
15687 nobrTagInScope: null,
15688 pTagInButtonScope: null,
15689
15690 listItemTagAutoclosing: null,
15691 dlItemTagAutoclosing: null
15692 };
15693
15694 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
15695 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
15696 var info = { tag: tag, instance: instance };
15697
15698 if (inScopeTags.indexOf(tag) !== -1) {
15699 ancestorInfo.aTagInScope = null;
15700 ancestorInfo.buttonTagInScope = null;
15701 ancestorInfo.nobrTagInScope = null;
15702 }
15703 if (buttonScopeTags.indexOf(tag) !== -1) {
15704 ancestorInfo.pTagInButtonScope = null;
15705 }
15706
15707 // See rules for 'li', 'dd', 'dt' start tags in
15708 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15709 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
15710 ancestorInfo.listItemTagAutoclosing = null;
15711 ancestorInfo.dlItemTagAutoclosing = null;
15712 }
15713
15714 ancestorInfo.current = info;
15715
15716 if (tag === 'form') {
15717 ancestorInfo.formTag = info;
15718 }
15719 if (tag === 'a') {
15720 ancestorInfo.aTagInScope = info;
15721 }
15722 if (tag === 'button') {
15723 ancestorInfo.buttonTagInScope = info;
15724 }
15725 if (tag === 'nobr') {
15726 ancestorInfo.nobrTagInScope = info;
15727 }
15728 if (tag === 'p') {
15729 ancestorInfo.pTagInButtonScope = info;
15730 }
15731 if (tag === 'li') {
15732 ancestorInfo.listItemTagAutoclosing = info;
15733 }
15734 if (tag === 'dd' || tag === 'dt') {
15735 ancestorInfo.dlItemTagAutoclosing = info;
15736 }
15737
15738 return ancestorInfo;
15739 };
15740
15741 /**
15742 * Returns whether
15743 */
15744 var isTagValidWithParent = function (tag, parentTag) {
15745 // First, let's check if we're in an unusual parsing mode...
15746 switch (parentTag) {
15747 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
15748 case 'select':
15749 return tag === 'option' || tag === 'optgroup' || tag === '#text';
15750 case 'optgroup':
15751 return tag === 'option' || tag === '#text';
15752 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
15753 // but
15754 case 'option':
15755 return tag === '#text';
15756 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
15757 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
15758 // No special behavior since these rules fall back to "in body" mode for
15759 // all except special table nodes which cause bad parsing behavior anyway.
15760
15761 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
15762 case 'tr':
15763 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
15764 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
15765 case 'tbody':
15766 case 'thead':
15767 case 'tfoot':
15768 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
15769 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
15770 case 'colgroup':
15771 return tag === 'col' || tag === 'template';
15772 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
15773 case 'table':
15774 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
15775 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
15776 case 'head':
15777 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
15778 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
15779 case 'html':
15780 return tag === 'head' || tag === 'body';
15781 case '#document':
15782 return tag === 'html';
15783 }
15784
15785 // Probably in the "in body" parsing mode, so we outlaw only tag combos
15786 // where the parsing rules cause implicit opens or closes to be added.
15787 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15788 switch (tag) {
15789 case 'h1':
15790 case 'h2':
15791 case 'h3':
15792 case 'h4':
15793 case 'h5':
15794 case 'h6':
15795 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
15796
15797 case 'rp':
15798 case 'rt':
15799 return impliedEndTags.indexOf(parentTag) === -1;
15800
15801 case 'body':
15802 case 'caption':
15803 case 'col':
15804 case 'colgroup':
15805 case 'frame':
15806 case 'head':
15807 case 'html':
15808 case 'tbody':
15809 case 'td':
15810 case 'tfoot':
15811 case 'th':
15812 case 'thead':
15813 case 'tr':
15814 // These tags are only valid with a few parents that have special child
15815 // parsing rules -- if we're down here, then none of those matched and
15816 // so we allow it only if we don't know what the parent is, as all other
15817 // cases are invalid.
15818 return parentTag == null;
15819 }
15820
15821 return true;
15822 };
15823
15824 /**
15825 * Returns whether
15826 */
15827 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
15828 switch (tag) {
15829 case 'address':
15830 case 'article':
15831 case 'aside':
15832 case 'blockquote':
15833 case 'center':
15834 case 'details':
15835 case 'dialog':
15836 case 'dir':
15837 case 'div':
15838 case 'dl':
15839 case 'fieldset':
15840 case 'figcaption':
15841 case 'figure':
15842 case 'footer':
15843 case 'header':
15844 case 'hgroup':
15845 case 'main':
15846 case 'menu':
15847 case 'nav':
15848 case 'ol':
15849 case 'p':
15850 case 'section':
15851 case 'summary':
15852 case 'ul':
15853 case 'pre':
15854 case 'listing':
15855 case 'table':
15856 case 'hr':
15857 case 'xmp':
15858 case 'h1':
15859 case 'h2':
15860 case 'h3':
15861 case 'h4':
15862 case 'h5':
15863 case 'h6':
15864 return ancestorInfo.pTagInButtonScope;
15865
15866 case 'form':
15867 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
15868
15869 case 'li':
15870 return ancestorInfo.listItemTagAutoclosing;
15871
15872 case 'dd':
15873 case 'dt':
15874 return ancestorInfo.dlItemTagAutoclosing;
15875
15876 case 'button':
15877 return ancestorInfo.buttonTagInScope;
15878
15879 case 'a':
15880 // Spec says something about storing a list of markers, but it sounds
15881 // equivalent to this check.
15882 return ancestorInfo.aTagInScope;
15883
15884 case 'nobr':
15885 return ancestorInfo.nobrTagInScope;
15886 }
15887
15888 return null;
15889 };
15890
15891 var didWarn = {};
15892
15893 validateDOMNesting = function (childTag, childText, ancestorInfo) {
15894 ancestorInfo = ancestorInfo || emptyAncestorInfo;
15895 var parentInfo = ancestorInfo.current;
15896 var parentTag = parentInfo && parentInfo.tag;
15897
15898 if (childText != null) {
15899 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
15900 childTag = '#text';
15901 }
15902
15903 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15904 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15905 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15906 if (!invalidParentOrAncestor) {
15907 return;
15908 }
15909
15910 var ancestorTag = invalidParentOrAncestor.tag;
15911 var addendum = getCurrentFiberStackAddendum$6();
15912
15913 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15914 if (didWarn[warnKey]) {
15915 return;
15916 }
15917 didWarn[warnKey] = true;
15918
15919 var tagDisplayName = childTag;
15920 var whitespaceInfo = '';
15921 if (childTag === '#text') {
15922 if (/\S/.test(childText)) {
15923 tagDisplayName = 'Text nodes';
15924 } else {
15925 tagDisplayName = 'Whitespace text nodes';
15926 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15927 }
15928 } else {
15929 tagDisplayName = '<' + childTag + '>';
15930 }
15931
15932 if (invalidParent) {
15933 var info = '';
15934 if (ancestorTag === 'table' && childTag === 'tr') {
15935 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15936 }
15937 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15938 } else {
15939 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15940 }
15941 };
15942
15943 // TODO: turn this into a named export
15944 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15945}
15946
15947var validateDOMNesting$1 = validateDOMNesting;
15948
15949// TODO: This type is shared between the reconciler and ReactDOM, but will
15950// eventually be lifted out to the renderer.
15951
15952// TODO: direct imports like some-package/src/* are bad. Fix me.
15953var createElement = createElement$1;
15954var createTextNode = createTextNode$1;
15955var setInitialProperties = setInitialProperties$1;
15956var diffProperties = diffProperties$1;
15957var updateProperties = updateProperties$1;
15958var diffHydratedProperties = diffHydratedProperties$1;
15959var diffHydratedText = diffHydratedText$1;
15960var warnForUnmatchedText = warnForUnmatchedText$1;
15961var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15962var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15963var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15964var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15965var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15966var precacheFiberNode = precacheFiberNode$1;
15967var updateFiberProps = updateFiberProps$1;
15968
15969
15970var SUPPRESS_HYDRATION_WARNING = void 0;
15971var topLevelUpdateWarnings = void 0;
15972var warnOnInvalidCallback = void 0;
15973var didWarnAboutUnstableCreatePortal = false;
15974
15975{
15976 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15977 if (typeof Map !== 'function' || Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
15978 warning_1(false, 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
15979 }
15980
15981 topLevelUpdateWarnings = function (container) {
15982 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15983 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15984 if (hostInstance) {
15985 warning_1(hostInstance.parentNode === container, '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.');
15986 }
15987 }
15988
15989 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15990 var rootEl = getReactRootElementInContainer(container);
15991 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15992
15993 warning_1(!hasNonRootReactChild || isRootRenderedBySomeReact, '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.');
15994
15995 warning_1(container.nodeType !== ELEMENT_NODE || !container.tagName || container.tagName.toUpperCase() !== 'BODY', '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.');
15996 };
15997
15998 warnOnInvalidCallback = function (callback, callerName) {
15999 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
16000 };
16001}
16002
16003injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
16004
16005var eventsEnabled = null;
16006var selectionInformation = null;
16007
16008function ReactBatch(root) {
16009 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
16010 this._expirationTime = expirationTime;
16011 this._root = root;
16012 this._next = null;
16013 this._callbacks = null;
16014 this._didComplete = false;
16015 this._hasChildren = false;
16016 this._children = null;
16017 this._defer = true;
16018}
16019ReactBatch.prototype.render = function (children) {
16020 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
16021 this._hasChildren = true;
16022 this._children = children;
16023 var internalRoot = this._root._internalRoot;
16024 var expirationTime = this._expirationTime;
16025 var work = new ReactWork();
16026 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
16027 return work;
16028};
16029ReactBatch.prototype.then = function (onComplete) {
16030 if (this._didComplete) {
16031 onComplete();
16032 return;
16033 }
16034 var callbacks = this._callbacks;
16035 if (callbacks === null) {
16036 callbacks = this._callbacks = [];
16037 }
16038 callbacks.push(onComplete);
16039};
16040ReactBatch.prototype.commit = function () {
16041 var internalRoot = this._root._internalRoot;
16042 var firstBatch = internalRoot.firstBatch;
16043 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
16044
16045 if (!this._hasChildren) {
16046 // This batch is empty. Return.
16047 this._next = null;
16048 this._defer = false;
16049 return;
16050 }
16051
16052 var expirationTime = this._expirationTime;
16053
16054 // Ensure this is the first batch in the list.
16055 if (firstBatch !== this) {
16056 // This batch is not the earliest batch. We need to move it to the front.
16057 // Update its expiration time to be the expiration time of the earliest
16058 // batch, so that we can flush it without flushing the other batches.
16059 if (this._hasChildren) {
16060 expirationTime = this._expirationTime = firstBatch._expirationTime;
16061 // Rendering this batch again ensures its children will be the final state
16062 // when we flush (updates are processed in insertion order: last
16063 // update wins).
16064 // TODO: This forces a restart. Should we print a warning?
16065 this.render(this._children);
16066 }
16067
16068 // Remove the batch from the list.
16069 var previous = null;
16070 var batch = firstBatch;
16071 while (batch !== this) {
16072 previous = batch;
16073 batch = batch._next;
16074 }
16075 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
16076 previous._next = batch._next;
16077
16078 // Add it to the front.
16079 this._next = firstBatch;
16080 firstBatch = internalRoot.firstBatch = this;
16081 }
16082
16083 // Synchronously flush all the work up to this batch's expiration time.
16084 this._defer = false;
16085 DOMRenderer.flushRoot(internalRoot, expirationTime);
16086
16087 // Pop the batch from the list.
16088 var next = this._next;
16089 this._next = null;
16090 firstBatch = internalRoot.firstBatch = next;
16091
16092 // Append the next earliest batch's children to the update queue.
16093 if (firstBatch !== null && firstBatch._hasChildren) {
16094 firstBatch.render(firstBatch._children);
16095 }
16096};
16097ReactBatch.prototype._onComplete = function () {
16098 if (this._didComplete) {
16099 return;
16100 }
16101 this._didComplete = true;
16102 var callbacks = this._callbacks;
16103 if (callbacks === null) {
16104 return;
16105 }
16106 // TODO: Error handling.
16107 for (var i = 0; i < callbacks.length; i++) {
16108 var _callback = callbacks[i];
16109 _callback();
16110 }
16111};
16112
16113function ReactWork() {
16114 this._callbacks = null;
16115 this._didCommit = false;
16116 // TODO: Avoid need to bind by replacing callbacks in the update queue with
16117 // list of Work objects.
16118 this._onCommit = this._onCommit.bind(this);
16119}
16120ReactWork.prototype.then = function (onCommit) {
16121 if (this._didCommit) {
16122 onCommit();
16123 return;
16124 }
16125 var callbacks = this._callbacks;
16126 if (callbacks === null) {
16127 callbacks = this._callbacks = [];
16128 }
16129 callbacks.push(onCommit);
16130};
16131ReactWork.prototype._onCommit = function () {
16132 if (this._didCommit) {
16133 return;
16134 }
16135 this._didCommit = true;
16136 var callbacks = this._callbacks;
16137 if (callbacks === null) {
16138 return;
16139 }
16140 // TODO: Error handling.
16141 for (var i = 0; i < callbacks.length; i++) {
16142 var _callback2 = callbacks[i];
16143 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
16144 _callback2();
16145 }
16146};
16147
16148function ReactRoot(container, isAsync, hydrate) {
16149 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
16150 this._internalRoot = root;
16151}
16152ReactRoot.prototype.render = function (children, callback) {
16153 var root = this._internalRoot;
16154 var work = new ReactWork();
16155 callback = callback === undefined ? null : callback;
16156 {
16157 warnOnInvalidCallback(callback, 'render');
16158 }
16159 if (callback !== null) {
16160 work.then(callback);
16161 }
16162 DOMRenderer.updateContainer(children, root, null, work._onCommit);
16163 return work;
16164};
16165ReactRoot.prototype.unmount = function (callback) {
16166 var root = this._internalRoot;
16167 var work = new ReactWork();
16168 callback = callback === undefined ? null : callback;
16169 {
16170 warnOnInvalidCallback(callback, 'render');
16171 }
16172 if (callback !== null) {
16173 work.then(callback);
16174 }
16175 DOMRenderer.updateContainer(null, root, null, work._onCommit);
16176 return work;
16177};
16178ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
16179 var root = this._internalRoot;
16180 var work = new ReactWork();
16181 callback = callback === undefined ? null : callback;
16182 {
16183 warnOnInvalidCallback(callback, 'render');
16184 }
16185 if (callback !== null) {
16186 work.then(callback);
16187 }
16188 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
16189 return work;
16190};
16191ReactRoot.prototype.createBatch = function () {
16192 var batch = new ReactBatch(this);
16193 var expirationTime = batch._expirationTime;
16194
16195 var internalRoot = this._internalRoot;
16196 var firstBatch = internalRoot.firstBatch;
16197 if (firstBatch === null) {
16198 internalRoot.firstBatch = batch;
16199 batch._next = null;
16200 } else {
16201 // Insert sorted by expiration time then insertion order
16202 var insertAfter = null;
16203 var insertBefore = firstBatch;
16204 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
16205 insertAfter = insertBefore;
16206 insertBefore = insertBefore._next;
16207 }
16208 batch._next = insertBefore;
16209 if (insertAfter !== null) {
16210 insertAfter._next = batch;
16211 }
16212 }
16213
16214 return batch;
16215};
16216
16217/**
16218 * True if the supplied DOM node is a valid node element.
16219 *
16220 * @param {?DOMElement} node The candidate DOM node.
16221 * @return {boolean} True if the DOM is a valid DOM node.
16222 * @internal
16223 */
16224function isValidContainer(node) {
16225 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 '));
16226}
16227
16228function getReactRootElementInContainer(container) {
16229 if (!container) {
16230 return null;
16231 }
16232
16233 if (container.nodeType === DOCUMENT_NODE) {
16234 return container.documentElement;
16235 } else {
16236 return container.firstChild;
16237 }
16238}
16239
16240function shouldHydrateDueToLegacyHeuristic(container) {
16241 var rootElement = getReactRootElementInContainer(container);
16242 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
16243}
16244
16245function shouldAutoFocusHostComponent(type, props) {
16246 switch (type) {
16247 case 'button':
16248 case 'input':
16249 case 'select':
16250 case 'textarea':
16251 return !!props.autoFocus;
16252 }
16253 return false;
16254}
16255
16256var DOMRenderer = reactReconciler({
16257 getRootHostContext: function (rootContainerInstance) {
16258 var type = void 0;
16259 var namespace = void 0;
16260 var nodeType = rootContainerInstance.nodeType;
16261 switch (nodeType) {
16262 case DOCUMENT_NODE:
16263 case DOCUMENT_FRAGMENT_NODE:
16264 {
16265 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
16266 var root = rootContainerInstance.documentElement;
16267 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
16268 break;
16269 }
16270 default:
16271 {
16272 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
16273 var ownNamespace = container.namespaceURI || null;
16274 type = container.tagName;
16275 namespace = getChildNamespace(ownNamespace, type);
16276 break;
16277 }
16278 }
16279 {
16280 var validatedTag = type.toLowerCase();
16281 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
16282 return { namespace: namespace, ancestorInfo: _ancestorInfo };
16283 }
16284 return namespace;
16285 },
16286 getChildHostContext: function (parentHostContext, type) {
16287 {
16288 var parentHostContextDev = parentHostContext;
16289 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
16290 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
16291 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
16292 }
16293 var parentNamespace = parentHostContext;
16294 return getChildNamespace(parentNamespace, type);
16295 },
16296 getPublicInstance: function (instance) {
16297 return instance;
16298 },
16299 prepareForCommit: function () {
16300 eventsEnabled = isEnabled();
16301 selectionInformation = getSelectionInformation();
16302 setEnabled(false);
16303 },
16304 resetAfterCommit: function () {
16305 restoreSelection(selectionInformation);
16306 selectionInformation = null;
16307 setEnabled(eventsEnabled);
16308 eventsEnabled = null;
16309 },
16310 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
16311 var parentNamespace = void 0;
16312 {
16313 // TODO: take namespace into account when validating.
16314 var hostContextDev = hostContext;
16315 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
16316 if (typeof props.children === 'string' || typeof props.children === 'number') {
16317 var string = '' + props.children;
16318 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
16319 validateDOMNesting$1(null, string, ownAncestorInfo);
16320 }
16321 parentNamespace = hostContextDev.namespace;
16322 }
16323 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
16324 precacheFiberNode(internalInstanceHandle, domElement);
16325 updateFiberProps(domElement, props);
16326 return domElement;
16327 },
16328 appendInitialChild: function (parentInstance, child) {
16329 parentInstance.appendChild(child);
16330 },
16331 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
16332 setInitialProperties(domElement, type, props, rootContainerInstance);
16333 return shouldAutoFocusHostComponent(type, props);
16334 },
16335 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
16336 {
16337 var hostContextDev = hostContext;
16338 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
16339 var string = '' + newProps.children;
16340 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
16341 validateDOMNesting$1(null, string, ownAncestorInfo);
16342 }
16343 }
16344 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
16345 },
16346 shouldSetTextContent: function (type, props) {
16347 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
16348 },
16349 shouldDeprioritizeSubtree: function (type, props) {
16350 return !!props.hidden;
16351 },
16352 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
16353 {
16354 var hostContextDev = hostContext;
16355 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
16356 }
16357 var textNode = createTextNode(text, rootContainerInstance);
16358 precacheFiberNode(internalInstanceHandle, textNode);
16359 return textNode;
16360 },
16361
16362
16363 now: now,
16364
16365 mutation: {
16366 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
16367 // Despite the naming that might imply otherwise, this method only
16368 // fires if there is an `Update` effect scheduled during mounting.
16369 // This happens if `finalizeInitialChildren` returns `true` (which it
16370 // does to implement the `autoFocus` attribute on the client). But
16371 // there are also other cases when this might happen (such as patching
16372 // up text content during hydration mismatch). So we'll check this again.
16373 if (shouldAutoFocusHostComponent(type, newProps)) {
16374 domElement.focus();
16375 }
16376 },
16377 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
16378 // Update the props handle so that we know which props are the ones with
16379 // with current event handlers.
16380 updateFiberProps(domElement, newProps);
16381 // Apply the diff to the DOM node.
16382 updateProperties(domElement, updatePayload, type, oldProps, newProps);
16383 },
16384 resetTextContent: function (domElement) {
16385 setTextContent(domElement, '');
16386 },
16387 commitTextUpdate: function (textInstance, oldText, newText) {
16388 textInstance.nodeValue = newText;
16389 },
16390 appendChild: function (parentInstance, child) {
16391 parentInstance.appendChild(child);
16392 },
16393 appendChildToContainer: function (container, child) {
16394 if (container.nodeType === COMMENT_NODE) {
16395 container.parentNode.insertBefore(child, container);
16396 } else {
16397 container.appendChild(child);
16398 }
16399 },
16400 insertBefore: function (parentInstance, child, beforeChild) {
16401 parentInstance.insertBefore(child, beforeChild);
16402 },
16403 insertInContainerBefore: function (container, child, beforeChild) {
16404 if (container.nodeType === COMMENT_NODE) {
16405 container.parentNode.insertBefore(child, beforeChild);
16406 } else {
16407 container.insertBefore(child, beforeChild);
16408 }
16409 },
16410 removeChild: function (parentInstance, child) {
16411 parentInstance.removeChild(child);
16412 },
16413 removeChildFromContainer: function (container, child) {
16414 if (container.nodeType === COMMENT_NODE) {
16415 container.parentNode.removeChild(child);
16416 } else {
16417 container.removeChild(child);
16418 }
16419 }
16420 },
16421
16422 hydration: {
16423 canHydrateInstance: function (instance, type, props) {
16424 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
16425 return null;
16426 }
16427 // This has now been refined to an element node.
16428 return instance;
16429 },
16430 canHydrateTextInstance: function (instance, text) {
16431 if (text === '' || instance.nodeType !== TEXT_NODE) {
16432 // Empty strings are not parsed by HTML so there won't be a correct match here.
16433 return null;
16434 }
16435 // This has now been refined to a text node.
16436 return instance;
16437 },
16438 getNextHydratableSibling: function (instance) {
16439 var node = instance.nextSibling;
16440 // Skip non-hydratable nodes.
16441 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
16442 node = node.nextSibling;
16443 }
16444 return node;
16445 },
16446 getFirstHydratableChild: function (parentInstance) {
16447 var next = parentInstance.firstChild;
16448 // Skip non-hydratable nodes.
16449 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
16450 next = next.nextSibling;
16451 }
16452 return next;
16453 },
16454 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
16455 precacheFiberNode(internalInstanceHandle, instance);
16456 // TODO: Possibly defer this until the commit phase where all the events
16457 // get attached.
16458 updateFiberProps(instance, props);
16459 var parentNamespace = void 0;
16460 {
16461 var hostContextDev = hostContext;
16462 parentNamespace = hostContextDev.namespace;
16463 }
16464 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
16465 },
16466 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
16467 precacheFiberNode(internalInstanceHandle, textInstance);
16468 return diffHydratedText(textInstance, text);
16469 },
16470 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
16471 {
16472 warnForUnmatchedText(textInstance, text);
16473 }
16474 },
16475 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
16476 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16477 warnForUnmatchedText(textInstance, text);
16478 }
16479 },
16480 didNotHydrateContainerInstance: function (parentContainer, instance) {
16481 {
16482 if (instance.nodeType === 1) {
16483 warnForDeletedHydratableElement(parentContainer, instance);
16484 } else {
16485 warnForDeletedHydratableText(parentContainer, instance);
16486 }
16487 }
16488 },
16489 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
16490 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16491 if (instance.nodeType === 1) {
16492 warnForDeletedHydratableElement(parentInstance, instance);
16493 } else {
16494 warnForDeletedHydratableText(parentInstance, instance);
16495 }
16496 }
16497 },
16498 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
16499 {
16500 warnForInsertedHydratedElement(parentContainer, type, props);
16501 }
16502 },
16503 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
16504 {
16505 warnForInsertedHydratedText(parentContainer, text);
16506 }
16507 },
16508 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
16509 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16510 warnForInsertedHydratedElement(parentInstance, type, props);
16511 }
16512 },
16513 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
16514 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16515 warnForInsertedHydratedText(parentInstance, text);
16516 }
16517 }
16518 },
16519
16520 scheduleDeferredCallback: rIC,
16521 cancelDeferredCallback: cIC
16522});
16523
16524injection$3.injectRenderer(DOMRenderer);
16525
16526var warnedAboutHydrateAPI = false;
16527
16528function legacyCreateRootFromDOMContainer(container, forceHydrate) {
16529 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
16530 // First clear any existing content.
16531 if (!shouldHydrate) {
16532 var warned = false;
16533 var rootSibling = void 0;
16534 while (rootSibling = container.lastChild) {
16535 {
16536 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
16537 warned = true;
16538 warning_1(false, '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.');
16539 }
16540 }
16541 container.removeChild(rootSibling);
16542 }
16543 }
16544 {
16545 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
16546 warnedAboutHydrateAPI = true;
16547 lowPriorityWarning$1(false, 'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');
16548 }
16549 }
16550 // Legacy roots are not async by default.
16551 var isAsync = false;
16552 return new ReactRoot(container, isAsync, shouldHydrate);
16553}
16554
16555function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
16556 // TODO: Ensure all entry points contain this check
16557 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
16558
16559 {
16560 topLevelUpdateWarnings(container);
16561 }
16562
16563 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
16564 // member of intersection type." Whyyyyyy.
16565 var root = container._reactRootContainer;
16566 if (!root) {
16567 // Initial mount
16568 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
16569 if (typeof callback === 'function') {
16570 var originalCallback = callback;
16571 callback = function () {
16572 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
16573 originalCallback.call(instance);
16574 };
16575 }
16576 // Initial mount should not be batched.
16577 DOMRenderer.unbatchedUpdates(function () {
16578 if (parentComponent != null) {
16579 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
16580 } else {
16581 root.render(children, callback);
16582 }
16583 });
16584 } else {
16585 if (typeof callback === 'function') {
16586 var _originalCallback = callback;
16587 callback = function () {
16588 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
16589 _originalCallback.call(instance);
16590 };
16591 }
16592 // Update
16593 if (parentComponent != null) {
16594 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
16595 } else {
16596 root.render(children, callback);
16597 }
16598 }
16599 return DOMRenderer.getPublicRootInstance(root._internalRoot);
16600}
16601
16602function createPortal(children, container) {
16603 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
16604
16605 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
16606 // TODO: pass ReactDOM portal implementation as third argument
16607 return createPortal$1(children, container, null, key);
16608}
16609
16610var ReactDOM = {
16611 createPortal: createPortal,
16612
16613 findDOMNode: function (componentOrElement) {
16614 {
16615 var owner = ReactCurrentOwner.current;
16616 if (owner !== null) {
16617 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
16618 warning_1(warnedAboutRefsInRender, '%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) || 'A component');
16619 owner.stateNode._warnedAboutRefsInRender = true;
16620 }
16621 }
16622 if (componentOrElement == null) {
16623 return null;
16624 }
16625 if (componentOrElement.nodeType === ELEMENT_NODE) {
16626 return componentOrElement;
16627 }
16628
16629 var inst = get(componentOrElement);
16630 if (inst) {
16631 return DOMRenderer.findHostInstance(inst);
16632 }
16633
16634 if (typeof componentOrElement.render === 'function') {
16635 invariant_1(false, 'Unable to find node on an unmounted component.');
16636 } else {
16637 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
16638 }
16639 },
16640 hydrate: function (element, container, callback) {
16641 // TODO: throw or warn if we couldn't hydrate?
16642 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
16643 },
16644 render: function (element, container, callback) {
16645 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
16646 },
16647 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
16648 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
16649 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
16650 },
16651 unmountComponentAtNode: function (container) {
16652 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
16653
16654 if (container._reactRootContainer) {
16655 {
16656 var rootEl = getReactRootElementInContainer(container);
16657 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
16658 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
16659 }
16660
16661 // Unmount should not be batched.
16662 DOMRenderer.unbatchedUpdates(function () {
16663 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
16664 container._reactRootContainer = null;
16665 });
16666 });
16667 // If you call unmountComponentAtNode twice in quick succession, you'll
16668 // get `true` twice. That's probably fine?
16669 return true;
16670 } else {
16671 {
16672 var _rootEl = getReactRootElementInContainer(container);
16673 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
16674
16675 // Check if the container itself is a React root node.
16676 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
16677
16678 warning_1(!hasNonRootReactChild, "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.');
16679 }
16680
16681 return false;
16682 }
16683 },
16684
16685
16686 // Temporary alias since we already shipped React 16 RC with it.
16687 // TODO: remove in React 17.
16688 unstable_createPortal: function () {
16689 if (!didWarnAboutUnstableCreatePortal) {
16690 didWarnAboutUnstableCreatePortal = true;
16691 lowPriorityWarning$1(false, 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.');
16692 }
16693 return createPortal.apply(undefined, arguments);
16694 },
16695
16696
16697 unstable_batchedUpdates: DOMRenderer.batchedUpdates,
16698
16699 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
16700
16701 flushSync: DOMRenderer.flushSync,
16702
16703 unstable_flushControlled: DOMRenderer.flushControlled,
16704
16705 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
16706 // For TapEventPlugin which is popular in open source
16707 EventPluginHub: EventPluginHub,
16708 // Used by test-utils
16709 EventPluginRegistry: EventPluginRegistry,
16710 EventPropagators: EventPropagators,
16711 ReactControlledComponent: ReactControlledComponent,
16712 ReactDOMComponentTree: ReactDOMComponentTree,
16713 ReactDOMEventListener: ReactDOMEventListener
16714 }
16715};
16716
16717if (enableCreateRoot) {
16718 ReactDOM.createRoot = function createRoot(container, options) {
16719 var hydrate = options != null && options.hydrate === true;
16720 return new ReactRoot(container, true, hydrate);
16721 };
16722}
16723
16724var foundDevTools = DOMRenderer.injectIntoDevTools({
16725 findFiberByHostInstance: getClosestInstanceFromNode,
16726 bundleType: 1,
16727 version: ReactVersion,
16728 rendererPackageName: 'react-dom'
16729});
16730
16731{
16732 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
16733 // If we're in Chrome or Firefox, provide a download link if not installed.
16734 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
16735 var protocol = window.location.protocol;
16736 // Don't warn in exotic cases like chrome-extension://.
16737 if (/^(https?|file):$/.test(protocol)) {
16738 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://fb.me/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://fb.me/react-devtools-faq' : ''), 'font-weight:bold');
16739 }
16740 }
16741 }
16742}
16743
16744
16745
16746var ReactDOM$2 = Object.freeze({
16747 default: ReactDOM
16748});
16749
16750var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
16751
16752// TODO: decide on the top-level export form.
16753// This is hacky but makes it work with both Rollup and Jest.
16754var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
16755
16756return reactDom;
16757
16758})));