· 8 years ago · Feb 21, 2018, 08:34 AM
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:
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 Err = 64;
3784var Ref = 128;
3785
3786var MOUNTING = 1;
3787var MOUNTED = 2;
3788var UNMOUNTED = 3;
3789
3790function isFiberMountedImpl(fiber) {
3791 var node = fiber;
3792 if (!fiber.alternate) {
3793 // If there is no alternate, this might be a new tree that isn't inserted
3794 // yet. If it is, then it will have a pending insertion effect on it.
3795 if ((node.effectTag & Placement) !== NoEffect) {
3796 return MOUNTING;
3797 }
3798 while (node['return']) {
3799 node = node['return'];
3800 if ((node.effectTag & Placement) !== NoEffect) {
3801 return MOUNTING;
3802 }
3803 }
3804 } else {
3805 while (node['return']) {
3806 node = node['return'];
3807 }
3808 }
3809 if (node.tag === HostRoot) {
3810 // TODO: Check if this was a nested HostRoot when used with
3811 // renderContainerIntoSubtree.
3812 return MOUNTED;
3813 }
3814 // If we didn't hit the root, that means that we're in an disconnected tree
3815 // that has been unmounted.
3816 return UNMOUNTED;
3817}
3818
3819function isFiberMounted(fiber) {
3820 return isFiberMountedImpl(fiber) === MOUNTED;
3821}
3822
3823function isMounted(component) {
3824 {
3825 var owner = ReactCurrentOwner.current;
3826 if (owner !== null && owner.tag === ClassComponent) {
3827 var ownerFiber = owner;
3828 var instance = ownerFiber.stateNode;
3829 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');
3830 instance._warnedAboutRefsInRender = true;
3831 }
3832 }
3833
3834 var fiber = get(component);
3835 if (!fiber) {
3836 return false;
3837 }
3838 return isFiberMountedImpl(fiber) === MOUNTED;
3839}
3840
3841function assertIsMounted(fiber) {
3842 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3843}
3844
3845function findCurrentFiberUsingSlowPath(fiber) {
3846 var alternate = fiber.alternate;
3847 if (!alternate) {
3848 // If there is no alternate, then we only need to check if it is mounted.
3849 var state = isFiberMountedImpl(fiber);
3850 !(state !== UNMOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3851 if (state === MOUNTING) {
3852 return null;
3853 }
3854 return fiber;
3855 }
3856 // If we have two possible branches, we'll walk backwards up to the root
3857 // to see what path the root points to. On the way we may hit one of the
3858 // special cases and we'll deal with them.
3859 var a = fiber;
3860 var b = alternate;
3861 while (true) {
3862 var parentA = a['return'];
3863 var parentB = parentA ? parentA.alternate : null;
3864 if (!parentA || !parentB) {
3865 // We're at the root.
3866 break;
3867 }
3868
3869 // If both copies of the parent fiber point to the same child, we can
3870 // assume that the child is current. This happens when we bailout on low
3871 // priority: the bailed out fiber's child reuses the current child.
3872 if (parentA.child === parentB.child) {
3873 var child = parentA.child;
3874 while (child) {
3875 if (child === a) {
3876 // We've determined that A is the current branch.
3877 assertIsMounted(parentA);
3878 return fiber;
3879 }
3880 if (child === b) {
3881 // We've determined that B is the current branch.
3882 assertIsMounted(parentA);
3883 return alternate;
3884 }
3885 child = child.sibling;
3886 }
3887 // We should never have an alternate for any mounting node. So the only
3888 // way this could possibly happen is if this was unmounted, if at all.
3889 invariant_1(false, 'Unable to find node on an unmounted component.');
3890 }
3891
3892 if (a['return'] !== b['return']) {
3893 // The return pointer of A and the return pointer of B point to different
3894 // fibers. We assume that return pointers never criss-cross, so A must
3895 // belong to the child set of A.return, and B must belong to the child
3896 // set of B.return.
3897 a = parentA;
3898 b = parentB;
3899 } else {
3900 // The return pointers point to the same fiber. We'll have to use the
3901 // default, slow path: scan the child sets of each parent alternate to see
3902 // which child belongs to which set.
3903 //
3904 // Search parent A's child set
3905 var didFindChild = false;
3906 var _child = parentA.child;
3907 while (_child) {
3908 if (_child === a) {
3909 didFindChild = true;
3910 a = parentA;
3911 b = parentB;
3912 break;
3913 }
3914 if (_child === b) {
3915 didFindChild = true;
3916 b = parentA;
3917 a = parentB;
3918 break;
3919 }
3920 _child = _child.sibling;
3921 }
3922 if (!didFindChild) {
3923 // Search parent B's child set
3924 _child = parentB.child;
3925 while (_child) {
3926 if (_child === a) {
3927 didFindChild = true;
3928 a = parentB;
3929 b = parentA;
3930 break;
3931 }
3932 if (_child === b) {
3933 didFindChild = true;
3934 b = parentB;
3935 a = parentA;
3936 break;
3937 }
3938 _child = _child.sibling;
3939 }
3940 !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;
3941 }
3942 }
3943
3944 !(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;
3945 }
3946 // If the root is not a host container, we're in a disconnected tree. I.e.
3947 // unmounted.
3948 !(a.tag === HostRoot) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3949 if (a.stateNode.current === a) {
3950 // We've determined that A is the current branch.
3951 return fiber;
3952 }
3953 // Otherwise B has to be current branch.
3954 return alternate;
3955}
3956
3957function findCurrentHostFiber(parent) {
3958 var currentParent = findCurrentFiberUsingSlowPath(parent);
3959 if (!currentParent) {
3960 return null;
3961 }
3962
3963 // Next we'll drill down this component to find the first HostComponent/Text.
3964 var node = currentParent;
3965 while (true) {
3966 if (node.tag === HostComponent || node.tag === HostText) {
3967 return node;
3968 } else if (node.child) {
3969 node.child['return'] = node;
3970 node = node.child;
3971 continue;
3972 }
3973 if (node === currentParent) {
3974 return null;
3975 }
3976 while (!node.sibling) {
3977 if (!node['return'] || node['return'] === currentParent) {
3978 return null;
3979 }
3980 node = node['return'];
3981 }
3982 node.sibling['return'] = node['return'];
3983 node = node.sibling;
3984 }
3985 // Flow needs the return null here, but ESLint complains about it.
3986 // eslint-disable-next-line no-unreachable
3987 return null;
3988}
3989
3990function findCurrentHostFiberWithNoPortals(parent) {
3991 var currentParent = findCurrentFiberUsingSlowPath(parent);
3992 if (!currentParent) {
3993 return null;
3994 }
3995
3996 // Next we'll drill down this component to find the first HostComponent/Text.
3997 var node = currentParent;
3998 while (true) {
3999 if (node.tag === HostComponent || node.tag === HostText) {
4000 return node;
4001 } else if (node.child && node.tag !== HostPortal) {
4002 node.child['return'] = node;
4003 node = node.child;
4004 continue;
4005 }
4006 if (node === currentParent) {
4007 return null;
4008 }
4009 while (!node.sibling) {
4010 if (!node['return'] || node['return'] === currentParent) {
4011 return null;
4012 }
4013 node = node['return'];
4014 }
4015 node.sibling['return'] = node['return'];
4016 node = node.sibling;
4017 }
4018 // Flow needs the return null here, but ESLint complains about it.
4019 // eslint-disable-next-line no-unreachable
4020 return null;
4021}
4022
4023function addEventBubbleListener(element, eventType, listener) {
4024 element.addEventListener(eventType, listener, false);
4025}
4026
4027function addEventCaptureListener(element, eventType, listener) {
4028 element.addEventListener(eventType, listener, true);
4029}
4030
4031/**
4032 * @interface Event
4033 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4034 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4035 */
4036var SyntheticAnimationEvent = SyntheticEvent$1.extend({
4037 animationName: null,
4038 elapsedTime: null,
4039 pseudoElement: null
4040});
4041
4042/**
4043 * @interface Event
4044 * @see http://www.w3.org/TR/clipboard-apis/
4045 */
4046var SyntheticClipboardEvent = SyntheticEvent$1.extend({
4047 clipboardData: function (event) {
4048 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4049 }
4050});
4051
4052/**
4053 * @interface FocusEvent
4054 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4055 */
4056var SyntheticFocusEvent = SyntheticUIEvent.extend({
4057 relatedTarget: null
4058});
4059
4060/**
4061 * `charCode` represents the actual "character code" and is safe to use with
4062 * `String.fromCharCode`. As such, only keys that correspond to printable
4063 * characters produce a valid `charCode`, the only exception to this is Enter.
4064 * The Tab-key is considered non-printable and does not have a `charCode`,
4065 * presumably because it does not produce a tab-character in browsers.
4066 *
4067 * @param {object} nativeEvent Native browser event.
4068 * @return {number} Normalized `charCode` property.
4069 */
4070function getEventCharCode(nativeEvent) {
4071 var charCode = void 0;
4072 var keyCode = nativeEvent.keyCode;
4073
4074 if ('charCode' in nativeEvent) {
4075 charCode = nativeEvent.charCode;
4076
4077 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4078 if (charCode === 0 && keyCode === 13) {
4079 charCode = 13;
4080 }
4081 } else {
4082 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4083 charCode = keyCode;
4084 }
4085
4086 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4087 // report Enter as charCode 10 when ctrl is pressed.
4088 if (charCode === 10) {
4089 charCode = 13;
4090 }
4091
4092 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4093 // Must not discard the (non-)printable Enter-key.
4094 if (charCode >= 32 || charCode === 13) {
4095 return charCode;
4096 }
4097
4098 return 0;
4099}
4100
4101/**
4102 * Normalization of deprecated HTML5 `key` values
4103 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4104 */
4105var normalizeKey = {
4106 Esc: 'Escape',
4107 Spacebar: ' ',
4108 Left: 'ArrowLeft',
4109 Up: 'ArrowUp',
4110 Right: 'ArrowRight',
4111 Down: 'ArrowDown',
4112 Del: 'Delete',
4113 Win: 'OS',
4114 Menu: 'ContextMenu',
4115 Apps: 'ContextMenu',
4116 Scroll: 'ScrollLock',
4117 MozPrintableKey: 'Unidentified'
4118};
4119
4120/**
4121 * Translation from legacy `keyCode` to HTML5 `key`
4122 * Only special keys supported, all others depend on keyboard layout or browser
4123 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4124 */
4125var translateToKey = {
4126 '8': 'Backspace',
4127 '9': 'Tab',
4128 '12': 'Clear',
4129 '13': 'Enter',
4130 '16': 'Shift',
4131 '17': 'Control',
4132 '18': 'Alt',
4133 '19': 'Pause',
4134 '20': 'CapsLock',
4135 '27': 'Escape',
4136 '32': ' ',
4137 '33': 'PageUp',
4138 '34': 'PageDown',
4139 '35': 'End',
4140 '36': 'Home',
4141 '37': 'ArrowLeft',
4142 '38': 'ArrowUp',
4143 '39': 'ArrowRight',
4144 '40': 'ArrowDown',
4145 '45': 'Insert',
4146 '46': 'Delete',
4147 '112': 'F1',
4148 '113': 'F2',
4149 '114': 'F3',
4150 '115': 'F4',
4151 '116': 'F5',
4152 '117': 'F6',
4153 '118': 'F7',
4154 '119': 'F8',
4155 '120': 'F9',
4156 '121': 'F10',
4157 '122': 'F11',
4158 '123': 'F12',
4159 '144': 'NumLock',
4160 '145': 'ScrollLock',
4161 '224': 'Meta'
4162};
4163
4164/**
4165 * @param {object} nativeEvent Native browser event.
4166 * @return {string} Normalized `key` property.
4167 */
4168function getEventKey(nativeEvent) {
4169 if (nativeEvent.key) {
4170 // Normalize inconsistent values reported by browsers due to
4171 // implementations of a working draft specification.
4172
4173 // FireFox implements `key` but returns `MozPrintableKey` for all
4174 // printable characters (normalized to `Unidentified`), ignore it.
4175 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4176 if (key !== 'Unidentified') {
4177 return key;
4178 }
4179 }
4180
4181 // Browser does not implement `key`, polyfill as much of it as we can.
4182 if (nativeEvent.type === 'keypress') {
4183 var charCode = getEventCharCode(nativeEvent);
4184
4185 // The enter-key is technically both printable and non-printable and can
4186 // thus be captured by `keypress`, no other non-printable key should.
4187 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4188 }
4189 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4190 // While user keyboard layout determines the actual meaning of each
4191 // `keyCode` value, almost all function keys have a universal value.
4192 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4193 }
4194 return '';
4195}
4196
4197/**
4198 * @interface KeyboardEvent
4199 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4200 */
4201var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4202 key: getEventKey,
4203 location: null,
4204 ctrlKey: null,
4205 shiftKey: null,
4206 altKey: null,
4207 metaKey: null,
4208 repeat: null,
4209 locale: null,
4210 getModifierState: getEventModifierState,
4211 // Legacy Interface
4212 charCode: function (event) {
4213 // `charCode` is the result of a KeyPress event and represents the value of
4214 // the actual printable character.
4215
4216 // KeyPress is deprecated, but its replacement is not yet final and not
4217 // implemented in any major browser. Only KeyPress has charCode.
4218 if (event.type === 'keypress') {
4219 return getEventCharCode(event);
4220 }
4221 return 0;
4222 },
4223 keyCode: function (event) {
4224 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4225 // physical keyboard key.
4226
4227 // The actual meaning of the value depends on the users' keyboard layout
4228 // which cannot be detected. Assuming that it is a US keyboard layout
4229 // provides a surprisingly accurate mapping for US and European users.
4230 // Due to this, it is left to the user to implement at this time.
4231 if (event.type === 'keydown' || event.type === 'keyup') {
4232 return event.keyCode;
4233 }
4234 return 0;
4235 },
4236 which: function (event) {
4237 // `which` is an alias for either `keyCode` or `charCode` depending on the
4238 // type of the event.
4239 if (event.type === 'keypress') {
4240 return getEventCharCode(event);
4241 }
4242 if (event.type === 'keydown' || event.type === 'keyup') {
4243 return event.keyCode;
4244 }
4245 return 0;
4246 }
4247});
4248
4249/**
4250 * @interface DragEvent
4251 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4252 */
4253var SyntheticDragEvent = SyntheticMouseEvent.extend({
4254 dataTransfer: null
4255});
4256
4257/**
4258 * @interface TouchEvent
4259 * @see http://www.w3.org/TR/touch-events/
4260 */
4261var SyntheticTouchEvent = SyntheticUIEvent.extend({
4262 touches: null,
4263 targetTouches: null,
4264 changedTouches: null,
4265 altKey: null,
4266 metaKey: null,
4267 ctrlKey: null,
4268 shiftKey: null,
4269 getModifierState: getEventModifierState
4270});
4271
4272/**
4273 * @interface Event
4274 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4275 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4276 */
4277var SyntheticTransitionEvent = SyntheticEvent$1.extend({
4278 propertyName: null,
4279 elapsedTime: null,
4280 pseudoElement: null
4281});
4282
4283/**
4284 * @interface WheelEvent
4285 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4286 */
4287var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4288 deltaX: function (event) {
4289 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4290 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4291 },
4292 deltaY: function (event) {
4293 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4294 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4295 'wheelDelta' in event ? -event.wheelDelta : 0;
4296 },
4297
4298 deltaZ: null,
4299
4300 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4301 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4302 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4303 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4304 deltaMode: null
4305});
4306
4307/**
4308 * Turns
4309 * ['abort', ...]
4310 * into
4311 * eventTypes = {
4312 * 'abort': {
4313 * phasedRegistrationNames: {
4314 * bubbled: 'onAbort',
4315 * captured: 'onAbortCapture',
4316 * },
4317 * dependencies: ['topAbort'],
4318 * },
4319 * ...
4320 * };
4321 * topLevelEventsToDispatchConfig = {
4322 * 'topAbort': { sameConfig }
4323 * };
4324 */
4325var 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'];
4326var 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'];
4327
4328var eventTypes$4 = {};
4329var topLevelEventsToDispatchConfig = {};
4330
4331function addEventTypeNameToConfig(event, isInteractive) {
4332 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4333 var onEvent = 'on' + capitalizedEvent;
4334 var topEvent = 'top' + capitalizedEvent;
4335
4336 var type = {
4337 phasedRegistrationNames: {
4338 bubbled: onEvent,
4339 captured: onEvent + 'Capture'
4340 },
4341 dependencies: [topEvent],
4342 isInteractive: isInteractive
4343 };
4344 eventTypes$4[event] = type;
4345 topLevelEventsToDispatchConfig[topEvent] = type;
4346}
4347
4348interactiveEventTypeNames.forEach(function (eventTypeName) {
4349 addEventTypeNameToConfig(eventTypeName, true);
4350});
4351nonInteractiveEventTypeNames.forEach(function (eventTypeName) {
4352 addEventTypeNameToConfig(eventTypeName, false);
4353});
4354
4355// Only used in DEV for exhaustiveness validation.
4356var 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'];
4357
4358var SimpleEventPlugin = {
4359 eventTypes: eventTypes$4,
4360
4361 isInteractiveTopLevelEventType: function (topLevelType) {
4362 var config = topLevelEventsToDispatchConfig[topLevelType];
4363 return config !== undefined && config.isInteractive === true;
4364 },
4365
4366
4367 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4368 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4369 if (!dispatchConfig) {
4370 return null;
4371 }
4372 var EventConstructor = void 0;
4373 switch (topLevelType) {
4374 case 'topKeyPress':
4375 // Firefox creates a keypress event for function keys too. This removes
4376 // the unwanted keypress events. Enter is however both printable and
4377 // non-printable. One would expect Tab to be as well (but it isn't).
4378 if (getEventCharCode(nativeEvent) === 0) {
4379 return null;
4380 }
4381 /* falls through */
4382 case 'topKeyDown':
4383 case 'topKeyUp':
4384 EventConstructor = SyntheticKeyboardEvent;
4385 break;
4386 case 'topBlur':
4387 case 'topFocus':
4388 EventConstructor = SyntheticFocusEvent;
4389 break;
4390 case 'topClick':
4391 // Firefox creates a click event on right mouse clicks. This removes the
4392 // unwanted click events.
4393 if (nativeEvent.button === 2) {
4394 return null;
4395 }
4396 /* falls through */
4397 case 'topDoubleClick':
4398 case 'topMouseDown':
4399 case 'topMouseMove':
4400 case 'topMouseUp':
4401 // TODO: Disabled elements should not respond to mouse events
4402 /* falls through */
4403 case 'topMouseOut':
4404 case 'topMouseOver':
4405 case 'topContextMenu':
4406 EventConstructor = SyntheticMouseEvent;
4407 break;
4408 case 'topDrag':
4409 case 'topDragEnd':
4410 case 'topDragEnter':
4411 case 'topDragExit':
4412 case 'topDragLeave':
4413 case 'topDragOver':
4414 case 'topDragStart':
4415 case 'topDrop':
4416 EventConstructor = SyntheticDragEvent;
4417 break;
4418 case 'topTouchCancel':
4419 case 'topTouchEnd':
4420 case 'topTouchMove':
4421 case 'topTouchStart':
4422 EventConstructor = SyntheticTouchEvent;
4423 break;
4424 case 'topAnimationEnd':
4425 case 'topAnimationIteration':
4426 case 'topAnimationStart':
4427 EventConstructor = SyntheticAnimationEvent;
4428 break;
4429 case 'topTransitionEnd':
4430 EventConstructor = SyntheticTransitionEvent;
4431 break;
4432 case 'topScroll':
4433 EventConstructor = SyntheticUIEvent;
4434 break;
4435 case 'topWheel':
4436 EventConstructor = SyntheticWheelEvent;
4437 break;
4438 case 'topCopy':
4439 case 'topCut':
4440 case 'topPaste':
4441 EventConstructor = SyntheticClipboardEvent;
4442 break;
4443 default:
4444 {
4445 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4446 warning_1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4447 }
4448 }
4449 // HTML Events
4450 // @see http://www.w3.org/TR/html5/index.html#events-0
4451 EventConstructor = SyntheticEvent$1;
4452 break;
4453 }
4454 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4455 accumulateTwoPhaseDispatches(event);
4456 return event;
4457 }
4458};
4459
4460var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4461
4462
4463var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4464var callbackBookkeepingPool = [];
4465
4466/**
4467 * Find the deepest React component completely containing the root of the
4468 * passed-in instance (for use when entire React trees are nested within each
4469 * other). If React trees are not nested, returns null.
4470 */
4471function findRootContainerNode(inst) {
4472 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4473 // traversal, but caching is difficult to do correctly without using a
4474 // mutation observer to listen for all DOM changes.
4475 while (inst['return']) {
4476 inst = inst['return'];
4477 }
4478 if (inst.tag !== HostRoot) {
4479 // This can happen if we're in a detached tree.
4480 return null;
4481 }
4482 return inst.stateNode.containerInfo;
4483}
4484
4485// Used to store ancestor hierarchy in top level callback
4486function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4487 if (callbackBookkeepingPool.length) {
4488 var instance = callbackBookkeepingPool.pop();
4489 instance.topLevelType = topLevelType;
4490 instance.nativeEvent = nativeEvent;
4491 instance.targetInst = targetInst;
4492 return instance;
4493 }
4494 return {
4495 topLevelType: topLevelType,
4496 nativeEvent: nativeEvent,
4497 targetInst: targetInst,
4498 ancestors: []
4499 };
4500}
4501
4502function releaseTopLevelCallbackBookKeeping(instance) {
4503 instance.topLevelType = null;
4504 instance.nativeEvent = null;
4505 instance.targetInst = null;
4506 instance.ancestors.length = 0;
4507 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4508 callbackBookkeepingPool.push(instance);
4509 }
4510}
4511
4512function handleTopLevel(bookKeeping) {
4513 var targetInst = bookKeeping.targetInst;
4514
4515 // Loop through the hierarchy, in case there's any nested components.
4516 // It's important that we build the array of ancestors before calling any
4517 // event handlers, because event handlers can modify the DOM, leading to
4518 // inconsistencies with ReactMount's node cache. See #1105.
4519 var ancestor = targetInst;
4520 do {
4521 if (!ancestor) {
4522 bookKeeping.ancestors.push(ancestor);
4523 break;
4524 }
4525 var root = findRootContainerNode(ancestor);
4526 if (!root) {
4527 break;
4528 }
4529 bookKeeping.ancestors.push(ancestor);
4530 ancestor = getClosestInstanceFromNode(root);
4531 } while (ancestor);
4532
4533 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4534 targetInst = bookKeeping.ancestors[i];
4535 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4536 }
4537}
4538
4539// TODO: can we stop exporting these?
4540var _enabled = true;
4541
4542function setEnabled(enabled) {
4543 _enabled = !!enabled;
4544}
4545
4546function isEnabled() {
4547 return _enabled;
4548}
4549
4550/**
4551 * Traps top-level events by using event bubbling.
4552 *
4553 * @param {string} topLevelType Record from `BrowserEventConstants`.
4554 * @param {string} handlerBaseName Event name (e.g. "click").
4555 * @param {object} element Element on which to attach listener.
4556 * @return {?object} An object with a remove function which will forcefully
4557 * remove the listener.
4558 * @internal
4559 */
4560function trapBubbledEvent(topLevelType, handlerBaseName, element) {
4561 if (!element) {
4562 return null;
4563 }
4564 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4565
4566 addEventBubbleListener(element, handlerBaseName,
4567 // Check if interactive and wrap in interactiveUpdates
4568 dispatch.bind(null, topLevelType));
4569}
4570
4571/**
4572 * Traps a top-level event by using event capturing.
4573 *
4574 * @param {string} topLevelType Record from `BrowserEventConstants`.
4575 * @param {string} handlerBaseName Event name (e.g. "click").
4576 * @param {object} element Element on which to attach listener.
4577 * @return {?object} An object with a remove function which will forcefully
4578 * remove the listener.
4579 * @internal
4580 */
4581function trapCapturedEvent(topLevelType, handlerBaseName, element) {
4582 if (!element) {
4583 return null;
4584 }
4585 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4586
4587 addEventCaptureListener(element, handlerBaseName,
4588 // Check if interactive and wrap in interactiveUpdates
4589 dispatch.bind(null, topLevelType));
4590}
4591
4592function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4593 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4594}
4595
4596function dispatchEvent(topLevelType, nativeEvent) {
4597 if (!_enabled) {
4598 return;
4599 }
4600
4601 var nativeEventTarget = getEventTarget(nativeEvent);
4602 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4603 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4604 // If we get an event (ex: img onload) before committing that
4605 // component's mount, ignore it for now (that is, treat it as if it was an
4606 // event on a non-React tree). We might also consider queueing events and
4607 // dispatching them after the mount.
4608 targetInst = null;
4609 }
4610
4611 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4612
4613 try {
4614 // Event queue being processed in the same cycle allows
4615 // `preventDefault`.
4616 batchedUpdates(handleTopLevel, bookKeeping);
4617 } finally {
4618 releaseTopLevelCallbackBookKeeping(bookKeeping);
4619 }
4620}
4621
4622var ReactDOMEventListener = Object.freeze({
4623 get _enabled () { return _enabled; },
4624 setEnabled: setEnabled,
4625 isEnabled: isEnabled,
4626 trapBubbledEvent: trapBubbledEvent,
4627 trapCapturedEvent: trapCapturedEvent,
4628 dispatchEvent: dispatchEvent
4629});
4630
4631/**
4632 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4633 *
4634 * @param {string} styleProp
4635 * @param {string} eventName
4636 * @returns {object}
4637 */
4638function makePrefixMap(styleProp, eventName) {
4639 var prefixes = {};
4640
4641 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4642 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4643 prefixes['Moz' + styleProp] = 'moz' + eventName;
4644 prefixes['ms' + styleProp] = 'MS' + eventName;
4645 prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
4646
4647 return prefixes;
4648}
4649
4650/**
4651 * A list of event names to a configurable list of vendor prefixes.
4652 */
4653var vendorPrefixes = {
4654 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4655 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4656 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4657 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4658};
4659
4660/**
4661 * Event names that have already been detected and prefixed (if applicable).
4662 */
4663var prefixedEventNames = {};
4664
4665/**
4666 * Element to check for prefixes on.
4667 */
4668var style = {};
4669
4670/**
4671 * Bootstrap if a DOM exists.
4672 */
4673if (ExecutionEnvironment_1.canUseDOM) {
4674 style = document.createElement('div').style;
4675
4676 // On some platforms, in particular some releases of Android 4.x,
4677 // the un-prefixed "animation" and "transition" properties are defined on the
4678 // style object but the events that fire will still be prefixed, so we need
4679 // to check if the un-prefixed events are usable, and if not remove them from the map.
4680 if (!('AnimationEvent' in window)) {
4681 delete vendorPrefixes.animationend.animation;
4682 delete vendorPrefixes.animationiteration.animation;
4683 delete vendorPrefixes.animationstart.animation;
4684 }
4685
4686 // Same as above
4687 if (!('TransitionEvent' in window)) {
4688 delete vendorPrefixes.transitionend.transition;
4689 }
4690}
4691
4692/**
4693 * Attempts to determine the correct vendor prefixed event name.
4694 *
4695 * @param {string} eventName
4696 * @returns {string}
4697 */
4698function getVendorPrefixedEventName(eventName) {
4699 if (prefixedEventNames[eventName]) {
4700 return prefixedEventNames[eventName];
4701 } else if (!vendorPrefixes[eventName]) {
4702 return eventName;
4703 }
4704
4705 var prefixMap = vendorPrefixes[eventName];
4706
4707 for (var styleProp in prefixMap) {
4708 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
4709 return prefixedEventNames[eventName] = prefixMap[styleProp];
4710 }
4711 }
4712
4713 return eventName;
4714}
4715
4716/**
4717 * Types of raw signals from the browser caught at the top level.
4718 *
4719 * For events like 'submit' or audio/video events which don't consistently
4720 * bubble (which we trap at a lower node than `document`), binding
4721 * at `document` would cause duplicate events so we don't include them here.
4722 */
4723var topLevelTypes = {
4724 topAnimationEnd: getVendorPrefixedEventName('animationend'),
4725 topAnimationIteration: getVendorPrefixedEventName('animationiteration'),
4726 topAnimationStart: getVendorPrefixedEventName('animationstart'),
4727 topBlur: 'blur',
4728 topCancel: 'cancel',
4729 topChange: 'change',
4730 topClick: 'click',
4731 topClose: 'close',
4732 topCompositionEnd: 'compositionend',
4733 topCompositionStart: 'compositionstart',
4734 topCompositionUpdate: 'compositionupdate',
4735 topContextMenu: 'contextmenu',
4736 topCopy: 'copy',
4737 topCut: 'cut',
4738 topDoubleClick: 'dblclick',
4739 topDrag: 'drag',
4740 topDragEnd: 'dragend',
4741 topDragEnter: 'dragenter',
4742 topDragExit: 'dragexit',
4743 topDragLeave: 'dragleave',
4744 topDragOver: 'dragover',
4745 topDragStart: 'dragstart',
4746 topDrop: 'drop',
4747 topFocus: 'focus',
4748 topInput: 'input',
4749 topKeyDown: 'keydown',
4750 topKeyPress: 'keypress',
4751 topKeyUp: 'keyup',
4752 topLoad: 'load',
4753 topLoadStart: 'loadstart',
4754 topMouseDown: 'mousedown',
4755 topMouseMove: 'mousemove',
4756 topMouseOut: 'mouseout',
4757 topMouseOver: 'mouseover',
4758 topMouseUp: 'mouseup',
4759 topPaste: 'paste',
4760 topScroll: 'scroll',
4761 topSelectionChange: 'selectionchange',
4762 topTextInput: 'textInput',
4763 topToggle: 'toggle',
4764 topTouchCancel: 'touchcancel',
4765 topTouchEnd: 'touchend',
4766 topTouchMove: 'touchmove',
4767 topTouchStart: 'touchstart',
4768 topTransitionEnd: getVendorPrefixedEventName('transitionend'),
4769 topWheel: 'wheel'
4770};
4771
4772// There are so many media events, it makes sense to just
4773// maintain a list of them. Note these aren't technically
4774// "top-level" since they don't bubble. We should come up
4775// with a better naming convention if we come to refactoring
4776// the event system.
4777var mediaEventTypes = {
4778 topAbort: 'abort',
4779 topCanPlay: 'canplay',
4780 topCanPlayThrough: 'canplaythrough',
4781 topDurationChange: 'durationchange',
4782 topEmptied: 'emptied',
4783 topEncrypted: 'encrypted',
4784 topEnded: 'ended',
4785 topError: 'error',
4786 topLoadedData: 'loadeddata',
4787 topLoadedMetadata: 'loadedmetadata',
4788 topLoadStart: 'loadstart',
4789 topPause: 'pause',
4790 topPlay: 'play',
4791 topPlaying: 'playing',
4792 topProgress: 'progress',
4793 topRateChange: 'ratechange',
4794 topSeeked: 'seeked',
4795 topSeeking: 'seeking',
4796 topStalled: 'stalled',
4797 topSuspend: 'suspend',
4798 topTimeUpdate: 'timeupdate',
4799 topVolumeChange: 'volumechange',
4800 topWaiting: 'waiting'
4801};
4802
4803/**
4804 * Summary of `ReactBrowserEventEmitter` event handling:
4805 *
4806 * - Top-level delegation is used to trap most native browser events. This
4807 * may only occur in the main thread and is the responsibility of
4808 * ReactDOMEventListener, which is injected and can therefore support
4809 * pluggable event sources. This is the only work that occurs in the main
4810 * thread.
4811 *
4812 * - We normalize and de-duplicate events to account for browser quirks. This
4813 * may be done in the worker thread.
4814 *
4815 * - Forward these native events (with the associated top-level type used to
4816 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4817 * to extract any synthetic events.
4818 *
4819 * - The `EventPluginHub` will then process each event by annotating them with
4820 * "dispatches", a sequence of listeners and IDs that care about that event.
4821 *
4822 * - The `EventPluginHub` then dispatches the events.
4823 *
4824 * Overview of React and the event system:
4825 *
4826 * +------------+ .
4827 * | DOM | .
4828 * +------------+ .
4829 * | .
4830 * v .
4831 * +------------+ .
4832 * | ReactEvent | .
4833 * | Listener | .
4834 * +------------+ . +-----------+
4835 * | . +--------+|SimpleEvent|
4836 * | . | |Plugin |
4837 * +-----|------+ . v +-----------+
4838 * | | | . +--------------+ +------------+
4839 * | +-----------.--->|EventPluginHub| | Event |
4840 * | | . | | +-----------+ | Propagators|
4841 * | ReactEvent | . | | |TapEvent | |------------|
4842 * | Emitter | . | |<---+|Plugin | |other plugin|
4843 * | | . | | +-----------+ | utilities |
4844 * | +-----------.--->| | +------------+
4845 * | | | . +--------------+
4846 * +-----|------+ . ^ +-----------+
4847 * | . | |Enter/Leave|
4848 * + . +-------+|Plugin |
4849 * +-------------+ . +-----------+
4850 * | application | .
4851 * |-------------| .
4852 * | | .
4853 * | | .
4854 * +-------------+ .
4855 * .
4856 * React Core . General Purpose Event Plugin System
4857 */
4858
4859var alreadyListeningTo = {};
4860var reactTopListenersCounter = 0;
4861
4862/**
4863 * To ensure no conflicts with other potential React instances on the page
4864 */
4865var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4866
4867function getListeningForDocument(mountAt) {
4868 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4869 // directly.
4870 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4871 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4872 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4873 }
4874 return alreadyListeningTo[mountAt[topListenersIDKey]];
4875}
4876
4877/**
4878 * We listen for bubbled touch events on the document object.
4879 *
4880 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4881 * mounting `onmousemove` events at some node that was not the document
4882 * element. The symptoms were that if your mouse is not moving over something
4883 * contained within that mount point (for example on the background) the
4884 * top-level listeners for `onmousemove` won't be called. However, if you
4885 * register the `mousemove` on the document object, then it will of course
4886 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4887 * top-level listeners to the document object only, at least for these
4888 * movement types of events and possibly all events.
4889 *
4890 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4891 *
4892 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
4893 * they bubble to document.
4894 *
4895 * @param {string} registrationName Name of listener (e.g. `onClick`).
4896 * @param {object} contentDocumentHandle Document which owns the container
4897 */
4898function listenTo(registrationName, contentDocumentHandle) {
4899 var mountAt = contentDocumentHandle;
4900 var isListening = getListeningForDocument(mountAt);
4901 var dependencies = registrationNameDependencies[registrationName];
4902
4903 for (var i = 0; i < dependencies.length; i++) {
4904 var dependency = dependencies[i];
4905 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4906 if (dependency === 'topScroll') {
4907 trapCapturedEvent('topScroll', 'scroll', mountAt);
4908 } else if (dependency === 'topFocus' || dependency === 'topBlur') {
4909 trapCapturedEvent('topFocus', 'focus', mountAt);
4910 trapCapturedEvent('topBlur', 'blur', mountAt);
4911
4912 // to make sure blur and focus event listeners are only attached once
4913 isListening.topBlur = true;
4914 isListening.topFocus = true;
4915 } else if (dependency === 'topCancel') {
4916 if (isEventSupported('cancel', true)) {
4917 trapCapturedEvent('topCancel', 'cancel', mountAt);
4918 }
4919 isListening.topCancel = true;
4920 } else if (dependency === 'topClose') {
4921 if (isEventSupported('close', true)) {
4922 trapCapturedEvent('topClose', 'close', mountAt);
4923 }
4924 isListening.topClose = true;
4925 } else if (topLevelTypes.hasOwnProperty(dependency)) {
4926 trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
4927 }
4928
4929 isListening[dependency] = true;
4930 }
4931 }
4932}
4933
4934function isListeningToAllDependencies(registrationName, mountAt) {
4935 var isListening = getListeningForDocument(mountAt);
4936 var dependencies = registrationNameDependencies[registrationName];
4937 for (var i = 0; i < dependencies.length; i++) {
4938 var dependency = dependencies[i];
4939 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4940 return false;
4941 }
4942 }
4943 return true;
4944}
4945
4946/**
4947 * Copyright (c) 2013-present, Facebook, Inc.
4948 *
4949 * This source code is licensed under the MIT license found in the
4950 * LICENSE file in the root directory of this source tree.
4951 *
4952 * @typechecks
4953 */
4954
4955/**
4956 * @param {*} object The object to check.
4957 * @return {boolean} Whether or not the object is a DOM node.
4958 */
4959function isNode(object) {
4960 var doc = object ? object.ownerDocument || object : document;
4961 var defaultView = doc.defaultView || window;
4962 return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
4963}
4964
4965var isNode_1 = isNode;
4966
4967/**
4968 * Copyright (c) 2013-present, Facebook, Inc.
4969 *
4970 * This source code is licensed under the MIT license found in the
4971 * LICENSE file in the root directory of this source tree.
4972 *
4973 * @typechecks
4974 */
4975
4976
4977
4978/**
4979 * @param {*} object The object to check.
4980 * @return {boolean} Whether or not the object is a DOM text node.
4981 */
4982function isTextNode(object) {
4983 return isNode_1(object) && object.nodeType == 3;
4984}
4985
4986var isTextNode_1 = isTextNode;
4987
4988/**
4989 * Copyright (c) 2013-present, Facebook, Inc.
4990 *
4991 * This source code is licensed under the MIT license found in the
4992 * LICENSE file in the root directory of this source tree.
4993 *
4994 *
4995 */
4996
4997
4998
4999/*eslint-disable no-bitwise */
5000
5001/**
5002 * Checks if a given DOM node contains or is another DOM node.
5003 */
5004function containsNode(outerNode, innerNode) {
5005 if (!outerNode || !innerNode) {
5006 return false;
5007 } else if (outerNode === innerNode) {
5008 return true;
5009 } else if (isTextNode_1(outerNode)) {
5010 return false;
5011 } else if (isTextNode_1(innerNode)) {
5012 return containsNode(outerNode, innerNode.parentNode);
5013 } else if ('contains' in outerNode) {
5014 return outerNode.contains(innerNode);
5015 } else if (outerNode.compareDocumentPosition) {
5016 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5017 } else {
5018 return false;
5019 }
5020}
5021
5022var containsNode_1 = containsNode;
5023
5024/**
5025 * Given any node return the first leaf node without children.
5026 *
5027 * @param {DOMElement|DOMTextNode} node
5028 * @return {DOMElement|DOMTextNode}
5029 */
5030function getLeafNode(node) {
5031 while (node && node.firstChild) {
5032 node = node.firstChild;
5033 }
5034 return node;
5035}
5036
5037/**
5038 * Get the next sibling within a container. This will walk up the
5039 * DOM if a node's siblings have been exhausted.
5040 *
5041 * @param {DOMElement|DOMTextNode} node
5042 * @return {?DOMElement|DOMTextNode}
5043 */
5044function getSiblingNode(node) {
5045 while (node) {
5046 if (node.nextSibling) {
5047 return node.nextSibling;
5048 }
5049 node = node.parentNode;
5050 }
5051}
5052
5053/**
5054 * Get object describing the nodes which contain characters at offset.
5055 *
5056 * @param {DOMElement|DOMTextNode} root
5057 * @param {number} offset
5058 * @return {?object}
5059 */
5060function getNodeForCharacterOffset(root, offset) {
5061 var node = getLeafNode(root);
5062 var nodeStart = 0;
5063 var nodeEnd = 0;
5064
5065 while (node) {
5066 if (node.nodeType === TEXT_NODE) {
5067 nodeEnd = nodeStart + node.textContent.length;
5068
5069 if (nodeStart <= offset && nodeEnd >= offset) {
5070 return {
5071 node: node,
5072 offset: offset - nodeStart
5073 };
5074 }
5075
5076 nodeStart = nodeEnd;
5077 }
5078
5079 node = getLeafNode(getSiblingNode(node));
5080 }
5081}
5082
5083/**
5084 * @param {DOMElement} outerNode
5085 * @return {?object}
5086 */
5087function getOffsets(outerNode) {
5088 var selection = window.getSelection && window.getSelection();
5089
5090 if (!selection || selection.rangeCount === 0) {
5091 return null;
5092 }
5093
5094 var anchorNode = selection.anchorNode,
5095 anchorOffset = selection.anchorOffset,
5096 focusNode = selection.focusNode,
5097 focusOffset = selection.focusOffset;
5098
5099 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5100 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5101 // expose properties, triggering a "Permission denied error" if any of its
5102 // properties are accessed. The only seemingly possible way to avoid erroring
5103 // is to access a property that typically works for non-anonymous divs and
5104 // catch any error that may otherwise arise. See
5105 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5106
5107 try {
5108 /* eslint-disable no-unused-expressions */
5109 anchorNode.nodeType;
5110 focusNode.nodeType;
5111 /* eslint-enable no-unused-expressions */
5112 } catch (e) {
5113 return null;
5114 }
5115
5116 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5117}
5118
5119/**
5120 * Returns {start, end} where `start` is the character/codepoint index of
5121 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5122 * `end` is the index of (focusNode, focusOffset).
5123 *
5124 * Returns null if you pass in garbage input but we should probably just crash.
5125 *
5126 * Exported only for testing.
5127 */
5128function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5129 var length = 0;
5130 var start = -1;
5131 var end = -1;
5132 var indexWithinAnchor = 0;
5133 var indexWithinFocus = 0;
5134 var node = outerNode;
5135 var parentNode = null;
5136
5137 outer: while (true) {
5138 var next = null;
5139
5140 while (true) {
5141 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5142 start = length + anchorOffset;
5143 }
5144 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5145 end = length + focusOffset;
5146 }
5147
5148 if (node.nodeType === TEXT_NODE) {
5149 length += node.nodeValue.length;
5150 }
5151
5152 if ((next = node.firstChild) === null) {
5153 break;
5154 }
5155 // Moving from `node` to its first child `next`.
5156 parentNode = node;
5157 node = next;
5158 }
5159
5160 while (true) {
5161 if (node === outerNode) {
5162 // If `outerNode` has children, this is always the second time visiting
5163 // it. If it has no children, this is still the first loop, and the only
5164 // valid selection is anchorNode and focusNode both equal to this node
5165 // and both offsets 0, in which case we will have handled above.
5166 break outer;
5167 }
5168 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5169 start = length;
5170 }
5171 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5172 end = length;
5173 }
5174 if ((next = node.nextSibling) !== null) {
5175 break;
5176 }
5177 node = parentNode;
5178 parentNode = node.parentNode;
5179 }
5180
5181 // Moving from `node` to its next sibling `next`.
5182 node = next;
5183 }
5184
5185 if (start === -1 || end === -1) {
5186 // This should never happen. (Would happen if the anchor/focus nodes aren't
5187 // actually inside the passed-in node.)
5188 return null;
5189 }
5190
5191 return {
5192 start: start,
5193 end: end
5194 };
5195}
5196
5197/**
5198 * In modern non-IE browsers, we can support both forward and backward
5199 * selections.
5200 *
5201 * Note: IE10+ supports the Selection object, but it does not support
5202 * the `extend` method, which means that even in modern IE, it's not possible
5203 * to programmatically create a backward selection. Thus, for all IE
5204 * versions, we use the old IE API to create our selections.
5205 *
5206 * @param {DOMElement|DOMTextNode} node
5207 * @param {object} offsets
5208 */
5209function setOffsets(node, offsets) {
5210 if (!window.getSelection) {
5211 return;
5212 }
5213
5214 var selection = window.getSelection();
5215 var length = node[getTextContentAccessor()].length;
5216 var start = Math.min(offsets.start, length);
5217 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5218
5219 // IE 11 uses modern selection, but doesn't support the extend method.
5220 // Flip backward selections, so we can set with a single range.
5221 if (!selection.extend && start > end) {
5222 var temp = end;
5223 end = start;
5224 start = temp;
5225 }
5226
5227 var startMarker = getNodeForCharacterOffset(node, start);
5228 var endMarker = getNodeForCharacterOffset(node, end);
5229
5230 if (startMarker && endMarker) {
5231 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5232 return;
5233 }
5234 var range = document.createRange();
5235 range.setStart(startMarker.node, startMarker.offset);
5236 selection.removeAllRanges();
5237
5238 if (start > end) {
5239 selection.addRange(range);
5240 selection.extend(endMarker.node, endMarker.offset);
5241 } else {
5242 range.setEnd(endMarker.node, endMarker.offset);
5243 selection.addRange(range);
5244 }
5245 }
5246}
5247
5248function isInDocument(node) {
5249 return containsNode_1(document.documentElement, node);
5250}
5251
5252/**
5253 * @ReactInputSelection: React input selection module. Based on Selection.js,
5254 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5255 * assume buttons have range selections allowed).
5256 * Input selection module for React.
5257 */
5258
5259function hasSelectionCapabilities(elem) {
5260 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5261 return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
5262}
5263
5264function getSelectionInformation() {
5265 var focusedElem = getActiveElement_1();
5266 return {
5267 focusedElem: focusedElem,
5268 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5269 };
5270}
5271
5272/**
5273 * @restoreSelection: If any selection information was potentially lost,
5274 * restore it. This is useful when performing operations that could remove dom
5275 * nodes and place them back in, resulting in focus being lost.
5276 */
5277function restoreSelection(priorSelectionInformation) {
5278 var curFocusedElem = getActiveElement_1();
5279 var priorFocusedElem = priorSelectionInformation.focusedElem;
5280 var priorSelectionRange = priorSelectionInformation.selectionRange;
5281 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5282 if (hasSelectionCapabilities(priorFocusedElem)) {
5283 setSelection(priorFocusedElem, priorSelectionRange);
5284 }
5285
5286 // Focusing a node can change the scroll position, which is undesirable
5287 var ancestors = [];
5288 var ancestor = priorFocusedElem;
5289 while (ancestor = ancestor.parentNode) {
5290 if (ancestor.nodeType === ELEMENT_NODE) {
5291 ancestors.push({
5292 element: ancestor,
5293 left: ancestor.scrollLeft,
5294 top: ancestor.scrollTop
5295 });
5296 }
5297 }
5298
5299 priorFocusedElem.focus();
5300
5301 for (var i = 0; i < ancestors.length; i++) {
5302 var info = ancestors[i];
5303 info.element.scrollLeft = info.left;
5304 info.element.scrollTop = info.top;
5305 }
5306 }
5307}
5308
5309/**
5310 * @getSelection: Gets the selection bounds of a focused textarea, input or
5311 * contentEditable node.
5312 * -@input: Look up selection bounds of this input
5313 * -@return {start: selectionStart, end: selectionEnd}
5314 */
5315function getSelection$1(input) {
5316 var selection = void 0;
5317
5318 if ('selectionStart' in input) {
5319 // Modern browser with input or textarea.
5320 selection = {
5321 start: input.selectionStart,
5322 end: input.selectionEnd
5323 };
5324 } else {
5325 // Content editable or old IE textarea.
5326 selection = getOffsets(input);
5327 }
5328
5329 return selection || { start: 0, end: 0 };
5330}
5331
5332/**
5333 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5334 * the input.
5335 * -@input Set selection bounds of this input or textarea
5336 * -@offsets Object of same form that is returned from get*
5337 */
5338function setSelection(input, offsets) {
5339 var start = offsets.start,
5340 end = offsets.end;
5341
5342 if (end === undefined) {
5343 end = start;
5344 }
5345
5346 if ('selectionStart' in input) {
5347 input.selectionStart = start;
5348 input.selectionEnd = Math.min(end, input.value.length);
5349 } else {
5350 setOffsets(input, offsets);
5351 }
5352}
5353
5354var skipSelectionChangeEvent = ExecutionEnvironment_1.canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5355
5356var eventTypes$3 = {
5357 select: {
5358 phasedRegistrationNames: {
5359 bubbled: 'onSelect',
5360 captured: 'onSelectCapture'
5361 },
5362 dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange']
5363 }
5364};
5365
5366var activeElement$1 = null;
5367var activeElementInst$1 = null;
5368var lastSelection = null;
5369var mouseDown = false;
5370
5371/**
5372 * Get an object which is a unique representation of the current selection.
5373 *
5374 * The return value will not be consistent across nodes or browsers, but
5375 * two identical selections on the same node will return identical objects.
5376 *
5377 * @param {DOMElement} node
5378 * @return {object}
5379 */
5380function getSelection(node) {
5381 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5382 return {
5383 start: node.selectionStart,
5384 end: node.selectionEnd
5385 };
5386 } else if (window.getSelection) {
5387 var selection = window.getSelection();
5388 return {
5389 anchorNode: selection.anchorNode,
5390 anchorOffset: selection.anchorOffset,
5391 focusNode: selection.focusNode,
5392 focusOffset: selection.focusOffset
5393 };
5394 }
5395}
5396
5397/**
5398 * Poll selection to see whether it's changed.
5399 *
5400 * @param {object} nativeEvent
5401 * @return {?SyntheticEvent}
5402 */
5403function constructSelectEvent(nativeEvent, nativeEventTarget) {
5404 // Ensure we have the right element, and that the user is not dragging a
5405 // selection (this matches native `select` event behavior). In HTML5, select
5406 // fires only on input and textarea thus if there's no focused element we
5407 // won't dispatch.
5408 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement_1()) {
5409 return null;
5410 }
5411
5412 // Only fire when selection has actually changed.
5413 var currentSelection = getSelection(activeElement$1);
5414 if (!lastSelection || !shallowEqual_1(lastSelection, currentSelection)) {
5415 lastSelection = currentSelection;
5416
5417 var syntheticEvent = SyntheticEvent$1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5418
5419 syntheticEvent.type = 'select';
5420 syntheticEvent.target = activeElement$1;
5421
5422 accumulateTwoPhaseDispatches(syntheticEvent);
5423
5424 return syntheticEvent;
5425 }
5426
5427 return null;
5428}
5429
5430/**
5431 * This plugin creates an `onSelect` event that normalizes select events
5432 * across form elements.
5433 *
5434 * Supported elements are:
5435 * - input (see `isTextInputElement`)
5436 * - textarea
5437 * - contentEditable
5438 *
5439 * This differs from native browser implementations in the following ways:
5440 * - Fires on contentEditable fields as well as inputs.
5441 * - Fires for collapsed selection.
5442 * - Fires after user input.
5443 */
5444var SelectEventPlugin = {
5445 eventTypes: eventTypes$3,
5446
5447 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5448 var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE ? nativeEventTarget : nativeEventTarget.ownerDocument;
5449 // Track whether all listeners exists for this plugin. If none exist, we do
5450 // not extract events. See #3639.
5451 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5452 return null;
5453 }
5454
5455 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5456
5457 switch (topLevelType) {
5458 // Track the input node that has focus.
5459 case 'topFocus':
5460 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5461 activeElement$1 = targetNode;
5462 activeElementInst$1 = targetInst;
5463 lastSelection = null;
5464 }
5465 break;
5466 case 'topBlur':
5467 activeElement$1 = null;
5468 activeElementInst$1 = null;
5469 lastSelection = null;
5470 break;
5471 // Don't fire the event while the user is dragging. This matches the
5472 // semantics of the native select event.
5473 case 'topMouseDown':
5474 mouseDown = true;
5475 break;
5476 case 'topContextMenu':
5477 case 'topMouseUp':
5478 mouseDown = false;
5479 return constructSelectEvent(nativeEvent, nativeEventTarget);
5480 // Chrome and IE fire non-standard event when selection is changed (and
5481 // sometimes when it hasn't). IE's event fires out of order with respect
5482 // to key and input events on deletion, so we discard it.
5483 //
5484 // Firefox doesn't support selectionchange, so check selection status
5485 // after each key entry. The selection changes after keydown and before
5486 // keyup, but we check on keydown as well in the case of holding down a
5487 // key, when multiple keydown events are fired but only one keyup is.
5488 // This is also our approach for IE handling, for the reason above.
5489 case 'topSelectionChange':
5490 if (skipSelectionChangeEvent) {
5491 break;
5492 }
5493 // falls through
5494 case 'topKeyDown':
5495 case 'topKeyUp':
5496 return constructSelectEvent(nativeEvent, nativeEventTarget);
5497 }
5498
5499 return null;
5500 }
5501};
5502
5503/**
5504 * Inject modules for resolving DOM hierarchy and plugin ordering.
5505 */
5506injection.injectEventPluginOrder(DOMEventPluginOrder);
5507injection$1.injectComponentTree(ReactDOMComponentTree);
5508
5509/**
5510 * Some important event plugins included by default (without having to require
5511 * them).
5512 */
5513injection.injectEventPluginsByName({
5514 SimpleEventPlugin: SimpleEventPlugin,
5515 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5516 ChangeEventPlugin: ChangeEventPlugin,
5517 SelectEventPlugin: SelectEventPlugin,
5518 BeforeInputEventPlugin: BeforeInputEventPlugin
5519});
5520
5521/**
5522 * Copyright (c) 2013-present, Facebook, Inc.
5523 *
5524 * This source code is licensed under the MIT license found in the
5525 * LICENSE file in the root directory of this source tree.
5526 *
5527 */
5528
5529
5530
5531var emptyObject = {};
5532
5533{
5534 Object.freeze(emptyObject);
5535}
5536
5537var emptyObject_1 = emptyObject;
5538
5539var valueStack = [];
5540
5541var fiberStack = void 0;
5542
5543{
5544 fiberStack = [];
5545}
5546
5547var index = -1;
5548
5549function createCursor(defaultValue) {
5550 return {
5551 current: defaultValue
5552 };
5553}
5554
5555
5556
5557function pop(cursor, fiber) {
5558 if (index < 0) {
5559 {
5560 warning_1(false, 'Unexpected pop.');
5561 }
5562 return;
5563 }
5564
5565 {
5566 if (fiber !== fiberStack[index]) {
5567 warning_1(false, 'Unexpected Fiber popped.');
5568 }
5569 }
5570
5571 cursor.current = valueStack[index];
5572
5573 valueStack[index] = null;
5574
5575 {
5576 fiberStack[index] = null;
5577 }
5578
5579 index--;
5580}
5581
5582function push(cursor, value, fiber) {
5583 index++;
5584
5585 valueStack[index] = cursor.current;
5586
5587 {
5588 fiberStack[index] = fiber;
5589 }
5590
5591 cursor.current = value;
5592}
5593
5594function reset$1() {
5595 while (index > -1) {
5596 valueStack[index] = null;
5597
5598 {
5599 fiberStack[index] = null;
5600 }
5601
5602 index--;
5603 }
5604}
5605
5606// Exports ReactDOM.createRoot
5607var enableCreateRoot = false;
5608var enableUserTimingAPI = true;
5609
5610// Mutating mode (React DOM, React ART, React Native):
5611var enableMutatingReconciler = true;
5612// Experimental noop mode (currently unused):
5613var enableNoopReconciler = false;
5614// Experimental persistent mode (Fabric):
5615var enablePersistentReconciler = false;
5616// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
5617var debugRenderPhaseSideEffects = false;
5618
5619// In some cases, StrictMode should also double-render lifecycles.
5620// This can be confusing for tests though,
5621// And it can be bad for performance in production.
5622// This feature flag can be used to control the behavior:
5623var debugRenderPhaseSideEffectsForStrictMode = true;
5624
5625// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
5626var warnAboutDeprecatedLifecycles = false;
5627
5628// Only used in www builds.
5629
5630// Prefix measurements so that it's possible to filter them.
5631// Longer prefixes are hard to read in DevTools.
5632var reactEmoji = '\u269B';
5633var warningEmoji = '\u26D4';
5634var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
5635
5636// Keep track of current fiber so that we know the path to unwind on pause.
5637// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5638var currentFiber = null;
5639// If we're in the middle of user code, which fiber and method is it?
5640// Reusing `currentFiber` would be confusing for this because user code fiber
5641// can change during commit phase too, but we don't need to unwind it (since
5642// lifecycles in the commit phase don't resemble a tree).
5643var currentPhase = null;
5644var currentPhaseFiber = null;
5645// Did lifecycle hook schedule an update? This is often a performance problem,
5646// so we will keep track of it, and include it in the report.
5647// Track commits caused by cascading updates.
5648var isCommitting = false;
5649var hasScheduledUpdateInCurrentCommit = false;
5650var hasScheduledUpdateInCurrentPhase = false;
5651var commitCountInCurrentWorkLoop = 0;
5652var effectCountInCurrentCommit = 0;
5653var isWaitingForCallback = false;
5654// During commits, we only show a measurement once per method name
5655// to avoid stretch the commit phase with measurement overhead.
5656var labelsInCurrentCommit = new Set();
5657
5658var formatMarkName = function (markName) {
5659 return reactEmoji + ' ' + markName;
5660};
5661
5662var formatLabel = function (label, warning) {
5663 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
5664 var suffix = warning ? ' Warning: ' + warning : '';
5665 return '' + prefix + label + suffix;
5666};
5667
5668var beginMark = function (markName) {
5669 performance.mark(formatMarkName(markName));
5670};
5671
5672var clearMark = function (markName) {
5673 performance.clearMarks(formatMarkName(markName));
5674};
5675
5676var endMark = function (label, markName, warning) {
5677 var formattedMarkName = formatMarkName(markName);
5678 var formattedLabel = formatLabel(label, warning);
5679 try {
5680 performance.measure(formattedLabel, formattedMarkName);
5681 } catch (err) {}
5682 // If previous mark was missing for some reason, this will throw.
5683 // This could only happen if React crashed in an unexpected place earlier.
5684 // Don't pile on with more errors.
5685
5686 // Clear marks immediately to avoid growing buffer.
5687 performance.clearMarks(formattedMarkName);
5688 performance.clearMeasures(formattedLabel);
5689};
5690
5691var getFiberMarkName = function (label, debugID) {
5692 return label + ' (#' + debugID + ')';
5693};
5694
5695var getFiberLabel = function (componentName, isMounted, phase) {
5696 if (phase === null) {
5697 // These are composite component total time measurements.
5698 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
5699 } else {
5700 // Composite component methods.
5701 return componentName + '.' + phase;
5702 }
5703};
5704
5705var beginFiberMark = function (fiber, phase) {
5706 var componentName = getComponentName(fiber) || 'Unknown';
5707 var debugID = fiber._debugID;
5708 var isMounted = fiber.alternate !== null;
5709 var label = getFiberLabel(componentName, isMounted, phase);
5710
5711 if (isCommitting && labelsInCurrentCommit.has(label)) {
5712 // During the commit phase, we don't show duplicate labels because
5713 // there is a fixed overhead for every measurement, and we don't
5714 // want to stretch the commit phase beyond necessary.
5715 return false;
5716 }
5717 labelsInCurrentCommit.add(label);
5718
5719 var markName = getFiberMarkName(label, debugID);
5720 beginMark(markName);
5721 return true;
5722};
5723
5724var clearFiberMark = function (fiber, phase) {
5725 var componentName = getComponentName(fiber) || 'Unknown';
5726 var debugID = fiber._debugID;
5727 var isMounted = fiber.alternate !== null;
5728 var label = getFiberLabel(componentName, isMounted, phase);
5729 var markName = getFiberMarkName(label, debugID);
5730 clearMark(markName);
5731};
5732
5733var endFiberMark = function (fiber, phase, warning) {
5734 var componentName = getComponentName(fiber) || 'Unknown';
5735 var debugID = fiber._debugID;
5736 var isMounted = fiber.alternate !== null;
5737 var label = getFiberLabel(componentName, isMounted, phase);
5738 var markName = getFiberMarkName(label, debugID);
5739 endMark(label, markName, warning);
5740};
5741
5742var shouldIgnoreFiber = function (fiber) {
5743 // Host components should be skipped in the timeline.
5744 // We could check typeof fiber.type, but does this work with RN?
5745 switch (fiber.tag) {
5746 case HostRoot:
5747 case HostComponent:
5748 case HostText:
5749 case HostPortal:
5750 case CallComponent:
5751 case ReturnComponent:
5752 case Fragment:
5753 case ContextProvider:
5754 case ContextConsumer:
5755 return true;
5756 default:
5757 return false;
5758 }
5759};
5760
5761var clearPendingPhaseMeasurement = function () {
5762 if (currentPhase !== null && currentPhaseFiber !== null) {
5763 clearFiberMark(currentPhaseFiber, currentPhase);
5764 }
5765 currentPhaseFiber = null;
5766 currentPhase = null;
5767 hasScheduledUpdateInCurrentPhase = false;
5768};
5769
5770var pauseTimers = function () {
5771 // Stops all currently active measurements so that they can be resumed
5772 // if we continue in a later deferred loop from the same unit of work.
5773 var fiber = currentFiber;
5774 while (fiber) {
5775 if (fiber._debugIsCurrentlyTiming) {
5776 endFiberMark(fiber, null, null);
5777 }
5778 fiber = fiber['return'];
5779 }
5780};
5781
5782var resumeTimersRecursively = function (fiber) {
5783 if (fiber['return'] !== null) {
5784 resumeTimersRecursively(fiber['return']);
5785 }
5786 if (fiber._debugIsCurrentlyTiming) {
5787 beginFiberMark(fiber, null);
5788 }
5789};
5790
5791var resumeTimers = function () {
5792 // Resumes all measurements that were active during the last deferred loop.
5793 if (currentFiber !== null) {
5794 resumeTimersRecursively(currentFiber);
5795 }
5796};
5797
5798function recordEffect() {
5799 if (enableUserTimingAPI) {
5800 effectCountInCurrentCommit++;
5801 }
5802}
5803
5804function recordScheduleUpdate() {
5805 if (enableUserTimingAPI) {
5806 if (isCommitting) {
5807 hasScheduledUpdateInCurrentCommit = true;
5808 }
5809 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
5810 hasScheduledUpdateInCurrentPhase = true;
5811 }
5812 }
5813}
5814
5815function startRequestCallbackTimer() {
5816 if (enableUserTimingAPI) {
5817 if (supportsUserTiming && !isWaitingForCallback) {
5818 isWaitingForCallback = true;
5819 beginMark('(Waiting for async callback...)');
5820 }
5821 }
5822}
5823
5824function stopRequestCallbackTimer(didExpire) {
5825 if (enableUserTimingAPI) {
5826 if (supportsUserTiming) {
5827 isWaitingForCallback = false;
5828 var warning = didExpire ? 'React was blocked by main thread' : null;
5829 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
5830 }
5831 }
5832}
5833
5834function startWorkTimer(fiber) {
5835 if (enableUserTimingAPI) {
5836 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5837 return;
5838 }
5839 // If we pause, this is the fiber to unwind from.
5840 currentFiber = fiber;
5841 if (!beginFiberMark(fiber, null)) {
5842 return;
5843 }
5844 fiber._debugIsCurrentlyTiming = true;
5845 }
5846}
5847
5848function cancelWorkTimer(fiber) {
5849 if (enableUserTimingAPI) {
5850 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5851 return;
5852 }
5853 // Remember we shouldn't complete measurement for this fiber.
5854 // Otherwise flamechart will be deep even for small updates.
5855 fiber._debugIsCurrentlyTiming = false;
5856 clearFiberMark(fiber, null);
5857 }
5858}
5859
5860function stopWorkTimer(fiber) {
5861 if (enableUserTimingAPI) {
5862 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5863 return;
5864 }
5865 // If we pause, its parent is the fiber to unwind from.
5866 currentFiber = fiber['return'];
5867 if (!fiber._debugIsCurrentlyTiming) {
5868 return;
5869 }
5870 fiber._debugIsCurrentlyTiming = false;
5871 endFiberMark(fiber, null, null);
5872 }
5873}
5874
5875function stopFailedWorkTimer(fiber) {
5876 if (enableUserTimingAPI) {
5877 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5878 return;
5879 }
5880 // If we pause, its parent is the fiber to unwind from.
5881 currentFiber = fiber['return'];
5882 if (!fiber._debugIsCurrentlyTiming) {
5883 return;
5884 }
5885 fiber._debugIsCurrentlyTiming = false;
5886 var warning = 'An error was thrown inside this error boundary';
5887 endFiberMark(fiber, null, warning);
5888 }
5889}
5890
5891function startPhaseTimer(fiber, phase) {
5892 if (enableUserTimingAPI) {
5893 if (!supportsUserTiming) {
5894 return;
5895 }
5896 clearPendingPhaseMeasurement();
5897 if (!beginFiberMark(fiber, phase)) {
5898 return;
5899 }
5900 currentPhaseFiber = fiber;
5901 currentPhase = phase;
5902 }
5903}
5904
5905function stopPhaseTimer() {
5906 if (enableUserTimingAPI) {
5907 if (!supportsUserTiming) {
5908 return;
5909 }
5910 if (currentPhase !== null && currentPhaseFiber !== null) {
5911 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
5912 endFiberMark(currentPhaseFiber, currentPhase, warning);
5913 }
5914 currentPhase = null;
5915 currentPhaseFiber = null;
5916 }
5917}
5918
5919function startWorkLoopTimer(nextUnitOfWork) {
5920 if (enableUserTimingAPI) {
5921 currentFiber = nextUnitOfWork;
5922 if (!supportsUserTiming) {
5923 return;
5924 }
5925 commitCountInCurrentWorkLoop = 0;
5926 // This is top level call.
5927 // Any other measurements are performed within.
5928 beginMark('(React Tree Reconciliation)');
5929 // Resume any measurements that were in progress during the last loop.
5930 resumeTimers();
5931 }
5932}
5933
5934function stopWorkLoopTimer(interruptedBy) {
5935 if (enableUserTimingAPI) {
5936 if (!supportsUserTiming) {
5937 return;
5938 }
5939 var warning = null;
5940 if (interruptedBy !== null) {
5941 if (interruptedBy.tag === HostRoot) {
5942 warning = 'A top-level update interrupted the previous render';
5943 } else {
5944 var componentName = getComponentName(interruptedBy) || 'Unknown';
5945 warning = 'An update to ' + componentName + ' interrupted the previous render';
5946 }
5947 } else if (commitCountInCurrentWorkLoop > 1) {
5948 warning = 'There were cascading updates';
5949 }
5950 commitCountInCurrentWorkLoop = 0;
5951 // Pause any measurements until the next loop.
5952 pauseTimers();
5953 endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning);
5954 }
5955}
5956
5957function startCommitTimer() {
5958 if (enableUserTimingAPI) {
5959 if (!supportsUserTiming) {
5960 return;
5961 }
5962 isCommitting = true;
5963 hasScheduledUpdateInCurrentCommit = false;
5964 labelsInCurrentCommit.clear();
5965 beginMark('(Committing Changes)');
5966 }
5967}
5968
5969function stopCommitTimer() {
5970 if (enableUserTimingAPI) {
5971 if (!supportsUserTiming) {
5972 return;
5973 }
5974
5975 var warning = null;
5976 if (hasScheduledUpdateInCurrentCommit) {
5977 warning = 'Lifecycle hook scheduled a cascading update';
5978 } else if (commitCountInCurrentWorkLoop > 0) {
5979 warning = 'Caused by a cascading update in earlier commit';
5980 }
5981 hasScheduledUpdateInCurrentCommit = false;
5982 commitCountInCurrentWorkLoop++;
5983 isCommitting = false;
5984 labelsInCurrentCommit.clear();
5985
5986 endMark('(Committing Changes)', '(Committing Changes)', warning);
5987 }
5988}
5989
5990function startCommitHostEffectsTimer() {
5991 if (enableUserTimingAPI) {
5992 if (!supportsUserTiming) {
5993 return;
5994 }
5995 effectCountInCurrentCommit = 0;
5996 beginMark('(Committing Host Effects)');
5997 }
5998}
5999
6000function stopCommitHostEffectsTimer() {
6001 if (enableUserTimingAPI) {
6002 if (!supportsUserTiming) {
6003 return;
6004 }
6005 var count = effectCountInCurrentCommit;
6006 effectCountInCurrentCommit = 0;
6007 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
6008 }
6009}
6010
6011function startCommitLifeCyclesTimer() {
6012 if (enableUserTimingAPI) {
6013 if (!supportsUserTiming) {
6014 return;
6015 }
6016 effectCountInCurrentCommit = 0;
6017 beginMark('(Calling Lifecycle Methods)');
6018 }
6019}
6020
6021function stopCommitLifeCyclesTimer() {
6022 if (enableUserTimingAPI) {
6023 if (!supportsUserTiming) {
6024 return;
6025 }
6026 var count = effectCountInCurrentCommit;
6027 effectCountInCurrentCommit = 0;
6028 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
6029 }
6030}
6031
6032var warnedAboutMissingGetChildContext = void 0;
6033
6034{
6035 warnedAboutMissingGetChildContext = {};
6036}
6037
6038// A cursor to the current merged context object on the stack.
6039var contextStackCursor = createCursor(emptyObject_1);
6040// A cursor to a boolean indicating whether the context has changed.
6041var didPerformWorkStackCursor = createCursor(false);
6042// Keep track of the previous context object that was on the stack.
6043// We use this to get access to the parent context after we have already
6044// pushed the next context provider, and now need to merge their contexts.
6045var previousContext = emptyObject_1;
6046
6047function getUnmaskedContext(workInProgress) {
6048 var hasOwnContext = isContextProvider(workInProgress);
6049 if (hasOwnContext) {
6050 // If the fiber is a context provider itself, when we read its context
6051 // we have already pushed its own child context on the stack. A context
6052 // provider should not "see" its own child context. Therefore we read the
6053 // previous (parent) context instead for a context provider.
6054 return previousContext;
6055 }
6056 return contextStackCursor.current;
6057}
6058
6059function cacheContext(workInProgress, unmaskedContext, maskedContext) {
6060 var instance = workInProgress.stateNode;
6061 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
6062 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
6063}
6064
6065function getMaskedContext(workInProgress, unmaskedContext) {
6066 var type = workInProgress.type;
6067 var contextTypes = type.contextTypes;
6068 if (!contextTypes) {
6069 return emptyObject_1;
6070 }
6071
6072 // Avoid recreating masked context unless unmasked context has changed.
6073 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
6074 // This may trigger infinite loops if componentWillReceiveProps calls setState.
6075 var instance = workInProgress.stateNode;
6076 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
6077 return instance.__reactInternalMemoizedMaskedChildContext;
6078 }
6079
6080 var context = {};
6081 for (var key in contextTypes) {
6082 context[key] = unmaskedContext[key];
6083 }
6084
6085 {
6086 var name = getComponentName(workInProgress) || 'Unknown';
6087 checkPropTypes_1(contextTypes, context, 'context', name, ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6088 }
6089
6090 // Cache unmasked context so we can avoid recreating masked context unless necessary.
6091 // Context is created before the class component is instantiated so check for instance.
6092 if (instance) {
6093 cacheContext(workInProgress, unmaskedContext, context);
6094 }
6095
6096 return context;
6097}
6098
6099function hasContextChanged() {
6100 return didPerformWorkStackCursor.current;
6101}
6102
6103function isContextConsumer(fiber) {
6104 return fiber.tag === ClassComponent && fiber.type.contextTypes != null;
6105}
6106
6107function isContextProvider(fiber) {
6108 return fiber.tag === ClassComponent && fiber.type.childContextTypes != null;
6109}
6110
6111function popContextProvider(fiber) {
6112 if (!isContextProvider(fiber)) {
6113 return;
6114 }
6115
6116 pop(didPerformWorkStackCursor, fiber);
6117 pop(contextStackCursor, fiber);
6118}
6119
6120function popTopLevelContextObject(fiber) {
6121 pop(didPerformWorkStackCursor, fiber);
6122 pop(contextStackCursor, fiber);
6123}
6124
6125function pushTopLevelContextObject(fiber, context, didChange) {
6126 !(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;
6127
6128 push(contextStackCursor, context, fiber);
6129 push(didPerformWorkStackCursor, didChange, fiber);
6130}
6131
6132function processChildContext(fiber, parentContext) {
6133 var instance = fiber.stateNode;
6134 var childContextTypes = fiber.type.childContextTypes;
6135
6136 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
6137 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
6138 if (typeof instance.getChildContext !== 'function') {
6139 {
6140 var componentName = getComponentName(fiber) || 'Unknown';
6141
6142 if (!warnedAboutMissingGetChildContext[componentName]) {
6143 warnedAboutMissingGetChildContext[componentName] = true;
6144 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);
6145 }
6146 }
6147 return parentContext;
6148 }
6149
6150 var childContext = void 0;
6151 {
6152 ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
6153 }
6154 startPhaseTimer(fiber, 'getChildContext');
6155 childContext = instance.getChildContext();
6156 stopPhaseTimer();
6157 {
6158 ReactDebugCurrentFiber.setCurrentPhase(null);
6159 }
6160 for (var contextKey in childContext) {
6161 !(contextKey in childContextTypes) ? invariant_1(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(fiber) || 'Unknown', contextKey) : void 0;
6162 }
6163 {
6164 var name = getComponentName(fiber) || 'Unknown';
6165 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
6166 // In practice, there is one case in which we won't get a stack. It's when
6167 // somebody calls unstable_renderSubtreeIntoContainer() and we process
6168 // context from the parent component instance. The stack will be missing
6169 // because it's outside of the reconciliation, and so the pointer has not
6170 // been set. This is rare and doesn't matter. We'll also remove that API.
6171 ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6172 }
6173
6174 return _assign({}, parentContext, childContext);
6175}
6176
6177function pushContextProvider(workInProgress) {
6178 if (!isContextProvider(workInProgress)) {
6179 return false;
6180 }
6181
6182 var instance = workInProgress.stateNode;
6183 // We push the context as early as possible to ensure stack integrity.
6184 // If the instance does not exist yet, we will push null at first,
6185 // and replace it on the stack later when invalidating the context.
6186 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject_1;
6187
6188 // Remember the parent context so we can merge with it later.
6189 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
6190 previousContext = contextStackCursor.current;
6191 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
6192 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
6193
6194 return true;
6195}
6196
6197function invalidateContextProvider(workInProgress, didChange) {
6198 var instance = workInProgress.stateNode;
6199 !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;
6200
6201 if (didChange) {
6202 // Merge parent and own context.
6203 // Skip this if we're not updating due to sCU.
6204 // This avoids unnecessarily recomputing memoized values.
6205 var mergedContext = processChildContext(workInProgress, previousContext);
6206 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
6207
6208 // Replace the old (or empty) context with the new one.
6209 // It is important to unwind the context in the reverse order.
6210 pop(didPerformWorkStackCursor, workInProgress);
6211 pop(contextStackCursor, workInProgress);
6212 // Now push the new context and mark that it has changed.
6213 push(contextStackCursor, mergedContext, workInProgress);
6214 push(didPerformWorkStackCursor, didChange, workInProgress);
6215 } else {
6216 pop(didPerformWorkStackCursor, workInProgress);
6217 push(didPerformWorkStackCursor, didChange, workInProgress);
6218 }
6219}
6220
6221function resetContext() {
6222 previousContext = emptyObject_1;
6223 contextStackCursor.current = emptyObject_1;
6224 didPerformWorkStackCursor.current = false;
6225}
6226
6227function findCurrentUnmaskedContext(fiber) {
6228 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
6229 // makes sense elsewhere
6230 !(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;
6231
6232 var node = fiber;
6233 while (node.tag !== HostRoot) {
6234 if (isContextProvider(node)) {
6235 return node.stateNode.__reactInternalMemoizedMergedChildContext;
6236 }
6237 var parent = node['return'];
6238 !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;
6239 node = parent;
6240 }
6241 return node.stateNode.context;
6242}
6243
6244// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
6245// Math.pow(2, 30) - 1
6246// 0b111111111111111111111111111111
6247var MAX_SIGNED_31_BIT_INT = 1073741823;
6248
6249// TODO: Use an opaque type once ESLint et al support the syntax
6250
6251
6252var NoWork = 0;
6253var Sync = 1;
6254var Never = MAX_SIGNED_31_BIT_INT;
6255
6256var UNIT_SIZE = 10;
6257var MAGIC_NUMBER_OFFSET = 2;
6258
6259// 1 unit of expiration time represents 10ms.
6260function msToExpirationTime(ms) {
6261 // Always add an offset so that we don't clash with the magic number for NoWork.
6262 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET;
6263}
6264
6265function expirationTimeToMs(expirationTime) {
6266 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE;
6267}
6268
6269function ceiling(num, precision) {
6270 return ((num / precision | 0) + 1) * precision;
6271}
6272
6273function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6274 return ceiling(currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
6275}
6276
6277var NoContext = 0;
6278var AsyncMode = 1;
6279var StrictMode = 2;
6280
6281var hasBadMapPolyfill = void 0;
6282
6283{
6284 hasBadMapPolyfill = false;
6285 try {
6286 var nonExtensibleObject = Object.preventExtensions({});
6287 var testMap = new Map([[nonExtensibleObject, null]]);
6288 var testSet = new Set([nonExtensibleObject]);
6289 // This is necessary for Rollup to not consider these unused.
6290 // https://github.com/rollup/rollup/issues/1771
6291 // TODO: we can remove these if Rollup fixes the bug.
6292 testMap.set(0, 0);
6293 testSet.add(0);
6294 } catch (e) {
6295 // TODO: Consider warning about bad polyfills
6296 hasBadMapPolyfill = true;
6297 }
6298}
6299
6300// A Fiber is work on a Component that needs to be done or was done. There can
6301// be more than one per component.
6302
6303
6304var debugCounter = void 0;
6305
6306{
6307 debugCounter = 1;
6308}
6309
6310function FiberNode(tag, pendingProps, key, mode) {
6311 // Instance
6312 this.tag = tag;
6313 this.key = key;
6314 this.type = null;
6315 this.stateNode = null;
6316
6317 // Fiber
6318 this['return'] = null;
6319 this.child = null;
6320 this.sibling = null;
6321 this.index = 0;
6322
6323 this.ref = null;
6324
6325 this.pendingProps = pendingProps;
6326 this.memoizedProps = null;
6327 this.updateQueue = null;
6328 this.memoizedState = null;
6329
6330 this.mode = mode;
6331
6332 // Effects
6333 this.effectTag = NoEffect;
6334 this.nextEffect = null;
6335
6336 this.firstEffect = null;
6337 this.lastEffect = null;
6338
6339 this.expirationTime = NoWork;
6340
6341 this.alternate = null;
6342
6343 {
6344 this._debugID = debugCounter++;
6345 this._debugSource = null;
6346 this._debugOwner = null;
6347 this._debugIsCurrentlyTiming = false;
6348 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
6349 Object.preventExtensions(this);
6350 }
6351 }
6352}
6353
6354// This is a constructor function, rather than a POJO constructor, still
6355// please ensure we do the following:
6356// 1) Nobody should add any instance methods on this. Instance methods can be
6357// more difficult to predict when they get optimized and they are almost
6358// never inlined properly in static compilers.
6359// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
6360// always know when it is a fiber.
6361// 3) We might want to experiment with using numeric keys since they are easier
6362// to optimize in a non-JIT environment.
6363// 4) We can easily go from a constructor to a createFiber object literal if that
6364// is faster.
6365// 5) It should be easy to port this to a C struct and keep a C implementation
6366// compatible.
6367var createFiber = function (tag, pendingProps, key, mode) {
6368 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
6369 return new FiberNode(tag, pendingProps, key, mode);
6370};
6371
6372function shouldConstruct(Component) {
6373 return !!(Component.prototype && Component.prototype.isReactComponent);
6374}
6375
6376// This is used to create an alternate fiber to do work on.
6377function createWorkInProgress(current, pendingProps, expirationTime) {
6378 var workInProgress = current.alternate;
6379 if (workInProgress === null) {
6380 // We use a double buffering pooling technique because we know that we'll
6381 // only ever need at most two versions of a tree. We pool the "other" unused
6382 // node that we're free to reuse. This is lazily created to avoid allocating
6383 // extra objects for things that are never updated. It also allow us to
6384 // reclaim the extra memory if needed.
6385 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
6386 workInProgress.type = current.type;
6387 workInProgress.stateNode = current.stateNode;
6388
6389 {
6390 // DEV-only fields
6391 workInProgress._debugID = current._debugID;
6392 workInProgress._debugSource = current._debugSource;
6393 workInProgress._debugOwner = current._debugOwner;
6394 }
6395
6396 workInProgress.alternate = current;
6397 current.alternate = workInProgress;
6398 } else {
6399 workInProgress.pendingProps = pendingProps;
6400
6401 // We already have an alternate.
6402 // Reset the effect tag.
6403 workInProgress.effectTag = NoEffect;
6404
6405 // The effect list is no longer valid.
6406 workInProgress.nextEffect = null;
6407 workInProgress.firstEffect = null;
6408 workInProgress.lastEffect = null;
6409 }
6410
6411 workInProgress.expirationTime = expirationTime;
6412
6413 workInProgress.child = current.child;
6414 workInProgress.memoizedProps = current.memoizedProps;
6415 workInProgress.memoizedState = current.memoizedState;
6416 workInProgress.updateQueue = current.updateQueue;
6417
6418 // These will be overridden during the parent's reconciliation
6419 workInProgress.sibling = current.sibling;
6420 workInProgress.index = current.index;
6421 workInProgress.ref = current.ref;
6422
6423 return workInProgress;
6424}
6425
6426function createHostRootFiber(isAsync) {
6427 var mode = isAsync ? AsyncMode | StrictMode : NoContext;
6428 return createFiber(HostRoot, null, null, mode);
6429}
6430
6431function createFiberFromElement(element, mode, expirationTime) {
6432 var owner = null;
6433 {
6434 owner = element._owner;
6435 }
6436
6437 var fiber = void 0;
6438 var type = element.type;
6439 var key = element.key;
6440 var pendingProps = element.props;
6441
6442 var fiberTag = void 0;
6443 if (typeof type === 'function') {
6444 fiberTag = shouldConstruct(type) ? ClassComponent : IndeterminateComponent;
6445 } else if (typeof type === 'string') {
6446 fiberTag = HostComponent;
6447 } else {
6448 switch (type) {
6449 case REACT_FRAGMENT_TYPE:
6450 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
6451 case REACT_ASYNC_MODE_TYPE:
6452 fiberTag = Mode;
6453 mode |= AsyncMode | StrictMode;
6454 break;
6455 case REACT_STRICT_MODE_TYPE:
6456 fiberTag = Mode;
6457 mode |= StrictMode;
6458 break;
6459 case REACT_CALL_TYPE:
6460 fiberTag = CallComponent;
6461 break;
6462 case REACT_RETURN_TYPE:
6463 fiberTag = ReturnComponent;
6464 break;
6465 default:
6466 {
6467 if (typeof type === 'object' && type !== null) {
6468 switch (type.$$typeof) {
6469 case REACT_PROVIDER_TYPE:
6470 fiberTag = ContextProvider;
6471 break;
6472 case REACT_CONTEXT_TYPE:
6473 // This is a consumer
6474 fiberTag = ContextConsumer;
6475 break;
6476 default:
6477 if (typeof type.tag === 'number') {
6478 // Currently assumed to be a continuation and therefore is a
6479 // fiber already.
6480 // TODO: The yield system is currently broken for updates in
6481 // some cases. The reified yield stores a fiber, but we don't
6482 // know which fiber that is; the current or a workInProgress?
6483 // When the continuation gets rendered here we don't know if we
6484 // can reuse that fiber or if we need to clone it. There is
6485 // probably a clever way to restructure this.
6486 fiber = type;
6487 fiber.pendingProps = pendingProps;
6488 fiber.expirationTime = expirationTime;
6489 return fiber;
6490 } else {
6491 throwOnInvalidElementType(type, owner);
6492 }
6493 break;
6494 }
6495 } else {
6496 throwOnInvalidElementType(type, owner);
6497 }
6498 }
6499 }
6500 }
6501
6502 fiber = createFiber(fiberTag, pendingProps, key, mode);
6503 fiber.type = type;
6504 fiber.expirationTime = expirationTime;
6505
6506 {
6507 fiber._debugSource = element._source;
6508 fiber._debugOwner = element._owner;
6509 }
6510
6511 return fiber;
6512}
6513
6514function throwOnInvalidElementType(type, owner) {
6515 var info = '';
6516 {
6517 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
6518 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.';
6519 }
6520 var ownerName = owner ? getComponentName(owner) : null;
6521 if (ownerName) {
6522 info += '\n\nCheck the render method of `' + ownerName + '`.';
6523 }
6524 }
6525 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);
6526}
6527
6528function createFiberFromFragment(elements, mode, expirationTime, key) {
6529 var fiber = createFiber(Fragment, elements, key, mode);
6530 fiber.expirationTime = expirationTime;
6531 return fiber;
6532}
6533
6534function createFiberFromText(content, mode, expirationTime) {
6535 var fiber = createFiber(HostText, content, null, mode);
6536 fiber.expirationTime = expirationTime;
6537 return fiber;
6538}
6539
6540function createFiberFromHostInstanceForDeletion() {
6541 var fiber = createFiber(HostComponent, null, null, NoContext);
6542 fiber.type = 'DELETED';
6543 return fiber;
6544}
6545
6546function createFiberFromPortal(portal, mode, expirationTime) {
6547 var pendingProps = portal.children !== null ? portal.children : [];
6548 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
6549 fiber.expirationTime = expirationTime;
6550 fiber.stateNode = {
6551 containerInfo: portal.containerInfo,
6552 pendingChildren: null, // Used by persistent updates
6553 implementation: portal.implementation
6554 };
6555 return fiber;
6556}
6557
6558// TODO: This should be lifted into the renderer.
6559
6560
6561function createFiberRoot(containerInfo, isAsync, hydrate) {
6562 // Cyclic construction. This cheats the type system right now because
6563 // stateNode is any.
6564 var uninitializedFiber = createHostRootFiber(isAsync);
6565 var root = {
6566 current: uninitializedFiber,
6567 containerInfo: containerInfo,
6568 pendingChildren: null,
6569 remainingExpirationTime: NoWork,
6570 isReadyForCommit: false,
6571 finishedWork: null,
6572 context: null,
6573 pendingContext: null,
6574 hydrate: hydrate,
6575 firstBatch: null,
6576 nextScheduledRoot: null
6577 };
6578 uninitializedFiber.stateNode = root;
6579 return root;
6580}
6581
6582var onCommitFiberRoot = null;
6583var onCommitFiberUnmount = null;
6584var hasLoggedError = false;
6585
6586function catchErrors(fn) {
6587 return function (arg) {
6588 try {
6589 return fn(arg);
6590 } catch (err) {
6591 if (true && !hasLoggedError) {
6592 hasLoggedError = true;
6593 warning_1(false, 'React DevTools encountered an error: %s', err);
6594 }
6595 }
6596 };
6597}
6598
6599function injectInternals(internals) {
6600 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
6601 // No DevTools
6602 return false;
6603 }
6604 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
6605 if (hook.isDisabled) {
6606 // This isn't a real property on the hook, but it can be set to opt out
6607 // of DevTools integration and associated warnings and logs.
6608 // https://github.com/facebook/react/issues/3877
6609 return true;
6610 }
6611 if (!hook.supportsFiber) {
6612 {
6613 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');
6614 }
6615 // DevTools exists, even though it doesn't support Fiber.
6616 return true;
6617 }
6618 try {
6619 var rendererID = hook.inject(internals);
6620 // We have successfully injected, so now it is safe to set up hooks.
6621 onCommitFiberRoot = catchErrors(function (root) {
6622 return hook.onCommitFiberRoot(rendererID, root);
6623 });
6624 onCommitFiberUnmount = catchErrors(function (fiber) {
6625 return hook.onCommitFiberUnmount(rendererID, fiber);
6626 });
6627 } catch (err) {
6628 // Catch all errors because it is unsafe to throw during initialization.
6629 {
6630 warning_1(false, 'React DevTools encountered an error: %s.', err);
6631 }
6632 }
6633 // DevTools exists
6634 return true;
6635}
6636
6637function onCommitRoot(root) {
6638 if (typeof onCommitFiberRoot === 'function') {
6639 onCommitFiberRoot(root);
6640 }
6641}
6642
6643function onCommitUnmount(fiber) {
6644 if (typeof onCommitFiberUnmount === 'function') {
6645 onCommitFiberUnmount(fiber);
6646 }
6647}
6648
6649/**
6650 * Forked from fbjs/warning:
6651 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
6652 *
6653 * Only change is we use console.warn instead of console.error,
6654 * and do nothing when 'console' is not supported.
6655 * This really simplifies the code.
6656 * ---
6657 * Similar to invariant but only logs a warning if the condition is not met.
6658 * This can be used to log issues in development environments in critical
6659 * paths. Removing the logging code for production environments will keep the
6660 * same logic and follow the same code paths.
6661 */
6662
6663var lowPriorityWarning = function () {};
6664
6665{
6666 var printWarning$1 = function (format) {
6667 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6668 args[_key - 1] = arguments[_key];
6669 }
6670
6671 var argIndex = 0;
6672 var message = 'Warning: ' + format.replace(/%s/g, function () {
6673 return args[argIndex++];
6674 });
6675 if (typeof console !== 'undefined') {
6676 console.warn(message);
6677 }
6678 try {
6679 // --- Welcome to debugging React ---
6680 // This error was thrown as a convenience so that you can use this stack
6681 // to find the callsite that caused this warning to fire.
6682 throw new Error(message);
6683 } catch (x) {}
6684 };
6685
6686 lowPriorityWarning = function (condition, format) {
6687 if (format === undefined) {
6688 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
6689 }
6690 if (!condition) {
6691 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
6692 args[_key2 - 2] = arguments[_key2];
6693 }
6694
6695 printWarning$1.apply(undefined, [format].concat(args));
6696 }
6697 };
6698}
6699
6700var lowPriorityWarning$1 = lowPriorityWarning;
6701
6702var ReactStrictModeWarnings = {
6703 discardPendingWarnings: function () {},
6704 flushPendingDeprecationWarnings: function () {},
6705 flushPendingUnsafeLifecycleWarnings: function () {},
6706 recordDeprecationWarnings: function (fiber, instance) {},
6707 recordUnsafeLifecycleWarnings: function (fiber, instance) {}
6708};
6709
6710{
6711 var LIFECYCLE_SUGGESTIONS = {
6712 UNSAFE_componentWillMount: 'componentDidMount',
6713 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
6714 UNSAFE_componentWillUpdate: 'componentDidUpdate'
6715 };
6716
6717 var pendingComponentWillMountWarnings = [];
6718 var pendingComponentWillReceivePropsWarnings = [];
6719 var pendingComponentWillUpdateWarnings = [];
6720 var pendingUnsafeLifecycleWarnings = new Map();
6721
6722 // Tracks components we have already warned about.
6723 var didWarnAboutDeprecatedLifecycles = new Set();
6724 var didWarnAboutUnsafeLifecycles = new Set();
6725
6726 ReactStrictModeWarnings.discardPendingWarnings = function () {
6727 pendingComponentWillMountWarnings = [];
6728 pendingComponentWillReceivePropsWarnings = [];
6729 pendingComponentWillUpdateWarnings = [];
6730 pendingUnsafeLifecycleWarnings = new Map();
6731 };
6732
6733 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
6734 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
6735 var lifecyclesWarningMesages = [];
6736
6737 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
6738 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
6739 if (lifecycleWarnings.length > 0) {
6740 var componentNames = new Set();
6741 lifecycleWarnings.forEach(function (fiber) {
6742 componentNames.add(getComponentName(fiber) || 'Component');
6743 didWarnAboutUnsafeLifecycles.add(fiber.type);
6744 });
6745
6746 var formatted = lifecycle.replace('UNSAFE_', '');
6747 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
6748 var sortedComponentNames = Array.from(componentNames).sort().join(', ');
6749
6750 lifecyclesWarningMesages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
6751 }
6752 });
6753
6754 if (lifecyclesWarningMesages.length > 0) {
6755 var strictRootComponentStack = getStackAddendumByWorkInProgressFiber(strictRoot);
6756
6757 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'));
6758 }
6759 });
6760
6761 pendingUnsafeLifecycleWarnings = new Map();
6762 };
6763
6764 var getStrictRoot = function (fiber) {
6765 var maybeStrictRoot = null;
6766
6767 while (fiber !== null) {
6768 if (fiber.mode & StrictMode) {
6769 maybeStrictRoot = fiber;
6770 }
6771
6772 fiber = fiber['return'];
6773 }
6774
6775 return maybeStrictRoot;
6776 };
6777
6778 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
6779 if (pendingComponentWillMountWarnings.length > 0) {
6780 var uniqueNames = new Set();
6781 pendingComponentWillMountWarnings.forEach(function (fiber) {
6782 uniqueNames.add(getComponentName(fiber) || 'Component');
6783 didWarnAboutDeprecatedLifecycles.add(fiber.type);
6784 });
6785
6786 var sortedNames = Array.from(uniqueNames).sort().join(', ');
6787
6788 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);
6789
6790 pendingComponentWillMountWarnings = [];
6791 }
6792
6793 if (pendingComponentWillReceivePropsWarnings.length > 0) {
6794 var _uniqueNames = new Set();
6795 pendingComponentWillReceivePropsWarnings.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, '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);
6803
6804 pendingComponentWillReceivePropsWarnings = [];
6805 }
6806
6807 if (pendingComponentWillUpdateWarnings.length > 0) {
6808 var _uniqueNames2 = new Set();
6809 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
6810 _uniqueNames2.add(getComponentName(fiber) || 'Component');
6811 didWarnAboutDeprecatedLifecycles.add(fiber.type);
6812 });
6813
6814 var _sortedNames2 = Array.from(_uniqueNames2).sort().join(', ');
6815
6816 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);
6817
6818 pendingComponentWillUpdateWarnings = [];
6819 }
6820 };
6821
6822 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
6823 // Dedup strategy: Warn once per component.
6824 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
6825 return;
6826 }
6827
6828 // Don't warn about react-lifecycles-compat polyfilled components.
6829 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
6830 pendingComponentWillMountWarnings.push(fiber);
6831 }
6832 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
6833 pendingComponentWillReceivePropsWarnings.push(fiber);
6834 }
6835 if (typeof instance.componentWillUpdate === 'function') {
6836 pendingComponentWillUpdateWarnings.push(fiber);
6837 }
6838 };
6839
6840 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
6841 var strictRoot = getStrictRoot(fiber);
6842
6843 // Dedup strategy: Warn once per component.
6844 // This is difficult to track any other way since component names
6845 // are often vague and are likely to collide between 3rd party libraries.
6846 // An expand property is probably okay to use here since it's DEV-only,
6847 // and will only be set in the event of serious warnings.
6848 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
6849 return;
6850 }
6851
6852 // Don't warn about react-lifecycles-compat polyfilled components.
6853 // Note that it is sufficient to check for the presence of a
6854 // single lifecycle, componentWillMount, with the polyfill flag.
6855 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning === true) {
6856 return;
6857 }
6858
6859 var warningsForRoot = void 0;
6860 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
6861 warningsForRoot = {
6862 UNSAFE_componentWillMount: [],
6863 UNSAFE_componentWillReceiveProps: [],
6864 UNSAFE_componentWillUpdate: []
6865 };
6866
6867 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
6868 } else {
6869 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
6870 }
6871
6872 var unsafeLifecycles = [];
6873 if (typeof instance.componentWillMount === 'function' || typeof instance.UNSAFE_componentWillMount === 'function') {
6874 unsafeLifecycles.push('UNSAFE_componentWillMount');
6875 }
6876 if (typeof instance.componentWillReceiveProps === 'function' || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
6877 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
6878 }
6879 if (typeof instance.componentWillUpdate === 'function' || typeof instance.UNSAFE_componentWillUpdate === 'function') {
6880 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
6881 }
6882
6883 if (unsafeLifecycles.length > 0) {
6884 unsafeLifecycles.forEach(function (lifecycle) {
6885 warningsForRoot[lifecycle].push(fiber);
6886 });
6887 }
6888 };
6889}
6890
6891var didWarnUpdateInsideUpdate = void 0;
6892
6893{
6894 didWarnUpdateInsideUpdate = false;
6895}
6896
6897// Callbacks are not validated until invocation
6898
6899
6900// Singly linked-list of updates. When an update is scheduled, it is added to
6901// the queue of the current fiber and the work-in-progress fiber. The two queues
6902// are separate but they share a persistent structure.
6903//
6904// During reconciliation, updates are removed from the work-in-progress fiber,
6905// but they remain on the current fiber. That ensures that if a work-in-progress
6906// is aborted, the aborted updates are recovered by cloning from current.
6907//
6908// The work-in-progress queue is always a subset of the current queue.
6909//
6910// When the tree is committed, the work-in-progress becomes the current.
6911
6912
6913function createUpdateQueue(baseState) {
6914 var queue = {
6915 baseState: baseState,
6916 expirationTime: NoWork,
6917 first: null,
6918 last: null,
6919 callbackList: null,
6920 hasForceUpdate: false,
6921 isInitialized: false
6922 };
6923 {
6924 queue.isProcessing = false;
6925 }
6926 return queue;
6927}
6928
6929function insertUpdateIntoQueue(queue, update) {
6930 // Append the update to the end of the list.
6931 if (queue.last === null) {
6932 // Queue is empty
6933 queue.first = queue.last = update;
6934 } else {
6935 queue.last.next = update;
6936 queue.last = update;
6937 }
6938 if (queue.expirationTime === NoWork || queue.expirationTime > update.expirationTime) {
6939 queue.expirationTime = update.expirationTime;
6940 }
6941}
6942
6943function insertUpdateIntoFiber(fiber, update) {
6944 // We'll have at least one and at most two distinct update queues.
6945 var alternateFiber = fiber.alternate;
6946 var queue1 = fiber.updateQueue;
6947 if (queue1 === null) {
6948 // TODO: We don't know what the base state will be until we begin work.
6949 // It depends on which fiber is the next current. Initialize with an empty
6950 // base state, then set to the memoizedState when rendering. Not super
6951 // happy with this approach.
6952 queue1 = fiber.updateQueue = createUpdateQueue(null);
6953 }
6954
6955 var queue2 = void 0;
6956 if (alternateFiber !== null) {
6957 queue2 = alternateFiber.updateQueue;
6958 if (queue2 === null) {
6959 queue2 = alternateFiber.updateQueue = createUpdateQueue(null);
6960 }
6961 } else {
6962 queue2 = null;
6963 }
6964 queue2 = queue2 !== queue1 ? queue2 : null;
6965
6966 // Warn if an update is scheduled from inside an updater function.
6967 {
6968 if ((queue1.isProcessing || queue2 !== null && queue2.isProcessing) && !didWarnUpdateInsideUpdate) {
6969 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.');
6970 didWarnUpdateInsideUpdate = true;
6971 }
6972 }
6973
6974 // If there's only one queue, add the update to that queue and exit.
6975 if (queue2 === null) {
6976 insertUpdateIntoQueue(queue1, update);
6977 return;
6978 }
6979
6980 // If either queue is empty, we need to add to both queues.
6981 if (queue1.last === null || queue2.last === null) {
6982 insertUpdateIntoQueue(queue1, update);
6983 insertUpdateIntoQueue(queue2, update);
6984 return;
6985 }
6986
6987 // If both lists are not empty, the last update is the same for both lists
6988 // because of structural sharing. So, we should only append to one of
6989 // the lists.
6990 insertUpdateIntoQueue(queue1, update);
6991 // But we still need to update the `last` pointer of queue2.
6992 queue2.last = update;
6993}
6994
6995function getUpdateExpirationTime(fiber) {
6996 if (fiber.tag !== ClassComponent && fiber.tag !== HostRoot) {
6997 return NoWork;
6998 }
6999 var updateQueue = fiber.updateQueue;
7000 if (updateQueue === null) {
7001 return NoWork;
7002 }
7003 return updateQueue.expirationTime;
7004}
7005
7006function getStateFromUpdate(update, instance, prevState, props) {
7007 var partialState = update.partialState;
7008 if (typeof partialState === 'function') {
7009 return partialState.call(instance, prevState, props);
7010 } else {
7011 return partialState;
7012 }
7013}
7014
7015function processUpdateQueue(current, workInProgress, queue, instance, props, renderExpirationTime) {
7016 if (current !== null && current.updateQueue === queue) {
7017 // We need to create a work-in-progress queue, by cloning the current queue.
7018 var currentQueue = queue;
7019 queue = workInProgress.updateQueue = {
7020 baseState: currentQueue.baseState,
7021 expirationTime: currentQueue.expirationTime,
7022 first: currentQueue.first,
7023 last: currentQueue.last,
7024 isInitialized: currentQueue.isInitialized,
7025 // These fields are no longer valid because they were already committed.
7026 // Reset them.
7027 callbackList: null,
7028 hasForceUpdate: false
7029 };
7030 }
7031
7032 {
7033 // Set this flag so we can warn if setState is called inside the update
7034 // function of another setState.
7035 queue.isProcessing = true;
7036 }
7037
7038 // Reset the remaining expiration time. If we skip over any updates, we'll
7039 // increase this accordingly.
7040 queue.expirationTime = NoWork;
7041
7042 // TODO: We don't know what the base state will be until we begin work.
7043 // It depends on which fiber is the next current. Initialize with an empty
7044 // base state, then set to the memoizedState when rendering. Not super
7045 // happy with this approach.
7046 var state = void 0;
7047 if (queue.isInitialized) {
7048 state = queue.baseState;
7049 } else {
7050 state = queue.baseState = workInProgress.memoizedState;
7051 queue.isInitialized = true;
7052 }
7053 var dontMutatePrevState = true;
7054 var update = queue.first;
7055 var didSkip = false;
7056 while (update !== null) {
7057 var updateExpirationTime = update.expirationTime;
7058 if (updateExpirationTime > renderExpirationTime) {
7059 // This update does not have sufficient priority. Skip it.
7060 var remainingExpirationTime = queue.expirationTime;
7061 if (remainingExpirationTime === NoWork || remainingExpirationTime > updateExpirationTime) {
7062 // Update the remaining expiration time.
7063 queue.expirationTime = updateExpirationTime;
7064 }
7065 if (!didSkip) {
7066 didSkip = true;
7067 queue.baseState = state;
7068 }
7069 // Continue to the next update.
7070 update = update.next;
7071 continue;
7072 }
7073
7074 // This update does have sufficient priority.
7075
7076 // If no previous updates were skipped, drop this update from the queue by
7077 // advancing the head of the list.
7078 if (!didSkip) {
7079 queue.first = update.next;
7080 if (queue.first === null) {
7081 queue.last = null;
7082 }
7083 }
7084
7085 // Invoke setState callback an extra time to help detect side-effects.
7086 // Ignore the return value in this case.
7087 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7088 getStateFromUpdate(update, instance, state, props);
7089 }
7090
7091 // Process the update
7092 var _partialState = void 0;
7093 if (update.isReplace) {
7094 state = getStateFromUpdate(update, instance, state, props);
7095 dontMutatePrevState = true;
7096 } else {
7097 _partialState = getStateFromUpdate(update, instance, state, props);
7098 if (_partialState) {
7099 if (dontMutatePrevState) {
7100 // $FlowFixMe: Idk how to type this properly.
7101 state = _assign({}, state, _partialState);
7102 } else {
7103 state = _assign(state, _partialState);
7104 }
7105 dontMutatePrevState = false;
7106 }
7107 }
7108 if (update.isForced) {
7109 queue.hasForceUpdate = true;
7110 }
7111 if (update.callback !== null) {
7112 // Append to list of callbacks.
7113 var _callbackList = queue.callbackList;
7114 if (_callbackList === null) {
7115 _callbackList = queue.callbackList = [];
7116 }
7117 _callbackList.push(update);
7118 }
7119 update = update.next;
7120 }
7121
7122 if (queue.callbackList !== null) {
7123 workInProgress.effectTag |= Callback;
7124 } else if (queue.first === null && !queue.hasForceUpdate) {
7125 // The queue is empty. We can reset it.
7126 workInProgress.updateQueue = null;
7127 }
7128
7129 if (!didSkip) {
7130 didSkip = true;
7131 queue.baseState = state;
7132 }
7133
7134 {
7135 // No longer processing.
7136 queue.isProcessing = false;
7137 }
7138
7139 return state;
7140}
7141
7142function commitCallbacks(queue, context) {
7143 var callbackList = queue.callbackList;
7144 if (callbackList === null) {
7145 return;
7146 }
7147 // Set the list to null to make sure they don't get called more than once.
7148 queue.callbackList = null;
7149 for (var i = 0; i < callbackList.length; i++) {
7150 var update = callbackList[i];
7151 var _callback = update.callback;
7152 // This update might be processed again. Clear the callback so it's only
7153 // called once.
7154 update.callback = null;
7155 !(typeof _callback === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0;
7156 _callback.call(context);
7157 }
7158}
7159
7160var fakeInternalInstance = {};
7161var isArray = Array.isArray;
7162
7163var didWarnAboutStateAssignmentForComponent = void 0;
7164var didWarnAboutUndefinedDerivedState = void 0;
7165var didWarnAboutUninitializedState = void 0;
7166var didWarnAboutWillReceivePropsAndDerivedState = void 0;
7167var warnOnInvalidCallback$1 = void 0;
7168
7169{
7170 didWarnAboutStateAssignmentForComponent = {};
7171 didWarnAboutUndefinedDerivedState = {};
7172 didWarnAboutUninitializedState = {};
7173 didWarnAboutWillReceivePropsAndDerivedState = {};
7174
7175 var didWarnOnInvalidCallback = {};
7176
7177 warnOnInvalidCallback$1 = function (callback, callerName) {
7178 if (callback === null || typeof callback === 'function') {
7179 return;
7180 }
7181 var key = callerName + '_' + callback;
7182 if (!didWarnOnInvalidCallback[key]) {
7183 warning_1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
7184 didWarnOnInvalidCallback[key] = true;
7185 }
7186 };
7187
7188 // This is so gross but it's at least non-critical and can be removed if
7189 // it causes problems. This is meant to give a nicer error message for
7190 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
7191 // ...)) which otherwise throws a "_processChildContext is not a function"
7192 // exception.
7193 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
7194 enumerable: false,
7195 value: function () {
7196 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).');
7197 }
7198 });
7199 Object.freeze(fakeInternalInstance);
7200}
7201
7202var ReactFiberClassComponent = function (scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState) {
7203 // Class component state updater
7204 var updater = {
7205 isMounted: isMounted,
7206 enqueueSetState: function (instance, partialState, callback) {
7207 var fiber = get(instance);
7208 callback = callback === undefined ? null : callback;
7209 {
7210 warnOnInvalidCallback$1(callback, 'setState');
7211 }
7212 var expirationTime = computeExpirationForFiber(fiber);
7213 var update = {
7214 expirationTime: expirationTime,
7215 partialState: partialState,
7216 callback: callback,
7217 isReplace: false,
7218 isForced: false,
7219 nextCallback: null,
7220 next: null
7221 };
7222 insertUpdateIntoFiber(fiber, update);
7223 scheduleWork(fiber, expirationTime);
7224 },
7225 enqueueReplaceState: function (instance, state, callback) {
7226 var fiber = get(instance);
7227 callback = callback === undefined ? null : callback;
7228 {
7229 warnOnInvalidCallback$1(callback, 'replaceState');
7230 }
7231 var expirationTime = computeExpirationForFiber(fiber);
7232 var update = {
7233 expirationTime: expirationTime,
7234 partialState: state,
7235 callback: callback,
7236 isReplace: true,
7237 isForced: false,
7238 nextCallback: null,
7239 next: null
7240 };
7241 insertUpdateIntoFiber(fiber, update);
7242 scheduleWork(fiber, expirationTime);
7243 },
7244 enqueueForceUpdate: function (instance, callback) {
7245 var fiber = get(instance);
7246 callback = callback === undefined ? null : callback;
7247 {
7248 warnOnInvalidCallback$1(callback, 'forceUpdate');
7249 }
7250 var expirationTime = computeExpirationForFiber(fiber);
7251 var update = {
7252 expirationTime: expirationTime,
7253 partialState: null,
7254 callback: callback,
7255 isReplace: false,
7256 isForced: true,
7257 nextCallback: null,
7258 next: null
7259 };
7260 insertUpdateIntoFiber(fiber, update);
7261 scheduleWork(fiber, expirationTime);
7262 }
7263 };
7264
7265 function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
7266 if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) {
7267 // If the workInProgress already has an Update effect, return true
7268 return true;
7269 }
7270
7271 var instance = workInProgress.stateNode;
7272 var type = workInProgress.type;
7273 if (typeof instance.shouldComponentUpdate === 'function') {
7274 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
7275 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext);
7276 stopPhaseTimer();
7277
7278 {
7279 warning_1(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(workInProgress) || 'Unknown');
7280 }
7281
7282 return shouldUpdate;
7283 }
7284
7285 if (type.prototype && type.prototype.isPureReactComponent) {
7286 return !shallowEqual_1(oldProps, newProps) || !shallowEqual_1(oldState, newState);
7287 }
7288
7289 return true;
7290 }
7291
7292 function checkClassInstance(workInProgress) {
7293 var instance = workInProgress.stateNode;
7294 var type = workInProgress.type;
7295 {
7296 var name = getComponentName(workInProgress);
7297 var renderPresent = instance.render;
7298
7299 if (!renderPresent) {
7300 if (type.prototype && typeof type.prototype.render === 'function') {
7301 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
7302 } else {
7303 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
7304 }
7305 }
7306
7307 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
7308 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);
7309 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
7310 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);
7311 var noInstancePropTypes = !instance.propTypes;
7312 warning_1(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
7313 var noInstanceContextTypes = !instance.contextTypes;
7314 warning_1(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
7315 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
7316 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);
7317 if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
7318 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');
7319 }
7320 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
7321 warning_1(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
7322 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
7323 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);
7324 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
7325 warning_1(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
7326 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
7327 warning_1(noUnsafeComponentWillRecieveProps, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
7328 var hasMutatedProps = instance.props !== workInProgress.pendingProps;
7329 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);
7330 var noInstanceDefaultProps = !instance.defaultProps;
7331 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);
7332 }
7333
7334 var state = instance.state;
7335 if (state && (typeof state !== 'object' || isArray(state))) {
7336 warning_1(false, '%s.state: must be set to an object or null', getComponentName(workInProgress));
7337 }
7338 if (typeof instance.getChildContext === 'function') {
7339 warning_1(typeof workInProgress.type.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', getComponentName(workInProgress));
7340 }
7341 }
7342
7343 function resetInputPointers(workInProgress, instance) {
7344 instance.props = workInProgress.memoizedProps;
7345 instance.state = workInProgress.memoizedState;
7346 }
7347
7348 function adoptClassInstance(workInProgress, instance) {
7349 instance.updater = updater;
7350 workInProgress.stateNode = instance;
7351 // The instance needs access to the fiber so that it can schedule updates
7352 set(instance, workInProgress);
7353 {
7354 instance._reactInternalInstance = fakeInternalInstance;
7355 }
7356 }
7357
7358 function constructClassInstance(workInProgress, props) {
7359 var ctor = workInProgress.type;
7360 var unmaskedContext = getUnmaskedContext(workInProgress);
7361 var needsContext = isContextConsumer(workInProgress);
7362 var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject_1;
7363
7364 // Instantiate twice to help detect side-effects.
7365 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7366 new ctor(props, context); // eslint-disable-line no-new
7367 }
7368
7369 var instance = new ctor(props, context);
7370 var state = instance.state !== null && instance.state !== undefined ? instance.state : null;
7371 adoptClassInstance(workInProgress, instance);
7372
7373 {
7374 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
7375 var componentName = getComponentName(workInProgress) || 'Unknown';
7376 if (!didWarnAboutUninitializedState[componentName]) {
7377 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');
7378 didWarnAboutUninitializedState[componentName] = true;
7379 }
7380 }
7381 }
7382
7383 workInProgress.memoizedState = state;
7384
7385 var partialState = callGetDerivedStateFromProps(workInProgress, instance, props);
7386
7387 if (partialState !== null && partialState !== undefined) {
7388 // Render-phase updates (like this) should not be added to the update queue,
7389 // So that multiple render passes do not enqueue multiple updates.
7390 // Instead, just synchronously merge the returned state into the instance.
7391 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
7392 }
7393
7394 // Cache unmasked context so we can avoid recreating masked context unless necessary.
7395 // ReactFiberContext usually updates this cache but can't for newly-created instances.
7396 if (needsContext) {
7397 cacheContext(workInProgress, unmaskedContext, context);
7398 }
7399
7400 return instance;
7401 }
7402
7403 function callComponentWillMount(workInProgress, instance) {
7404 startPhaseTimer(workInProgress, 'componentWillMount');
7405 var oldState = instance.state;
7406
7407 if (typeof instance.componentWillMount === 'function') {
7408 instance.componentWillMount();
7409 }
7410 if (typeof instance.UNSAFE_componentWillMount === 'function') {
7411 instance.UNSAFE_componentWillMount();
7412 }
7413
7414 stopPhaseTimer();
7415
7416 if (oldState !== instance.state) {
7417 {
7418 warning_1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress));
7419 }
7420 updater.enqueueReplaceState(instance, instance.state, null);
7421 }
7422 }
7423
7424 function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) {
7425 var oldState = instance.state;
7426 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7427 if (typeof instance.componentWillReceiveProps === 'function') {
7428 instance.componentWillReceiveProps(newProps, newContext);
7429 }
7430 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
7431 instance.UNSAFE_componentWillReceiveProps(newProps, newContext);
7432 }
7433 stopPhaseTimer();
7434
7435 if (instance.state !== oldState) {
7436 {
7437 var componentName = getComponentName(workInProgress) || 'Component';
7438 if (!didWarnAboutStateAssignmentForComponent[componentName]) {
7439 warning_1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
7440 didWarnAboutStateAssignmentForComponent[componentName] = true;
7441 }
7442 }
7443 updater.enqueueReplaceState(instance, instance.state, null);
7444 }
7445 }
7446
7447 function callGetDerivedStateFromProps(workInProgress, instance, props) {
7448 var type = workInProgress.type;
7449
7450
7451 if (typeof type.getDerivedStateFromProps === 'function') {
7452 {
7453 // Don't warn about react-lifecycles-compat polyfilled components
7454 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
7455 var componentName = getComponentName(workInProgress) || 'Unknown';
7456 if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) {
7457 warning_1(false, '%s: Defines both componentWillReceiveProps() and static ' + 'getDerivedStateFromProps() methods. We recommend using ' + 'only getDerivedStateFromProps().', componentName);
7458 didWarnAboutWillReceivePropsAndDerivedState[componentName] = true;
7459 }
7460 }
7461 }
7462
7463 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7464 // Invoke method an extra time to help detect side-effects.
7465 type.getDerivedStateFromProps.call(null, props, workInProgress.memoizedState);
7466 }
7467
7468 var partialState = type.getDerivedStateFromProps.call(null, props, workInProgress.memoizedState);
7469
7470 {
7471 if (partialState === undefined) {
7472 var _componentName = getComponentName(workInProgress) || 'Unknown';
7473 if (!didWarnAboutUndefinedDerivedState[_componentName]) {
7474 warning_1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', _componentName);
7475 didWarnAboutUndefinedDerivedState[_componentName] = _componentName;
7476 }
7477 }
7478 }
7479
7480 return partialState;
7481 }
7482 }
7483
7484 // Invokes the mount life-cycles on a previously never rendered instance.
7485 function mountClassInstance(workInProgress, renderExpirationTime) {
7486 var current = workInProgress.alternate;
7487
7488 {
7489 checkClassInstance(workInProgress);
7490 }
7491
7492 var instance = workInProgress.stateNode;
7493 var props = workInProgress.pendingProps;
7494 var unmaskedContext = getUnmaskedContext(workInProgress);
7495
7496 instance.props = props;
7497 instance.state = workInProgress.memoizedState;
7498 instance.refs = emptyObject_1;
7499 instance.context = getMaskedContext(workInProgress, unmaskedContext);
7500
7501 {
7502 if (workInProgress.mode & StrictMode) {
7503 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
7504 }
7505
7506 if (warnAboutDeprecatedLifecycles) {
7507 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
7508 }
7509 }
7510
7511 // In order to support react-lifecycles-compat polyfilled components,
7512 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7513 if ((typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function') && typeof workInProgress.type.getDerivedStateFromProps !== 'function') {
7514 callComponentWillMount(workInProgress, instance);
7515 // If we had additional state updates during this life-cycle, let's
7516 // process them now.
7517 var updateQueue = workInProgress.updateQueue;
7518 if (updateQueue !== null) {
7519 instance.state = processUpdateQueue(current, workInProgress, updateQueue, instance, props, renderExpirationTime);
7520 }
7521 }
7522 if (typeof instance.componentDidMount === 'function') {
7523 workInProgress.effectTag |= Update;
7524 }
7525 }
7526
7527 // Called on a preexisting class instance. Returns false if a resumed render
7528 // could be reused.
7529 // function resumeMountClassInstance(
7530 // workInProgress: Fiber,
7531 // priorityLevel: PriorityLevel,
7532 // ): boolean {
7533 // const instance = workInProgress.stateNode;
7534 // resetInputPointers(workInProgress, instance);
7535
7536 // let newState = workInProgress.memoizedState;
7537 // let newProps = workInProgress.pendingProps;
7538 // if (!newProps) {
7539 // // If there isn't any new props, then we'll reuse the memoized props.
7540 // // This could be from already completed work.
7541 // newProps = workInProgress.memoizedProps;
7542 // invariant(
7543 // newProps != null,
7544 // 'There should always be pending or memoized props. This error is ' +
7545 // 'likely caused by a bug in React. Please file an issue.',
7546 // );
7547 // }
7548 // const newUnmaskedContext = getUnmaskedContext(workInProgress);
7549 // const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7550
7551 // const oldContext = instance.context;
7552 // const oldProps = workInProgress.memoizedProps;
7553
7554 // if (
7555 // typeof instance.componentWillReceiveProps === 'function' &&
7556 // (oldProps !== newProps || oldContext !== newContext)
7557 // ) {
7558 // callComponentWillReceiveProps(
7559 // workInProgress,
7560 // instance,
7561 // newProps,
7562 // newContext,
7563 // );
7564 // }
7565
7566 // // Process the update queue before calling shouldComponentUpdate
7567 // const updateQueue = workInProgress.updateQueue;
7568 // if (updateQueue !== null) {
7569 // newState = processUpdateQueue(
7570 // workInProgress,
7571 // updateQueue,
7572 // instance,
7573 // newState,
7574 // newProps,
7575 // priorityLevel,
7576 // );
7577 // }
7578
7579 // // TODO: Should we deal with a setState that happened after the last
7580 // // componentWillMount and before this componentWillMount? Probably
7581 // // unsupported anyway.
7582
7583 // if (
7584 // !checkShouldComponentUpdate(
7585 // workInProgress,
7586 // workInProgress.memoizedProps,
7587 // newProps,
7588 // workInProgress.memoizedState,
7589 // newState,
7590 // newContext,
7591 // )
7592 // ) {
7593 // // Update the existing instance's state, props, and context pointers even
7594 // // though we're bailing out.
7595 // instance.props = newProps;
7596 // instance.state = newState;
7597 // instance.context = newContext;
7598 // return false;
7599 // }
7600
7601 // // Update the input pointers now so that they are correct when we call
7602 // // componentWillMount
7603 // instance.props = newProps;
7604 // instance.state = newState;
7605 // instance.context = newContext;
7606
7607 // if (typeof instance.componentWillMount === 'function') {
7608 // callComponentWillMount(workInProgress, instance);
7609 // // componentWillMount may have called setState. Process the update queue.
7610 // const newUpdateQueue = workInProgress.updateQueue;
7611 // if (newUpdateQueue !== null) {
7612 // newState = processUpdateQueue(
7613 // workInProgress,
7614 // newUpdateQueue,
7615 // instance,
7616 // newState,
7617 // newProps,
7618 // priorityLevel,
7619 // );
7620 // }
7621 // }
7622
7623 // if (typeof instance.componentDidMount === 'function') {
7624 // workInProgress.effectTag |= Update;
7625 // }
7626
7627 // instance.state = newState;
7628
7629 // return true;
7630 // }
7631
7632 // Invokes the update life-cycles and returns false if it shouldn't rerender.
7633 function updateClassInstance(current, workInProgress, renderExpirationTime) {
7634 var instance = workInProgress.stateNode;
7635 resetInputPointers(workInProgress, instance);
7636
7637 var oldProps = workInProgress.memoizedProps;
7638 var newProps = workInProgress.pendingProps;
7639 var oldContext = instance.context;
7640 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7641 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7642
7643 // Note: During these life-cycles, instance.props/instance.state are what
7644 // ever the previously attempted to render - not the "current". However,
7645 // during componentDidUpdate we pass the "current" props.
7646
7647 // In order to support react-lifecycles-compat polyfilled components,
7648 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7649 if ((typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function') && typeof workInProgress.type.getDerivedStateFromProps !== 'function') {
7650 if (oldProps !== newProps || oldContext !== newContext) {
7651 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7652 }
7653 }
7654
7655 var partialState = void 0;
7656 if (oldProps !== newProps) {
7657 partialState = callGetDerivedStateFromProps(workInProgress, instance, newProps);
7658 }
7659
7660 // Compute the next state using the memoized state and the update queue.
7661 var oldState = workInProgress.memoizedState;
7662 // TODO: Previous state can be null.
7663 var newState = void 0;
7664 if (workInProgress.updateQueue !== null) {
7665 newState = processUpdateQueue(current, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7666 } else {
7667 newState = oldState;
7668 }
7669
7670 if (partialState !== null && partialState !== undefined) {
7671 // Render-phase updates (like this) should not be added to the update queue,
7672 // So that multiple render passes do not enqueue multiple updates.
7673 // Instead, just synchronously merge the returned state into the instance.
7674 newState = newState === null || newState === undefined ? partialState : _assign({}, newState, partialState);
7675 }
7676
7677 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7678 // If an update was already in progress, we should schedule an Update
7679 // effect even though we're bailing out, so that cWU/cDU are called.
7680 if (typeof instance.componentDidUpdate === 'function') {
7681 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7682 workInProgress.effectTag |= Update;
7683 }
7684 }
7685 return false;
7686 }
7687
7688 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7689
7690 if (shouldUpdate) {
7691 // In order to support react-lifecycles-compat polyfilled components,
7692 // Unsafe lifecycles should not be invoked for any component with the new gDSFP.
7693 if ((typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function') && typeof workInProgress.type.getDerivedStateFromProps !== 'function') {
7694 startPhaseTimer(workInProgress, 'componentWillUpdate');
7695 if (typeof instance.componentWillUpdate === 'function') {
7696 instance.componentWillUpdate(newProps, newState, newContext);
7697 }
7698 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
7699 instance.UNSAFE_componentWillUpdate(newProps, newState, newContext);
7700 }
7701 stopPhaseTimer();
7702 }
7703 if (typeof instance.componentDidUpdate === 'function') {
7704 workInProgress.effectTag |= Update;
7705 }
7706 } else {
7707 // If an update was already in progress, we should schedule an Update
7708 // effect even though we're bailing out, so that cWU/cDU are called.
7709 if (typeof instance.componentDidUpdate === 'function') {
7710 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7711 workInProgress.effectTag |= Update;
7712 }
7713 }
7714
7715 // If shouldComponentUpdate returned false, we should still update the
7716 // memoized props/state to indicate that this work can be reused.
7717 memoizeProps(workInProgress, newProps);
7718 memoizeState(workInProgress, newState);
7719 }
7720
7721 // Update the existing instance's state, props, and context pointers even
7722 // if shouldComponentUpdate returns false.
7723 instance.props = newProps;
7724 instance.state = newState;
7725 instance.context = newContext;
7726
7727 return shouldUpdate;
7728 }
7729
7730 return {
7731 adoptClassInstance: adoptClassInstance,
7732 callGetDerivedStateFromProps: callGetDerivedStateFromProps,
7733 constructClassInstance: constructClassInstance,
7734 mountClassInstance: mountClassInstance,
7735 // resumeMountClassInstance,
7736 updateClassInstance: updateClassInstance
7737 };
7738};
7739
7740var getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
7741
7742
7743var didWarnAboutMaps = void 0;
7744var didWarnAboutStringRefInStrictMode = void 0;
7745var ownerHasKeyUseWarning = void 0;
7746var ownerHasFunctionTypeWarning = void 0;
7747var warnForMissingKey = function (child) {};
7748
7749{
7750 didWarnAboutMaps = false;
7751 didWarnAboutStringRefInStrictMode = {};
7752
7753 /**
7754 * Warn if there's no key explicitly set on dynamic arrays of children or
7755 * object keys are not valid. This allows us to keep track of children between
7756 * updates.
7757 */
7758 ownerHasKeyUseWarning = {};
7759 ownerHasFunctionTypeWarning = {};
7760
7761 warnForMissingKey = function (child) {
7762 if (child === null || typeof child !== 'object') {
7763 return;
7764 }
7765 if (!child._store || child._store.validated || child.key != null) {
7766 return;
7767 }
7768 !(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;
7769 child._store.validated = true;
7770
7771 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() || '');
7772 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
7773 return;
7774 }
7775 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
7776
7777 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());
7778 };
7779}
7780
7781var isArray$1 = Array.isArray;
7782
7783function coerceRef(returnFiber, current, element) {
7784 var mixedRef = element.ref;
7785 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
7786 {
7787 if (returnFiber.mode & StrictMode) {
7788 var componentName = getComponentName(returnFiber) || 'Component';
7789 if (!didWarnAboutStringRefInStrictMode[componentName]) {
7790 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));
7791 didWarnAboutStringRefInStrictMode[componentName] = true;
7792 }
7793 }
7794 }
7795
7796 if (element._owner) {
7797 var owner = element._owner;
7798 var inst = void 0;
7799 if (owner) {
7800 var ownerFiber = owner;
7801 !(ownerFiber.tag === ClassComponent) ? invariant_1(false, 'Stateless function components cannot have refs.') : void 0;
7802 inst = ownerFiber.stateNode;
7803 }
7804 !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;
7805 var stringRef = '' + mixedRef;
7806 // Check if previous string ref matches new string ref
7807 if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
7808 return current.ref;
7809 }
7810 var ref = function (value) {
7811 var refs = inst.refs === emptyObject_1 ? inst.refs = {} : inst.refs;
7812 if (value === null) {
7813 delete refs[stringRef];
7814 } else {
7815 refs[stringRef] = value;
7816 }
7817 };
7818 ref._stringRef = stringRef;
7819 return ref;
7820 } else {
7821 !(typeof mixedRef === 'string') ? invariant_1(false, 'Expected ref to be a function or a string.') : void 0;
7822 !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;
7823 }
7824 }
7825 return mixedRef;
7826}
7827
7828function throwOnInvalidObjectType(returnFiber, newChild) {
7829 if (returnFiber.type !== 'textarea') {
7830 var addendum = '';
7831 {
7832 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$2() || '');
7833 }
7834 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);
7835 }
7836}
7837
7838function warnOnFunctionType() {
7839 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() || '');
7840
7841 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
7842 return;
7843 }
7844 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
7845
7846 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() || '');
7847}
7848
7849// This wrapper function exists because I expect to clone the code in each path
7850// to be able to optimize each path individually by branching early. This needs
7851// a compiler or we can do it manually. Helpers that don't need this branching
7852// live outside of this function.
7853function ChildReconciler(shouldTrackSideEffects) {
7854 function deleteChild(returnFiber, childToDelete) {
7855 if (!shouldTrackSideEffects) {
7856 // Noop.
7857 return;
7858 }
7859 // Deletions are added in reversed order so we add it to the front.
7860 // At this point, the return fiber's effect list is empty except for
7861 // deletions, so we can just append the deletion to the list. The remaining
7862 // effects aren't added until the complete phase. Once we implement
7863 // resuming, this may not be true.
7864 var last = returnFiber.lastEffect;
7865 if (last !== null) {
7866 last.nextEffect = childToDelete;
7867 returnFiber.lastEffect = childToDelete;
7868 } else {
7869 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7870 }
7871 childToDelete.nextEffect = null;
7872 childToDelete.effectTag = Deletion;
7873 }
7874
7875 function deleteRemainingChildren(returnFiber, currentFirstChild) {
7876 if (!shouldTrackSideEffects) {
7877 // Noop.
7878 return null;
7879 }
7880
7881 // TODO: For the shouldClone case, this could be micro-optimized a bit by
7882 // assuming that after the first child we've already added everything.
7883 var childToDelete = currentFirstChild;
7884 while (childToDelete !== null) {
7885 deleteChild(returnFiber, childToDelete);
7886 childToDelete = childToDelete.sibling;
7887 }
7888 return null;
7889 }
7890
7891 function mapRemainingChildren(returnFiber, currentFirstChild) {
7892 // Add the remaining children to a temporary map so that we can find them by
7893 // keys quickly. Implicit (null) keys get added to this set with their index
7894 var existingChildren = new Map();
7895
7896 var existingChild = currentFirstChild;
7897 while (existingChild !== null) {
7898 if (existingChild.key !== null) {
7899 existingChildren.set(existingChild.key, existingChild);
7900 } else {
7901 existingChildren.set(existingChild.index, existingChild);
7902 }
7903 existingChild = existingChild.sibling;
7904 }
7905 return existingChildren;
7906 }
7907
7908 function useFiber(fiber, pendingProps, expirationTime) {
7909 // We currently set sibling to null and index to 0 here because it is easy
7910 // to forget to do before returning it. E.g. for the single child case.
7911 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
7912 clone.index = 0;
7913 clone.sibling = null;
7914 return clone;
7915 }
7916
7917 function placeChild(newFiber, lastPlacedIndex, newIndex) {
7918 newFiber.index = newIndex;
7919 if (!shouldTrackSideEffects) {
7920 // Noop.
7921 return lastPlacedIndex;
7922 }
7923 var current = newFiber.alternate;
7924 if (current !== null) {
7925 var oldIndex = current.index;
7926 if (oldIndex < lastPlacedIndex) {
7927 // This is a move.
7928 newFiber.effectTag = Placement;
7929 return lastPlacedIndex;
7930 } else {
7931 // This item can stay in place.
7932 return oldIndex;
7933 }
7934 } else {
7935 // This is an insertion.
7936 newFiber.effectTag = Placement;
7937 return lastPlacedIndex;
7938 }
7939 }
7940
7941 function placeSingleChild(newFiber) {
7942 // This is simpler for the single child case. We only need to do a
7943 // placement for inserting new children.
7944 if (shouldTrackSideEffects && newFiber.alternate === null) {
7945 newFiber.effectTag = Placement;
7946 }
7947 return newFiber;
7948 }
7949
7950 function updateTextNode(returnFiber, current, textContent, expirationTime) {
7951 if (current === null || current.tag !== HostText) {
7952 // Insert
7953 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
7954 created['return'] = returnFiber;
7955 return created;
7956 } else {
7957 // Update
7958 var existing = useFiber(current, textContent, expirationTime);
7959 existing['return'] = returnFiber;
7960 return existing;
7961 }
7962 }
7963
7964 function updateElement(returnFiber, current, element, expirationTime) {
7965 if (current !== null && current.type === element.type) {
7966 // Move based on index
7967 var existing = useFiber(current, element.props, expirationTime);
7968 existing.ref = coerceRef(returnFiber, current, element);
7969 existing['return'] = returnFiber;
7970 {
7971 existing._debugSource = element._source;
7972 existing._debugOwner = element._owner;
7973 }
7974 return existing;
7975 } else {
7976 // Insert
7977 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
7978 created.ref = coerceRef(returnFiber, current, element);
7979 created['return'] = returnFiber;
7980 return created;
7981 }
7982 }
7983
7984 function updatePortal(returnFiber, current, portal, expirationTime) {
7985 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
7986 // Insert
7987 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
7988 created['return'] = returnFiber;
7989 return created;
7990 } else {
7991 // Update
7992 var existing = useFiber(current, portal.children || [], expirationTime);
7993 existing['return'] = returnFiber;
7994 return existing;
7995 }
7996 }
7997
7998 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
7999 if (current === null || current.tag !== Fragment) {
8000 // Insert
8001 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
8002 created['return'] = returnFiber;
8003 return created;
8004 } else {
8005 // Update
8006 var existing = useFiber(current, fragment, expirationTime);
8007 existing['return'] = returnFiber;
8008 return existing;
8009 }
8010 }
8011
8012 function createChild(returnFiber, newChild, expirationTime) {
8013 if (typeof newChild === 'string' || typeof newChild === 'number') {
8014 // Text nodes don't have keys. If the previous node is implicitly keyed
8015 // we can continue to replace it without aborting even if it is not a text
8016 // node.
8017 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
8018 created['return'] = returnFiber;
8019 return created;
8020 }
8021
8022 if (typeof newChild === 'object' && newChild !== null) {
8023 switch (newChild.$$typeof) {
8024 case REACT_ELEMENT_TYPE:
8025 {
8026 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
8027 _created.ref = coerceRef(returnFiber, null, newChild);
8028 _created['return'] = returnFiber;
8029 return _created;
8030 }
8031 case REACT_PORTAL_TYPE:
8032 {
8033 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
8034 _created2['return'] = returnFiber;
8035 return _created2;
8036 }
8037 }
8038
8039 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8040 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
8041 _created3['return'] = returnFiber;
8042 return _created3;
8043 }
8044
8045 throwOnInvalidObjectType(returnFiber, newChild);
8046 }
8047
8048 {
8049 if (typeof newChild === 'function') {
8050 warnOnFunctionType();
8051 }
8052 }
8053
8054 return null;
8055 }
8056
8057 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
8058 // Update the fiber if the keys match, otherwise return null.
8059
8060 var key = oldFiber !== null ? oldFiber.key : null;
8061
8062 if (typeof newChild === 'string' || typeof newChild === 'number') {
8063 // Text nodes don't have keys. If the previous node is implicitly keyed
8064 // we can continue to replace it without aborting even if it is not a text
8065 // node.
8066 if (key !== null) {
8067 return null;
8068 }
8069 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
8070 }
8071
8072 if (typeof newChild === 'object' && newChild !== null) {
8073 switch (newChild.$$typeof) {
8074 case REACT_ELEMENT_TYPE:
8075 {
8076 if (newChild.key === key) {
8077 if (newChild.type === REACT_FRAGMENT_TYPE) {
8078 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
8079 }
8080 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
8081 } else {
8082 return null;
8083 }
8084 }
8085 case REACT_PORTAL_TYPE:
8086 {
8087 if (newChild.key === key) {
8088 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
8089 } else {
8090 return null;
8091 }
8092 }
8093 }
8094
8095 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8096 if (key !== null) {
8097 return null;
8098 }
8099
8100 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
8101 }
8102
8103 throwOnInvalidObjectType(returnFiber, newChild);
8104 }
8105
8106 {
8107 if (typeof newChild === 'function') {
8108 warnOnFunctionType();
8109 }
8110 }
8111
8112 return null;
8113 }
8114
8115 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
8116 if (typeof newChild === 'string' || typeof newChild === 'number') {
8117 // Text nodes don't have keys, so we neither have to check the old nor
8118 // new node for the key. If both are text nodes, they match.
8119 var matchedFiber = existingChildren.get(newIdx) || null;
8120 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
8121 }
8122
8123 if (typeof newChild === 'object' && newChild !== null) {
8124 switch (newChild.$$typeof) {
8125 case REACT_ELEMENT_TYPE:
8126 {
8127 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
8128 if (newChild.type === REACT_FRAGMENT_TYPE) {
8129 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
8130 }
8131 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
8132 }
8133 case REACT_PORTAL_TYPE:
8134 {
8135 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
8136 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
8137 }
8138 }
8139
8140 if (isArray$1(newChild) || getIteratorFn(newChild)) {
8141 var _matchedFiber3 = existingChildren.get(newIdx) || null;
8142 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
8143 }
8144
8145 throwOnInvalidObjectType(returnFiber, newChild);
8146 }
8147
8148 {
8149 if (typeof newChild === 'function') {
8150 warnOnFunctionType();
8151 }
8152 }
8153
8154 return null;
8155 }
8156
8157 /**
8158 * Warns if there is a duplicate or missing key
8159 */
8160 function warnOnInvalidKey(child, knownKeys) {
8161 {
8162 if (typeof child !== 'object' || child === null) {
8163 return knownKeys;
8164 }
8165 switch (child.$$typeof) {
8166 case REACT_ELEMENT_TYPE:
8167 case REACT_PORTAL_TYPE:
8168 warnForMissingKey(child);
8169 var key = child.key;
8170 if (typeof key !== 'string') {
8171 break;
8172 }
8173 if (knownKeys === null) {
8174 knownKeys = new Set();
8175 knownKeys.add(key);
8176 break;
8177 }
8178 if (!knownKeys.has(key)) {
8179 knownKeys.add(key);
8180 break;
8181 }
8182 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());
8183 break;
8184 default:
8185 break;
8186 }
8187 }
8188 return knownKeys;
8189 }
8190
8191 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
8192 // This algorithm can't optimize by searching from boths ends since we
8193 // don't have backpointers on fibers. I'm trying to see how far we can get
8194 // with that model. If it ends up not being worth the tradeoffs, we can
8195 // add it later.
8196
8197 // Even with a two ended optimization, we'd want to optimize for the case
8198 // where there are few changes and brute force the comparison instead of
8199 // going for the Map. It'd like to explore hitting that path first in
8200 // forward-only mode and only go for the Map once we notice that we need
8201 // lots of look ahead. This doesn't handle reversal as well as two ended
8202 // search but that's unusual. Besides, for the two ended optimization to
8203 // work on Iterables, we'd need to copy the whole set.
8204
8205 // In this first iteration, we'll just live with hitting the bad case
8206 // (adding everything to a Map) in for every insert/move.
8207
8208 // If you change this code, also update reconcileChildrenIterator() which
8209 // uses the same algorithm.
8210
8211 {
8212 // First, validate keys.
8213 var knownKeys = null;
8214 for (var i = 0; i < newChildren.length; i++) {
8215 var child = newChildren[i];
8216 knownKeys = warnOnInvalidKey(child, knownKeys);
8217 }
8218 }
8219
8220 var resultingFirstChild = null;
8221 var previousNewFiber = null;
8222
8223 var oldFiber = currentFirstChild;
8224 var lastPlacedIndex = 0;
8225 var newIdx = 0;
8226 var nextOldFiber = null;
8227 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
8228 if (oldFiber.index > newIdx) {
8229 nextOldFiber = oldFiber;
8230 oldFiber = null;
8231 } else {
8232 nextOldFiber = oldFiber.sibling;
8233 }
8234 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
8235 if (newFiber === null) {
8236 // TODO: This breaks on empty slots like null children. That's
8237 // unfortunate because it triggers the slow path all the time. We need
8238 // a better way to communicate whether this was a miss or null,
8239 // boolean, undefined, etc.
8240 if (oldFiber === null) {
8241 oldFiber = nextOldFiber;
8242 }
8243 break;
8244 }
8245 if (shouldTrackSideEffects) {
8246 if (oldFiber && newFiber.alternate === null) {
8247 // We matched the slot, but we didn't reuse the existing fiber, so we
8248 // need to delete the existing child.
8249 deleteChild(returnFiber, oldFiber);
8250 }
8251 }
8252 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8253 if (previousNewFiber === null) {
8254 // TODO: Move out of the loop. This only happens for the first run.
8255 resultingFirstChild = newFiber;
8256 } else {
8257 // TODO: Defer siblings if we're not at the right index for this slot.
8258 // I.e. if we had null values before, then we want to defer this
8259 // for each null value. However, we also don't want to call updateSlot
8260 // with the previous one.
8261 previousNewFiber.sibling = newFiber;
8262 }
8263 previousNewFiber = newFiber;
8264 oldFiber = nextOldFiber;
8265 }
8266
8267 if (newIdx === newChildren.length) {
8268 // We've reached the end of the new children. We can delete the rest.
8269 deleteRemainingChildren(returnFiber, oldFiber);
8270 return resultingFirstChild;
8271 }
8272
8273 if (oldFiber === null) {
8274 // If we don't have any more existing children we can choose a fast path
8275 // since the rest will all be insertions.
8276 for (; newIdx < newChildren.length; newIdx++) {
8277 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
8278 if (!_newFiber) {
8279 continue;
8280 }
8281 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
8282 if (previousNewFiber === null) {
8283 // TODO: Move out of the loop. This only happens for the first run.
8284 resultingFirstChild = _newFiber;
8285 } else {
8286 previousNewFiber.sibling = _newFiber;
8287 }
8288 previousNewFiber = _newFiber;
8289 }
8290 return resultingFirstChild;
8291 }
8292
8293 // Add all children to a key map for quick lookups.
8294 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8295
8296 // Keep scanning and use the map to restore deleted items as moves.
8297 for (; newIdx < newChildren.length; newIdx++) {
8298 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
8299 if (_newFiber2) {
8300 if (shouldTrackSideEffects) {
8301 if (_newFiber2.alternate !== null) {
8302 // The new fiber is a work in progress, but if there exists a
8303 // current, that means that we reused the fiber. We need to delete
8304 // it from the child list so that we don't add it to the deletion
8305 // list.
8306 existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key);
8307 }
8308 }
8309 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
8310 if (previousNewFiber === null) {
8311 resultingFirstChild = _newFiber2;
8312 } else {
8313 previousNewFiber.sibling = _newFiber2;
8314 }
8315 previousNewFiber = _newFiber2;
8316 }
8317 }
8318
8319 if (shouldTrackSideEffects) {
8320 // Any existing children that weren't consumed above were deleted. We need
8321 // to add them to the deletion list.
8322 existingChildren.forEach(function (child) {
8323 return deleteChild(returnFiber, child);
8324 });
8325 }
8326
8327 return resultingFirstChild;
8328 }
8329
8330 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
8331 // This is the same implementation as reconcileChildrenArray(),
8332 // but using the iterator instead.
8333
8334 var iteratorFn = getIteratorFn(newChildrenIterable);
8335 !(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;
8336
8337 {
8338 // Warn about using Maps as children
8339 if (typeof newChildrenIterable.entries === 'function') {
8340 var possibleMap = newChildrenIterable;
8341 if (possibleMap.entries === iteratorFn) {
8342 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());
8343 didWarnAboutMaps = true;
8344 }
8345 }
8346
8347 // First, validate keys.
8348 // We'll get a different iterator later for the main pass.
8349 var _newChildren = iteratorFn.call(newChildrenIterable);
8350 if (_newChildren) {
8351 var knownKeys = null;
8352 var _step = _newChildren.next();
8353 for (; !_step.done; _step = _newChildren.next()) {
8354 var child = _step.value;
8355 knownKeys = warnOnInvalidKey(child, knownKeys);
8356 }
8357 }
8358 }
8359
8360 var newChildren = iteratorFn.call(newChildrenIterable);
8361 !(newChildren != null) ? invariant_1(false, 'An iterable object provided no iterator.') : void 0;
8362
8363 var resultingFirstChild = null;
8364 var previousNewFiber = null;
8365
8366 var oldFiber = currentFirstChild;
8367 var lastPlacedIndex = 0;
8368 var newIdx = 0;
8369 var nextOldFiber = null;
8370
8371 var step = newChildren.next();
8372 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
8373 if (oldFiber.index > newIdx) {
8374 nextOldFiber = oldFiber;
8375 oldFiber = null;
8376 } else {
8377 nextOldFiber = oldFiber.sibling;
8378 }
8379 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
8380 if (newFiber === null) {
8381 // TODO: This breaks on empty slots like null children. That's
8382 // unfortunate because it triggers the slow path all the time. We need
8383 // a better way to communicate whether this was a miss or null,
8384 // boolean, undefined, etc.
8385 if (!oldFiber) {
8386 oldFiber = nextOldFiber;
8387 }
8388 break;
8389 }
8390 if (shouldTrackSideEffects) {
8391 if (oldFiber && newFiber.alternate === null) {
8392 // We matched the slot, but we didn't reuse the existing fiber, so we
8393 // need to delete the existing child.
8394 deleteChild(returnFiber, oldFiber);
8395 }
8396 }
8397 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8398 if (previousNewFiber === null) {
8399 // TODO: Move out of the loop. This only happens for the first run.
8400 resultingFirstChild = newFiber;
8401 } else {
8402 // TODO: Defer siblings if we're not at the right index for this slot.
8403 // I.e. if we had null values before, then we want to defer this
8404 // for each null value. However, we also don't want to call updateSlot
8405 // with the previous one.
8406 previousNewFiber.sibling = newFiber;
8407 }
8408 previousNewFiber = newFiber;
8409 oldFiber = nextOldFiber;
8410 }
8411
8412 if (step.done) {
8413 // We've reached the end of the new children. We can delete the rest.
8414 deleteRemainingChildren(returnFiber, oldFiber);
8415 return resultingFirstChild;
8416 }
8417
8418 if (oldFiber === null) {
8419 // If we don't have any more existing children we can choose a fast path
8420 // since the rest will all be insertions.
8421 for (; !step.done; newIdx++, step = newChildren.next()) {
8422 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
8423 if (_newFiber3 === null) {
8424 continue;
8425 }
8426 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
8427 if (previousNewFiber === null) {
8428 // TODO: Move out of the loop. This only happens for the first run.
8429 resultingFirstChild = _newFiber3;
8430 } else {
8431 previousNewFiber.sibling = _newFiber3;
8432 }
8433 previousNewFiber = _newFiber3;
8434 }
8435 return resultingFirstChild;
8436 }
8437
8438 // Add all children to a key map for quick lookups.
8439 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8440
8441 // Keep scanning and use the map to restore deleted items as moves.
8442 for (; !step.done; newIdx++, step = newChildren.next()) {
8443 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
8444 if (_newFiber4 !== null) {
8445 if (shouldTrackSideEffects) {
8446 if (_newFiber4.alternate !== null) {
8447 // The new fiber is a work in progress, but if there exists a
8448 // current, that means that we reused the fiber. We need to delete
8449 // it from the child list so that we don't add it to the deletion
8450 // list.
8451 existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key);
8452 }
8453 }
8454 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
8455 if (previousNewFiber === null) {
8456 resultingFirstChild = _newFiber4;
8457 } else {
8458 previousNewFiber.sibling = _newFiber4;
8459 }
8460 previousNewFiber = _newFiber4;
8461 }
8462 }
8463
8464 if (shouldTrackSideEffects) {
8465 // Any existing children that weren't consumed above were deleted. We need
8466 // to add them to the deletion list.
8467 existingChildren.forEach(function (child) {
8468 return deleteChild(returnFiber, child);
8469 });
8470 }
8471
8472 return resultingFirstChild;
8473 }
8474
8475 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
8476 // There's no need to check for keys on text nodes since we don't have a
8477 // way to define them.
8478 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
8479 // We already have an existing node so let's just update it and delete
8480 // the rest.
8481 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
8482 var existing = useFiber(currentFirstChild, textContent, expirationTime);
8483 existing['return'] = returnFiber;
8484 return existing;
8485 }
8486 // The existing first child is not a text node so we need to create one
8487 // and delete the existing ones.
8488 deleteRemainingChildren(returnFiber, currentFirstChild);
8489 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
8490 created['return'] = returnFiber;
8491 return created;
8492 }
8493
8494 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
8495 var key = element.key;
8496 var child = currentFirstChild;
8497 while (child !== null) {
8498 // TODO: If key === null and child.key === null, then this only applies to
8499 // the first item in the list.
8500 if (child.key === key) {
8501 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) {
8502 deleteRemainingChildren(returnFiber, child.sibling);
8503 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
8504 existing.ref = coerceRef(returnFiber, child, element);
8505 existing['return'] = returnFiber;
8506 {
8507 existing._debugSource = element._source;
8508 existing._debugOwner = element._owner;
8509 }
8510 return existing;
8511 } else {
8512 deleteRemainingChildren(returnFiber, child);
8513 break;
8514 }
8515 } else {
8516 deleteChild(returnFiber, child);
8517 }
8518 child = child.sibling;
8519 }
8520
8521 if (element.type === REACT_FRAGMENT_TYPE) {
8522 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
8523 created['return'] = returnFiber;
8524 return created;
8525 } else {
8526 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
8527 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
8528 _created4['return'] = returnFiber;
8529 return _created4;
8530 }
8531 }
8532
8533 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
8534 var key = portal.key;
8535 var child = currentFirstChild;
8536 while (child !== null) {
8537 // TODO: If key === null and child.key === null, then this only applies to
8538 // the first item in the list.
8539 if (child.key === key) {
8540 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
8541 deleteRemainingChildren(returnFiber, child.sibling);
8542 var existing = useFiber(child, portal.children || [], expirationTime);
8543 existing['return'] = returnFiber;
8544 return existing;
8545 } else {
8546 deleteRemainingChildren(returnFiber, child);
8547 break;
8548 }
8549 } else {
8550 deleteChild(returnFiber, child);
8551 }
8552 child = child.sibling;
8553 }
8554
8555 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
8556 created['return'] = returnFiber;
8557 return created;
8558 }
8559
8560 // This API will tag the children with the side-effect of the reconciliation
8561 // itself. They will be added to the side-effect list as we pass through the
8562 // children and the parent.
8563 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
8564 // This function is not recursive.
8565 // If the top level item is an array, we treat it as a set of children,
8566 // not as a fragment. Nested arrays on the other hand will be treated as
8567 // fragment nodes. Recursion happens at the normal flow.
8568
8569 // Handle top level unkeyed fragments as if they were arrays.
8570 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
8571 // We treat the ambiguous cases above the same.
8572 if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
8573 newChild = newChild.props.children;
8574 }
8575
8576 // Handle object types
8577 var isObject = typeof newChild === 'object' && newChild !== null;
8578
8579 if (isObject) {
8580 switch (newChild.$$typeof) {
8581 case REACT_ELEMENT_TYPE:
8582 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
8583 case REACT_PORTAL_TYPE:
8584 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
8585 }
8586 }
8587
8588 if (typeof newChild === 'string' || typeof newChild === 'number') {
8589 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
8590 }
8591
8592 if (isArray$1(newChild)) {
8593 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
8594 }
8595
8596 if (getIteratorFn(newChild)) {
8597 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
8598 }
8599
8600 if (isObject) {
8601 throwOnInvalidObjectType(returnFiber, newChild);
8602 }
8603
8604 {
8605 if (typeof newChild === 'function') {
8606 warnOnFunctionType();
8607 }
8608 }
8609 if (typeof newChild === 'undefined') {
8610 // If the new child is undefined, and the return fiber is a composite
8611 // component, throw an error. If Fiber return types are disabled,
8612 // we already threw above.
8613 switch (returnFiber.tag) {
8614 case ClassComponent:
8615 {
8616 {
8617 var instance = returnFiber.stateNode;
8618 if (instance.render._isMockFunction) {
8619 // We allow auto-mocks to proceed as if they're returning null.
8620 break;
8621 }
8622 }
8623 }
8624 // Intentionally fall through to the next case, which handles both
8625 // functions and classes
8626 // eslint-disable-next-lined no-fallthrough
8627 case FunctionalComponent:
8628 {
8629 var Component = returnFiber.type;
8630 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');
8631 }
8632 }
8633 }
8634
8635 // Remaining cases are all treated as empty.
8636 return deleteRemainingChildren(returnFiber, currentFirstChild);
8637 }
8638
8639 return reconcileChildFibers;
8640}
8641
8642var reconcileChildFibers = ChildReconciler(true);
8643var mountChildFibers = ChildReconciler(false);
8644
8645function cloneChildFibers(current, workInProgress) {
8646 !(current === null || workInProgress.child === current.child) ? invariant_1(false, 'Resuming work not yet implemented.') : void 0;
8647
8648 if (workInProgress.child === null) {
8649 return;
8650 }
8651
8652 var currentChild = workInProgress.child;
8653 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8654 workInProgress.child = newChild;
8655
8656 newChild['return'] = workInProgress;
8657 while (currentChild.sibling !== null) {
8658 currentChild = currentChild.sibling;
8659 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8660 newChild['return'] = workInProgress;
8661 }
8662 newChild.sibling = null;
8663}
8664
8665var changedBitsStack = [];
8666var currentValueStack = [];
8667var stack = [];
8668var index$1 = -1;
8669
8670var rendererSigil = void 0;
8671{
8672 // Use this to detect multiple renderers using the same context
8673 rendererSigil = {};
8674}
8675
8676function pushProvider(providerFiber) {
8677 var context = providerFiber.type.context;
8678 index$1 += 1;
8679 changedBitsStack[index$1] = context.changedBits;
8680 currentValueStack[index$1] = context.currentValue;
8681 stack[index$1] = providerFiber;
8682 context.currentValue = providerFiber.pendingProps.value;
8683 context.changedBits = providerFiber.stateNode;
8684
8685 {
8686 warning_1(context._currentRenderer === null || context._currentRenderer === rendererSigil, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
8687 context._currentRenderer = rendererSigil;
8688 }
8689}
8690
8691function popProvider(providerFiber) {
8692 {
8693 warning_1(index$1 > -1 && providerFiber === stack[index$1], 'Unexpected pop.');
8694 }
8695 var changedBits = changedBitsStack[index$1];
8696 var currentValue = currentValueStack[index$1];
8697 changedBitsStack[index$1] = null;
8698 currentValueStack[index$1] = null;
8699 stack[index$1] = null;
8700 index$1 -= 1;
8701 var context = providerFiber.type.context;
8702 context.currentValue = currentValue;
8703 context.changedBits = changedBits;
8704}
8705
8706function resetProviderStack() {
8707 for (var i = index$1; i > -1; i--) {
8708 var providerFiber = stack[i];
8709 var context = providerFiber.type.context;
8710 context.currentValue = context.defaultValue;
8711 context.changedBits = 0;
8712 changedBitsStack[i] = null;
8713 currentValueStack[i] = null;
8714 stack[i] = null;
8715 {
8716 context._currentRenderer = null;
8717 }
8718 }
8719 index$1 = -1;
8720}
8721
8722var didWarnAboutBadClass = void 0;
8723var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0;
8724var didWarnAboutStatelessRefs = void 0;
8725
8726{
8727 didWarnAboutBadClass = {};
8728 didWarnAboutGetDerivedStateOnFunctionalComponent = {};
8729 didWarnAboutStatelessRefs = {};
8730}
8731
8732var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber) {
8733 var shouldSetTextContent = config.shouldSetTextContent,
8734 shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree;
8735 var pushHostContext = hostContext.pushHostContext,
8736 pushHostContainer = hostContext.pushHostContainer;
8737 var enterHydrationState = hydrationContext.enterHydrationState,
8738 resetHydrationState = hydrationContext.resetHydrationState,
8739 tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance;
8740
8741 var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState),
8742 adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance,
8743 callGetDerivedStateFromProps = _ReactFiberClassCompo.callGetDerivedStateFromProps,
8744 constructClassInstance = _ReactFiberClassCompo.constructClassInstance,
8745 mountClassInstance = _ReactFiberClassCompo.mountClassInstance,
8746 updateClassInstance = _ReactFiberClassCompo.updateClassInstance;
8747
8748 // TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
8749
8750
8751 function reconcileChildren(current, workInProgress, nextChildren) {
8752 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, workInProgress.expirationTime);
8753 }
8754
8755 function reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime) {
8756 if (current === null) {
8757 // If this is a fresh new component that hasn't been rendered yet, we
8758 // won't update its child set by applying minimal side-effects. Instead,
8759 // we will add them all to the child before it gets rendered. That means
8760 // we can optimize this reconciliation pass by not tracking side-effects.
8761 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8762 } else {
8763 // If the current child is the same as the work in progress, it means that
8764 // we haven't yet started any work on these children. Therefore, we use
8765 // the clone algorithm to create a copy of all the current children.
8766
8767 // If we had any progressed work already, that is invalid at this point so
8768 // let's throw it out.
8769 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8770 }
8771 }
8772
8773 function updateFragment(current, workInProgress) {
8774 var nextChildren = workInProgress.pendingProps;
8775 if (hasContextChanged()) {
8776 // Normally we can bail out on props equality but if context has changed
8777 // we don't do the bailout and we have to reuse existing props instead.
8778 } else if (workInProgress.memoizedProps === nextChildren) {
8779 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8780 }
8781 reconcileChildren(current, workInProgress, nextChildren);
8782 memoizeProps(workInProgress, nextChildren);
8783 return workInProgress.child;
8784 }
8785
8786 function updateMode(current, workInProgress) {
8787 var nextChildren = workInProgress.pendingProps.children;
8788 if (hasContextChanged()) {
8789 // Normally we can bail out on props equality but if context has changed
8790 // we don't do the bailout and we have to reuse existing props instead.
8791 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
8792 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8793 }
8794 reconcileChildren(current, workInProgress, nextChildren);
8795 memoizeProps(workInProgress, nextChildren);
8796 return workInProgress.child;
8797 }
8798
8799 function markRef(current, workInProgress) {
8800 var ref = workInProgress.ref;
8801 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8802 // Schedule a Ref effect
8803 workInProgress.effectTag |= Ref;
8804 }
8805 }
8806
8807 function updateFunctionalComponent(current, workInProgress) {
8808 var fn = workInProgress.type;
8809 var nextProps = workInProgress.pendingProps;
8810
8811 if (hasContextChanged()) {
8812 // Normally we can bail out on props equality but if context has changed
8813 // we don't do the bailout and we have to reuse existing props instead.
8814 } else {
8815 if (workInProgress.memoizedProps === nextProps) {
8816 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8817 }
8818 // TODO: consider bringing fn.shouldComponentUpdate() back.
8819 // It used to be here.
8820 }
8821
8822 var unmaskedContext = getUnmaskedContext(workInProgress);
8823 var context = getMaskedContext(workInProgress, unmaskedContext);
8824
8825 var nextChildren = void 0;
8826
8827 {
8828 ReactCurrentOwner.current = workInProgress;
8829 ReactDebugCurrentFiber.setCurrentPhase('render');
8830 nextChildren = fn(nextProps, context);
8831 ReactDebugCurrentFiber.setCurrentPhase(null);
8832 }
8833 // React DevTools reads this flag.
8834 workInProgress.effectTag |= PerformedWork;
8835 reconcileChildren(current, workInProgress, nextChildren);
8836 memoizeProps(workInProgress, nextProps);
8837 return workInProgress.child;
8838 }
8839
8840 function updateClassComponent(current, workInProgress, renderExpirationTime) {
8841 // Push context providers early to prevent context stack mismatches.
8842 // During mounting we don't know the child context yet as the instance doesn't exist.
8843 // We will invalidate the child context in finishClassComponent() right after rendering.
8844 var hasContext = pushContextProvider(workInProgress);
8845
8846 var shouldUpdate = void 0;
8847 if (current === null) {
8848 if (!workInProgress.stateNode) {
8849 // In the initial pass we might need to construct the instance.
8850 constructClassInstance(workInProgress, workInProgress.pendingProps);
8851 mountClassInstance(workInProgress, renderExpirationTime);
8852
8853 shouldUpdate = true;
8854 } else {
8855 invariant_1(false, 'Resuming work not yet implemented.');
8856 // In a resume, we'll already have an instance we can reuse.
8857 // shouldUpdate = resumeMountClassInstance(workInProgress, renderExpirationTime);
8858 }
8859 } else {
8860 shouldUpdate = updateClassInstance(current, workInProgress, renderExpirationTime);
8861 }
8862 return finishClassComponent(current, workInProgress, shouldUpdate, hasContext);
8863 }
8864
8865 function finishClassComponent(current, workInProgress, shouldUpdate, hasContext) {
8866 // Refs should update even if shouldComponentUpdate returns false
8867 markRef(current, workInProgress);
8868
8869 if (!shouldUpdate) {
8870 // Context providers should defer to sCU for rendering
8871 if (hasContext) {
8872 invalidateContextProvider(workInProgress, false);
8873 }
8874
8875 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8876 }
8877
8878 var instance = workInProgress.stateNode;
8879
8880 // Rerender
8881 ReactCurrentOwner.current = workInProgress;
8882 var nextChildren = void 0;
8883 {
8884 ReactDebugCurrentFiber.setCurrentPhase('render');
8885 nextChildren = instance.render();
8886 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8887 instance.render();
8888 }
8889 ReactDebugCurrentFiber.setCurrentPhase(null);
8890 }
8891 // React DevTools reads this flag.
8892 workInProgress.effectTag |= PerformedWork;
8893 reconcileChildren(current, workInProgress, nextChildren);
8894 // Memoize props and state using the values we just used to render.
8895 // TODO: Restructure so we never read values from the instance.
8896 memoizeState(workInProgress, instance.state);
8897 memoizeProps(workInProgress, instance.props);
8898
8899 // The context might have changed so we need to recalculate it.
8900 if (hasContext) {
8901 invalidateContextProvider(workInProgress, true);
8902 }
8903
8904 return workInProgress.child;
8905 }
8906
8907 function pushHostRootContext(workInProgress) {
8908 var root = workInProgress.stateNode;
8909 if (root.pendingContext) {
8910 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8911 } else if (root.context) {
8912 // Should always be set
8913 pushTopLevelContextObject(workInProgress, root.context, false);
8914 }
8915 pushHostContainer(workInProgress, root.containerInfo);
8916 }
8917
8918 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8919 pushHostRootContext(workInProgress);
8920 var updateQueue = workInProgress.updateQueue;
8921 if (updateQueue !== null) {
8922 var prevState = workInProgress.memoizedState;
8923 var state = processUpdateQueue(current, workInProgress, updateQueue, null, null, renderExpirationTime);
8924 if (prevState === state) {
8925 // If the state is the same as before, that's a bailout because we had
8926 // no work that expires at this time.
8927 resetHydrationState();
8928 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8929 }
8930 var element = state.element;
8931 var root = workInProgress.stateNode;
8932 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
8933 // If we don't have any current children this might be the first pass.
8934 // We always try to hydrate. If this isn't a hydration pass there won't
8935 // be any children to hydrate which is effectively the same thing as
8936 // not hydrating.
8937
8938 // This is a bit of a hack. We track the host root as a placement to
8939 // know that we're currently in a mounting state. That way isMounted
8940 // works as expected. We must reset this before committing.
8941 // TODO: Delete this when we delete isMounted and findDOMNode.
8942 workInProgress.effectTag |= Placement;
8943
8944 // Ensure that children mount into this root without tracking
8945 // side-effects. This ensures that we don't store Placement effects on
8946 // nodes that will be hydrated.
8947 workInProgress.child = mountChildFibers(workInProgress, null, element, renderExpirationTime);
8948 } else {
8949 // Otherwise reset hydration state in case we aborted and resumed another
8950 // root.
8951 resetHydrationState();
8952 reconcileChildren(current, workInProgress, element);
8953 }
8954 memoizeState(workInProgress, state);
8955 return workInProgress.child;
8956 }
8957 resetHydrationState();
8958 // If there is no update queue, that's a bailout because the root has no props.
8959 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8960 }
8961
8962 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8963 pushHostContext(workInProgress);
8964
8965 if (current === null) {
8966 tryToClaimNextHydratableInstance(workInProgress);
8967 }
8968
8969 var type = workInProgress.type;
8970 var memoizedProps = workInProgress.memoizedProps;
8971 var nextProps = workInProgress.pendingProps;
8972 var prevProps = current !== null ? current.memoizedProps : null;
8973
8974 if (hasContextChanged()) {
8975 // Normally we can bail out on props equality but if context has changed
8976 // we don't do the bailout and we have to reuse existing props instead.
8977 } else if (memoizedProps === nextProps) {
8978 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8979 }
8980
8981 var nextChildren = nextProps.children;
8982 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8983
8984 if (isDirectTextChild) {
8985 // We special case a direct text child of a host node. This is a common
8986 // case. We won't handle it as a reified child. We will instead handle
8987 // this in the host environment that also have access to this prop. That
8988 // avoids allocating another HostText fiber and traversing it.
8989 nextChildren = null;
8990 } else if (prevProps && shouldSetTextContent(type, prevProps)) {
8991 // If we're switching from a direct text child to a normal child, or to
8992 // empty, we need to schedule the text content to be reset.
8993 workInProgress.effectTag |= ContentReset;
8994 }
8995
8996 markRef(current, workInProgress);
8997
8998 // Check the host config to see if the children are offscreen/hidden.
8999 if (renderExpirationTime !== Never && workInProgress.mode & AsyncMode && shouldDeprioritizeSubtree(type, nextProps)) {
9000 // Down-prioritize the children.
9001 workInProgress.expirationTime = Never;
9002 // Bailout and come back to this fiber later.
9003 return null;
9004 }
9005
9006 reconcileChildren(current, workInProgress, nextChildren);
9007 memoizeProps(workInProgress, nextProps);
9008 return workInProgress.child;
9009 }
9010
9011 function updateHostText(current, workInProgress) {
9012 if (current === null) {
9013 tryToClaimNextHydratableInstance(workInProgress);
9014 }
9015 var nextProps = workInProgress.pendingProps;
9016 memoizeProps(workInProgress, nextProps);
9017 // Nothing to do here. This is terminal. We'll do the completion step
9018 // immediately after.
9019 return null;
9020 }
9021
9022 function mountIndeterminateComponent(current, workInProgress, renderExpirationTime) {
9023 !(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;
9024 var fn = workInProgress.type;
9025 var props = workInProgress.pendingProps;
9026 var unmaskedContext = getUnmaskedContext(workInProgress);
9027 var context = getMaskedContext(workInProgress, unmaskedContext);
9028
9029 var value = void 0;
9030
9031 {
9032 if (fn.prototype && typeof fn.prototype.render === 'function') {
9033 var componentName = getComponentName(workInProgress) || 'Unknown';
9034
9035 if (!didWarnAboutBadClass[componentName]) {
9036 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);
9037 didWarnAboutBadClass[componentName] = true;
9038 }
9039 }
9040 ReactCurrentOwner.current = workInProgress;
9041 value = fn(props, context);
9042 }
9043 // React DevTools reads this flag.
9044 workInProgress.effectTag |= PerformedWork;
9045
9046 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9047 var Component = workInProgress.type;
9048
9049 // Proceed under the assumption that this is a class instance
9050 workInProgress.tag = ClassComponent;
9051
9052 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
9053
9054 if (typeof Component.getDerivedStateFromProps === 'function') {
9055 var partialState = callGetDerivedStateFromProps(workInProgress, value, props);
9056
9057 if (partialState !== null && partialState !== undefined) {
9058 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
9059 }
9060 }
9061
9062 // Push context providers early to prevent context stack mismatches.
9063 // During mounting we don't know the child context yet as the instance doesn't exist.
9064 // We will invalidate the child context in finishClassComponent() right after rendering.
9065 var hasContext = pushContextProvider(workInProgress);
9066 adoptClassInstance(workInProgress, value);
9067 mountClassInstance(workInProgress, renderExpirationTime);
9068 return finishClassComponent(current, workInProgress, true, hasContext);
9069 } else {
9070 // Proceed under the assumption that this is a functional component
9071 workInProgress.tag = FunctionalComponent;
9072 {
9073 var _Component = workInProgress.type;
9074
9075 if (_Component) {
9076 warning_1(!_Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', _Component.displayName || _Component.name || 'Component');
9077 }
9078 if (workInProgress.ref !== null) {
9079 var info = '';
9080 var ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
9081 if (ownerName) {
9082 info += '\n\nCheck the render method of `' + ownerName + '`.';
9083 }
9084
9085 var warningKey = ownerName || workInProgress._debugID || '';
9086 var debugSource = workInProgress._debugSource;
9087 if (debugSource) {
9088 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
9089 }
9090 if (!didWarnAboutStatelessRefs[warningKey]) {
9091 didWarnAboutStatelessRefs[warningKey] = true;
9092 warning_1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber.getCurrentFiberStackAddendum());
9093 }
9094 }
9095
9096 if (typeof fn.getDerivedStateFromProps === 'function') {
9097 var _componentName = getComponentName(workInProgress) || 'Unknown';
9098
9099 if (!didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName]) {
9100 warning_1(false, '%s: Stateless functional components do not support getDerivedStateFromProps.', _componentName);
9101 didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName] = true;
9102 }
9103 }
9104 }
9105 reconcileChildren(current, workInProgress, value);
9106 memoizeProps(workInProgress, props);
9107 return workInProgress.child;
9108 }
9109 }
9110
9111 function updateCallComponent(current, workInProgress, renderExpirationTime) {
9112 var nextProps = workInProgress.pendingProps;
9113 if (hasContextChanged()) {
9114 // Normally we can bail out on props equality but if context has changed
9115 // we don't do the bailout and we have to reuse existing props instead.
9116 } else if (workInProgress.memoizedProps === nextProps) {
9117 nextProps = workInProgress.memoizedProps;
9118 // TODO: When bailing out, we might need to return the stateNode instead
9119 // of the child. To check it for work.
9120 // return bailoutOnAlreadyFinishedWork(current, workInProgress);
9121 }
9122
9123 var nextChildren = nextProps.children;
9124
9125 // The following is a fork of reconcileChildrenAtExpirationTime but using
9126 // stateNode to store the child.
9127 if (current === null) {
9128 workInProgress.stateNode = mountChildFibers(workInProgress, workInProgress.stateNode, nextChildren, renderExpirationTime);
9129 } else {
9130 workInProgress.stateNode = reconcileChildFibers(workInProgress, current.stateNode, nextChildren, renderExpirationTime);
9131 }
9132
9133 memoizeProps(workInProgress, nextProps);
9134 // This doesn't take arbitrary time so we could synchronously just begin
9135 // eagerly do the work of workInProgress.child as an optimization.
9136 return workInProgress.stateNode;
9137 }
9138
9139 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
9140 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9141 var nextChildren = workInProgress.pendingProps;
9142 if (hasContextChanged()) {
9143 // Normally we can bail out on props equality but if context has changed
9144 // we don't do the bailout and we have to reuse existing props instead.
9145 } else if (workInProgress.memoizedProps === nextChildren) {
9146 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9147 }
9148
9149 if (current === null) {
9150 // Portals are special because we don't append the children during mount
9151 // but at commit. Therefore we need to track insertions which the normal
9152 // flow doesn't do during mount. This doesn't happen at the root because
9153 // the root always starts with a "current" with a null child.
9154 // TODO: Consider unifying this with how the root works.
9155 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9156 memoizeProps(workInProgress, nextChildren);
9157 } else {
9158 reconcileChildren(current, workInProgress, nextChildren);
9159 memoizeProps(workInProgress, nextChildren);
9160 }
9161 return workInProgress.child;
9162 }
9163
9164 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
9165 var fiber = workInProgress.child;
9166 while (fiber !== null) {
9167 var nextFiber = void 0;
9168 // Visit this fiber.
9169 switch (fiber.tag) {
9170 case ContextConsumer:
9171 // Check if the context matches.
9172 var observedBits = fiber.stateNode | 0;
9173 if (fiber.type === context && (observedBits & changedBits) !== 0) {
9174 // Update the expiration time of all the ancestors, including
9175 // the alternates.
9176 var node = fiber;
9177 while (node !== null) {
9178 var alternate = node.alternate;
9179 if (node.expirationTime === NoWork || node.expirationTime > renderExpirationTime) {
9180 node.expirationTime = renderExpirationTime;
9181 if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > renderExpirationTime)) {
9182 alternate.expirationTime = renderExpirationTime;
9183 }
9184 } else if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > renderExpirationTime)) {
9185 alternate.expirationTime = renderExpirationTime;
9186 } else {
9187 // Neither alternate was updated, which means the rest of the
9188 // ancestor path already has sufficient priority.
9189 break;
9190 }
9191 node = node['return'];
9192 }
9193 // Don't scan deeper than a matching consumer. When we render the
9194 // consumer, we'll continue scanning from that point. This way the
9195 // scanning work is time-sliced.
9196 nextFiber = null;
9197 } else {
9198 // Traverse down.
9199 nextFiber = fiber.child;
9200 }
9201 break;
9202 case ContextProvider:
9203 // Don't scan deeper if this is a matching provider
9204 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
9205 break;
9206 default:
9207 // Traverse down.
9208 nextFiber = fiber.child;
9209 break;
9210 }
9211 if (nextFiber !== null) {
9212 // Set the return pointer of the child to the work-in-progress fiber.
9213 nextFiber['return'] = fiber;
9214 } else {
9215 // No child. Traverse to next sibling.
9216 nextFiber = fiber;
9217 while (nextFiber !== null) {
9218 if (nextFiber === workInProgress) {
9219 // We're back to the root of this subtree. Exit.
9220 nextFiber = null;
9221 break;
9222 }
9223 var sibling = nextFiber.sibling;
9224 if (sibling !== null) {
9225 nextFiber = sibling;
9226 break;
9227 }
9228 // No more siblings. Traverse up.
9229 nextFiber = nextFiber['return'];
9230 }
9231 }
9232 fiber = nextFiber;
9233 }
9234 }
9235
9236 function updateContextProvider(current, workInProgress, renderExpirationTime) {
9237 var providerType = workInProgress.type;
9238 var context = providerType.context;
9239
9240 var newProps = workInProgress.pendingProps;
9241 var oldProps = workInProgress.memoizedProps;
9242
9243 if (hasContextChanged()) {
9244 // Normally we can bail out on props equality but if context has changed
9245 // we don't do the bailout and we have to reuse existing props instead.
9246 } else if (oldProps === newProps) {
9247 workInProgress.stateNode = 0;
9248 pushProvider(workInProgress);
9249 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9250 }
9251 workInProgress.memoizedProps = newProps;
9252
9253 var newValue = newProps.value;
9254
9255 var changedBits = void 0;
9256 if (oldProps === null) {
9257 // Initial render
9258 changedBits = MAX_SIGNED_31_BIT_INT;
9259 } else {
9260 var oldValue = oldProps.value;
9261 // Use Object.is to compare the new context value to the old value.
9262 // Inlined Object.is polyfill.
9263 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9264 if (oldValue === newValue && (oldValue !== 0 || 1 / oldValue === 1 / newValue) || oldValue !== oldValue && newValue !== newValue // eslint-disable-line no-self-compare
9265 ) {
9266 // No change.
9267 changedBits = 0;
9268 } else {
9269 changedBits = typeof context.calculateChangedBits === 'function' ? context.calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
9270 {
9271 warning_1((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
9272 }
9273 changedBits |= 0;
9274
9275 if (changedBits !== 0) {
9276 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9277 }
9278 }
9279 }
9280
9281 workInProgress.stateNode = changedBits;
9282 pushProvider(workInProgress);
9283
9284 if (oldProps !== null && oldProps.children === newProps.children) {
9285 return bailoutOnAlreadyFinishedWork(current, workInProgress);
9286 }
9287 var newChildren = newProps.children;
9288 reconcileChildren(current, workInProgress, newChildren);
9289 return workInProgress.child;
9290 }
9291
9292 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
9293 var context = workInProgress.type;
9294 var newProps = workInProgress.pendingProps;
9295
9296 var newValue = context.currentValue;
9297 var changedBits = context.changedBits;
9298
9299 if (changedBits !== 0) {
9300 // Context change propagation stops at matching consumers, for time-
9301 // slicing. Continue the propagation here.
9302 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9303 }
9304
9305 // Store the observedBits on the fiber's stateNode for quick access.
9306 var observedBits = newProps.observedBits;
9307 if (observedBits === undefined || observedBits === null) {
9308 // Subscribe to all changes by default
9309 observedBits = MAX_SIGNED_31_BIT_INT;
9310 }
9311 workInProgress.stateNode = observedBits;
9312
9313 var render = newProps.children;
9314 var newChildren = render(newValue);
9315 reconcileChildren(current, workInProgress, newChildren);
9316 return workInProgress.child;
9317 }
9318
9319 /*
9320 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
9321 let child = firstChild;
9322 do {
9323 // Ensure that the first and last effect of the parent corresponds
9324 // to the children's first and last effect.
9325 if (!returnFiber.firstEffect) {
9326 returnFiber.firstEffect = child.firstEffect;
9327 }
9328 if (child.lastEffect) {
9329 if (returnFiber.lastEffect) {
9330 returnFiber.lastEffect.nextEffect = child.firstEffect;
9331 }
9332 returnFiber.lastEffect = child.lastEffect;
9333 }
9334 } while (child = child.sibling);
9335 }
9336 */
9337
9338 function bailoutOnAlreadyFinishedWork(current, workInProgress) {
9339 cancelWorkTimer(workInProgress);
9340
9341 // TODO: We should ideally be able to bail out early if the children have no
9342 // more work to do. However, since we don't have a separation of this
9343 // Fiber's priority and its children yet - we don't know without doing lots
9344 // of the same work we do anyway. Once we have that separation we can just
9345 // bail out here if the children has no more work at this priority level.
9346 // if (workInProgress.priorityOfChildren <= priorityLevel) {
9347 // // If there are side-effects in these children that have not yet been
9348 // // committed we need to ensure that they get properly transferred up.
9349 // if (current && current.child !== workInProgress.child) {
9350 // reuseChildrenEffects(workInProgress, child);
9351 // }
9352 // return null;
9353 // }
9354
9355 cloneChildFibers(current, workInProgress);
9356 return workInProgress.child;
9357 }
9358
9359 function bailoutOnLowPriority(current, workInProgress) {
9360 cancelWorkTimer(workInProgress);
9361
9362 // TODO: Handle HostComponent tags here as well and call pushHostContext()?
9363 // See PR 8590 discussion for context
9364 switch (workInProgress.tag) {
9365 case HostRoot:
9366 pushHostRootContext(workInProgress);
9367 break;
9368 case ClassComponent:
9369 pushContextProvider(workInProgress);
9370 break;
9371 case HostPortal:
9372 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9373 break;
9374 case ContextProvider:
9375 pushProvider(workInProgress);
9376 break;
9377 }
9378 // TODO: What if this is currently in progress?
9379 // How can that happen? How is this not being cloned?
9380 return null;
9381 }
9382
9383 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead
9384 function memoizeProps(workInProgress, nextProps) {
9385 workInProgress.memoizedProps = nextProps;
9386 }
9387
9388 function memoizeState(workInProgress, nextState) {
9389 workInProgress.memoizedState = nextState;
9390 // Don't reset the updateQueue, in case there are pending updates. Resetting
9391 // is handled by processUpdateQueue.
9392 }
9393
9394 function beginWork(current, workInProgress, renderExpirationTime) {
9395 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
9396 return bailoutOnLowPriority(current, workInProgress);
9397 }
9398
9399 switch (workInProgress.tag) {
9400 case IndeterminateComponent:
9401 return mountIndeterminateComponent(current, workInProgress, renderExpirationTime);
9402 case FunctionalComponent:
9403 return updateFunctionalComponent(current, workInProgress);
9404 case ClassComponent:
9405 return updateClassComponent(current, workInProgress, renderExpirationTime);
9406 case HostRoot:
9407 return updateHostRoot(current, workInProgress, renderExpirationTime);
9408 case HostComponent:
9409 return updateHostComponent(current, workInProgress, renderExpirationTime);
9410 case HostText:
9411 return updateHostText(current, workInProgress);
9412 case CallHandlerPhase:
9413 // This is a restart. Reset the tag to the initial phase.
9414 workInProgress.tag = CallComponent;
9415 // Intentionally fall through since this is now the same.
9416 case CallComponent:
9417 return updateCallComponent(current, workInProgress, renderExpirationTime);
9418 case ReturnComponent:
9419 // A return component is just a placeholder, we can just run through the
9420 // next one immediately.
9421 return null;
9422 case HostPortal:
9423 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9424 case Fragment:
9425 return updateFragment(current, workInProgress);
9426 case Mode:
9427 return updateMode(current, workInProgress);
9428 case ContextProvider:
9429 return updateContextProvider(current, workInProgress, renderExpirationTime);
9430 case ContextConsumer:
9431 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9432 default:
9433 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9434 }
9435 }
9436
9437 function beginFailedWork(current, workInProgress, renderExpirationTime) {
9438 // Push context providers here to avoid a push/pop context mismatch.
9439 switch (workInProgress.tag) {
9440 case ClassComponent:
9441 pushContextProvider(workInProgress);
9442 break;
9443 case HostRoot:
9444 pushHostRootContext(workInProgress);
9445 break;
9446 default:
9447 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
9448 }
9449
9450 // Add an error effect so we can handle the error during the commit phase
9451 workInProgress.effectTag |= Err;
9452
9453 // This is a weird case where we do "resume" work ? work that failed on
9454 // our first attempt. Because we no longer have a notion of "progressed
9455 // deletions," reset the child to the current child to make sure we delete
9456 // it again. TODO: Find a better way to handle this, perhaps during a more
9457 // general overhaul of error handling.
9458 if (current === null) {
9459 workInProgress.child = null;
9460 } else if (workInProgress.child !== current.child) {
9461 workInProgress.child = current.child;
9462 }
9463
9464 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
9465 return bailoutOnLowPriority(current, workInProgress);
9466 }
9467
9468 // If we don't bail out, we're going be recomputing our children so we need
9469 // to drop our effect list.
9470 workInProgress.firstEffect = null;
9471 workInProgress.lastEffect = null;
9472
9473 // Unmount the current children as if the component rendered null
9474 var nextChildren = null;
9475 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime);
9476
9477 if (workInProgress.tag === ClassComponent) {
9478 var instance = workInProgress.stateNode;
9479 workInProgress.memoizedProps = instance.props;
9480 workInProgress.memoizedState = instance.state;
9481 }
9482
9483 return workInProgress.child;
9484 }
9485
9486 return {
9487 beginWork: beginWork,
9488 beginFailedWork: beginFailedWork
9489 };
9490};
9491
9492var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) {
9493 var createInstance = config.createInstance,
9494 createTextInstance = config.createTextInstance,
9495 appendInitialChild = config.appendInitialChild,
9496 finalizeInitialChildren = config.finalizeInitialChildren,
9497 prepareUpdate = config.prepareUpdate,
9498 mutation = config.mutation,
9499 persistence = config.persistence;
9500 var getRootHostContainer = hostContext.getRootHostContainer,
9501 popHostContext = hostContext.popHostContext,
9502 getHostContext = hostContext.getHostContext,
9503 popHostContainer = hostContext.popHostContainer;
9504 var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance,
9505 prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance,
9506 popHydrationState = hydrationContext.popHydrationState;
9507
9508
9509 function markUpdate(workInProgress) {
9510 // Tag the fiber with an update effect. This turns a Placement into
9511 // an UpdateAndPlacement.
9512 workInProgress.effectTag |= Update;
9513 }
9514
9515 function markRef(workInProgress) {
9516 workInProgress.effectTag |= Ref;
9517 }
9518
9519 function appendAllReturns(returns, workInProgress) {
9520 var node = workInProgress.stateNode;
9521 if (node) {
9522 node['return'] = workInProgress;
9523 }
9524 while (node !== null) {
9525 if (node.tag === HostComponent || node.tag === HostText || node.tag === HostPortal) {
9526 invariant_1(false, 'A call cannot have host component children.');
9527 } else if (node.tag === ReturnComponent) {
9528 returns.push(node.pendingProps.value);
9529 } else if (node.child !== null) {
9530 node.child['return'] = node;
9531 node = node.child;
9532 continue;
9533 }
9534 while (node.sibling === null) {
9535 if (node['return'] === null || node['return'] === workInProgress) {
9536 return;
9537 }
9538 node = node['return'];
9539 }
9540 node.sibling['return'] = node['return'];
9541 node = node.sibling;
9542 }
9543 }
9544
9545 function moveCallToHandlerPhase(current, workInProgress, renderExpirationTime) {
9546 var props = workInProgress.memoizedProps;
9547 !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;
9548
9549 // First step of the call has completed. Now we need to do the second.
9550 // TODO: It would be nice to have a multi stage call represented by a
9551 // single component, or at least tail call optimize nested ones. Currently
9552 // that requires additional fields that we don't want to add to the fiber.
9553 // So this requires nested handlers.
9554 // Note: This doesn't mutate the alternate node. I don't think it needs to
9555 // since this stage is reset for every pass.
9556 workInProgress.tag = CallHandlerPhase;
9557
9558 // Build up the returns.
9559 // TODO: Compare this to a generator or opaque helpers like Children.
9560 var returns = [];
9561 appendAllReturns(returns, workInProgress);
9562 var fn = props.handler;
9563 var childProps = props.props;
9564 var nextChildren = fn(childProps, returns);
9565
9566 var currentFirstChild = current !== null ? current.child : null;
9567 workInProgress.child = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, renderExpirationTime);
9568 return workInProgress.child;
9569 }
9570
9571 function appendAllChildren(parent, workInProgress) {
9572 // We only have the top Fiber that was created but we need recurse down its
9573 // children to find all the terminal nodes.
9574 var node = workInProgress.child;
9575 while (node !== null) {
9576 if (node.tag === HostComponent || node.tag === HostText) {
9577 appendInitialChild(parent, node.stateNode);
9578 } else if (node.tag === HostPortal) {
9579 // If we have a portal child, then we don't want to traverse
9580 // down its children. Instead, we'll get insertions from each child in
9581 // the portal directly.
9582 } else if (node.child !== null) {
9583 node.child['return'] = node;
9584 node = node.child;
9585 continue;
9586 }
9587 if (node === workInProgress) {
9588 return;
9589 }
9590 while (node.sibling === null) {
9591 if (node['return'] === null || node['return'] === workInProgress) {
9592 return;
9593 }
9594 node = node['return'];
9595 }
9596 node.sibling['return'] = node['return'];
9597 node = node.sibling;
9598 }
9599 }
9600
9601 var updateHostContainer = void 0;
9602 var updateHostComponent = void 0;
9603 var updateHostText = void 0;
9604 if (mutation) {
9605 if (enableMutatingReconciler) {
9606 // Mutation mode
9607 updateHostContainer = function (workInProgress) {
9608 // Noop
9609 };
9610 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9611 // TODO: Type this specific to this type of component.
9612 workInProgress.updateQueue = updatePayload;
9613 // If the update payload indicates that there is a change or if there
9614 // is a new ref we mark this as an update. All the work is done in commitWork.
9615 if (updatePayload) {
9616 markUpdate(workInProgress);
9617 }
9618 };
9619 updateHostText = function (current, workInProgress, oldText, newText) {
9620 // If the text differs, mark it as an update. All the work in done in commitWork.
9621 if (oldText !== newText) {
9622 markUpdate(workInProgress);
9623 }
9624 };
9625 } else {
9626 invariant_1(false, 'Mutating reconciler is disabled.');
9627 }
9628 } else if (persistence) {
9629 if (enablePersistentReconciler) {
9630 // Persistent host tree mode
9631 var cloneInstance = persistence.cloneInstance,
9632 createContainerChildSet = persistence.createContainerChildSet,
9633 appendChildToContainerChildSet = persistence.appendChildToContainerChildSet,
9634 finalizeContainerChildren = persistence.finalizeContainerChildren;
9635
9636 // An unfortunate fork of appendAllChildren because we have two different parent types.
9637
9638 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) {
9639 // We only have the top Fiber that was created but we need recurse down its
9640 // children to find all the terminal nodes.
9641 var node = workInProgress.child;
9642 while (node !== null) {
9643 if (node.tag === HostComponent || node.tag === HostText) {
9644 appendChildToContainerChildSet(containerChildSet, node.stateNode);
9645 } else if (node.tag === HostPortal) {
9646 // If we have a portal child, then we don't want to traverse
9647 // down its children. Instead, we'll get insertions from each child in
9648 // the portal directly.
9649 } else if (node.child !== null) {
9650 node.child['return'] = node;
9651 node = node.child;
9652 continue;
9653 }
9654 if (node === workInProgress) {
9655 return;
9656 }
9657 while (node.sibling === null) {
9658 if (node['return'] === null || node['return'] === workInProgress) {
9659 return;
9660 }
9661 node = node['return'];
9662 }
9663 node.sibling['return'] = node['return'];
9664 node = node.sibling;
9665 }
9666 };
9667 updateHostContainer = function (workInProgress) {
9668 var portalOrRoot = workInProgress.stateNode;
9669 var childrenUnchanged = workInProgress.firstEffect === null;
9670 if (childrenUnchanged) {
9671 // No changes, just reuse the existing instance.
9672 } else {
9673 var container = portalOrRoot.containerInfo;
9674 var newChildSet = createContainerChildSet(container);
9675 if (finalizeContainerChildren(container, newChildSet)) {
9676 markUpdate(workInProgress);
9677 }
9678 portalOrRoot.pendingChildren = newChildSet;
9679 // If children might have changed, we have to add them all to the set.
9680 appendAllChildrenToContainer(newChildSet, workInProgress);
9681 // Schedule an update on the container to swap out the container.
9682 markUpdate(workInProgress);
9683 }
9684 };
9685 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9686 // If there are no effects associated with this node, then none of our children had any updates.
9687 // This guarantees that we can reuse all of them.
9688 var childrenUnchanged = workInProgress.firstEffect === null;
9689 var currentInstance = current.stateNode;
9690 if (childrenUnchanged && updatePayload === null) {
9691 // No changes, just reuse the existing instance.
9692 // Note that this might release a previous clone.
9693 workInProgress.stateNode = currentInstance;
9694 } else {
9695 var recyclableInstance = workInProgress.stateNode;
9696 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9697 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9698 markUpdate(workInProgress);
9699 }
9700 workInProgress.stateNode = newInstance;
9701 if (childrenUnchanged) {
9702 // If there are no other effects in this tree, we need to flag this node as having one.
9703 // Even though we're not going to use it for anything.
9704 // Otherwise parents won't know that there are new children to propagate upwards.
9705 markUpdate(workInProgress);
9706 } else {
9707 // If children might have changed, we have to add them all to the set.
9708 appendAllChildren(newInstance, workInProgress);
9709 }
9710 }
9711 };
9712 updateHostText = function (current, workInProgress, oldText, newText) {
9713 if (oldText !== newText) {
9714 // If the text content differs, we'll create a new text instance for it.
9715 var rootContainerInstance = getRootHostContainer();
9716 var currentHostContext = getHostContext();
9717 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9718 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9719 // This lets the parents know that at least one of their children has changed.
9720 markUpdate(workInProgress);
9721 }
9722 };
9723 } else {
9724 invariant_1(false, 'Persistent reconciler is disabled.');
9725 }
9726 } else {
9727 if (enableNoopReconciler) {
9728 // No host operations
9729 updateHostContainer = function (workInProgress) {
9730 // Noop
9731 };
9732 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9733 // Noop
9734 };
9735 updateHostText = function (current, workInProgress, oldText, newText) {
9736 // Noop
9737 };
9738 } else {
9739 invariant_1(false, 'Noop reconciler is disabled.');
9740 }
9741 }
9742
9743 function completeWork(current, workInProgress, renderExpirationTime) {
9744 var newProps = workInProgress.pendingProps;
9745 switch (workInProgress.tag) {
9746 case FunctionalComponent:
9747 return null;
9748 case ClassComponent:
9749 {
9750 // We are leaving this subtree, so pop context if any.
9751 popContextProvider(workInProgress);
9752 return null;
9753 }
9754 case HostRoot:
9755 {
9756 popHostContainer(workInProgress);
9757 popTopLevelContextObject(workInProgress);
9758 var fiberRoot = workInProgress.stateNode;
9759 if (fiberRoot.pendingContext) {
9760 fiberRoot.context = fiberRoot.pendingContext;
9761 fiberRoot.pendingContext = null;
9762 }
9763
9764 if (current === null || current.child === null) {
9765 // If we hydrated, pop so that we can delete any remaining children
9766 // that weren't hydrated.
9767 popHydrationState(workInProgress);
9768 // This resets the hacky state to fix isMounted before committing.
9769 // TODO: Delete this when we delete isMounted and findDOMNode.
9770 workInProgress.effectTag &= ~Placement;
9771 }
9772 updateHostContainer(workInProgress);
9773 return null;
9774 }
9775 case HostComponent:
9776 {
9777 popHostContext(workInProgress);
9778 var rootContainerInstance = getRootHostContainer();
9779 var type = workInProgress.type;
9780 if (current !== null && workInProgress.stateNode != null) {
9781 // If we have an alternate, that means this is an update and we need to
9782 // schedule a side-effect to do the updates.
9783 var oldProps = current.memoizedProps;
9784 // If we get updated because one of our children updated, we don't
9785 // have newProps so we'll have to reuse them.
9786 // TODO: Split the update API as separate for the props vs. children.
9787 // Even better would be if children weren't special cased at all tho.
9788 var instance = workInProgress.stateNode;
9789 var currentHostContext = getHostContext();
9790 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9791
9792 updateHostComponent(current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9793
9794 if (current.ref !== workInProgress.ref) {
9795 markRef(workInProgress);
9796 }
9797 } else {
9798 if (!newProps) {
9799 !(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;
9800 // This can happen when we abort work.
9801 return null;
9802 }
9803
9804 var _currentHostContext = getHostContext();
9805 // TODO: Move createInstance to beginWork and keep it on a context
9806 // "stack" as the parent. Then append children as we go in beginWork
9807 // or completeWork depending on we want to add then top->down or
9808 // bottom->up. Top->down is faster in IE11.
9809 var wasHydrated = popHydrationState(workInProgress);
9810 if (wasHydrated) {
9811 // TODO: Move this and createInstance step into the beginPhase
9812 // to consolidate.
9813 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) {
9814 // If changes to the hydrated node needs to be applied at the
9815 // commit-phase we mark this as such.
9816 markUpdate(workInProgress);
9817 }
9818 } else {
9819 var _instance = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress);
9820
9821 appendAllChildren(_instance, workInProgress);
9822
9823 // Certain renderers require commit-time effects for initial mount.
9824 // (eg DOM renderer supports auto-focus for certain elements).
9825 // Make sure such renderers get scheduled for later work.
9826 if (finalizeInitialChildren(_instance, type, newProps, rootContainerInstance, _currentHostContext)) {
9827 markUpdate(workInProgress);
9828 }
9829 workInProgress.stateNode = _instance;
9830 }
9831
9832 if (workInProgress.ref !== null) {
9833 // If there is a ref on a host node we need to schedule a callback
9834 markRef(workInProgress);
9835 }
9836 }
9837 return null;
9838 }
9839 case HostText:
9840 {
9841 var newText = newProps;
9842 if (current && workInProgress.stateNode != null) {
9843 var oldText = current.memoizedProps;
9844 // If we have an alternate, that means this is an update and we need
9845 // to schedule a side-effect to do the updates.
9846 updateHostText(current, workInProgress, oldText, newText);
9847 } else {
9848 if (typeof newText !== 'string') {
9849 !(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;
9850 // This can happen when we abort work.
9851 return null;
9852 }
9853 var _rootContainerInstance = getRootHostContainer();
9854 var _currentHostContext2 = getHostContext();
9855 var _wasHydrated = popHydrationState(workInProgress);
9856 if (_wasHydrated) {
9857 if (prepareToHydrateHostTextInstance(workInProgress)) {
9858 markUpdate(workInProgress);
9859 }
9860 } else {
9861 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress);
9862 }
9863 }
9864 return null;
9865 }
9866 case CallComponent:
9867 return moveCallToHandlerPhase(current, workInProgress, renderExpirationTime);
9868 case CallHandlerPhase:
9869 // Reset the tag to now be a first phase call.
9870 workInProgress.tag = CallComponent;
9871 return null;
9872 case ReturnComponent:
9873 // Does nothing.
9874 return null;
9875 case Fragment:
9876 return null;
9877 case Mode:
9878 return null;
9879 case HostPortal:
9880 popHostContainer(workInProgress);
9881 updateHostContainer(workInProgress);
9882 return null;
9883 case ContextProvider:
9884 // Pop provider fiber
9885 popProvider(workInProgress);
9886 return null;
9887 case ContextConsumer:
9888 return null;
9889 // Error cases
9890 case IndeterminateComponent:
9891 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.');
9892 // eslint-disable-next-line no-fallthrough
9893 default:
9894 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9895 }
9896 }
9897
9898 return {
9899 completeWork: completeWork
9900 };
9901};
9902
9903var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback;
9904var hasCaughtError$1 = ReactErrorUtils.hasCaughtError;
9905var clearCaughtError$1 = ReactErrorUtils.clearCaughtError;
9906
9907
9908var ReactFiberCommitWork = function (config, captureError) {
9909 var getPublicInstance = config.getPublicInstance,
9910 mutation = config.mutation,
9911 persistence = config.persistence;
9912
9913
9914 var callComponentWillUnmountWithTimer = function (current, instance) {
9915 startPhaseTimer(current, 'componentWillUnmount');
9916 instance.props = current.memoizedProps;
9917 instance.state = current.memoizedState;
9918 instance.componentWillUnmount();
9919 stopPhaseTimer();
9920 };
9921
9922 // Capture errors so they don't interrupt unmounting.
9923 function safelyCallComponentWillUnmount(current, instance) {
9924 {
9925 invokeGuardedCallback$3(null, callComponentWillUnmountWithTimer, null, current, instance);
9926 if (hasCaughtError$1()) {
9927 var unmountError = clearCaughtError$1();
9928 captureError(current, unmountError);
9929 }
9930 }
9931 }
9932
9933 function safelyDetachRef(current) {
9934 var ref = current.ref;
9935 if (ref !== null) {
9936 if (typeof ref === 'function') {
9937 {
9938 invokeGuardedCallback$3(null, ref, null, null);
9939 if (hasCaughtError$1()) {
9940 var refError = clearCaughtError$1();
9941 captureError(current, refError);
9942 }
9943 }
9944 } else {
9945 ref.value = null;
9946 }
9947 }
9948 }
9949
9950 function commitLifeCycles(current, finishedWork) {
9951 switch (finishedWork.tag) {
9952 case ClassComponent:
9953 {
9954 var instance = finishedWork.stateNode;
9955 if (finishedWork.effectTag & Update) {
9956 if (current === null) {
9957 startPhaseTimer(finishedWork, 'componentDidMount');
9958 instance.props = finishedWork.memoizedProps;
9959 instance.state = finishedWork.memoizedState;
9960 instance.componentDidMount();
9961 stopPhaseTimer();
9962 } else {
9963 var prevProps = current.memoizedProps;
9964 var prevState = current.memoizedState;
9965 startPhaseTimer(finishedWork, 'componentDidUpdate');
9966 instance.props = finishedWork.memoizedProps;
9967 instance.state = finishedWork.memoizedState;
9968 instance.componentDidUpdate(prevProps, prevState);
9969 stopPhaseTimer();
9970 }
9971 }
9972 var updateQueue = finishedWork.updateQueue;
9973 if (updateQueue !== null) {
9974 commitCallbacks(updateQueue, instance);
9975 }
9976 return;
9977 }
9978 case HostRoot:
9979 {
9980 var _updateQueue = finishedWork.updateQueue;
9981 if (_updateQueue !== null) {
9982 var _instance = null;
9983 if (finishedWork.child !== null) {
9984 switch (finishedWork.child.tag) {
9985 case HostComponent:
9986 _instance = getPublicInstance(finishedWork.child.stateNode);
9987 break;
9988 case ClassComponent:
9989 _instance = finishedWork.child.stateNode;
9990 break;
9991 }
9992 }
9993 commitCallbacks(_updateQueue, _instance);
9994 }
9995 return;
9996 }
9997 case HostComponent:
9998 {
9999 var _instance2 = finishedWork.stateNode;
10000
10001 // Renderers may schedule work to be done after host components are mounted
10002 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10003 // These effects should only be committed when components are first mounted,
10004 // aka when there is no current/alternate.
10005 if (current === null && finishedWork.effectTag & Update) {
10006 var type = finishedWork.type;
10007 var props = finishedWork.memoizedProps;
10008 commitMount(_instance2, type, props, finishedWork);
10009 }
10010
10011 return;
10012 }
10013 case HostText:
10014 {
10015 // We have no life-cycles associated with text.
10016 return;
10017 }
10018 case HostPortal:
10019 {
10020 // We have no life-cycles associated with portals.
10021 return;
10022 }
10023 default:
10024 {
10025 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.');
10026 }
10027 }
10028 }
10029
10030 function commitAttachRef(finishedWork) {
10031 var ref = finishedWork.ref;
10032 if (ref !== null) {
10033 var instance = finishedWork.stateNode;
10034 var instanceToUse = void 0;
10035 switch (finishedWork.tag) {
10036 case HostComponent:
10037 instanceToUse = getPublicInstance(instance);
10038 break;
10039 default:
10040 instanceToUse = instance;
10041 }
10042 if (typeof ref === 'function') {
10043 ref(instanceToUse);
10044 } else {
10045 ref.value = instanceToUse;
10046 }
10047 }
10048 }
10049
10050 function commitDetachRef(current) {
10051 var currentRef = current.ref;
10052 if (currentRef !== null) {
10053 if (typeof currentRef === 'function') {
10054 currentRef(null);
10055 } else {
10056 currentRef.value = null;
10057 }
10058 }
10059 }
10060
10061 // User-originating errors (lifecycles and refs) should not interrupt
10062 // deletion, so don't let them throw. Host-originating errors should
10063 // interrupt deletion, so it's okay
10064 function commitUnmount(current) {
10065 if (typeof onCommitUnmount === 'function') {
10066 onCommitUnmount(current);
10067 }
10068
10069 switch (current.tag) {
10070 case ClassComponent:
10071 {
10072 safelyDetachRef(current);
10073 var instance = current.stateNode;
10074 if (typeof instance.componentWillUnmount === 'function') {
10075 safelyCallComponentWillUnmount(current, instance);
10076 }
10077 return;
10078 }
10079 case HostComponent:
10080 {
10081 safelyDetachRef(current);
10082 return;
10083 }
10084 case CallComponent:
10085 {
10086 commitNestedUnmounts(current.stateNode);
10087 return;
10088 }
10089 case HostPortal:
10090 {
10091 // TODO: this is recursive.
10092 // We are also not using this parent because
10093 // the portal will get pushed immediately.
10094 if (enableMutatingReconciler && mutation) {
10095 unmountHostComponents(current);
10096 } else if (enablePersistentReconciler && persistence) {
10097 emptyPortalContainer(current);
10098 }
10099 return;
10100 }
10101 }
10102 }
10103
10104 function commitNestedUnmounts(root) {
10105 // While we're inside a removed host node we don't want to call
10106 // removeChild on the inner nodes because they're removed by the top
10107 // call anyway. We also want to call componentWillUnmount on all
10108 // composites before this host node is removed from the tree. Therefore
10109 var node = root;
10110 while (true) {
10111 commitUnmount(node);
10112 // Visit children because they may contain more composite or host nodes.
10113 // Skip portals because commitUnmount() currently visits them recursively.
10114 if (node.child !== null && (
10115 // If we use mutation we drill down into portals using commitUnmount above.
10116 // If we don't use mutation we drill down into portals here instead.
10117 !mutation || node.tag !== HostPortal)) {
10118 node.child['return'] = node;
10119 node = node.child;
10120 continue;
10121 }
10122 if (node === root) {
10123 return;
10124 }
10125 while (node.sibling === null) {
10126 if (node['return'] === null || node['return'] === root) {
10127 return;
10128 }
10129 node = node['return'];
10130 }
10131 node.sibling['return'] = node['return'];
10132 node = node.sibling;
10133 }
10134 }
10135
10136 function detachFiber(current) {
10137 // Cut off the return pointers to disconnect it from the tree. Ideally, we
10138 // should clear the child pointer of the parent alternate to let this
10139 // get GC:ed but we don't know which for sure which parent is the current
10140 // one so we'll settle for GC:ing the subtree of this child. This child
10141 // itself will be GC:ed when the parent updates the next time.
10142 current['return'] = null;
10143 current.child = null;
10144 if (current.alternate) {
10145 current.alternate.child = null;
10146 current.alternate['return'] = null;
10147 }
10148 }
10149
10150 var emptyPortalContainer = void 0;
10151
10152 if (!mutation) {
10153 var commitContainer = void 0;
10154 if (persistence) {
10155 var replaceContainerChildren = persistence.replaceContainerChildren,
10156 createContainerChildSet = persistence.createContainerChildSet;
10157
10158 emptyPortalContainer = function (current) {
10159 var portal = current.stateNode;
10160 var containerInfo = portal.containerInfo;
10161
10162 var emptyChildSet = createContainerChildSet(containerInfo);
10163 replaceContainerChildren(containerInfo, emptyChildSet);
10164 };
10165 commitContainer = function (finishedWork) {
10166 switch (finishedWork.tag) {
10167 case ClassComponent:
10168 {
10169 return;
10170 }
10171 case HostComponent:
10172 {
10173 return;
10174 }
10175 case HostText:
10176 {
10177 return;
10178 }
10179 case HostRoot:
10180 case HostPortal:
10181 {
10182 var portalOrRoot = finishedWork.stateNode;
10183 var containerInfo = portalOrRoot.containerInfo,
10184 _pendingChildren = portalOrRoot.pendingChildren;
10185
10186 replaceContainerChildren(containerInfo, _pendingChildren);
10187 return;
10188 }
10189 default:
10190 {
10191 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.');
10192 }
10193 }
10194 };
10195 } else {
10196 commitContainer = function (finishedWork) {
10197 // Noop
10198 };
10199 }
10200 if (enablePersistentReconciler || enableNoopReconciler) {
10201 return {
10202 commitResetTextContent: function (finishedWork) {},
10203 commitPlacement: function (finishedWork) {},
10204 commitDeletion: function (current) {
10205 // Detach refs and call componentWillUnmount() on the whole subtree.
10206 commitNestedUnmounts(current);
10207 detachFiber(current);
10208 },
10209 commitWork: function (current, finishedWork) {
10210 commitContainer(finishedWork);
10211 },
10212
10213 commitLifeCycles: commitLifeCycles,
10214 commitAttachRef: commitAttachRef,
10215 commitDetachRef: commitDetachRef
10216 };
10217 } else if (persistence) {
10218 invariant_1(false, 'Persistent reconciler is disabled.');
10219 } else {
10220 invariant_1(false, 'Noop reconciler is disabled.');
10221 }
10222 }
10223 var commitMount = mutation.commitMount,
10224 commitUpdate = mutation.commitUpdate,
10225 resetTextContent = mutation.resetTextContent,
10226 commitTextUpdate = mutation.commitTextUpdate,
10227 appendChild = mutation.appendChild,
10228 appendChildToContainer = mutation.appendChildToContainer,
10229 insertBefore = mutation.insertBefore,
10230 insertInContainerBefore = mutation.insertInContainerBefore,
10231 removeChild = mutation.removeChild,
10232 removeChildFromContainer = mutation.removeChildFromContainer;
10233
10234
10235 function getHostParentFiber(fiber) {
10236 var parent = fiber['return'];
10237 while (parent !== null) {
10238 if (isHostParent(parent)) {
10239 return parent;
10240 }
10241 parent = parent['return'];
10242 }
10243 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
10244 }
10245
10246 function isHostParent(fiber) {
10247 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10248 }
10249
10250 function getHostSibling(fiber) {
10251 // We're going to search forward into the tree until we find a sibling host
10252 // node. Unfortunately, if multiple insertions are done in a row we have to
10253 // search past them. This leads to exponential search for the next sibling.
10254 var node = fiber;
10255 siblings: while (true) {
10256 // If we didn't find anything, let's try the next sibling.
10257 while (node.sibling === null) {
10258 if (node['return'] === null || isHostParent(node['return'])) {
10259 // If we pop out of the root or hit the parent the fiber we are the
10260 // last sibling.
10261 return null;
10262 }
10263 node = node['return'];
10264 }
10265 node.sibling['return'] = node['return'];
10266 node = node.sibling;
10267 while (node.tag !== HostComponent && node.tag !== HostText) {
10268 // If it is not host node and, we might have a host node inside it.
10269 // Try to search down until we find one.
10270 if (node.effectTag & Placement) {
10271 // If we don't have a child, try the siblings instead.
10272 continue siblings;
10273 }
10274 // If we don't have a child, try the siblings instead.
10275 // We also skip portals because they are not part of this host tree.
10276 if (node.child === null || node.tag === HostPortal) {
10277 continue siblings;
10278 } else {
10279 node.child['return'] = node;
10280 node = node.child;
10281 }
10282 }
10283 // Check if this host node is stable or about to be placed.
10284 if (!(node.effectTag & Placement)) {
10285 // Found it!
10286 return node.stateNode;
10287 }
10288 }
10289 }
10290
10291 function commitPlacement(finishedWork) {
10292 // Recursively insert all host nodes into the parent.
10293 var parentFiber = getHostParentFiber(finishedWork);
10294 var parent = void 0;
10295 var isContainer = void 0;
10296 switch (parentFiber.tag) {
10297 case HostComponent:
10298 parent = parentFiber.stateNode;
10299 isContainer = false;
10300 break;
10301 case HostRoot:
10302 parent = parentFiber.stateNode.containerInfo;
10303 isContainer = true;
10304 break;
10305 case HostPortal:
10306 parent = parentFiber.stateNode.containerInfo;
10307 isContainer = true;
10308 break;
10309 default:
10310 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
10311 }
10312 if (parentFiber.effectTag & ContentReset) {
10313 // Reset the text content of the parent before doing any insertions
10314 resetTextContent(parent);
10315 // Clear ContentReset from the effect tag
10316 parentFiber.effectTag &= ~ContentReset;
10317 }
10318
10319 var before = getHostSibling(finishedWork);
10320 // We only have the top Fiber that was inserted but we need recurse down its
10321 // children to find all the terminal nodes.
10322 var node = finishedWork;
10323 while (true) {
10324 if (node.tag === HostComponent || node.tag === HostText) {
10325 if (before) {
10326 if (isContainer) {
10327 insertInContainerBefore(parent, node.stateNode, before);
10328 } else {
10329 insertBefore(parent, node.stateNode, before);
10330 }
10331 } else {
10332 if (isContainer) {
10333 appendChildToContainer(parent, node.stateNode);
10334 } else {
10335 appendChild(parent, node.stateNode);
10336 }
10337 }
10338 } else if (node.tag === HostPortal) {
10339 // If the insertion itself is a portal, then we don't want to traverse
10340 // down its children. Instead, we'll get insertions from each child in
10341 // the portal directly.
10342 } else if (node.child !== null) {
10343 node.child['return'] = node;
10344 node = node.child;
10345 continue;
10346 }
10347 if (node === finishedWork) {
10348 return;
10349 }
10350 while (node.sibling === null) {
10351 if (node['return'] === null || node['return'] === finishedWork) {
10352 return;
10353 }
10354 node = node['return'];
10355 }
10356 node.sibling['return'] = node['return'];
10357 node = node.sibling;
10358 }
10359 }
10360
10361 function unmountHostComponents(current) {
10362 // We only have the top Fiber that was inserted but we need recurse down its
10363 var node = current;
10364
10365 // Each iteration, currentParent is populated with node's host parent if not
10366 // currentParentIsValid.
10367 var currentParentIsValid = false;
10368 var currentParent = void 0;
10369 var currentParentIsContainer = void 0;
10370
10371 while (true) {
10372 if (!currentParentIsValid) {
10373 var parent = node['return'];
10374 findParent: while (true) {
10375 !(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;
10376 switch (parent.tag) {
10377 case HostComponent:
10378 currentParent = parent.stateNode;
10379 currentParentIsContainer = false;
10380 break findParent;
10381 case HostRoot:
10382 currentParent = parent.stateNode.containerInfo;
10383 currentParentIsContainer = true;
10384 break findParent;
10385 case HostPortal:
10386 currentParent = parent.stateNode.containerInfo;
10387 currentParentIsContainer = true;
10388 break findParent;
10389 }
10390 parent = parent['return'];
10391 }
10392 currentParentIsValid = true;
10393 }
10394
10395 if (node.tag === HostComponent || node.tag === HostText) {
10396 commitNestedUnmounts(node);
10397 // After all the children have unmounted, it is now safe to remove the
10398 // node from the tree.
10399 if (currentParentIsContainer) {
10400 removeChildFromContainer(currentParent, node.stateNode);
10401 } else {
10402 removeChild(currentParent, node.stateNode);
10403 }
10404 // Don't visit children because we already visited them.
10405 } else if (node.tag === HostPortal) {
10406 // When we go into a portal, it becomes the parent to remove from.
10407 // We will reassign it back when we pop the portal on the way up.
10408 currentParent = node.stateNode.containerInfo;
10409 // Visit children because portals might contain host components.
10410 if (node.child !== null) {
10411 node.child['return'] = node;
10412 node = node.child;
10413 continue;
10414 }
10415 } else {
10416 commitUnmount(node);
10417 // Visit children because we may find more host components below.
10418 if (node.child !== null) {
10419 node.child['return'] = node;
10420 node = node.child;
10421 continue;
10422 }
10423 }
10424 if (node === current) {
10425 return;
10426 }
10427 while (node.sibling === null) {
10428 if (node['return'] === null || node['return'] === current) {
10429 return;
10430 }
10431 node = node['return'];
10432 if (node.tag === HostPortal) {
10433 // When we go out of the portal, we need to restore the parent.
10434 // Since we don't keep a stack of them, we will search for it.
10435 currentParentIsValid = false;
10436 }
10437 }
10438 node.sibling['return'] = node['return'];
10439 node = node.sibling;
10440 }
10441 }
10442
10443 function commitDeletion(current) {
10444 // Recursively delete all host nodes from the parent.
10445 // Detach refs and call componentWillUnmount() on the whole subtree.
10446 unmountHostComponents(current);
10447 detachFiber(current);
10448 }
10449
10450 function commitWork(current, finishedWork) {
10451 switch (finishedWork.tag) {
10452 case ClassComponent:
10453 {
10454 return;
10455 }
10456 case HostComponent:
10457 {
10458 var instance = finishedWork.stateNode;
10459 if (instance != null) {
10460 // Commit the work prepared earlier.
10461 var newProps = finishedWork.memoizedProps;
10462 // For hydration we reuse the update path but we treat the oldProps
10463 // as the newProps. The updatePayload will contain the real change in
10464 // this case.
10465 var oldProps = current !== null ? current.memoizedProps : newProps;
10466 var type = finishedWork.type;
10467 // TODO: Type the updateQueue to be specific to host components.
10468 var updatePayload = finishedWork.updateQueue;
10469 finishedWork.updateQueue = null;
10470 if (updatePayload !== null) {
10471 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10472 }
10473 }
10474 return;
10475 }
10476 case HostText:
10477 {
10478 !(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;
10479 var textInstance = finishedWork.stateNode;
10480 var newText = finishedWork.memoizedProps;
10481 // For hydration we reuse the update path but we treat the oldProps
10482 // as the newProps. The updatePayload will contain the real change in
10483 // this case.
10484 var oldText = current !== null ? current.memoizedProps : newText;
10485 commitTextUpdate(textInstance, oldText, newText);
10486 return;
10487 }
10488 case HostRoot:
10489 {
10490 return;
10491 }
10492 default:
10493 {
10494 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.');
10495 }
10496 }
10497 }
10498
10499 function commitResetTextContent(current) {
10500 resetTextContent(current.stateNode);
10501 }
10502
10503 if (enableMutatingReconciler) {
10504 return {
10505 commitResetTextContent: commitResetTextContent,
10506 commitPlacement: commitPlacement,
10507 commitDeletion: commitDeletion,
10508 commitWork: commitWork,
10509 commitLifeCycles: commitLifeCycles,
10510 commitAttachRef: commitAttachRef,
10511 commitDetachRef: commitDetachRef
10512 };
10513 } else {
10514 invariant_1(false, 'Mutating reconciler is disabled.');
10515 }
10516};
10517
10518var NO_CONTEXT = {};
10519
10520var ReactFiberHostContext = function (config) {
10521 var getChildHostContext = config.getChildHostContext,
10522 getRootHostContext = config.getRootHostContext;
10523
10524
10525 var contextStackCursor = createCursor(NO_CONTEXT);
10526 var contextFiberStackCursor = createCursor(NO_CONTEXT);
10527 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
10528
10529 function requiredContext(c) {
10530 !(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;
10531 return c;
10532 }
10533
10534 function getRootHostContainer() {
10535 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10536 return rootInstance;
10537 }
10538
10539 function pushHostContainer(fiber, nextRootInstance) {
10540 // Push current root instance onto the stack;
10541 // This allows us to reset root when portals are popped.
10542 push(rootInstanceStackCursor, nextRootInstance, fiber);
10543
10544 var nextRootContext = getRootHostContext(nextRootInstance);
10545
10546 // Track the context and the Fiber that provided it.
10547 // This enables us to pop only Fibers that provide unique contexts.
10548 push(contextFiberStackCursor, fiber, fiber);
10549 push(contextStackCursor, nextRootContext, fiber);
10550 }
10551
10552 function popHostContainer(fiber) {
10553 pop(contextStackCursor, fiber);
10554 pop(contextFiberStackCursor, fiber);
10555 pop(rootInstanceStackCursor, fiber);
10556 }
10557
10558 function getHostContext() {
10559 var context = requiredContext(contextStackCursor.current);
10560 return context;
10561 }
10562
10563 function pushHostContext(fiber) {
10564 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10565 var context = requiredContext(contextStackCursor.current);
10566 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
10567
10568 // Don't push this Fiber's context unless it's unique.
10569 if (context === nextContext) {
10570 return;
10571 }
10572
10573 // Track the context and the Fiber that provided it.
10574 // This enables us to pop only Fibers that provide unique contexts.
10575 push(contextFiberStackCursor, fiber, fiber);
10576 push(contextStackCursor, nextContext, fiber);
10577 }
10578
10579 function popHostContext(fiber) {
10580 // Do not pop unless this Fiber provided the current context.
10581 // pushHostContext() only pushes Fibers that provide unique contexts.
10582 if (contextFiberStackCursor.current !== fiber) {
10583 return;
10584 }
10585
10586 pop(contextStackCursor, fiber);
10587 pop(contextFiberStackCursor, fiber);
10588 }
10589
10590 function resetHostContainer() {
10591 contextStackCursor.current = NO_CONTEXT;
10592 rootInstanceStackCursor.current = NO_CONTEXT;
10593 }
10594
10595 return {
10596 getHostContext: getHostContext,
10597 getRootHostContainer: getRootHostContainer,
10598 popHostContainer: popHostContainer,
10599 popHostContext: popHostContext,
10600 pushHostContainer: pushHostContainer,
10601 pushHostContext: pushHostContext,
10602 resetHostContainer: resetHostContainer
10603 };
10604};
10605
10606var ReactFiberHydrationContext = function (config) {
10607 var shouldSetTextContent = config.shouldSetTextContent,
10608 hydration = config.hydration;
10609
10610 // If this doesn't have hydration mode.
10611
10612 if (!hydration) {
10613 return {
10614 enterHydrationState: function () {
10615 return false;
10616 },
10617 resetHydrationState: function () {},
10618 tryToClaimNextHydratableInstance: function () {},
10619 prepareToHydrateHostInstance: function () {
10620 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10621 },
10622 prepareToHydrateHostTextInstance: function () {
10623 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10624 },
10625 popHydrationState: function (fiber) {
10626 return false;
10627 }
10628 };
10629 }
10630
10631 var canHydrateInstance = hydration.canHydrateInstance,
10632 canHydrateTextInstance = hydration.canHydrateTextInstance,
10633 getNextHydratableSibling = hydration.getNextHydratableSibling,
10634 getFirstHydratableChild = hydration.getFirstHydratableChild,
10635 hydrateInstance = hydration.hydrateInstance,
10636 hydrateTextInstance = hydration.hydrateTextInstance,
10637 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
10638 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
10639 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
10640 didNotHydrateInstance = hydration.didNotHydrateInstance,
10641 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
10642 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
10643 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
10644 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
10645
10646 // The deepest Fiber on the stack involved in a hydration context.
10647 // This may have been an insertion or a hydration.
10648
10649 var hydrationParentFiber = null;
10650 var nextHydratableInstance = null;
10651 var isHydrating = false;
10652
10653 function enterHydrationState(fiber) {
10654 var parentInstance = fiber.stateNode.containerInfo;
10655 nextHydratableInstance = getFirstHydratableChild(parentInstance);
10656 hydrationParentFiber = fiber;
10657 isHydrating = true;
10658 return true;
10659 }
10660
10661 function deleteHydratableInstance(returnFiber, instance) {
10662 {
10663 switch (returnFiber.tag) {
10664 case HostRoot:
10665 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
10666 break;
10667 case HostComponent:
10668 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
10669 break;
10670 }
10671 }
10672
10673 var childToDelete = createFiberFromHostInstanceForDeletion();
10674 childToDelete.stateNode = instance;
10675 childToDelete['return'] = returnFiber;
10676 childToDelete.effectTag = Deletion;
10677
10678 // This might seem like it belongs on progressedFirstDeletion. However,
10679 // these children are not part of the reconciliation list of children.
10680 // Even if we abort and rereconcile the children, that will try to hydrate
10681 // again and the nodes are still in the host tree so these will be
10682 // recreated.
10683 if (returnFiber.lastEffect !== null) {
10684 returnFiber.lastEffect.nextEffect = childToDelete;
10685 returnFiber.lastEffect = childToDelete;
10686 } else {
10687 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
10688 }
10689 }
10690
10691 function insertNonHydratedInstance(returnFiber, fiber) {
10692 fiber.effectTag |= Placement;
10693 {
10694 switch (returnFiber.tag) {
10695 case HostRoot:
10696 {
10697 var parentContainer = returnFiber.stateNode.containerInfo;
10698 switch (fiber.tag) {
10699 case HostComponent:
10700 var type = fiber.type;
10701 var props = fiber.pendingProps;
10702 didNotFindHydratableContainerInstance(parentContainer, type, props);
10703 break;
10704 case HostText:
10705 var text = fiber.pendingProps;
10706 didNotFindHydratableContainerTextInstance(parentContainer, text);
10707 break;
10708 }
10709 break;
10710 }
10711 case HostComponent:
10712 {
10713 var parentType = returnFiber.type;
10714 var parentProps = returnFiber.memoizedProps;
10715 var parentInstance = returnFiber.stateNode;
10716 switch (fiber.tag) {
10717 case HostComponent:
10718 var _type = fiber.type;
10719 var _props = fiber.pendingProps;
10720 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
10721 break;
10722 case HostText:
10723 var _text = fiber.pendingProps;
10724 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
10725 break;
10726 }
10727 break;
10728 }
10729 default:
10730 return;
10731 }
10732 }
10733 }
10734
10735 function tryHydrate(fiber, nextInstance) {
10736 switch (fiber.tag) {
10737 case HostComponent:
10738 {
10739 var type = fiber.type;
10740 var props = fiber.pendingProps;
10741 var instance = canHydrateInstance(nextInstance, type, props);
10742 if (instance !== null) {
10743 fiber.stateNode = instance;
10744 return true;
10745 }
10746 return false;
10747 }
10748 case HostText:
10749 {
10750 var text = fiber.pendingProps;
10751 var textInstance = canHydrateTextInstance(nextInstance, text);
10752 if (textInstance !== null) {
10753 fiber.stateNode = textInstance;
10754 return true;
10755 }
10756 return false;
10757 }
10758 default:
10759 return false;
10760 }
10761 }
10762
10763 function tryToClaimNextHydratableInstance(fiber) {
10764 if (!isHydrating) {
10765 return;
10766 }
10767 var nextInstance = nextHydratableInstance;
10768 if (!nextInstance) {
10769 // Nothing to hydrate. Make it an insertion.
10770 insertNonHydratedInstance(hydrationParentFiber, fiber);
10771 isHydrating = false;
10772 hydrationParentFiber = fiber;
10773 return;
10774 }
10775 if (!tryHydrate(fiber, nextInstance)) {
10776 // If we can't hydrate this instance let's try the next one.
10777 // We use this as a heuristic. It's based on intuition and not data so it
10778 // might be flawed or unnecessary.
10779 nextInstance = getNextHydratableSibling(nextInstance);
10780 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
10781 // Nothing to hydrate. Make it an insertion.
10782 insertNonHydratedInstance(hydrationParentFiber, fiber);
10783 isHydrating = false;
10784 hydrationParentFiber = fiber;
10785 return;
10786 }
10787 // We matched the next one, we'll now assume that the first one was
10788 // superfluous and we'll delete it. Since we can't eagerly delete it
10789 // we'll have to schedule a deletion. To do that, this node needs a dummy
10790 // fiber associated with it.
10791 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
10792 }
10793 hydrationParentFiber = fiber;
10794 nextHydratableInstance = getFirstHydratableChild(nextInstance);
10795 }
10796
10797 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
10798 var instance = fiber.stateNode;
10799 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
10800 // TODO: Type this specific to this type of component.
10801 fiber.updateQueue = updatePayload;
10802 // If the update payload indicates that there is a change or if there
10803 // is a new ref we mark this as an update.
10804 if (updatePayload !== null) {
10805 return true;
10806 }
10807 return false;
10808 }
10809
10810 function prepareToHydrateHostTextInstance(fiber) {
10811 var textInstance = fiber.stateNode;
10812 var textContent = fiber.memoizedProps;
10813 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
10814 {
10815 if (shouldUpdate) {
10816 // We assume that prepareToHydrateHostTextInstance is called in a context where the
10817 // hydration parent is the parent host component of this host text.
10818 var returnFiber = hydrationParentFiber;
10819 if (returnFiber !== null) {
10820 switch (returnFiber.tag) {
10821 case HostRoot:
10822 {
10823 var parentContainer = returnFiber.stateNode.containerInfo;
10824 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
10825 break;
10826 }
10827 case HostComponent:
10828 {
10829 var parentType = returnFiber.type;
10830 var parentProps = returnFiber.memoizedProps;
10831 var parentInstance = returnFiber.stateNode;
10832 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
10833 break;
10834 }
10835 }
10836 }
10837 }
10838 }
10839 return shouldUpdate;
10840 }
10841
10842 function popToNextHostParent(fiber) {
10843 var parent = fiber['return'];
10844 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
10845 parent = parent['return'];
10846 }
10847 hydrationParentFiber = parent;
10848 }
10849
10850 function popHydrationState(fiber) {
10851 if (fiber !== hydrationParentFiber) {
10852 // We're deeper than the current hydration context, inside an inserted
10853 // tree.
10854 return false;
10855 }
10856 if (!isHydrating) {
10857 // If we're not currently hydrating but we're in a hydration context, then
10858 // we were an insertion and now need to pop up reenter hydration of our
10859 // siblings.
10860 popToNextHostParent(fiber);
10861 isHydrating = true;
10862 return false;
10863 }
10864
10865 var type = fiber.type;
10866
10867 // If we have any remaining hydratable nodes, we need to delete them now.
10868 // We only do this deeper than head and body since they tend to have random
10869 // other nodes in them. We also ignore components with pure text content in
10870 // side of them.
10871 // TODO: Better heuristic.
10872 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
10873 var nextInstance = nextHydratableInstance;
10874 while (nextInstance) {
10875 deleteHydratableInstance(fiber, nextInstance);
10876 nextInstance = getNextHydratableSibling(nextInstance);
10877 }
10878 }
10879
10880 popToNextHostParent(fiber);
10881 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
10882 return true;
10883 }
10884
10885 function resetHydrationState() {
10886 hydrationParentFiber = null;
10887 nextHydratableInstance = null;
10888 isHydrating = false;
10889 }
10890
10891 return {
10892 enterHydrationState: enterHydrationState,
10893 resetHydrationState: resetHydrationState,
10894 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
10895 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
10896 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
10897 popHydrationState: popHydrationState
10898 };
10899};
10900
10901// This lets us hook into Fiber to debug what it's doing.
10902// See https://github.com/facebook/react/pull/8033.
10903// This is not part of the public API, not even for React DevTools.
10904// You may only inject a debugTool if you work on React Fiber itself.
10905var ReactFiberInstrumentation = {
10906 debugTool: null
10907};
10908
10909var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10910
10911// This module is forked in different environments.
10912// By default, return `true` to log errors to the console.
10913// Forks can return `false` if this isn't desirable.
10914function showErrorDialog(capturedError) {
10915 return true;
10916}
10917
10918function logCapturedError(capturedError) {
10919 var logError = showErrorDialog(capturedError);
10920
10921 // Allow injected showErrorDialog() to prevent default console.error logging.
10922 // This enables renderers like ReactNative to better manage redbox behavior.
10923 if (logError === false) {
10924 return;
10925 }
10926
10927 var error = capturedError.error;
10928 var suppressLogging = error && error.suppressReactErrorLogging;
10929 if (suppressLogging) {
10930 return;
10931 }
10932
10933 {
10934 var componentName = capturedError.componentName,
10935 componentStack = capturedError.componentStack,
10936 errorBoundaryName = capturedError.errorBoundaryName,
10937 errorBoundaryFound = capturedError.errorBoundaryFound,
10938 willRetry = capturedError.willRetry;
10939
10940
10941 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10942
10943 var errorBoundaryMessage = void 0;
10944 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10945 if (errorBoundaryFound && errorBoundaryName) {
10946 if (willRetry) {
10947 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10948 } else {
10949 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10950 }
10951 } else {
10952 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.';
10953 }
10954 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10955
10956 // In development, we provide our own message with just the component stack.
10957 // We don't include the original error message and JS stack because the browser
10958 // has already printed it. Even if the application swallows the error, it is still
10959 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10960 console.error(combinedMessage);
10961 }
10962}
10963
10964var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
10965var hasCaughtError = ReactErrorUtils.hasCaughtError;
10966var clearCaughtError = ReactErrorUtils.clearCaughtError;
10967
10968
10969var didWarnAboutStateTransition = void 0;
10970var didWarnSetStateChildContext = void 0;
10971var warnAboutUpdateOnUnmounted = void 0;
10972var warnAboutInvalidUpdates = void 0;
10973
10974{
10975 didWarnAboutStateTransition = false;
10976 didWarnSetStateChildContext = false;
10977 var didWarnStateUpdateForUnmountedComponent = {};
10978
10979 warnAboutUpdateOnUnmounted = function (fiber) {
10980 var componentName = getComponentName(fiber) || 'ReactClass';
10981 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10982 return;
10983 }
10984 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);
10985 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10986 };
10987
10988 warnAboutInvalidUpdates = function (instance) {
10989 switch (ReactDebugCurrentFiber.phase) {
10990 case 'getChildContext':
10991 if (didWarnSetStateChildContext) {
10992 return;
10993 }
10994 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10995 didWarnSetStateChildContext = true;
10996 break;
10997 case 'render':
10998 if (didWarnAboutStateTransition) {
10999 return;
11000 }
11001 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`.');
11002 didWarnAboutStateTransition = true;
11003 break;
11004 }
11005 };
11006}
11007
11008var ReactFiberScheduler = function (config) {
11009 var hostContext = ReactFiberHostContext(config);
11010 var hydrationContext = ReactFiberHydrationContext(config);
11011 var popHostContainer = hostContext.popHostContainer,
11012 popHostContext = hostContext.popHostContext,
11013 resetHostContainer = hostContext.resetHostContainer;
11014
11015 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
11016 beginWork = _ReactFiberBeginWork.beginWork,
11017 beginFailedWork = _ReactFiberBeginWork.beginFailedWork;
11018
11019 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
11020 completeWork = _ReactFiberCompleteWo.completeWork;
11021
11022 var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError),
11023 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
11024 commitPlacement = _ReactFiberCommitWork.commitPlacement,
11025 commitDeletion = _ReactFiberCommitWork.commitDeletion,
11026 commitWork = _ReactFiberCommitWork.commitWork,
11027 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
11028 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
11029 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
11030
11031 var now = config.now,
11032 scheduleDeferredCallback = config.scheduleDeferredCallback,
11033 cancelDeferredCallback = config.cancelDeferredCallback,
11034 prepareForCommit = config.prepareForCommit,
11035 resetAfterCommit = config.resetAfterCommit;
11036
11037 // Represents the current time in ms.
11038
11039 var startTime = now();
11040 var mostRecentCurrentTime = msToExpirationTime(0);
11041
11042 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
11043 var lastUniqueAsyncExpiration = 0;
11044
11045 // Represents the expiration time that incoming updates should use. (If this
11046 // is NoWork, use the default strategy: async updates in async mode, sync
11047 // updates in sync mode.)
11048 var expirationContext = NoWork;
11049
11050 var isWorking = false;
11051
11052 // The next work in progress fiber that we're currently working on.
11053 var nextUnitOfWork = null;
11054 var nextRoot = null;
11055 // The time at which we're currently rendering work.
11056 var nextRenderExpirationTime = NoWork;
11057
11058 // The next fiber with an effect that we're currently committing.
11059 var nextEffect = null;
11060
11061 // Keep track of which fibers have captured an error that need to be handled.
11062 // Work is removed from this collection after componentDidCatch is called.
11063 var capturedErrors = null;
11064 // Keep track of which fibers have failed during the current batch of work.
11065 // This is a different set than capturedErrors, because it is not reset until
11066 // the end of the batch. This is needed to propagate errors correctly if a
11067 // subtree fails more than once.
11068 var failedBoundaries = null;
11069 // Error boundaries that captured an error during the current commit.
11070 var commitPhaseBoundaries = null;
11071 var firstUncaughtError = null;
11072 var didFatal = false;
11073
11074 var isCommitting = false;
11075 var isUnmounting = false;
11076
11077 // Used for performance tracking.
11078 var interruptedBy = null;
11079
11080 function resetContextStack() {
11081 // Reset the stack
11082 reset$1();
11083 // Reset the cursors
11084 resetContext();
11085 resetProviderStack();
11086 resetHostContainer();
11087 }
11088
11089 function commitAllHostEffects() {
11090 while (nextEffect !== null) {
11091 {
11092 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
11093 }
11094 recordEffect();
11095
11096 var effectTag = nextEffect.effectTag;
11097 if (effectTag & ContentReset) {
11098 commitResetTextContent(nextEffect);
11099 }
11100
11101 if (effectTag & Ref) {
11102 var current = nextEffect.alternate;
11103 if (current !== null) {
11104 commitDetachRef(current);
11105 }
11106 }
11107
11108 // The following switch statement is only concerned about placement,
11109 // updates, and deletions. To avoid needing to add a case for every
11110 // possible bitmap value, we remove the secondary effects from the
11111 // effect tag and switch on that value.
11112 var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
11113 switch (primaryEffectTag) {
11114 case Placement:
11115 {
11116 commitPlacement(nextEffect);
11117 // Clear the "placement" from effect tag so that we know that this is inserted, before
11118 // any life-cycles like componentDidMount gets called.
11119 // TODO: findDOMNode doesn't rely on this any more but isMounted
11120 // does and isMounted is deprecated anyway so we should be able
11121 // to kill this.
11122 nextEffect.effectTag &= ~Placement;
11123 break;
11124 }
11125 case PlacementAndUpdate:
11126 {
11127 // Placement
11128 commitPlacement(nextEffect);
11129 // Clear the "placement" from effect tag so that we know that this is inserted, before
11130 // any life-cycles like componentDidMount gets called.
11131 nextEffect.effectTag &= ~Placement;
11132
11133 // Update
11134 var _current = nextEffect.alternate;
11135 commitWork(_current, nextEffect);
11136 break;
11137 }
11138 case Update:
11139 {
11140 var _current2 = nextEffect.alternate;
11141 commitWork(_current2, nextEffect);
11142 break;
11143 }
11144 case Deletion:
11145 {
11146 isUnmounting = true;
11147 commitDeletion(nextEffect);
11148 isUnmounting = false;
11149 break;
11150 }
11151 }
11152 nextEffect = nextEffect.nextEffect;
11153 }
11154
11155 {
11156 ReactDebugCurrentFiber.resetCurrentFiber();
11157 }
11158 }
11159
11160 function commitAllLifeCycles() {
11161 {
11162 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
11163
11164 if (warnAboutDeprecatedLifecycles) {
11165 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
11166 }
11167 }
11168
11169 while (nextEffect !== null) {
11170 var effectTag = nextEffect.effectTag;
11171
11172 if (effectTag & (Update | Callback)) {
11173 recordEffect();
11174 var current = nextEffect.alternate;
11175 commitLifeCycles(current, nextEffect);
11176 }
11177
11178 if (effectTag & Ref) {
11179 recordEffect();
11180 commitAttachRef(nextEffect);
11181 }
11182
11183 if (effectTag & Err) {
11184 recordEffect();
11185 commitErrorHandling(nextEffect);
11186 }
11187
11188 var next = nextEffect.nextEffect;
11189 // Ensure that we clean these up so that we don't accidentally keep them.
11190 // I'm not actually sure this matters because we can't reset firstEffect
11191 // and lastEffect since they're on every node, not just the effectful
11192 // ones. So we have to clean everything as we reuse nodes anyway.
11193 nextEffect.nextEffect = null;
11194 // Ensure that we reset the effectTag here so that we can rely on effect
11195 // tags to reason about the current life-cycle.
11196 nextEffect = next;
11197 }
11198 }
11199
11200 function commitRoot(finishedWork) {
11201 // We keep track of this so that captureError can collect any boundaries
11202 // that capture an error during the commit phase. The reason these aren't
11203 // local to this function is because errors that occur during cWU are
11204 // captured elsewhere, to prevent the unmount from being interrupted.
11205 isWorking = true;
11206 isCommitting = true;
11207 startCommitTimer();
11208
11209 var root = finishedWork.stateNode;
11210 !(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;
11211 root.isReadyForCommit = false;
11212
11213 // Reset this to null before calling lifecycles
11214 ReactCurrentOwner.current = null;
11215
11216 var firstEffect = void 0;
11217 if (finishedWork.effectTag > PerformedWork) {
11218 // A fiber's effect list consists only of its children, not itself. So if
11219 // the root has an effect, we need to add it to the end of the list. The
11220 // resulting list is the set that would belong to the root's parent, if
11221 // it had one; that is, all the effects in the tree including the root.
11222 if (finishedWork.lastEffect !== null) {
11223 finishedWork.lastEffect.nextEffect = finishedWork;
11224 firstEffect = finishedWork.firstEffect;
11225 } else {
11226 firstEffect = finishedWork;
11227 }
11228 } else {
11229 // There is no effect on the root.
11230 firstEffect = finishedWork.firstEffect;
11231 }
11232
11233 prepareForCommit(root.containerInfo);
11234
11235 // Commit all the side-effects within a tree. We'll do this in two passes.
11236 // The first pass performs all the host insertions, updates, deletions and
11237 // ref unmounts.
11238 nextEffect = firstEffect;
11239 startCommitHostEffectsTimer();
11240 while (nextEffect !== null) {
11241 var didError = false;
11242 var _error = void 0;
11243 {
11244 invokeGuardedCallback$2(null, commitAllHostEffects, null);
11245 if (hasCaughtError()) {
11246 didError = true;
11247 _error = clearCaughtError();
11248 }
11249 }
11250 if (didError) {
11251 !(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;
11252 captureError(nextEffect, _error);
11253 // Clean-up
11254 if (nextEffect !== null) {
11255 nextEffect = nextEffect.nextEffect;
11256 }
11257 }
11258 }
11259 stopCommitHostEffectsTimer();
11260
11261 resetAfterCommit(root.containerInfo);
11262
11263 // The work-in-progress tree is now the current tree. This must come after
11264 // the first pass of the commit phase, so that the previous tree is still
11265 // current during componentWillUnmount, but before the second pass, so that
11266 // the finished work is current during componentDidMount/Update.
11267 root.current = finishedWork;
11268
11269 // In the second pass we'll perform all life-cycles and ref callbacks.
11270 // Life-cycles happen as a separate pass so that all placements, updates,
11271 // and deletions in the entire tree have already been invoked.
11272 // This pass also triggers any renderer-specific initial effects.
11273 nextEffect = firstEffect;
11274 startCommitLifeCyclesTimer();
11275 while (nextEffect !== null) {
11276 var _didError = false;
11277 var _error2 = void 0;
11278 {
11279 invokeGuardedCallback$2(null, commitAllLifeCycles, null);
11280 if (hasCaughtError()) {
11281 _didError = true;
11282 _error2 = clearCaughtError();
11283 }
11284 }
11285 if (_didError) {
11286 !(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;
11287 captureError(nextEffect, _error2);
11288 if (nextEffect !== null) {
11289 nextEffect = nextEffect.nextEffect;
11290 }
11291 }
11292 }
11293
11294 isCommitting = false;
11295 isWorking = false;
11296 stopCommitLifeCyclesTimer();
11297 stopCommitTimer();
11298 if (typeof onCommitRoot === 'function') {
11299 onCommitRoot(finishedWork.stateNode);
11300 }
11301 if (true && ReactFiberInstrumentation_1.debugTool) {
11302 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11303 }
11304
11305 // If we caught any errors during this commit, schedule their boundaries
11306 // to update.
11307 if (commitPhaseBoundaries) {
11308 commitPhaseBoundaries.forEach(scheduleErrorRecovery);
11309 commitPhaseBoundaries = null;
11310 }
11311
11312 if (firstUncaughtError !== null) {
11313 var _error3 = firstUncaughtError;
11314 firstUncaughtError = null;
11315 onUncaughtError(_error3);
11316 }
11317
11318 var remainingTime = root.current.expirationTime;
11319
11320 if (remainingTime === NoWork) {
11321 capturedErrors = null;
11322 failedBoundaries = null;
11323 }
11324
11325 return remainingTime;
11326 }
11327
11328 function resetExpirationTime(workInProgress, renderTime) {
11329 if (renderTime !== Never && workInProgress.expirationTime === Never) {
11330 // The children of this component are hidden. Don't bubble their
11331 // expiration times.
11332 return;
11333 }
11334
11335 // Check for pending updates.
11336 var newExpirationTime = getUpdateExpirationTime(workInProgress);
11337
11338 // TODO: Calls need to visit stateNode
11339
11340 // Bubble up the earliest expiration time.
11341 var child = workInProgress.child;
11342 while (child !== null) {
11343 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
11344 newExpirationTime = child.expirationTime;
11345 }
11346 child = child.sibling;
11347 }
11348 workInProgress.expirationTime = newExpirationTime;
11349 }
11350
11351 function completeUnitOfWork(workInProgress) {
11352 while (true) {
11353 // The current, flushed, state of this fiber is the alternate.
11354 // Ideally nothing should rely on this, but relying on it here
11355 // means that we don't need an additional field on the work in
11356 // progress.
11357 var current = workInProgress.alternate;
11358 {
11359 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
11360 }
11361 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
11362 {
11363 ReactDebugCurrentFiber.resetCurrentFiber();
11364 }
11365
11366 var returnFiber = workInProgress['return'];
11367 var siblingFiber = workInProgress.sibling;
11368
11369 resetExpirationTime(workInProgress, nextRenderExpirationTime);
11370
11371 if (next !== null) {
11372 stopWorkTimer(workInProgress);
11373 if (true && ReactFiberInstrumentation_1.debugTool) {
11374 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11375 }
11376 // If completing this work spawned new work, do that next. We'll come
11377 // back here again.
11378 return next;
11379 }
11380
11381 if (returnFiber !== null) {
11382 // Append all the effects of the subtree and this fiber onto the effect
11383 // list of the parent. The completion order of the children affects the
11384 // side-effect order.
11385 if (returnFiber.firstEffect === null) {
11386 returnFiber.firstEffect = workInProgress.firstEffect;
11387 }
11388 if (workInProgress.lastEffect !== null) {
11389 if (returnFiber.lastEffect !== null) {
11390 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11391 }
11392 returnFiber.lastEffect = workInProgress.lastEffect;
11393 }
11394
11395 // If this fiber had side-effects, we append it AFTER the children's
11396 // side-effects. We can perform certain side-effects earlier if
11397 // needed, by doing multiple passes over the effect list. We don't want
11398 // to schedule our own side-effect on our own list because if end up
11399 // reusing children we'll schedule this effect onto itself since we're
11400 // at the end.
11401 var effectTag = workInProgress.effectTag;
11402 // Skip both NoWork and PerformedWork tags when creating the effect list.
11403 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11404 if (effectTag > PerformedWork) {
11405 if (returnFiber.lastEffect !== null) {
11406 returnFiber.lastEffect.nextEffect = workInProgress;
11407 } else {
11408 returnFiber.firstEffect = workInProgress;
11409 }
11410 returnFiber.lastEffect = workInProgress;
11411 }
11412 }
11413
11414 stopWorkTimer(workInProgress);
11415 if (true && ReactFiberInstrumentation_1.debugTool) {
11416 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11417 }
11418
11419 if (siblingFiber !== null) {
11420 // If there is more work to do in this returnFiber, do that next.
11421 return siblingFiber;
11422 } else if (returnFiber !== null) {
11423 // If there's no more work in this returnFiber. Complete the returnFiber.
11424 workInProgress = returnFiber;
11425 continue;
11426 } else {
11427 // We've reached the root.
11428 var root = workInProgress.stateNode;
11429 root.isReadyForCommit = true;
11430 return null;
11431 }
11432 }
11433
11434 // Without this explicit null return Flow complains of invalid return type
11435 // TODO Remove the above while(true) loop
11436 // eslint-disable-next-line no-unreachable
11437 return null;
11438 }
11439
11440 function performUnitOfWork(workInProgress) {
11441 // The current, flushed, state of this fiber is the alternate.
11442 // Ideally nothing should rely on this, but relying on it here
11443 // means that we don't need an additional field on the work in
11444 // progress.
11445 var current = workInProgress.alternate;
11446
11447 // See if beginning this work spawns more work.
11448 startWorkTimer(workInProgress);
11449 {
11450 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
11451 }
11452
11453 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
11454 {
11455 ReactDebugCurrentFiber.resetCurrentFiber();
11456 }
11457 if (true && ReactFiberInstrumentation_1.debugTool) {
11458 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11459 }
11460
11461 if (next === null) {
11462 // If this doesn't spawn new work, complete the current work.
11463 next = completeUnitOfWork(workInProgress);
11464 }
11465
11466 ReactCurrentOwner.current = null;
11467
11468 return next;
11469 }
11470
11471 function performFailedUnitOfWork(workInProgress) {
11472 {
11473 ReactStrictModeWarnings.discardPendingWarnings();
11474 }
11475
11476 // The current, flushed, state of this fiber is the alternate.
11477 // Ideally nothing should rely on this, but relying on it here
11478 // means that we don't need an additional field on the work in
11479 // progress.
11480 var current = workInProgress.alternate;
11481
11482 // See if beginning this work spawns more work.
11483 startWorkTimer(workInProgress);
11484 {
11485 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
11486 }
11487 var next = beginFailedWork(current, workInProgress, nextRenderExpirationTime);
11488 {
11489 ReactDebugCurrentFiber.resetCurrentFiber();
11490 }
11491 if (true && ReactFiberInstrumentation_1.debugTool) {
11492 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11493 }
11494
11495 if (next === null) {
11496 // If this doesn't spawn new work, complete the current work.
11497 next = completeUnitOfWork(workInProgress);
11498 }
11499
11500 ReactCurrentOwner.current = null;
11501
11502 return next;
11503 }
11504
11505 function workLoop(isAsync) {
11506 if (capturedErrors !== null) {
11507 // If there are unhandled errors, switch to the slow work loop.
11508 // TODO: How to avoid this check in the fast path? Maybe the renderer
11509 // could keep track of which roots have unhandled errors and call a
11510 // forked version of renderRoot.
11511 slowWorkLoopThatChecksForFailedWork(isAsync);
11512 return;
11513 }
11514 if (!isAsync) {
11515 // Flush all expired work.
11516 while (nextUnitOfWork !== null) {
11517 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11518 }
11519 } else {
11520 // Flush asynchronous work until the deadline runs out of time.
11521 while (nextUnitOfWork !== null && !shouldYield()) {
11522 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11523 }
11524 }
11525 }
11526
11527 function slowWorkLoopThatChecksForFailedWork(isAsync) {
11528 if (!isAsync) {
11529 // Flush all expired work.
11530 while (nextUnitOfWork !== null) {
11531 if (hasCapturedError(nextUnitOfWork)) {
11532 // Use a forked version of performUnitOfWork
11533 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11534 } else {
11535 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11536 }
11537 }
11538 } else {
11539 // Flush asynchronous work until the deadline runs out of time.
11540 while (nextUnitOfWork !== null && !shouldYield()) {
11541 if (hasCapturedError(nextUnitOfWork)) {
11542 // Use a forked version of performUnitOfWork
11543 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11544 } else {
11545 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11546 }
11547 }
11548 }
11549 }
11550
11551 function renderRootCatchBlock(root, failedWork, boundary, isAsync) {
11552 // We're going to restart the error boundary that captured the error.
11553 // Conceptually, we're unwinding the stack. We need to unwind the
11554 // context stack, too.
11555 unwindContexts(failedWork, boundary);
11556
11557 // Restart the error boundary using a forked version of
11558 // performUnitOfWork that deletes the boundary's children. The entire
11559 // failed subree will be unmounted. During the commit phase, a special
11560 // lifecycle method is called on the error boundary, which triggers
11561 // a re-render.
11562 nextUnitOfWork = performFailedUnitOfWork(boundary);
11563
11564 // Continue working.
11565 workLoop(isAsync);
11566 }
11567
11568 function renderRoot(root, expirationTime, isAsync) {
11569 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11570 isWorking = true;
11571
11572 // We're about to mutate the work-in-progress tree. If the root was pending
11573 // commit, it no longer is: we'll need to complete it again.
11574 root.isReadyForCommit = false;
11575
11576 // Check if we're starting from a fresh stack, or if we're resuming from
11577 // previously yielded work.
11578 if (root !== nextRoot || expirationTime !== nextRenderExpirationTime || nextUnitOfWork === null) {
11579 // Reset the stack and start working from the root.
11580 resetContextStack();
11581 nextRoot = root;
11582 nextRenderExpirationTime = expirationTime;
11583 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, expirationTime);
11584 }
11585
11586 startWorkLoopTimer(nextUnitOfWork);
11587
11588 var didError = false;
11589 var error = null;
11590 {
11591 invokeGuardedCallback$2(null, workLoop, null, isAsync);
11592 if (hasCaughtError()) {
11593 didError = true;
11594 error = clearCaughtError();
11595 }
11596 }
11597
11598 // An error was thrown during the render phase.
11599 while (didError) {
11600 if (didFatal) {
11601 // This was a fatal error. Don't attempt to recover from it.
11602 firstUncaughtError = error;
11603 break;
11604 }
11605
11606 var failedWork = nextUnitOfWork;
11607 if (failedWork === null) {
11608 // An error was thrown but there's no current unit of work. This can
11609 // happen during the commit phase if there's a bug in the renderer.
11610 didFatal = true;
11611 continue;
11612 }
11613
11614 // "Capture" the error by finding the nearest boundary. If there is no
11615 // error boundary, we use the root.
11616 var boundary = captureError(failedWork, error);
11617 !(boundary !== null) ? invariant_1(false, 'Should have found an error boundary. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11618
11619 if (didFatal) {
11620 // The error we just captured was a fatal error. This happens
11621 // when the error propagates to the root more than once.
11622 continue;
11623 }
11624
11625 didError = false;
11626 error = null;
11627 {
11628 invokeGuardedCallback$2(null, renderRootCatchBlock, null, root, failedWork, boundary, isAsync);
11629 if (hasCaughtError()) {
11630 didError = true;
11631 error = clearCaughtError();
11632 continue;
11633 }
11634 }
11635 // We're finished working. Exit the error loop.
11636 break;
11637 }
11638
11639 var uncaughtError = firstUncaughtError;
11640
11641 // We're done performing work. Time to clean up.
11642 stopWorkLoopTimer(interruptedBy);
11643 interruptedBy = null;
11644 isWorking = false;
11645 didFatal = false;
11646 firstUncaughtError = null;
11647
11648 if (uncaughtError !== null) {
11649 onUncaughtError(uncaughtError);
11650 }
11651
11652 return root.isReadyForCommit ? root.current.alternate : null;
11653 }
11654
11655 // Returns the boundary that captured the error, or null if the error is ignored
11656 function captureError(failedWork, error) {
11657 // It is no longer valid because we exited the user code.
11658 ReactCurrentOwner.current = null;
11659 {
11660 ReactDebugCurrentFiber.resetCurrentFiber();
11661 }
11662
11663 // Search for the nearest error boundary.
11664 var boundary = null;
11665
11666 // Passed to logCapturedError()
11667 var errorBoundaryFound = false;
11668 var willRetry = false;
11669 var errorBoundaryName = null;
11670
11671 // Host containers are a special case. If the failed work itself is a host
11672 // container, then it acts as its own boundary. In all other cases, we
11673 // ignore the work itself and only search through the parents.
11674 if (failedWork.tag === HostRoot) {
11675 boundary = failedWork;
11676
11677 if (isFailedBoundary(failedWork)) {
11678 // If this root already failed, there must have been an error when
11679 // attempting to unmount it. This is a worst-case scenario and
11680 // should only be possible if there's a bug in the renderer.
11681 didFatal = true;
11682 }
11683 } else {
11684 var node = failedWork['return'];
11685 while (node !== null && boundary === null) {
11686 if (node.tag === ClassComponent) {
11687 var instance = node.stateNode;
11688 if (typeof instance.componentDidCatch === 'function') {
11689 errorBoundaryFound = true;
11690 errorBoundaryName = getComponentName(node);
11691
11692 // Found an error boundary!
11693 boundary = node;
11694 willRetry = true;
11695 }
11696 } else if (node.tag === HostRoot) {
11697 // Treat the root like a no-op error boundary
11698 boundary = node;
11699 }
11700
11701 if (isFailedBoundary(node)) {
11702 // This boundary is already in a failed state.
11703
11704 // If we're currently unmounting, that means this error was
11705 // thrown while unmounting a failed subtree. We should ignore
11706 // the error.
11707 if (isUnmounting) {
11708 return null;
11709 }
11710
11711 // If we're in the commit phase, we should check to see if
11712 // this boundary already captured an error during this commit.
11713 // This case exists because multiple errors can be thrown during
11714 // a single commit without interruption.
11715 if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) {
11716 // If so, we should ignore this error.
11717 return null;
11718 }
11719
11720 // The error should propagate to the next boundary -? we keep looking.
11721 boundary = null;
11722 willRetry = false;
11723 }
11724
11725 node = node['return'];
11726 }
11727 }
11728
11729 if (boundary !== null) {
11730 // Add to the collection of failed boundaries. This lets us know that
11731 // subsequent errors in this subtree should propagate to the next boundary.
11732 if (failedBoundaries === null) {
11733 failedBoundaries = new Set();
11734 }
11735 failedBoundaries.add(boundary);
11736
11737 // This method is unsafe outside of the begin and complete phases.
11738 // We might be in the commit phase when an error is captured.
11739 // The risk is that the return path from this Fiber may not be accurate.
11740 // That risk is acceptable given the benefit of providing users more context.
11741 var _componentStack = getStackAddendumByWorkInProgressFiber(failedWork);
11742 var _componentName = getComponentName(failedWork);
11743
11744 // Add to the collection of captured errors. This is stored as a global
11745 // map of errors and their component stack location keyed by the boundaries
11746 // that capture them. We mostly use this Map as a Set; it's a Map only to
11747 // avoid adding a field to Fiber to store the error.
11748 if (capturedErrors === null) {
11749 capturedErrors = new Map();
11750 }
11751
11752 var capturedError = {
11753 componentName: _componentName,
11754 componentStack: _componentStack,
11755 error: error,
11756 errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
11757 errorBoundaryFound: errorBoundaryFound,
11758 errorBoundaryName: errorBoundaryName,
11759 willRetry: willRetry
11760 };
11761
11762 capturedErrors.set(boundary, capturedError);
11763
11764 try {
11765 logCapturedError(capturedError);
11766 } catch (e) {
11767 // Prevent cycle if logCapturedError() throws.
11768 // A cycle may still occur if logCapturedError renders a component that throws.
11769 var suppressLogging = e && e.suppressReactErrorLogging;
11770 if (!suppressLogging) {
11771 console.error(e);
11772 }
11773 }
11774
11775 // If we're in the commit phase, defer scheduling an update on the
11776 // boundary until after the commit is complete
11777 if (isCommitting) {
11778 if (commitPhaseBoundaries === null) {
11779 commitPhaseBoundaries = new Set();
11780 }
11781 commitPhaseBoundaries.add(boundary);
11782 } else {
11783 // Otherwise, schedule an update now.
11784 // TODO: Is this actually necessary during the render phase? Is it
11785 // possible to unwind and continue rendering at the same priority,
11786 // without corrupting internal state?
11787 scheduleErrorRecovery(boundary);
11788 }
11789 return boundary;
11790 } else if (firstUncaughtError === null) {
11791 // If no boundary is found, we'll need to throw the error
11792 firstUncaughtError = error;
11793 }
11794 return null;
11795 }
11796
11797 function hasCapturedError(fiber) {
11798 // TODO: capturedErrors should store the boundary instance, to avoid needing
11799 // to check the alternate.
11800 return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate));
11801 }
11802
11803 function isFailedBoundary(fiber) {
11804 // TODO: failedBoundaries should store the boundary instance, to avoid
11805 // needing to check the alternate.
11806 return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate));
11807 }
11808
11809 function commitErrorHandling(effectfulFiber) {
11810 var capturedError = void 0;
11811 if (capturedErrors !== null) {
11812 capturedError = capturedErrors.get(effectfulFiber);
11813 capturedErrors['delete'](effectfulFiber);
11814 if (capturedError == null) {
11815 if (effectfulFiber.alternate !== null) {
11816 effectfulFiber = effectfulFiber.alternate;
11817 capturedError = capturedErrors.get(effectfulFiber);
11818 capturedErrors['delete'](effectfulFiber);
11819 }
11820 }
11821 }
11822
11823 !(capturedError != null) ? invariant_1(false, 'No error for given unit of work. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11824
11825 switch (effectfulFiber.tag) {
11826 case ClassComponent:
11827 var instance = effectfulFiber.stateNode;
11828
11829 var info = {
11830 componentStack: capturedError.componentStack
11831 };
11832
11833 // Allow the boundary to handle the error, usually by scheduling
11834 // an update to itself
11835 instance.componentDidCatch(capturedError.error, info);
11836 return;
11837 case HostRoot:
11838 if (firstUncaughtError === null) {
11839 firstUncaughtError = capturedError.error;
11840 }
11841 return;
11842 default:
11843 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
11844 }
11845 }
11846
11847 function unwindContexts(from, to) {
11848 var node = from;
11849 while (node !== null) {
11850 switch (node.tag) {
11851 case ClassComponent:
11852 popContextProvider(node);
11853 break;
11854 case HostComponent:
11855 popHostContext(node);
11856 break;
11857 case HostRoot:
11858 popHostContainer(node);
11859 break;
11860 case HostPortal:
11861 popHostContainer(node);
11862 break;
11863 case ContextProvider:
11864 popProvider(node);
11865 break;
11866 }
11867 if (node === to || node.alternate === to) {
11868 stopFailedWorkTimer(node);
11869 break;
11870 } else {
11871 stopWorkTimer(node);
11872 }
11873 node = node['return'];
11874 }
11875 }
11876
11877 function computeAsyncExpiration() {
11878 // Given the current clock time, returns an expiration time. We use rounding
11879 // to batch like updates together.
11880 // Should complete within ~1000ms. 1200ms max.
11881 var currentTime = recalculateCurrentTime();
11882 var expirationMs = 1000;
11883 var bucketSizeMs = 200;
11884 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11885 }
11886
11887 function computeInteractiveExpiration() {
11888 // Should complete within ~500ms. 600ms max.
11889 var currentTime = recalculateCurrentTime();
11890 var expirationMs = 500;
11891 var bucketSizeMs = 100;
11892 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11893 }
11894
11895 // Creates a unique async expiration time.
11896 function computeUniqueAsyncExpiration() {
11897 var result = computeAsyncExpiration();
11898 if (result <= lastUniqueAsyncExpiration) {
11899 // Since we assume the current time monotonically increases, we only hit
11900 // this branch when computeUniqueAsyncExpiration is fired multiple times
11901 // within a 200ms window (or whatever the async bucket size is).
11902 result = lastUniqueAsyncExpiration + 1;
11903 }
11904 lastUniqueAsyncExpiration = result;
11905 return lastUniqueAsyncExpiration;
11906 }
11907
11908 function computeExpirationForFiber(fiber) {
11909 var expirationTime = void 0;
11910 if (expirationContext !== NoWork) {
11911 // An explicit expiration context was set;
11912 expirationTime = expirationContext;
11913 } else if (isWorking) {
11914 if (isCommitting) {
11915 // Updates that occur during the commit phase should have sync priority
11916 // by default.
11917 expirationTime = Sync;
11918 } else {
11919 // Updates during the render phase should expire at the same time as
11920 // the work that is being rendered.
11921 expirationTime = nextRenderExpirationTime;
11922 }
11923 } else {
11924 // No explicit expiration context was set, and we're not currently
11925 // performing work. Calculate a new expiration time.
11926 if (fiber.mode & AsyncMode) {
11927 if (isBatchingInteractiveUpdates) {
11928 // This is an interactive update
11929 expirationTime = computeInteractiveExpiration();
11930 } else {
11931 // This is an async update
11932 expirationTime = computeAsyncExpiration();
11933 }
11934 } else {
11935 // This is a sync update
11936 expirationTime = Sync;
11937 }
11938 }
11939 if (isBatchingInteractiveUpdates) {
11940 // This is an interactive update. Keep track of the lowest pending
11941 // interactive expiration time. This allows us to synchronously flush
11942 // all interactive updates when needed.
11943 if (lowestPendingInteractiveExpirationTime === NoWork || expirationTime > lowestPendingInteractiveExpirationTime) {
11944 lowestPendingInteractiveExpirationTime = expirationTime;
11945 }
11946 }
11947 return expirationTime;
11948 }
11949
11950 function scheduleWork(fiber, expirationTime) {
11951 return scheduleWorkImpl(fiber, expirationTime, false);
11952 }
11953
11954 function checkRootNeedsClearing(root, fiber, expirationTime) {
11955 if (!isWorking && root === nextRoot && expirationTime < nextRenderExpirationTime) {
11956 // Restart the root from the top.
11957 if (nextUnitOfWork !== null) {
11958 // This is an interruption. (Used for performance tracking.)
11959 interruptedBy = fiber;
11960 }
11961 nextRoot = null;
11962 nextUnitOfWork = null;
11963 nextRenderExpirationTime = NoWork;
11964 }
11965 }
11966
11967 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
11968 recordScheduleUpdate();
11969
11970 {
11971 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11972 var instance = fiber.stateNode;
11973 warnAboutInvalidUpdates(instance);
11974 }
11975 }
11976
11977 var node = fiber;
11978 while (node !== null) {
11979 // Walk the parent path to the root and update each node's
11980 // expiration time.
11981 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
11982 node.expirationTime = expirationTime;
11983 }
11984 if (node.alternate !== null) {
11985 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
11986 node.alternate.expirationTime = expirationTime;
11987 }
11988 }
11989 if (node['return'] === null) {
11990 if (node.tag === HostRoot) {
11991 var root = node.stateNode;
11992
11993 checkRootNeedsClearing(root, fiber, expirationTime);
11994 requestWork(root, expirationTime);
11995 checkRootNeedsClearing(root, fiber, expirationTime);
11996 } else {
11997 {
11998 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11999 warnAboutUpdateOnUnmounted(fiber);
12000 }
12001 }
12002 return;
12003 }
12004 }
12005 node = node['return'];
12006 }
12007 }
12008
12009 function scheduleErrorRecovery(fiber) {
12010 scheduleWorkImpl(fiber, Sync, true);
12011 }
12012
12013 function recalculateCurrentTime() {
12014 // Subtract initial time so it fits inside 32bits
12015 var ms = now() - startTime;
12016 mostRecentCurrentTime = msToExpirationTime(ms);
12017 return mostRecentCurrentTime;
12018 }
12019
12020 function deferredUpdates(fn) {
12021 var previousExpirationContext = expirationContext;
12022 expirationContext = computeAsyncExpiration();
12023 try {
12024 return fn();
12025 } finally {
12026 expirationContext = previousExpirationContext;
12027 }
12028 }
12029
12030 function syncUpdates(fn, a, b, c, d) {
12031 var previousExpirationContext = expirationContext;
12032 expirationContext = Sync;
12033 try {
12034 return fn(a, b, c, d);
12035 } finally {
12036 expirationContext = previousExpirationContext;
12037 }
12038 }
12039
12040 // TODO: Everything below this is written as if it has been lifted to the
12041 // renderers. I'll do this in a follow-up.
12042
12043 // Linked-list of roots
12044 var firstScheduledRoot = null;
12045 var lastScheduledRoot = null;
12046
12047 var callbackExpirationTime = NoWork;
12048 var callbackID = -1;
12049 var isRendering = false;
12050 var nextFlushedRoot = null;
12051 var nextFlushedExpirationTime = NoWork;
12052 var lowestPendingInteractiveExpirationTime = NoWork;
12053 var deadlineDidExpire = false;
12054 var hasUnhandledError = false;
12055 var unhandledError = null;
12056 var deadline = null;
12057
12058 var isBatchingUpdates = false;
12059 var isUnbatchingUpdates = false;
12060 var isBatchingInteractiveUpdates = false;
12061
12062 var completedBatches = null;
12063
12064 // Use these to prevent an infinite loop of nested updates
12065 var NESTED_UPDATE_LIMIT = 1000;
12066 var nestedUpdateCount = 0;
12067
12068 var timeHeuristicForUnitOfWork = 1;
12069
12070 function scheduleCallbackWithExpiration(expirationTime) {
12071 if (callbackExpirationTime !== NoWork) {
12072 // A callback is already scheduled. Check its expiration time (timeout).
12073 if (expirationTime > callbackExpirationTime) {
12074 // Existing callback has sufficient timeout. Exit.
12075 return;
12076 } else {
12077 // Existing callback has insufficient timeout. Cancel and schedule a
12078 // new one.
12079 cancelDeferredCallback(callbackID);
12080 }
12081 // The request callback timer is already running. Don't start a new one.
12082 } else {
12083 startRequestCallbackTimer();
12084 }
12085
12086 // Compute a timeout for the given expiration time.
12087 var currentMs = now() - startTime;
12088 var expirationMs = expirationTimeToMs(expirationTime);
12089 var timeout = expirationMs - currentMs;
12090
12091 callbackExpirationTime = expirationTime;
12092 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
12093 }
12094
12095 // requestWork is called by the scheduler whenever a root receives an update.
12096 // It's up to the renderer to call renderRoot at some point in the future.
12097 function requestWork(root, expirationTime) {
12098 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12099 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.');
12100 }
12101
12102 // Add the root to the schedule.
12103 // Check if this root is already part of the schedule.
12104 if (root.nextScheduledRoot === null) {
12105 // This root is not already scheduled. Add it.
12106 root.remainingExpirationTime = expirationTime;
12107 if (lastScheduledRoot === null) {
12108 firstScheduledRoot = lastScheduledRoot = root;
12109 root.nextScheduledRoot = root;
12110 } else {
12111 lastScheduledRoot.nextScheduledRoot = root;
12112 lastScheduledRoot = root;
12113 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12114 }
12115 } else {
12116 // This root is already scheduled, but its priority may have increased.
12117 var remainingExpirationTime = root.remainingExpirationTime;
12118 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
12119 // Update the priority.
12120 root.remainingExpirationTime = expirationTime;
12121 }
12122 }
12123
12124 if (isRendering) {
12125 // Prevent reentrancy. Remaining work will be scheduled at the end of
12126 // the currently rendering batch.
12127 return;
12128 }
12129
12130 if (isBatchingUpdates) {
12131 if (isUnbatchingUpdates) {
12132 // Flush work at the end of the batch.
12133 // ...unless we're inside unbatchedUpdates, in which case we should
12134 // flush it now.
12135 nextFlushedRoot = root;
12136 nextFlushedExpirationTime = Sync;
12137 performWorkOnRoot(root, Sync, false);
12138 }
12139 return;
12140 }
12141
12142 // TODO: Get rid of Sync and use current time?
12143 if (expirationTime === Sync) {
12144 performSyncWork();
12145 } else {
12146 scheduleCallbackWithExpiration(expirationTime);
12147 }
12148 }
12149
12150 function findHighestPriorityRoot() {
12151 var highestPriorityWork = NoWork;
12152 var highestPriorityRoot = null;
12153
12154 if (lastScheduledRoot !== null) {
12155 var previousScheduledRoot = lastScheduledRoot;
12156 var root = firstScheduledRoot;
12157 while (root !== null) {
12158 var remainingExpirationTime = root.remainingExpirationTime;
12159 if (remainingExpirationTime === NoWork) {
12160 // This root no longer has work. Remove it from the scheduler.
12161
12162 // TODO: This check is redudant, but Flow is confused by the branch
12163 // below where we set lastScheduledRoot to null, even though we break
12164 // from the loop right after.
12165 !(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;
12166 if (root === root.nextScheduledRoot) {
12167 // This is the only root in the list.
12168 root.nextScheduledRoot = null;
12169 firstScheduledRoot = lastScheduledRoot = null;
12170 break;
12171 } else if (root === firstScheduledRoot) {
12172 // This is the first root in the list.
12173 var next = root.nextScheduledRoot;
12174 firstScheduledRoot = next;
12175 lastScheduledRoot.nextScheduledRoot = next;
12176 root.nextScheduledRoot = null;
12177 } else if (root === lastScheduledRoot) {
12178 // This is the last root in the list.
12179 lastScheduledRoot = previousScheduledRoot;
12180 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12181 root.nextScheduledRoot = null;
12182 break;
12183 } else {
12184 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12185 root.nextScheduledRoot = null;
12186 }
12187 root = previousScheduledRoot.nextScheduledRoot;
12188 } else {
12189 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
12190 // Update the priority, if it's higher
12191 highestPriorityWork = remainingExpirationTime;
12192 highestPriorityRoot = root;
12193 }
12194 if (root === lastScheduledRoot) {
12195 break;
12196 }
12197 previousScheduledRoot = root;
12198 root = root.nextScheduledRoot;
12199 }
12200 }
12201 }
12202
12203 // If the next root is the same as the previous root, this is a nested
12204 // update. To prevent an infinite loop, increment the nested update count.
12205 var previousFlushedRoot = nextFlushedRoot;
12206 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot) {
12207 nestedUpdateCount++;
12208 } else {
12209 // Reset whenever we switch roots.
12210 nestedUpdateCount = 0;
12211 }
12212 nextFlushedRoot = highestPriorityRoot;
12213 nextFlushedExpirationTime = highestPriorityWork;
12214 }
12215
12216 function performAsyncWork(dl) {
12217 performWork(NoWork, true, dl);
12218 }
12219
12220 function performSyncWork() {
12221 performWork(Sync, false, null);
12222 }
12223
12224 function performWork(minExpirationTime, isAsync, dl) {
12225 deadline = dl;
12226
12227 // Keep working on roots until there's no more work, or until the we reach
12228 // the deadline.
12229 findHighestPriorityRoot();
12230
12231 if (enableUserTimingAPI && deadline !== null) {
12232 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
12233 stopRequestCallbackTimer(didExpire);
12234 }
12235
12236 if (isAsync) {
12237 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime) && (!deadlineDidExpire || recalculateCurrentTime() >= nextFlushedExpirationTime)) {
12238 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, !deadlineDidExpire);
12239 findHighestPriorityRoot();
12240 }
12241 } else {
12242 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime)) {
12243 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12244 findHighestPriorityRoot();
12245 }
12246 }
12247
12248 // We're done flushing work. Either we ran out of time in this callback,
12249 // or there's no more work left with sufficient priority.
12250
12251 // If we're inside a callback, set this to false since we just completed it.
12252 if (deadline !== null) {
12253 callbackExpirationTime = NoWork;
12254 callbackID = -1;
12255 }
12256 // If there's work left over, schedule a new callback.
12257 if (nextFlushedExpirationTime !== NoWork) {
12258 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
12259 }
12260
12261 // Clean-up.
12262 deadline = null;
12263 deadlineDidExpire = false;
12264 nestedUpdateCount = 0;
12265
12266 finishRendering();
12267 }
12268
12269 function flushRoot(root, expirationTime) {
12270 !!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;
12271 // Perform work on root as if the given expiration time is the current time.
12272 // This has the effect of synchronously flushing all work up to and
12273 // including the given time.
12274 performWorkOnRoot(root, expirationTime, false);
12275 finishRendering();
12276 }
12277
12278 function finishRendering() {
12279 if (completedBatches !== null) {
12280 var batches = completedBatches;
12281 completedBatches = null;
12282 for (var i = 0; i < batches.length; i++) {
12283 var batch = batches[i];
12284 try {
12285 batch._onComplete();
12286 } catch (error) {
12287 if (!hasUnhandledError) {
12288 hasUnhandledError = true;
12289 unhandledError = error;
12290 }
12291 }
12292 }
12293 }
12294
12295 if (hasUnhandledError) {
12296 var _error4 = unhandledError;
12297 unhandledError = null;
12298 hasUnhandledError = false;
12299 throw _error4;
12300 }
12301 }
12302
12303 function performWorkOnRoot(root, expirationTime, isAsync) {
12304 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12305
12306 isRendering = true;
12307
12308 // Check if this is async work or sync/expired work.
12309 if (!isAsync) {
12310 // Flush sync work.
12311 var finishedWork = root.finishedWork;
12312 if (finishedWork !== null) {
12313 // This root is already complete. We can commit it.
12314 completeRoot(root, finishedWork, expirationTime);
12315 } else {
12316 root.finishedWork = null;
12317 finishedWork = renderRoot(root, expirationTime, false);
12318 if (finishedWork !== null) {
12319 // We've completed the root. Commit it.
12320 completeRoot(root, finishedWork, expirationTime);
12321 }
12322 }
12323 } else {
12324 // Flush async work.
12325 var _finishedWork = root.finishedWork;
12326 if (_finishedWork !== null) {
12327 // This root is already complete. We can commit it.
12328 completeRoot(root, _finishedWork, expirationTime);
12329 } else {
12330 root.finishedWork = null;
12331 _finishedWork = renderRoot(root, expirationTime, true);
12332 if (_finishedWork !== null) {
12333 // We've completed the root. Check the deadline one more time
12334 // before committing.
12335 if (!shouldYield()) {
12336 // Still time left. Commit the root.
12337 completeRoot(root, _finishedWork, expirationTime);
12338 } else {
12339 // There's no time left. Mark this root as complete. We'll come
12340 // back and commit it later.
12341 root.finishedWork = _finishedWork;
12342 }
12343 }
12344 }
12345 }
12346
12347 isRendering = false;
12348 }
12349
12350 function completeRoot(root, finishedWork, expirationTime) {
12351 // Check if there's a batch that matches this expiration time.
12352 var firstBatch = root.firstBatch;
12353 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
12354 if (completedBatches === null) {
12355 completedBatches = [firstBatch];
12356 } else {
12357 completedBatches.push(firstBatch);
12358 }
12359 if (firstBatch._defer) {
12360 // This root is blocked from committing by a batch. Unschedule it until
12361 // we receive another update.
12362 root.finishedWork = finishedWork;
12363 root.remainingExpirationTime = NoWork;
12364 return;
12365 }
12366 }
12367
12368 // Commit the root.
12369 root.finishedWork = null;
12370 root.remainingExpirationTime = commitRoot(finishedWork);
12371 }
12372
12373 // When working on async work, the reconciler asks the renderer if it should
12374 // yield execution. For DOM, we implement this with requestIdleCallback.
12375 function shouldYield() {
12376 if (deadline === null) {
12377 return false;
12378 }
12379 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
12380 // Disregard deadline.didTimeout. Only expired work should be flushed
12381 // during a timeout. This path is only hit for non-expired work.
12382 return false;
12383 }
12384 deadlineDidExpire = true;
12385 return true;
12386 }
12387
12388 // TODO: Not happy about this hook. Conceptually, renderRoot should return a
12389 // tuple of (isReadyForCommit, didError, error)
12390 function onUncaughtError(error) {
12391 !(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;
12392 // Unschedule this root so we don't work on it again until there's
12393 // another update.
12394 nextFlushedRoot.remainingExpirationTime = NoWork;
12395 if (!hasUnhandledError) {
12396 hasUnhandledError = true;
12397 unhandledError = error;
12398 }
12399 }
12400
12401 // TODO: Batching should be implemented at the renderer level, not inside
12402 // the reconciler.
12403 function batchedUpdates(fn, a) {
12404 var previousIsBatchingUpdates = isBatchingUpdates;
12405 isBatchingUpdates = true;
12406 try {
12407 return fn(a);
12408 } finally {
12409 isBatchingUpdates = previousIsBatchingUpdates;
12410 if (!isBatchingUpdates && !isRendering) {
12411 performSyncWork();
12412 }
12413 }
12414 }
12415
12416 // TODO: Batching should be implemented at the renderer level, not inside
12417 // the reconciler.
12418 function unbatchedUpdates(fn, a) {
12419 if (isBatchingUpdates && !isUnbatchingUpdates) {
12420 isUnbatchingUpdates = true;
12421 try {
12422 return fn(a);
12423 } finally {
12424 isUnbatchingUpdates = false;
12425 }
12426 }
12427 return fn(a);
12428 }
12429
12430 // TODO: Batching should be implemented at the renderer level, not within
12431 // the reconciler.
12432 function flushSync(fn, a) {
12433 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
12434 var previousIsBatchingUpdates = isBatchingUpdates;
12435 isBatchingUpdates = true;
12436 try {
12437 return syncUpdates(fn, a);
12438 } finally {
12439 isBatchingUpdates = previousIsBatchingUpdates;
12440 performSyncWork();
12441 }
12442 }
12443
12444 function interactiveUpdates(fn, a, b) {
12445 if (isBatchingInteractiveUpdates) {
12446 return fn(a, b);
12447 }
12448 // If there are any pending interactive updates, synchronously flush them.
12449 // This needs to happen before we read any handlers, because the effect of
12450 // the previous event may influence which handlers are called during
12451 // this event.
12452 if (!isBatchingUpdates && !isRendering && lowestPendingInteractiveExpirationTime !== NoWork) {
12453 // Synchronously flush pending interactive updates.
12454 performWork(lowestPendingInteractiveExpirationTime, false, null);
12455 lowestPendingInteractiveExpirationTime = NoWork;
12456 }
12457 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
12458 var previousIsBatchingUpdates = isBatchingUpdates;
12459 isBatchingInteractiveUpdates = true;
12460 isBatchingUpdates = true;
12461 try {
12462 return fn(a, b);
12463 } finally {
12464 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
12465 isBatchingUpdates = previousIsBatchingUpdates;
12466 if (!isBatchingUpdates && !isRendering) {
12467 performSyncWork();
12468 }
12469 }
12470 }
12471
12472 function flushInteractiveUpdates() {
12473 if (!isRendering && lowestPendingInteractiveExpirationTime !== NoWork) {
12474 // Synchronously flush pending interactive updates.
12475 performWork(lowestPendingInteractiveExpirationTime, false, null);
12476 lowestPendingInteractiveExpirationTime = NoWork;
12477 }
12478 }
12479
12480 function flushControlled(fn) {
12481 var previousIsBatchingUpdates = isBatchingUpdates;
12482 isBatchingUpdates = true;
12483 try {
12484 syncUpdates(fn);
12485 } finally {
12486 isBatchingUpdates = previousIsBatchingUpdates;
12487 if (!isBatchingUpdates && !isRendering) {
12488 performWork(Sync, false, null);
12489 }
12490 }
12491 }
12492
12493 return {
12494 computeExpirationForFiber: computeExpirationForFiber,
12495 scheduleWork: scheduleWork,
12496 requestWork: requestWork,
12497 flushRoot: flushRoot,
12498 batchedUpdates: batchedUpdates,
12499 unbatchedUpdates: unbatchedUpdates,
12500 flushSync: flushSync,
12501 flushControlled: flushControlled,
12502 deferredUpdates: deferredUpdates,
12503 syncUpdates: syncUpdates,
12504 interactiveUpdates: interactiveUpdates,
12505 flushInteractiveUpdates: flushInteractiveUpdates,
12506 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
12507 };
12508};
12509
12510var didWarnAboutNestedUpdates = void 0;
12511
12512{
12513 didWarnAboutNestedUpdates = false;
12514}
12515
12516// 0 is PROD, 1 is DEV.
12517// Might add PROFILE later.
12518
12519
12520function getContextForSubtree(parentComponent) {
12521 if (!parentComponent) {
12522 return emptyObject_1;
12523 }
12524
12525 var fiber = get(parentComponent);
12526 var parentContext = findCurrentUnmaskedContext(fiber);
12527 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
12528}
12529
12530var ReactFiberReconciler$1 = function (config) {
12531 var getPublicInstance = config.getPublicInstance;
12532
12533 var _ReactFiberScheduler = ReactFiberScheduler(config),
12534 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
12535 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
12536 scheduleWork = _ReactFiberScheduler.scheduleWork,
12537 requestWork = _ReactFiberScheduler.requestWork,
12538 flushRoot = _ReactFiberScheduler.flushRoot,
12539 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
12540 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
12541 flushSync = _ReactFiberScheduler.flushSync,
12542 flushControlled = _ReactFiberScheduler.flushControlled,
12543 deferredUpdates = _ReactFiberScheduler.deferredUpdates,
12544 syncUpdates = _ReactFiberScheduler.syncUpdates,
12545 interactiveUpdates = _ReactFiberScheduler.interactiveUpdates,
12546 flushInteractiveUpdates = _ReactFiberScheduler.flushInteractiveUpdates;
12547
12548 function scheduleRootUpdate(current, element, expirationTime, callback) {
12549 {
12550 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
12551 didWarnAboutNestedUpdates = true;
12552 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');
12553 }
12554 }
12555
12556 callback = callback === undefined ? null : callback;
12557 {
12558 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
12559 }
12560
12561 var update = {
12562 expirationTime: expirationTime,
12563 partialState: { element: element },
12564 callback: callback,
12565 isReplace: false,
12566 isForced: false,
12567 next: null
12568 };
12569 insertUpdateIntoFiber(current, update);
12570 scheduleWork(current, expirationTime);
12571
12572 return expirationTime;
12573 }
12574
12575 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
12576 // TODO: If this is a nested container, this won't be the root.
12577 var current = container.current;
12578
12579 {
12580 if (ReactFiberInstrumentation_1.debugTool) {
12581 if (current.alternate === null) {
12582 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12583 } else if (element === null) {
12584 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12585 } else {
12586 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12587 }
12588 }
12589 }
12590
12591 var context = getContextForSubtree(parentComponent);
12592 if (container.context === null) {
12593 container.context = context;
12594 } else {
12595 container.pendingContext = context;
12596 }
12597
12598 return scheduleRootUpdate(current, element, expirationTime, callback);
12599 }
12600
12601 function findHostInstance(fiber) {
12602 var hostFiber = findCurrentHostFiber(fiber);
12603 if (hostFiber === null) {
12604 return null;
12605 }
12606 return hostFiber.stateNode;
12607 }
12608
12609 return {
12610 createContainer: function (containerInfo, isAsync, hydrate) {
12611 return createFiberRoot(containerInfo, isAsync, hydrate);
12612 },
12613 updateContainer: function (element, container, parentComponent, callback) {
12614 var current = container.current;
12615 var expirationTime = computeExpirationForFiber(current);
12616 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12617 },
12618
12619
12620 updateContainerAtExpirationTime: updateContainerAtExpirationTime,
12621
12622 flushRoot: flushRoot,
12623
12624 requestWork: requestWork,
12625
12626 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
12627
12628 batchedUpdates: batchedUpdates,
12629
12630 unbatchedUpdates: unbatchedUpdates,
12631
12632 deferredUpdates: deferredUpdates,
12633
12634 syncUpdates: syncUpdates,
12635
12636 interactiveUpdates: interactiveUpdates,
12637
12638 flushInteractiveUpdates: flushInteractiveUpdates,
12639
12640 flushControlled: flushControlled,
12641
12642 flushSync: flushSync,
12643
12644 getPublicRootInstance: function (container) {
12645 var containerFiber = container.current;
12646 if (!containerFiber.child) {
12647 return null;
12648 }
12649 switch (containerFiber.child.tag) {
12650 case HostComponent:
12651 return getPublicInstance(containerFiber.child.stateNode);
12652 default:
12653 return containerFiber.child.stateNode;
12654 }
12655 },
12656
12657
12658 findHostInstance: findHostInstance,
12659
12660 findHostInstanceWithNoPortals: function (fiber) {
12661 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
12662 if (hostFiber === null) {
12663 return null;
12664 }
12665 return hostFiber.stateNode;
12666 },
12667 injectIntoDevTools: function (devToolsConfig) {
12668 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12669
12670 return injectInternals(_assign({}, devToolsConfig, {
12671 findHostInstanceByFiber: function (fiber) {
12672 return findHostInstance(fiber);
12673 },
12674 findFiberByHostInstance: function (instance) {
12675 if (!findFiberByHostInstance) {
12676 // Might not be implemented by the renderer.
12677 return null;
12678 }
12679 return findFiberByHostInstance(instance);
12680 }
12681 }));
12682 }
12683 };
12684};
12685
12686var ReactFiberReconciler$2 = Object.freeze({
12687 default: ReactFiberReconciler$1
12688});
12689
12690var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
12691
12692// TODO: bundle Flow types with the package.
12693
12694
12695
12696// TODO: decide on the top-level export form.
12697// This is hacky but makes it work with both Rollup and Jest.
12698var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
12699
12700function createPortal$1(children, containerInfo,
12701// TODO: figure out the API for cross-renderer implementation.
12702implementation) {
12703 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
12704
12705 return {
12706 // This tag allow us to uniquely identify this as a React Portal
12707 $$typeof: REACT_PORTAL_TYPE,
12708 key: key == null ? null : '' + key,
12709 children: children,
12710 containerInfo: containerInfo,
12711 implementation: implementation
12712 };
12713}
12714
12715// TODO: this is special because it gets imported during build.
12716
12717var ReactVersion = '16.3.0-alpha.1';
12718
12719// a requestAnimationFrame, storing the time for the start of the frame, then
12720// scheduling a postMessage which gets scheduled after paint. Within the
12721// postMessage handler do as much work as possible until time + frame rate.
12722// By separating the idle call into a separate event tick we ensure that
12723// layout, paint and other browser work is counted against the available time.
12724// The frame rate is dynamically adjusted.
12725
12726{
12727 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
12728 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
12729 }
12730}
12731
12732var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
12733
12734var now = void 0;
12735if (hasNativePerformanceNow) {
12736 now = function () {
12737 return performance.now();
12738 };
12739} else {
12740 now = function () {
12741 return Date.now();
12742 };
12743}
12744
12745// TODO: There's no way to cancel, because Fiber doesn't atm.
12746var rIC = void 0;
12747var cIC = void 0;
12748
12749if (!ExecutionEnvironment_1.canUseDOM) {
12750 rIC = function (frameCallback) {
12751 return setTimeout(function () {
12752 frameCallback({
12753 timeRemaining: function () {
12754 return Infinity;
12755 }
12756 });
12757 });
12758 };
12759 cIC = function (timeoutID) {
12760 clearTimeout(timeoutID);
12761 };
12762} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
12763 // Polyfill requestIdleCallback and cancelIdleCallback
12764
12765 var scheduledRICCallback = null;
12766 var isIdleScheduled = false;
12767 var timeoutTime = -1;
12768
12769 var isAnimationFrameScheduled = false;
12770
12771 var frameDeadline = 0;
12772 // We start out assuming that we run at 30fps but then the heuristic tracking
12773 // will adjust this value to a faster fps if we get more frequent animation
12774 // frames.
12775 var previousFrameTime = 33;
12776 var activeFrameTime = 33;
12777
12778 var frameDeadlineObject = void 0;
12779 if (hasNativePerformanceNow) {
12780 frameDeadlineObject = {
12781 didTimeout: false,
12782 timeRemaining: function () {
12783 // We assume that if we have a performance timer that the rAF callback
12784 // gets a performance timer value. Not sure if this is always true.
12785 var remaining = frameDeadline - performance.now();
12786 return remaining > 0 ? remaining : 0;
12787 }
12788 };
12789 } else {
12790 frameDeadlineObject = {
12791 didTimeout: false,
12792 timeRemaining: function () {
12793 // Fallback to Date.now()
12794 var remaining = frameDeadline - Date.now();
12795 return remaining > 0 ? remaining : 0;
12796 }
12797 };
12798 }
12799
12800 // We use the postMessage trick to defer idle work until after the repaint.
12801 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12802 var idleTick = function (event) {
12803 if (event.source !== window || event.data !== messageKey) {
12804 return;
12805 }
12806
12807 isIdleScheduled = false;
12808
12809 var currentTime = now();
12810 if (frameDeadline - currentTime <= 0) {
12811 // There's no time left in this idle period. Check if the callback has
12812 // a timeout and whether it's been exceeded.
12813 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12814 // Exceeded the timeout. Invoke the callback even though there's no
12815 // time left.
12816 frameDeadlineObject.didTimeout = true;
12817 } else {
12818 // No timeout.
12819 if (!isAnimationFrameScheduled) {
12820 // Schedule another animation callback so we retry later.
12821 isAnimationFrameScheduled = true;
12822 requestAnimationFrame(animationTick);
12823 }
12824 // Exit without invoking the callback.
12825 return;
12826 }
12827 } else {
12828 // There's still time left in this idle period.
12829 frameDeadlineObject.didTimeout = false;
12830 }
12831
12832 timeoutTime = -1;
12833 var callback = scheduledRICCallback;
12834 scheduledRICCallback = null;
12835 if (callback !== null) {
12836 callback(frameDeadlineObject);
12837 }
12838 };
12839 // Assumes that we have addEventListener in this environment. Might need
12840 // something better for old IE.
12841 window.addEventListener('message', idleTick, false);
12842
12843 var animationTick = function (rafTime) {
12844 isAnimationFrameScheduled = false;
12845 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12846 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12847 if (nextFrameTime < 8) {
12848 // Defensive coding. We don't support higher frame rates than 120hz.
12849 // If we get lower than that, it is probably a bug.
12850 nextFrameTime = 8;
12851 }
12852 // If one frame goes long, then the next one can be short to catch up.
12853 // If two frames are short in a row, then that's an indication that we
12854 // actually have a higher frame rate than what we're currently optimizing.
12855 // We adjust our heuristic dynamically accordingly. For example, if we're
12856 // running on 120hz display or 90hz VR display.
12857 // Take the max of the two in case one of them was an anomaly due to
12858 // missed frame deadlines.
12859 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12860 } else {
12861 previousFrameTime = nextFrameTime;
12862 }
12863 frameDeadline = rafTime + activeFrameTime;
12864 if (!isIdleScheduled) {
12865 isIdleScheduled = true;
12866 window.postMessage(messageKey, '*');
12867 }
12868 };
12869
12870 rIC = function (callback, options) {
12871 // This assumes that we only schedule one callback at a time because that's
12872 // how Fiber uses it.
12873 scheduledRICCallback = callback;
12874 if (options != null && typeof options.timeout === 'number') {
12875 timeoutTime = now() + options.timeout;
12876 }
12877 if (!isAnimationFrameScheduled) {
12878 // If rAF didn't already schedule one, we need to schedule a frame.
12879 // TODO: If this rAF doesn't materialize because the browser throttles, we
12880 // might want to still have setTimeout trigger rIC as a backup to ensure
12881 // that we keep performing work.
12882 isAnimationFrameScheduled = true;
12883 requestAnimationFrame(animationTick);
12884 }
12885 return 0;
12886 };
12887
12888 cIC = function () {
12889 scheduledRICCallback = null;
12890 isIdleScheduled = false;
12891 timeoutTime = -1;
12892 };
12893} else {
12894 rIC = window.requestIdleCallback;
12895 cIC = window.cancelIdleCallback;
12896}
12897
12898var didWarnSelectedSetOnOption = false;
12899
12900function flattenChildren(children) {
12901 var content = '';
12902
12903 // Flatten children and warn if they aren't strings or numbers;
12904 // invalid types are ignored.
12905 // We can silently skip them because invalid DOM nesting warning
12906 // catches these cases in Fiber.
12907 React.Children.forEach(children, function (child) {
12908 if (child == null) {
12909 return;
12910 }
12911 if (typeof child === 'string' || typeof child === 'number') {
12912 content += child;
12913 }
12914 });
12915
12916 return content;
12917}
12918
12919/**
12920 * Implements an <option> host component that warns when `selected` is set.
12921 */
12922
12923function validateProps(element, props) {
12924 // TODO (yungsters): Remove support for `selected` in <option>.
12925 {
12926 if (props.selected != null && !didWarnSelectedSetOnOption) {
12927 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
12928 didWarnSelectedSetOnOption = true;
12929 }
12930 }
12931}
12932
12933function postMountWrapper$1(element, props) {
12934 // value="" should make a value attribute (#6219)
12935 if (props.value != null) {
12936 element.setAttribute('value', props.value);
12937 }
12938}
12939
12940function getHostProps$1(element, props) {
12941 var hostProps = _assign({ children: undefined }, props);
12942 var content = flattenChildren(props.children);
12943
12944 if (content) {
12945 hostProps.children = content;
12946 }
12947
12948 return hostProps;
12949}
12950
12951// TODO: direct imports like some-package/src/* are bad. Fix me.
12952var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
12953var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12954
12955
12956var didWarnValueDefaultValue$1 = void 0;
12957
12958{
12959 didWarnValueDefaultValue$1 = false;
12960}
12961
12962function getDeclarationErrorAddendum() {
12963 var ownerName = getCurrentFiberOwnerName$3();
12964 if (ownerName) {
12965 return '\n\nCheck the render method of `' + ownerName + '`.';
12966 }
12967 return '';
12968}
12969
12970var valuePropNames = ['value', 'defaultValue'];
12971
12972/**
12973 * Validation function for `value` and `defaultValue`.
12974 */
12975function checkSelectPropTypes(props) {
12976 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
12977
12978 for (var i = 0; i < valuePropNames.length; i++) {
12979 var propName = valuePropNames[i];
12980 if (props[propName] == null) {
12981 continue;
12982 }
12983 var isArray = Array.isArray(props[propName]);
12984 if (props.multiple && !isArray) {
12985 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
12986 } else if (!props.multiple && isArray) {
12987 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
12988 }
12989 }
12990}
12991
12992function updateOptions(node, multiple, propValue, setDefaultSelected) {
12993 var options = node.options;
12994
12995 if (multiple) {
12996 var selectedValues = propValue;
12997 var selectedValue = {};
12998 for (var i = 0; i < selectedValues.length; i++) {
12999 // Prefix to avoid chaos with special keys.
13000 selectedValue['$' + selectedValues[i]] = true;
13001 }
13002 for (var _i = 0; _i < options.length; _i++) {
13003 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
13004 if (options[_i].selected !== selected) {
13005 options[_i].selected = selected;
13006 }
13007 if (selected && setDefaultSelected) {
13008 options[_i].defaultSelected = true;
13009 }
13010 }
13011 } else {
13012 // Do not set `select.value` as exact behavior isn't consistent across all
13013 // browsers for all cases.
13014 var _selectedValue = '' + propValue;
13015 var defaultSelected = null;
13016 for (var _i2 = 0; _i2 < options.length; _i2++) {
13017 if (options[_i2].value === _selectedValue) {
13018 options[_i2].selected = true;
13019 if (setDefaultSelected) {
13020 options[_i2].defaultSelected = true;
13021 }
13022 return;
13023 }
13024 if (defaultSelected === null && !options[_i2].disabled) {
13025 defaultSelected = options[_i2];
13026 }
13027 }
13028 if (defaultSelected !== null) {
13029 defaultSelected.selected = true;
13030 }
13031 }
13032}
13033
13034/**
13035 * Implements a <select> host component that allows optionally setting the
13036 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
13037 * stringable. If `multiple` is true, the prop must be an array of stringables.
13038 *
13039 * If `value` is not supplied (or null/undefined), user actions that change the
13040 * selected option will trigger updates to the rendered options.
13041 *
13042 * If it is supplied (and not null/undefined), the rendered options will not
13043 * update in response to user actions. Instead, the `value` prop must change in
13044 * order for the rendered options to update.
13045 *
13046 * If `defaultValue` is provided, any options with the supplied values will be
13047 * selected.
13048 */
13049
13050function getHostProps$2(element, props) {
13051 return _assign({}, props, {
13052 value: undefined
13053 });
13054}
13055
13056function initWrapperState$1(element, props) {
13057 var node = element;
13058 {
13059 checkSelectPropTypes(props);
13060 }
13061
13062 var value = props.value;
13063 node._wrapperState = {
13064 initialValue: value != null ? value : props.defaultValue,
13065 wasMultiple: !!props.multiple
13066 };
13067
13068 {
13069 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
13070 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');
13071 didWarnValueDefaultValue$1 = true;
13072 }
13073 }
13074}
13075
13076function postMountWrapper$2(element, props) {
13077 var node = element;
13078 node.multiple = !!props.multiple;
13079 var value = props.value;
13080 if (value != null) {
13081 updateOptions(node, !!props.multiple, value, false);
13082 } else if (props.defaultValue != null) {
13083 updateOptions(node, !!props.multiple, props.defaultValue, true);
13084 }
13085}
13086
13087function postUpdateWrapper(element, props) {
13088 var node = element;
13089 // After the initial mount, we control selected-ness manually so don't pass
13090 // this value down
13091 node._wrapperState.initialValue = undefined;
13092
13093 var wasMultiple = node._wrapperState.wasMultiple;
13094 node._wrapperState.wasMultiple = !!props.multiple;
13095
13096 var value = props.value;
13097 if (value != null) {
13098 updateOptions(node, !!props.multiple, value, false);
13099 } else if (wasMultiple !== !!props.multiple) {
13100 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
13101 if (props.defaultValue != null) {
13102 updateOptions(node, !!props.multiple, props.defaultValue, true);
13103 } else {
13104 // Revert the select back to its default unselected state.
13105 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
13106 }
13107 }
13108}
13109
13110function restoreControlledState$2(element, props) {
13111 var node = element;
13112 var value = props.value;
13113
13114 if (value != null) {
13115 updateOptions(node, !!props.multiple, value, false);
13116 }
13117}
13118
13119// TODO: direct imports like some-package/src/* are bad. Fix me.
13120var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13121
13122var didWarnValDefaultVal = false;
13123
13124/**
13125 * Implements a <textarea> host component that allows setting `value`, and
13126 * `defaultValue`. This differs from the traditional DOM API because value is
13127 * usually set as PCDATA children.
13128 *
13129 * If `value` is not supplied (or null/undefined), user actions that affect the
13130 * value will trigger updates to the element.
13131 *
13132 * If `value` is supplied (and not null/undefined), the rendered element will
13133 * not trigger updates to the element. Instead, the `value` prop must change in
13134 * order for the rendered element to be updated.
13135 *
13136 * The rendered element will be initialized with an empty value, the prop
13137 * `defaultValue` if specified, or the children content (deprecated).
13138 */
13139
13140function getHostProps$3(element, props) {
13141 var node = element;
13142 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
13143
13144 // Always set children to the same thing. In IE9, the selection range will
13145 // get reset if `textContent` is mutated. We could add a check in setTextContent
13146 // to only set the value if/when the value differs from the node value (which would
13147 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
13148 // solution. The value can be a boolean or object so that's why it's forced
13149 // to be a string.
13150 var hostProps = _assign({}, props, {
13151 value: undefined,
13152 defaultValue: undefined,
13153 children: '' + node._wrapperState.initialValue
13154 });
13155
13156 return hostProps;
13157}
13158
13159function initWrapperState$2(element, props) {
13160 var node = element;
13161 {
13162 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
13163 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
13164 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');
13165 didWarnValDefaultVal = true;
13166 }
13167 }
13168
13169 var initialValue = props.value;
13170
13171 // Only bother fetching default value if we're going to use it
13172 if (initialValue == null) {
13173 var defaultValue = props.defaultValue;
13174 // TODO (yungsters): Remove support for children content in <textarea>.
13175 var children = props.children;
13176 if (children != null) {
13177 {
13178 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
13179 }
13180 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
13181 if (Array.isArray(children)) {
13182 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
13183 children = children[0];
13184 }
13185
13186 defaultValue = '' + children;
13187 }
13188 if (defaultValue == null) {
13189 defaultValue = '';
13190 }
13191 initialValue = defaultValue;
13192 }
13193
13194 node._wrapperState = {
13195 initialValue: '' + initialValue
13196 };
13197}
13198
13199function updateWrapper$1(element, props) {
13200 var node = element;
13201 var value = props.value;
13202 if (value != null) {
13203 // Cast `value` to a string to ensure the value is set correctly. While
13204 // browsers typically do this as necessary, jsdom doesn't.
13205 var newValue = '' + value;
13206
13207 // To avoid side effects (such as losing text selection), only set value if changed
13208 if (newValue !== node.value) {
13209 node.value = newValue;
13210 }
13211 if (props.defaultValue == null) {
13212 node.defaultValue = newValue;
13213 }
13214 }
13215 if (props.defaultValue != null) {
13216 node.defaultValue = props.defaultValue;
13217 }
13218}
13219
13220function postMountWrapper$3(element, props) {
13221 var node = element;
13222 // This is in postMount because we need access to the DOM node, which is not
13223 // available until after the component has mounted.
13224 var textContent = node.textContent;
13225
13226 // Only set node.value if textContent is equal to the expected
13227 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
13228 // will populate textContent as well.
13229 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
13230 if (textContent === node._wrapperState.initialValue) {
13231 node.value = textContent;
13232 }
13233}
13234
13235function restoreControlledState$3(element, props) {
13236 // DOM component is still mounted; update
13237 updateWrapper$1(element, props);
13238}
13239
13240var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
13241var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
13242var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
13243
13244var Namespaces = {
13245 html: HTML_NAMESPACE$1,
13246 mathml: MATH_NAMESPACE,
13247 svg: SVG_NAMESPACE
13248};
13249
13250// Assumes there is no parent namespace.
13251function getIntrinsicNamespace(type) {
13252 switch (type) {
13253 case 'svg':
13254 return SVG_NAMESPACE;
13255 case 'math':
13256 return MATH_NAMESPACE;
13257 default:
13258 return HTML_NAMESPACE$1;
13259 }
13260}
13261
13262function getChildNamespace(parentNamespace, type) {
13263 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
13264 // No (or default) parent namespace: potential entry point.
13265 return getIntrinsicNamespace(type);
13266 }
13267 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
13268 // We're leaving SVG.
13269 return HTML_NAMESPACE$1;
13270 }
13271 // By default, pass namespace below.
13272 return parentNamespace;
13273}
13274
13275/* globals MSApp */
13276
13277/**
13278 * Create a function which has 'unsafe' privileges (required by windows8 apps)
13279 */
13280var createMicrosoftUnsafeLocalFunction = function (func) {
13281 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
13282 return function (arg0, arg1, arg2, arg3) {
13283 MSApp.execUnsafeLocalFunction(function () {
13284 return func(arg0, arg1, arg2, arg3);
13285 });
13286 };
13287 } else {
13288 return func;
13289 }
13290};
13291
13292// SVG temp container for IE lacking innerHTML
13293var reusableSVGContainer = void 0;
13294
13295/**
13296 * Set the innerHTML property of a node
13297 *
13298 * @param {DOMElement} node
13299 * @param {string} html
13300 * @internal
13301 */
13302var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
13303 // IE does not have innerHTML for SVG nodes, so instead we inject the
13304 // new markup in a temp node and then move the child nodes across into
13305 // the target node
13306
13307 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
13308 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
13309 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
13310 var svgNode = reusableSVGContainer.firstChild;
13311 while (node.firstChild) {
13312 node.removeChild(node.firstChild);
13313 }
13314 while (svgNode.firstChild) {
13315 node.appendChild(svgNode.firstChild);
13316 }
13317 } else {
13318 node.innerHTML = html;
13319 }
13320});
13321
13322/**
13323 * Set the textContent property of a node. For text updates, it's faster
13324 * to set the `nodeValue` of the Text node directly instead of using
13325 * `.textContent` which will remove the existing node and create a new one.
13326 *
13327 * @param {DOMElement} node
13328 * @param {string} text
13329 * @internal
13330 */
13331var setTextContent = function (node, text) {
13332 if (text) {
13333 var firstChild = node.firstChild;
13334
13335 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
13336 firstChild.nodeValue = text;
13337 return;
13338 }
13339 }
13340 node.textContent = text;
13341};
13342
13343/**
13344 * CSS properties which accept numbers but are not in units of "px".
13345 */
13346var isUnitlessNumber = {
13347 animationIterationCount: true,
13348 borderImageOutset: true,
13349 borderImageSlice: true,
13350 borderImageWidth: true,
13351 boxFlex: true,
13352 boxFlexGroup: true,
13353 boxOrdinalGroup: true,
13354 columnCount: true,
13355 columns: true,
13356 flex: true,
13357 flexGrow: true,
13358 flexPositive: true,
13359 flexShrink: true,
13360 flexNegative: true,
13361 flexOrder: true,
13362 gridRow: true,
13363 gridRowEnd: true,
13364 gridRowSpan: true,
13365 gridRowStart: true,
13366 gridColumn: true,
13367 gridColumnEnd: true,
13368 gridColumnSpan: true,
13369 gridColumnStart: true,
13370 fontWeight: true,
13371 lineClamp: true,
13372 lineHeight: true,
13373 opacity: true,
13374 order: true,
13375 orphans: true,
13376 tabSize: true,
13377 widows: true,
13378 zIndex: true,
13379 zoom: true,
13380
13381 // SVG-related properties
13382 fillOpacity: true,
13383 floodOpacity: true,
13384 stopOpacity: true,
13385 strokeDasharray: true,
13386 strokeDashoffset: true,
13387 strokeMiterlimit: true,
13388 strokeOpacity: true,
13389 strokeWidth: true
13390};
13391
13392/**
13393 * @param {string} prefix vendor-specific prefix, eg: Webkit
13394 * @param {string} key style name, eg: transitionDuration
13395 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
13396 * WebkitTransitionDuration
13397 */
13398function prefixKey(prefix, key) {
13399 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
13400}
13401
13402/**
13403 * Support style names that may come passed in prefixed by adding permutations
13404 * of vendor prefixes.
13405 */
13406var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
13407
13408// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
13409// infinite loop, because it iterates over the newly added props too.
13410Object.keys(isUnitlessNumber).forEach(function (prop) {
13411 prefixes.forEach(function (prefix) {
13412 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
13413 });
13414});
13415
13416/**
13417 * Convert a value into the proper css writable value. The style name `name`
13418 * should be logical (no hyphens), as specified
13419 * in `CSSProperty.isUnitlessNumber`.
13420 *
13421 * @param {string} name CSS property name such as `topMargin`.
13422 * @param {*} value CSS property value such as `10px`.
13423 * @return {string} Normalized style value with dimensions applied.
13424 */
13425function dangerousStyleValue(name, value, isCustomProperty) {
13426 // Note that we've removed escapeTextForBrowser() calls here since the
13427 // whole string will be escaped when the attribute is injected into
13428 // the markup. If you provide unsafe user data here they can inject
13429 // arbitrary CSS which may be problematic (I couldn't repro this):
13430 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
13431 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
13432 // This is not an XSS hole but instead a potential CSS injection issue
13433 // which has lead to a greater discussion about how we're going to
13434 // trust URLs moving forward. See #2115901
13435
13436 var isEmpty = value == null || typeof value === 'boolean' || value === '';
13437 if (isEmpty) {
13438 return '';
13439 }
13440
13441 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
13442 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
13443 }
13444
13445 return ('' + value).trim();
13446}
13447
13448/**
13449 * Copyright (c) 2013-present, Facebook, Inc.
13450 *
13451 * This source code is licensed under the MIT license found in the
13452 * LICENSE file in the root directory of this source tree.
13453 *
13454 * @typechecks
13455 */
13456
13457var _uppercasePattern = /([A-Z])/g;
13458
13459/**
13460 * Hyphenates a camelcased string, for example:
13461 *
13462 * > hyphenate('backgroundColor')
13463 * < "background-color"
13464 *
13465 * For CSS style names, use `hyphenateStyleName` instead which works properly
13466 * with all vendor prefixes, including `ms`.
13467 *
13468 * @param {string} string
13469 * @return {string}
13470 */
13471function hyphenate(string) {
13472 return string.replace(_uppercasePattern, '-$1').toLowerCase();
13473}
13474
13475var hyphenate_1 = hyphenate;
13476
13477/**
13478 * Copyright (c) 2013-present, Facebook, Inc.
13479 *
13480 * This source code is licensed under the MIT license found in the
13481 * LICENSE file in the root directory of this source tree.
13482 *
13483 * @typechecks
13484 */
13485
13486
13487
13488
13489
13490var msPattern = /^ms-/;
13491
13492/**
13493 * Hyphenates a camelcased CSS property name, for example:
13494 *
13495 * > hyphenateStyleName('backgroundColor')
13496 * < "background-color"
13497 * > hyphenateStyleName('MozTransition')
13498 * < "-moz-transition"
13499 * > hyphenateStyleName('msTransition')
13500 * < "-ms-transition"
13501 *
13502 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
13503 * is converted to `-ms-`.
13504 *
13505 * @param {string} string
13506 * @return {string}
13507 */
13508function hyphenateStyleName(string) {
13509 return hyphenate_1(string).replace(msPattern, '-ms-');
13510}
13511
13512var hyphenateStyleName_1 = hyphenateStyleName;
13513
13514/**
13515 * Copyright (c) 2013-present, Facebook, Inc.
13516 *
13517 * This source code is licensed under the MIT license found in the
13518 * LICENSE file in the root directory of this source tree.
13519 *
13520 * @typechecks
13521 */
13522
13523var _hyphenPattern = /-(.)/g;
13524
13525/**
13526 * Camelcases a hyphenated string, for example:
13527 *
13528 * > camelize('background-color')
13529 * < "backgroundColor"
13530 *
13531 * @param {string} string
13532 * @return {string}
13533 */
13534function camelize(string) {
13535 return string.replace(_hyphenPattern, function (_, character) {
13536 return character.toUpperCase();
13537 });
13538}
13539
13540var camelize_1 = camelize;
13541
13542/**
13543 * Copyright (c) 2013-present, Facebook, Inc.
13544 *
13545 * This source code is licensed under the MIT license found in the
13546 * LICENSE file in the root directory of this source tree.
13547 *
13548 * @typechecks
13549 */
13550
13551
13552
13553
13554
13555var msPattern$1 = /^-ms-/;
13556
13557/**
13558 * Camelcases a hyphenated CSS property name, for example:
13559 *
13560 * > camelizeStyleName('background-color')
13561 * < "backgroundColor"
13562 * > camelizeStyleName('-moz-transition')
13563 * < "MozTransition"
13564 * > camelizeStyleName('-ms-transition')
13565 * < "msTransition"
13566 *
13567 * As Andi Smith suggests
13568 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
13569 * is converted to lowercase `ms`.
13570 *
13571 * @param {string} string
13572 * @return {string}
13573 */
13574function camelizeStyleName(string) {
13575 return camelize_1(string.replace(msPattern$1, 'ms-'));
13576}
13577
13578var camelizeStyleName_1 = camelizeStyleName;
13579
13580var warnValidStyle = emptyFunction_1;
13581
13582{
13583 // 'msTransform' is correct, but the other prefixes should be capitalized
13584 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
13585
13586 // style values shouldn't contain a semicolon
13587 var badStyleValueWithSemicolonPattern = /;\s*$/;
13588
13589 var warnedStyleNames = {};
13590 var warnedStyleValues = {};
13591 var warnedForNaNValue = false;
13592 var warnedForInfinityValue = false;
13593
13594 var warnHyphenatedStyleName = function (name, getStack) {
13595 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
13596 return;
13597 }
13598
13599 warnedStyleNames[name] = true;
13600 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
13601 };
13602
13603 var warnBadVendoredStyleName = function (name, getStack) {
13604 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
13605 return;
13606 }
13607
13608 warnedStyleNames[name] = true;
13609 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
13610 };
13611
13612 var warnStyleValueWithSemicolon = function (name, value, getStack) {
13613 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
13614 return;
13615 }
13616
13617 warnedStyleValues[value] = true;
13618 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
13619 };
13620
13621 var warnStyleValueIsNaN = function (name, value, getStack) {
13622 if (warnedForNaNValue) {
13623 return;
13624 }
13625
13626 warnedForNaNValue = true;
13627 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
13628 };
13629
13630 var warnStyleValueIsInfinity = function (name, value, getStack) {
13631 if (warnedForInfinityValue) {
13632 return;
13633 }
13634
13635 warnedForInfinityValue = true;
13636 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
13637 };
13638
13639 warnValidStyle = function (name, value, getStack) {
13640 if (name.indexOf('-') > -1) {
13641 warnHyphenatedStyleName(name, getStack);
13642 } else if (badVendoredStyleNamePattern.test(name)) {
13643 warnBadVendoredStyleName(name, getStack);
13644 } else if (badStyleValueWithSemicolonPattern.test(value)) {
13645 warnStyleValueWithSemicolon(name, value, getStack);
13646 }
13647
13648 if (typeof value === 'number') {
13649 if (isNaN(value)) {
13650 warnStyleValueIsNaN(name, value, getStack);
13651 } else if (!isFinite(value)) {
13652 warnStyleValueIsInfinity(name, value, getStack);
13653 }
13654 }
13655 };
13656}
13657
13658var warnValidStyle$1 = warnValidStyle;
13659
13660/**
13661 * Operations for dealing with CSS properties.
13662 */
13663
13664/**
13665 * This creates a string that is expected to be equivalent to the style
13666 * attribute generated by server-side rendering. It by-passes warnings and
13667 * security checks so it's not safe to use this value for anything other than
13668 * comparison. It is only used in DEV for SSR validation.
13669 */
13670function createDangerousStringForStyles(styles) {
13671 {
13672 var serialized = '';
13673 var delimiter = '';
13674 for (var styleName in styles) {
13675 if (!styles.hasOwnProperty(styleName)) {
13676 continue;
13677 }
13678 var styleValue = styles[styleName];
13679 if (styleValue != null) {
13680 var isCustomProperty = styleName.indexOf('--') === 0;
13681 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
13682 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
13683
13684 delimiter = ';';
13685 }
13686 }
13687 return serialized || null;
13688 }
13689}
13690
13691/**
13692 * Sets the value for multiple styles on a node. If a value is specified as
13693 * '' (empty string), the corresponding style property will be unset.
13694 *
13695 * @param {DOMElement} node
13696 * @param {object} styles
13697 */
13698function setValueForStyles(node, styles, getStack) {
13699 var style = node.style;
13700 for (var styleName in styles) {
13701 if (!styles.hasOwnProperty(styleName)) {
13702 continue;
13703 }
13704 var isCustomProperty = styleName.indexOf('--') === 0;
13705 {
13706 if (!isCustomProperty) {
13707 warnValidStyle$1(styleName, styles[styleName], getStack);
13708 }
13709 }
13710 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
13711 if (styleName === 'float') {
13712 styleName = 'cssFloat';
13713 }
13714 if (isCustomProperty) {
13715 style.setProperty(styleName, styleValue);
13716 } else {
13717 style[styleName] = styleValue;
13718 }
13719 }
13720}
13721
13722// For HTML, certain tags should omit their close tag. We keep a whitelist for
13723// those special-case tags.
13724
13725var omittedCloseTags = {
13726 area: true,
13727 base: true,
13728 br: true,
13729 col: true,
13730 embed: true,
13731 hr: true,
13732 img: true,
13733 input: true,
13734 keygen: true,
13735 link: true,
13736 meta: true,
13737 param: true,
13738 source: true,
13739 track: true,
13740 wbr: true
13741};
13742
13743// For HTML, certain tags cannot have children. This has the same purpose as
13744// `omittedCloseTags` except that `menuitem` should still have its closing tag.
13745
13746var voidElementTags = _assign({
13747 menuitem: true
13748}, omittedCloseTags);
13749
13750var HTML$1 = '__html';
13751
13752function assertValidProps(tag, props, getStack) {
13753 if (!props) {
13754 return;
13755 }
13756 // Note the use of `==` which checks for null or undefined.
13757 if (voidElementTags[tag]) {
13758 !(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;
13759 }
13760 if (props.dangerouslySetInnerHTML != null) {
13761 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
13762 !(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;
13763 }
13764 {
13765 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());
13766 }
13767 !(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;
13768}
13769
13770function isCustomComponent(tagName, props) {
13771 if (tagName.indexOf('-') === -1) {
13772 return typeof props.is === 'string';
13773 }
13774 switch (tagName) {
13775 // These are reserved SVG and MathML elements.
13776 // We don't mind this whitelist too much because we expect it to never grow.
13777 // The alternative is to track the namespace in a few places which is convoluted.
13778 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
13779 case 'annotation-xml':
13780 case 'color-profile':
13781 case 'font-face':
13782 case 'font-face-src':
13783 case 'font-face-uri':
13784 case 'font-face-format':
13785 case 'font-face-name':
13786 case 'missing-glyph':
13787 return false;
13788 default:
13789 return true;
13790 }
13791}
13792
13793// When adding attributes to the HTML or SVG whitelist, be sure to
13794// also add them to this module to ensure casing and incorrect name
13795// warnings.
13796var possibleStandardNames = {
13797 // HTML
13798 accept: 'accept',
13799 acceptcharset: 'acceptCharset',
13800 'accept-charset': 'acceptCharset',
13801 accesskey: 'accessKey',
13802 action: 'action',
13803 allowfullscreen: 'allowFullScreen',
13804 alt: 'alt',
13805 as: 'as',
13806 async: 'async',
13807 autocapitalize: 'autoCapitalize',
13808 autocomplete: 'autoComplete',
13809 autocorrect: 'autoCorrect',
13810 autofocus: 'autoFocus',
13811 autoplay: 'autoPlay',
13812 autosave: 'autoSave',
13813 capture: 'capture',
13814 cellpadding: 'cellPadding',
13815 cellspacing: 'cellSpacing',
13816 challenge: 'challenge',
13817 charset: 'charSet',
13818 checked: 'checked',
13819 children: 'children',
13820 cite: 'cite',
13821 'class': 'className',
13822 classid: 'classID',
13823 classname: 'className',
13824 cols: 'cols',
13825 colspan: 'colSpan',
13826 content: 'content',
13827 contenteditable: 'contentEditable',
13828 contextmenu: 'contextMenu',
13829 controls: 'controls',
13830 controlslist: 'controlsList',
13831 coords: 'coords',
13832 crossorigin: 'crossOrigin',
13833 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13834 data: 'data',
13835 datetime: 'dateTime',
13836 'default': 'default',
13837 defaultchecked: 'defaultChecked',
13838 defaultvalue: 'defaultValue',
13839 defer: 'defer',
13840 dir: 'dir',
13841 disabled: 'disabled',
13842 download: 'download',
13843 draggable: 'draggable',
13844 enctype: 'encType',
13845 'for': 'htmlFor',
13846 form: 'form',
13847 formmethod: 'formMethod',
13848 formaction: 'formAction',
13849 formenctype: 'formEncType',
13850 formnovalidate: 'formNoValidate',
13851 formtarget: 'formTarget',
13852 frameborder: 'frameBorder',
13853 headers: 'headers',
13854 height: 'height',
13855 hidden: 'hidden',
13856 high: 'high',
13857 href: 'href',
13858 hreflang: 'hrefLang',
13859 htmlfor: 'htmlFor',
13860 httpequiv: 'httpEquiv',
13861 'http-equiv': 'httpEquiv',
13862 icon: 'icon',
13863 id: 'id',
13864 innerhtml: 'innerHTML',
13865 inputmode: 'inputMode',
13866 integrity: 'integrity',
13867 is: 'is',
13868 itemid: 'itemID',
13869 itemprop: 'itemProp',
13870 itemref: 'itemRef',
13871 itemscope: 'itemScope',
13872 itemtype: 'itemType',
13873 keyparams: 'keyParams',
13874 keytype: 'keyType',
13875 kind: 'kind',
13876 label: 'label',
13877 lang: 'lang',
13878 list: 'list',
13879 loop: 'loop',
13880 low: 'low',
13881 manifest: 'manifest',
13882 marginwidth: 'marginWidth',
13883 marginheight: 'marginHeight',
13884 max: 'max',
13885 maxlength: 'maxLength',
13886 media: 'media',
13887 mediagroup: 'mediaGroup',
13888 method: 'method',
13889 min: 'min',
13890 minlength: 'minLength',
13891 multiple: 'multiple',
13892 muted: 'muted',
13893 name: 'name',
13894 nomodule: 'noModule',
13895 nonce: 'nonce',
13896 novalidate: 'noValidate',
13897 open: 'open',
13898 optimum: 'optimum',
13899 pattern: 'pattern',
13900 placeholder: 'placeholder',
13901 playsinline: 'playsInline',
13902 poster: 'poster',
13903 preload: 'preload',
13904 profile: 'profile',
13905 radiogroup: 'radioGroup',
13906 readonly: 'readOnly',
13907 referrerpolicy: 'referrerPolicy',
13908 rel: 'rel',
13909 required: 'required',
13910 reversed: 'reversed',
13911 role: 'role',
13912 rows: 'rows',
13913 rowspan: 'rowSpan',
13914 sandbox: 'sandbox',
13915 scope: 'scope',
13916 scoped: 'scoped',
13917 scrolling: 'scrolling',
13918 seamless: 'seamless',
13919 selected: 'selected',
13920 shape: 'shape',
13921 size: 'size',
13922 sizes: 'sizes',
13923 span: 'span',
13924 spellcheck: 'spellCheck',
13925 src: 'src',
13926 srcdoc: 'srcDoc',
13927 srclang: 'srcLang',
13928 srcset: 'srcSet',
13929 start: 'start',
13930 step: 'step',
13931 style: 'style',
13932 summary: 'summary',
13933 tabindex: 'tabIndex',
13934 target: 'target',
13935 title: 'title',
13936 type: 'type',
13937 usemap: 'useMap',
13938 value: 'value',
13939 width: 'width',
13940 wmode: 'wmode',
13941 wrap: 'wrap',
13942
13943 // SVG
13944 about: 'about',
13945 accentheight: 'accentHeight',
13946 'accent-height': 'accentHeight',
13947 accumulate: 'accumulate',
13948 additive: 'additive',
13949 alignmentbaseline: 'alignmentBaseline',
13950 'alignment-baseline': 'alignmentBaseline',
13951 allowreorder: 'allowReorder',
13952 alphabetic: 'alphabetic',
13953 amplitude: 'amplitude',
13954 arabicform: 'arabicForm',
13955 'arabic-form': 'arabicForm',
13956 ascent: 'ascent',
13957 attributename: 'attributeName',
13958 attributetype: 'attributeType',
13959 autoreverse: 'autoReverse',
13960 azimuth: 'azimuth',
13961 basefrequency: 'baseFrequency',
13962 baselineshift: 'baselineShift',
13963 'baseline-shift': 'baselineShift',
13964 baseprofile: 'baseProfile',
13965 bbox: 'bbox',
13966 begin: 'begin',
13967 bias: 'bias',
13968 by: 'by',
13969 calcmode: 'calcMode',
13970 capheight: 'capHeight',
13971 'cap-height': 'capHeight',
13972 clip: 'clip',
13973 clippath: 'clipPath',
13974 'clip-path': 'clipPath',
13975 clippathunits: 'clipPathUnits',
13976 cliprule: 'clipRule',
13977 'clip-rule': 'clipRule',
13978 color: 'color',
13979 colorinterpolation: 'colorInterpolation',
13980 'color-interpolation': 'colorInterpolation',
13981 colorinterpolationfilters: 'colorInterpolationFilters',
13982 'color-interpolation-filters': 'colorInterpolationFilters',
13983 colorprofile: 'colorProfile',
13984 'color-profile': 'colorProfile',
13985 colorrendering: 'colorRendering',
13986 'color-rendering': 'colorRendering',
13987 contentscripttype: 'contentScriptType',
13988 contentstyletype: 'contentStyleType',
13989 cursor: 'cursor',
13990 cx: 'cx',
13991 cy: 'cy',
13992 d: 'd',
13993 datatype: 'datatype',
13994 decelerate: 'decelerate',
13995 descent: 'descent',
13996 diffuseconstant: 'diffuseConstant',
13997 direction: 'direction',
13998 display: 'display',
13999 divisor: 'divisor',
14000 dominantbaseline: 'dominantBaseline',
14001 'dominant-baseline': 'dominantBaseline',
14002 dur: 'dur',
14003 dx: 'dx',
14004 dy: 'dy',
14005 edgemode: 'edgeMode',
14006 elevation: 'elevation',
14007 enablebackground: 'enableBackground',
14008 'enable-background': 'enableBackground',
14009 end: 'end',
14010 exponent: 'exponent',
14011 externalresourcesrequired: 'externalResourcesRequired',
14012 fill: 'fill',
14013 fillopacity: 'fillOpacity',
14014 'fill-opacity': 'fillOpacity',
14015 fillrule: 'fillRule',
14016 'fill-rule': 'fillRule',
14017 filter: 'filter',
14018 filterres: 'filterRes',
14019 filterunits: 'filterUnits',
14020 floodopacity: 'floodOpacity',
14021 'flood-opacity': 'floodOpacity',
14022 floodcolor: 'floodColor',
14023 'flood-color': 'floodColor',
14024 focusable: 'focusable',
14025 fontfamily: 'fontFamily',
14026 'font-family': 'fontFamily',
14027 fontsize: 'fontSize',
14028 'font-size': 'fontSize',
14029 fontsizeadjust: 'fontSizeAdjust',
14030 'font-size-adjust': 'fontSizeAdjust',
14031 fontstretch: 'fontStretch',
14032 'font-stretch': 'fontStretch',
14033 fontstyle: 'fontStyle',
14034 'font-style': 'fontStyle',
14035 fontvariant: 'fontVariant',
14036 'font-variant': 'fontVariant',
14037 fontweight: 'fontWeight',
14038 'font-weight': 'fontWeight',
14039 format: 'format',
14040 from: 'from',
14041 fx: 'fx',
14042 fy: 'fy',
14043 g1: 'g1',
14044 g2: 'g2',
14045 glyphname: 'glyphName',
14046 'glyph-name': 'glyphName',
14047 glyphorientationhorizontal: 'glyphOrientationHorizontal',
14048 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
14049 glyphorientationvertical: 'glyphOrientationVertical',
14050 'glyph-orientation-vertical': 'glyphOrientationVertical',
14051 glyphref: 'glyphRef',
14052 gradienttransform: 'gradientTransform',
14053 gradientunits: 'gradientUnits',
14054 hanging: 'hanging',
14055 horizadvx: 'horizAdvX',
14056 'horiz-adv-x': 'horizAdvX',
14057 horizoriginx: 'horizOriginX',
14058 'horiz-origin-x': 'horizOriginX',
14059 ideographic: 'ideographic',
14060 imagerendering: 'imageRendering',
14061 'image-rendering': 'imageRendering',
14062 in2: 'in2',
14063 'in': 'in',
14064 inlist: 'inlist',
14065 intercept: 'intercept',
14066 k1: 'k1',
14067 k2: 'k2',
14068 k3: 'k3',
14069 k4: 'k4',
14070 k: 'k',
14071 kernelmatrix: 'kernelMatrix',
14072 kernelunitlength: 'kernelUnitLength',
14073 kerning: 'kerning',
14074 keypoints: 'keyPoints',
14075 keysplines: 'keySplines',
14076 keytimes: 'keyTimes',
14077 lengthadjust: 'lengthAdjust',
14078 letterspacing: 'letterSpacing',
14079 'letter-spacing': 'letterSpacing',
14080 lightingcolor: 'lightingColor',
14081 'lighting-color': 'lightingColor',
14082 limitingconeangle: 'limitingConeAngle',
14083 local: 'local',
14084 markerend: 'markerEnd',
14085 'marker-end': 'markerEnd',
14086 markerheight: 'markerHeight',
14087 markermid: 'markerMid',
14088 'marker-mid': 'markerMid',
14089 markerstart: 'markerStart',
14090 'marker-start': 'markerStart',
14091 markerunits: 'markerUnits',
14092 markerwidth: 'markerWidth',
14093 mask: 'mask',
14094 maskcontentunits: 'maskContentUnits',
14095 maskunits: 'maskUnits',
14096 mathematical: 'mathematical',
14097 mode: 'mode',
14098 numoctaves: 'numOctaves',
14099 offset: 'offset',
14100 opacity: 'opacity',
14101 operator: 'operator',
14102 order: 'order',
14103 orient: 'orient',
14104 orientation: 'orientation',
14105 origin: 'origin',
14106 overflow: 'overflow',
14107 overlineposition: 'overlinePosition',
14108 'overline-position': 'overlinePosition',
14109 overlinethickness: 'overlineThickness',
14110 'overline-thickness': 'overlineThickness',
14111 paintorder: 'paintOrder',
14112 'paint-order': 'paintOrder',
14113 panose1: 'panose1',
14114 'panose-1': 'panose1',
14115 pathlength: 'pathLength',
14116 patterncontentunits: 'patternContentUnits',
14117 patterntransform: 'patternTransform',
14118 patternunits: 'patternUnits',
14119 pointerevents: 'pointerEvents',
14120 'pointer-events': 'pointerEvents',
14121 points: 'points',
14122 pointsatx: 'pointsAtX',
14123 pointsaty: 'pointsAtY',
14124 pointsatz: 'pointsAtZ',
14125 prefix: 'prefix',
14126 preservealpha: 'preserveAlpha',
14127 preserveaspectratio: 'preserveAspectRatio',
14128 primitiveunits: 'primitiveUnits',
14129 property: 'property',
14130 r: 'r',
14131 radius: 'radius',
14132 refx: 'refX',
14133 refy: 'refY',
14134 renderingintent: 'renderingIntent',
14135 'rendering-intent': 'renderingIntent',
14136 repeatcount: 'repeatCount',
14137 repeatdur: 'repeatDur',
14138 requiredextensions: 'requiredExtensions',
14139 requiredfeatures: 'requiredFeatures',
14140 resource: 'resource',
14141 restart: 'restart',
14142 result: 'result',
14143 results: 'results',
14144 rotate: 'rotate',
14145 rx: 'rx',
14146 ry: 'ry',
14147 scale: 'scale',
14148 security: 'security',
14149 seed: 'seed',
14150 shaperendering: 'shapeRendering',
14151 'shape-rendering': 'shapeRendering',
14152 slope: 'slope',
14153 spacing: 'spacing',
14154 specularconstant: 'specularConstant',
14155 specularexponent: 'specularExponent',
14156 speed: 'speed',
14157 spreadmethod: 'spreadMethod',
14158 startoffset: 'startOffset',
14159 stddeviation: 'stdDeviation',
14160 stemh: 'stemh',
14161 stemv: 'stemv',
14162 stitchtiles: 'stitchTiles',
14163 stopcolor: 'stopColor',
14164 'stop-color': 'stopColor',
14165 stopopacity: 'stopOpacity',
14166 'stop-opacity': 'stopOpacity',
14167 strikethroughposition: 'strikethroughPosition',
14168 'strikethrough-position': 'strikethroughPosition',
14169 strikethroughthickness: 'strikethroughThickness',
14170 'strikethrough-thickness': 'strikethroughThickness',
14171 string: 'string',
14172 stroke: 'stroke',
14173 strokedasharray: 'strokeDasharray',
14174 'stroke-dasharray': 'strokeDasharray',
14175 strokedashoffset: 'strokeDashoffset',
14176 'stroke-dashoffset': 'strokeDashoffset',
14177 strokelinecap: 'strokeLinecap',
14178 'stroke-linecap': 'strokeLinecap',
14179 strokelinejoin: 'strokeLinejoin',
14180 'stroke-linejoin': 'strokeLinejoin',
14181 strokemiterlimit: 'strokeMiterlimit',
14182 'stroke-miterlimit': 'strokeMiterlimit',
14183 strokewidth: 'strokeWidth',
14184 'stroke-width': 'strokeWidth',
14185 strokeopacity: 'strokeOpacity',
14186 'stroke-opacity': 'strokeOpacity',
14187 suppresscontenteditablewarning: 'suppressContentEditableWarning',
14188 suppresshydrationwarning: 'suppressHydrationWarning',
14189 surfacescale: 'surfaceScale',
14190 systemlanguage: 'systemLanguage',
14191 tablevalues: 'tableValues',
14192 targetx: 'targetX',
14193 targety: 'targetY',
14194 textanchor: 'textAnchor',
14195 'text-anchor': 'textAnchor',
14196 textdecoration: 'textDecoration',
14197 'text-decoration': 'textDecoration',
14198 textlength: 'textLength',
14199 textrendering: 'textRendering',
14200 'text-rendering': 'textRendering',
14201 to: 'to',
14202 transform: 'transform',
14203 'typeof': 'typeof',
14204 u1: 'u1',
14205 u2: 'u2',
14206 underlineposition: 'underlinePosition',
14207 'underline-position': 'underlinePosition',
14208 underlinethickness: 'underlineThickness',
14209 'underline-thickness': 'underlineThickness',
14210 unicode: 'unicode',
14211 unicodebidi: 'unicodeBidi',
14212 'unicode-bidi': 'unicodeBidi',
14213 unicoderange: 'unicodeRange',
14214 'unicode-range': 'unicodeRange',
14215 unitsperem: 'unitsPerEm',
14216 'units-per-em': 'unitsPerEm',
14217 unselectable: 'unselectable',
14218 valphabetic: 'vAlphabetic',
14219 'v-alphabetic': 'vAlphabetic',
14220 values: 'values',
14221 vectoreffect: 'vectorEffect',
14222 'vector-effect': 'vectorEffect',
14223 version: 'version',
14224 vertadvy: 'vertAdvY',
14225 'vert-adv-y': 'vertAdvY',
14226 vertoriginx: 'vertOriginX',
14227 'vert-origin-x': 'vertOriginX',
14228 vertoriginy: 'vertOriginY',
14229 'vert-origin-y': 'vertOriginY',
14230 vhanging: 'vHanging',
14231 'v-hanging': 'vHanging',
14232 videographic: 'vIdeographic',
14233 'v-ideographic': 'vIdeographic',
14234 viewbox: 'viewBox',
14235 viewtarget: 'viewTarget',
14236 visibility: 'visibility',
14237 vmathematical: 'vMathematical',
14238 'v-mathematical': 'vMathematical',
14239 vocab: 'vocab',
14240 widths: 'widths',
14241 wordspacing: 'wordSpacing',
14242 'word-spacing': 'wordSpacing',
14243 writingmode: 'writingMode',
14244 'writing-mode': 'writingMode',
14245 x1: 'x1',
14246 x2: 'x2',
14247 x: 'x',
14248 xchannelselector: 'xChannelSelector',
14249 xheight: 'xHeight',
14250 'x-height': 'xHeight',
14251 xlinkactuate: 'xlinkActuate',
14252 'xlink:actuate': 'xlinkActuate',
14253 xlinkarcrole: 'xlinkArcrole',
14254 'xlink:arcrole': 'xlinkArcrole',
14255 xlinkhref: 'xlinkHref',
14256 'xlink:href': 'xlinkHref',
14257 xlinkrole: 'xlinkRole',
14258 'xlink:role': 'xlinkRole',
14259 xlinkshow: 'xlinkShow',
14260 'xlink:show': 'xlinkShow',
14261 xlinktitle: 'xlinkTitle',
14262 'xlink:title': 'xlinkTitle',
14263 xlinktype: 'xlinkType',
14264 'xlink:type': 'xlinkType',
14265 xmlbase: 'xmlBase',
14266 'xml:base': 'xmlBase',
14267 xmllang: 'xmlLang',
14268 'xml:lang': 'xmlLang',
14269 xmlns: 'xmlns',
14270 'xml:space': 'xmlSpace',
14271 xmlnsxlink: 'xmlnsXlink',
14272 'xmlns:xlink': 'xmlnsXlink',
14273 xmlspace: 'xmlSpace',
14274 y1: 'y1',
14275 y2: 'y2',
14276 y: 'y',
14277 ychannelselector: 'yChannelSelector',
14278 z: 'z',
14279 zoomandpan: 'zoomAndPan'
14280};
14281
14282var ariaProperties = {
14283 'aria-current': 0, // state
14284 'aria-details': 0,
14285 'aria-disabled': 0, // state
14286 'aria-hidden': 0, // state
14287 'aria-invalid': 0, // state
14288 'aria-keyshortcuts': 0,
14289 'aria-label': 0,
14290 'aria-roledescription': 0,
14291 // Widget Attributes
14292 'aria-autocomplete': 0,
14293 'aria-checked': 0,
14294 'aria-expanded': 0,
14295 'aria-haspopup': 0,
14296 'aria-level': 0,
14297 'aria-modal': 0,
14298 'aria-multiline': 0,
14299 'aria-multiselectable': 0,
14300 'aria-orientation': 0,
14301 'aria-placeholder': 0,
14302 'aria-pressed': 0,
14303 'aria-readonly': 0,
14304 'aria-required': 0,
14305 'aria-selected': 0,
14306 'aria-sort': 0,
14307 'aria-valuemax': 0,
14308 'aria-valuemin': 0,
14309 'aria-valuenow': 0,
14310 'aria-valuetext': 0,
14311 // Live Region Attributes
14312 'aria-atomic': 0,
14313 'aria-busy': 0,
14314 'aria-live': 0,
14315 'aria-relevant': 0,
14316 // Drag-and-Drop Attributes
14317 'aria-dropeffect': 0,
14318 'aria-grabbed': 0,
14319 // Relationship Attributes
14320 'aria-activedescendant': 0,
14321 'aria-colcount': 0,
14322 'aria-colindex': 0,
14323 'aria-colspan': 0,
14324 'aria-controls': 0,
14325 'aria-describedby': 0,
14326 'aria-errormessage': 0,
14327 'aria-flowto': 0,
14328 'aria-labelledby': 0,
14329 'aria-owns': 0,
14330 'aria-posinset': 0,
14331 'aria-rowcount': 0,
14332 'aria-rowindex': 0,
14333 'aria-rowspan': 0,
14334 'aria-setsize': 0
14335};
14336
14337var warnedProperties = {};
14338var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
14339var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
14340
14341var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
14342
14343function getStackAddendum() {
14344 var stack = ReactDebugCurrentFrame.getStackAddendum();
14345 return stack != null ? stack : '';
14346}
14347
14348function validateProperty(tagName, name) {
14349 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
14350 return true;
14351 }
14352
14353 if (rARIACamel.test(name)) {
14354 var ariaName = 'aria-' + name.slice(4).toLowerCase();
14355 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
14356
14357 // If this is an aria-* attribute, but is not listed in the known DOM
14358 // DOM properties, then it is an invalid aria-* attribute.
14359 if (correctName == null) {
14360 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
14361 warnedProperties[name] = true;
14362 return true;
14363 }
14364 // aria-* attributes should be lowercase; suggest the lowercase version.
14365 if (name !== correctName) {
14366 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
14367 warnedProperties[name] = true;
14368 return true;
14369 }
14370 }
14371
14372 if (rARIA.test(name)) {
14373 var lowerCasedName = name.toLowerCase();
14374 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
14375
14376 // If this is an aria-* attribute, but is not listed in the known DOM
14377 // DOM properties, then it is an invalid aria-* attribute.
14378 if (standardName == null) {
14379 warnedProperties[name] = true;
14380 return false;
14381 }
14382 // aria-* attributes should be lowercase; suggest the lowercase version.
14383 if (name !== standardName) {
14384 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
14385 warnedProperties[name] = true;
14386 return true;
14387 }
14388 }
14389
14390 return true;
14391}
14392
14393function warnInvalidARIAProps(type, props) {
14394 var invalidProps = [];
14395
14396 for (var key in props) {
14397 var isValid = validateProperty(type, key);
14398 if (!isValid) {
14399 invalidProps.push(key);
14400 }
14401 }
14402
14403 var unknownPropString = invalidProps.map(function (prop) {
14404 return '`' + prop + '`';
14405 }).join(', ');
14406
14407 if (invalidProps.length === 1) {
14408 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
14409 } else if (invalidProps.length > 1) {
14410 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
14411 }
14412}
14413
14414function validateProperties(type, props) {
14415 if (isCustomComponent(type, props)) {
14416 return;
14417 }
14418 warnInvalidARIAProps(type, props);
14419}
14420
14421var didWarnValueNull = false;
14422
14423function getStackAddendum$1() {
14424 var stack = ReactDebugCurrentFrame.getStackAddendum();
14425 return stack != null ? stack : '';
14426}
14427
14428function validateProperties$1(type, props) {
14429 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
14430 return;
14431 }
14432
14433 if (props != null && props.value === null && !didWarnValueNull) {
14434 didWarnValueNull = true;
14435 if (type === 'select' && props.multiple) {
14436 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());
14437 } else {
14438 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());
14439 }
14440 }
14441}
14442
14443function getStackAddendum$2() {
14444 var stack = ReactDebugCurrentFrame.getStackAddendum();
14445 return stack != null ? stack : '';
14446}
14447
14448var validateProperty$1 = function () {};
14449
14450{
14451 var warnedProperties$1 = {};
14452 var _hasOwnProperty = Object.prototype.hasOwnProperty;
14453 var EVENT_NAME_REGEX = /^on./;
14454 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
14455 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
14456 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
14457
14458 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
14459 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
14460 return true;
14461 }
14462
14463 var lowerCasedName = name.toLowerCase();
14464 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
14465 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.');
14466 warnedProperties$1[name] = true;
14467 return true;
14468 }
14469
14470 // We can't rely on the event system being injected on the server.
14471 if (canUseEventSystem) {
14472 if (registrationNameModules.hasOwnProperty(name)) {
14473 return true;
14474 }
14475 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
14476 if (registrationName != null) {
14477 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
14478 warnedProperties$1[name] = true;
14479 return true;
14480 }
14481 if (EVENT_NAME_REGEX.test(name)) {
14482 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
14483 warnedProperties$1[name] = true;
14484 return true;
14485 }
14486 } else if (EVENT_NAME_REGEX.test(name)) {
14487 // If no event plugins have been injected, we are in a server environment.
14488 // So we can't tell if the event name is correct for sure, but we can filter
14489 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
14490 if (INVALID_EVENT_NAME_REGEX.test(name)) {
14491 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
14492 }
14493 warnedProperties$1[name] = true;
14494 return true;
14495 }
14496
14497 // Let the ARIA attribute hook validate ARIA attributes
14498 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
14499 return true;
14500 }
14501
14502 if (lowerCasedName === 'innerhtml') {
14503 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
14504 warnedProperties$1[name] = true;
14505 return true;
14506 }
14507
14508 if (lowerCasedName === 'aria') {
14509 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
14510 warnedProperties$1[name] = true;
14511 return true;
14512 }
14513
14514 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
14515 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());
14516 warnedProperties$1[name] = true;
14517 return true;
14518 }
14519
14520 if (typeof value === 'number' && isNaN(value)) {
14521 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
14522 warnedProperties$1[name] = true;
14523 return true;
14524 }
14525
14526 var propertyInfo = getPropertyInfo(name);
14527 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
14528
14529 // Known attributes should match the casing specified in the property config.
14530 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14531 var standardName = possibleStandardNames[lowerCasedName];
14532 if (standardName !== name) {
14533 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
14534 warnedProperties$1[name] = true;
14535 return true;
14536 }
14537 } else if (!isReserved && name !== lowerCasedName) {
14538 // Unknown attributes should have lowercase casing since that's how they
14539 // will be cased anyway with server rendering.
14540 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());
14541 warnedProperties$1[name] = true;
14542 return true;
14543 }
14544
14545 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
14546 if (value) {
14547 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());
14548 } else {
14549 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());
14550 }
14551 warnedProperties$1[name] = true;
14552 return true;
14553 }
14554
14555 // Now that we've validated casing, do not validate
14556 // data types for reserved props
14557 if (isReserved) {
14558 return true;
14559 }
14560
14561 // Warn when a known attribute is a bad type
14562 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
14563 warnedProperties$1[name] = true;
14564 return false;
14565 }
14566
14567 return true;
14568 };
14569}
14570
14571var warnUnknownProperties = function (type, props, canUseEventSystem) {
14572 var unknownProps = [];
14573 for (var key in props) {
14574 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
14575 if (!isValid) {
14576 unknownProps.push(key);
14577 }
14578 }
14579
14580 var unknownPropString = unknownProps.map(function (prop) {
14581 return '`' + prop + '`';
14582 }).join(', ');
14583 if (unknownProps.length === 1) {
14584 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());
14585 } else if (unknownProps.length > 1) {
14586 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());
14587 }
14588};
14589
14590function validateProperties$2(type, props, canUseEventSystem) {
14591 if (isCustomComponent(type, props)) {
14592 return;
14593 }
14594 warnUnknownProperties(type, props, canUseEventSystem);
14595}
14596
14597// TODO: direct imports like some-package/src/* are bad. Fix me.
14598var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
14599var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14600
14601var didWarnInvalidHydration = false;
14602var didWarnShadyDOM = false;
14603
14604var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
14605var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
14606var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
14607var AUTOFOCUS = 'autoFocus';
14608var CHILDREN = 'children';
14609var STYLE = 'style';
14610var HTML = '__html';
14611
14612var HTML_NAMESPACE = Namespaces.html;
14613
14614
14615var getStack = emptyFunction_1.thatReturns('');
14616
14617var warnedUnknownTags = void 0;
14618var suppressHydrationWarning = void 0;
14619
14620var validatePropertiesInDevelopment = void 0;
14621var warnForTextDifference = void 0;
14622var warnForPropDifference = void 0;
14623var warnForExtraAttributes = void 0;
14624var warnForInvalidEventListener = void 0;
14625
14626var normalizeMarkupForTextOrAttribute = void 0;
14627var normalizeHTML = void 0;
14628
14629{
14630 getStack = getCurrentFiberStackAddendum$3;
14631
14632 warnedUnknownTags = {
14633 // Chrome is the only major browser not shipping <time>. But as of July
14634 // 2017 it intends to ship it due to widespread usage. We intentionally
14635 // *don't* warn for <time> even if it's unrecognized by Chrome because
14636 // it soon will be, and many apps have been using it anyway.
14637 time: true,
14638 // There are working polyfills for <dialog>. Let people use it.
14639 dialog: true
14640 };
14641
14642 validatePropertiesInDevelopment = function (type, props) {
14643 validateProperties(type, props);
14644 validateProperties$1(type, props);
14645 validateProperties$2(type, props, /* canUseEventSystem */true);
14646 };
14647
14648 // HTML parsing normalizes CR and CRLF to LF.
14649 // It also can turn \u0000 into \uFFFD inside attributes.
14650 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
14651 // If we have a mismatch, it might be caused by that.
14652 // We will still patch up in this case but not fire the warning.
14653 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
14654 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
14655
14656 normalizeMarkupForTextOrAttribute = function (markup) {
14657 var markupString = typeof markup === 'string' ? markup : '' + markup;
14658 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
14659 };
14660
14661 warnForTextDifference = function (serverText, clientText) {
14662 if (didWarnInvalidHydration) {
14663 return;
14664 }
14665 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
14666 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
14667 if (normalizedServerText === normalizedClientText) {
14668 return;
14669 }
14670 didWarnInvalidHydration = true;
14671 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
14672 };
14673
14674 warnForPropDifference = function (propName, serverValue, clientValue) {
14675 if (didWarnInvalidHydration) {
14676 return;
14677 }
14678 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
14679 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
14680 if (normalizedServerValue === normalizedClientValue) {
14681 return;
14682 }
14683 didWarnInvalidHydration = true;
14684 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
14685 };
14686
14687 warnForExtraAttributes = function (attributeNames) {
14688 if (didWarnInvalidHydration) {
14689 return;
14690 }
14691 didWarnInvalidHydration = true;
14692 var names = [];
14693 attributeNames.forEach(function (name) {
14694 names.push(name);
14695 });
14696 warning_1(false, 'Extra attributes from the server: %s', names);
14697 };
14698
14699 warnForInvalidEventListener = function (registrationName, listener) {
14700 if (listener === false) {
14701 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());
14702 } else {
14703 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
14704 }
14705 };
14706
14707 // Parse the HTML and read it back to normalize the HTML string so that it
14708 // can be used for comparison.
14709 normalizeHTML = function (parent, html) {
14710 // We could have created a separate document here to avoid
14711 // re-initializing custom elements if they exist. But this breaks
14712 // how <noscript> is being handled. So we use the same document.
14713 // See the discussion in https://github.com/facebook/react/pull/11157.
14714 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
14715 testElement.innerHTML = html;
14716 return testElement.innerHTML;
14717 };
14718}
14719
14720function ensureListeningTo(rootContainerElement, registrationName) {
14721 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
14722 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
14723 listenTo(registrationName, doc);
14724}
14725
14726function getOwnerDocumentFromRootContainer(rootContainerElement) {
14727 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
14728}
14729
14730function trapClickOnNonInteractiveElement(node) {
14731 // Mobile Safari does not fire properly bubble click events on
14732 // non-interactive elements, which means delegated click listeners do not
14733 // fire. The workaround for this bug involves attaching an empty click
14734 // listener on the target node.
14735 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
14736 // Just set it using the onclick property so that we don't have to manage any
14737 // bookkeeping for it. Not sure if we need to clear it when the listener is
14738 // removed.
14739 // TODO: Only do this for the relevant Safaris maybe?
14740 node.onclick = emptyFunction_1;
14741}
14742
14743function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
14744 for (var propKey in nextProps) {
14745 if (!nextProps.hasOwnProperty(propKey)) {
14746 continue;
14747 }
14748 var nextProp = nextProps[propKey];
14749 if (propKey === STYLE) {
14750 {
14751 if (nextProp) {
14752 // Freeze the next style object so that we can assume it won't be
14753 // mutated. We have already warned for this in the past.
14754 Object.freeze(nextProp);
14755 }
14756 }
14757 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14758 setValueForStyles(domElement, nextProp, getStack);
14759 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14760 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14761 if (nextHtml != null) {
14762 setInnerHTML(domElement, nextHtml);
14763 }
14764 } else if (propKey === CHILDREN) {
14765 if (typeof nextProp === 'string') {
14766 // Avoid setting initial textContent when the text is empty. In IE11 setting
14767 // textContent on a <textarea> will cause the placeholder to not
14768 // show within the <textarea> until it has been focused and blurred again.
14769 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
14770 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
14771 if (canSetTextContent) {
14772 setTextContent(domElement, nextProp);
14773 }
14774 } else if (typeof nextProp === 'number') {
14775 setTextContent(domElement, '' + nextProp);
14776 }
14777 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14778 // Noop
14779 } else if (propKey === AUTOFOCUS) {
14780 // We polyfill it separately on the client during commit.
14781 // We blacklist it here rather than in the property list because we emit it in SSR.
14782 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14783 if (nextProp != null) {
14784 if (true && typeof nextProp !== 'function') {
14785 warnForInvalidEventListener(propKey, nextProp);
14786 }
14787 ensureListeningTo(rootContainerElement, propKey);
14788 }
14789 } else if (nextProp != null) {
14790 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14791 }
14792 }
14793}
14794
14795function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14796 // TODO: Handle wasCustomComponentTag
14797 for (var i = 0; i < updatePayload.length; i += 2) {
14798 var propKey = updatePayload[i];
14799 var propValue = updatePayload[i + 1];
14800 if (propKey === STYLE) {
14801 setValueForStyles(domElement, propValue, getStack);
14802 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14803 setInnerHTML(domElement, propValue);
14804 } else if (propKey === CHILDREN) {
14805 setTextContent(domElement, propValue);
14806 } else {
14807 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14808 }
14809 }
14810}
14811
14812function createElement$1(type, props, rootContainerElement, parentNamespace) {
14813 var isCustomComponentTag = void 0;
14814
14815 // We create tags in the namespace of their parent container, except HTML
14816 // tags get no namespace.
14817 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14818 var domElement = void 0;
14819 var namespaceURI = parentNamespace;
14820 if (namespaceURI === HTML_NAMESPACE) {
14821 namespaceURI = getIntrinsicNamespace(type);
14822 }
14823 if (namespaceURI === HTML_NAMESPACE) {
14824 {
14825 isCustomComponentTag = isCustomComponent(type, props);
14826 // Should this check be gated by parent namespace? Not sure we want to
14827 // allow <SVG> or <mATH>.
14828 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14829 }
14830
14831 if (type === 'script') {
14832 // Create the script via .innerHTML so its "parser-inserted" flag is
14833 // set to true and it does not execute
14834 var div = ownerDocument.createElement('div');
14835 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14836 // This is guaranteed to yield a script element.
14837 var firstChild = div.firstChild;
14838 domElement = div.removeChild(firstChild);
14839 } else if (typeof props.is === 'string') {
14840 // $FlowIssue `createElement` should be updated for Web Components
14841 domElement = ownerDocument.createElement(type, { is: props.is });
14842 } else {
14843 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14844 // See discussion in https://github.com/facebook/react/pull/6896
14845 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14846 domElement = ownerDocument.createElement(type);
14847 }
14848 } else {
14849 domElement = ownerDocument.createElementNS(namespaceURI, type);
14850 }
14851
14852 {
14853 if (namespaceURI === HTML_NAMESPACE) {
14854 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14855 warnedUnknownTags[type] = true;
14856 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);
14857 }
14858 }
14859 }
14860
14861 return domElement;
14862}
14863
14864function createTextNode$1(text, rootContainerElement) {
14865 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14866}
14867
14868function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14869 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14870 {
14871 validatePropertiesInDevelopment(tag, rawProps);
14872 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14873 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14874 didWarnShadyDOM = true;
14875 }
14876 }
14877
14878 // TODO: Make sure that we check isMounted before firing any of these events.
14879 var props = void 0;
14880 switch (tag) {
14881 case 'iframe':
14882 case 'object':
14883 trapBubbledEvent('topLoad', 'load', domElement);
14884 props = rawProps;
14885 break;
14886 case 'video':
14887 case 'audio':
14888 // Create listener for each media event
14889 for (var event in mediaEventTypes) {
14890 if (mediaEventTypes.hasOwnProperty(event)) {
14891 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14892 }
14893 }
14894 props = rawProps;
14895 break;
14896 case 'source':
14897 trapBubbledEvent('topError', 'error', domElement);
14898 props = rawProps;
14899 break;
14900 case 'img':
14901 case 'image':
14902 case 'link':
14903 trapBubbledEvent('topError', 'error', domElement);
14904 trapBubbledEvent('topLoad', 'load', domElement);
14905 props = rawProps;
14906 break;
14907 case 'form':
14908 trapBubbledEvent('topReset', 'reset', domElement);
14909 trapBubbledEvent('topSubmit', 'submit', domElement);
14910 props = rawProps;
14911 break;
14912 case 'details':
14913 trapBubbledEvent('topToggle', 'toggle', domElement);
14914 props = rawProps;
14915 break;
14916 case 'input':
14917 initWrapperState(domElement, rawProps);
14918 props = getHostProps(domElement, rawProps);
14919 trapBubbledEvent('topInvalid', 'invalid', domElement);
14920 // For controlled components we always need to ensure we're listening
14921 // to onChange. Even if there is no listener.
14922 ensureListeningTo(rootContainerElement, 'onChange');
14923 break;
14924 case 'option':
14925 validateProps(domElement, rawProps);
14926 props = getHostProps$1(domElement, rawProps);
14927 break;
14928 case 'select':
14929 initWrapperState$1(domElement, rawProps);
14930 props = getHostProps$2(domElement, rawProps);
14931 trapBubbledEvent('topInvalid', 'invalid', domElement);
14932 // For controlled components we always need to ensure we're listening
14933 // to onChange. Even if there is no listener.
14934 ensureListeningTo(rootContainerElement, 'onChange');
14935 break;
14936 case 'textarea':
14937 initWrapperState$2(domElement, rawProps);
14938 props = getHostProps$3(domElement, rawProps);
14939 trapBubbledEvent('topInvalid', 'invalid', domElement);
14940 // For controlled components we always need to ensure we're listening
14941 // to onChange. Even if there is no listener.
14942 ensureListeningTo(rootContainerElement, 'onChange');
14943 break;
14944 default:
14945 props = rawProps;
14946 }
14947
14948 assertValidProps(tag, props, getStack);
14949
14950 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
14951
14952 switch (tag) {
14953 case 'input':
14954 // TODO: Make sure we check if this is still unmounted or do any clean
14955 // up necessary since we never stop tracking anymore.
14956 track(domElement);
14957 postMountWrapper(domElement, rawProps);
14958 break;
14959 case 'textarea':
14960 // TODO: Make sure we check if this is still unmounted or do any clean
14961 // up necessary since we never stop tracking anymore.
14962 track(domElement);
14963 postMountWrapper$3(domElement, rawProps);
14964 break;
14965 case 'option':
14966 postMountWrapper$1(domElement, rawProps);
14967 break;
14968 case 'select':
14969 postMountWrapper$2(domElement, rawProps);
14970 break;
14971 default:
14972 if (typeof props.onClick === 'function') {
14973 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14974 trapClickOnNonInteractiveElement(domElement);
14975 }
14976 break;
14977 }
14978}
14979
14980// Calculate the diff between the two objects.
14981function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
14982 {
14983 validatePropertiesInDevelopment(tag, nextRawProps);
14984 }
14985
14986 var updatePayload = null;
14987
14988 var lastProps = void 0;
14989 var nextProps = void 0;
14990 switch (tag) {
14991 case 'input':
14992 lastProps = getHostProps(domElement, lastRawProps);
14993 nextProps = getHostProps(domElement, nextRawProps);
14994 updatePayload = [];
14995 break;
14996 case 'option':
14997 lastProps = getHostProps$1(domElement, lastRawProps);
14998 nextProps = getHostProps$1(domElement, nextRawProps);
14999 updatePayload = [];
15000 break;
15001 case 'select':
15002 lastProps = getHostProps$2(domElement, lastRawProps);
15003 nextProps = getHostProps$2(domElement, nextRawProps);
15004 updatePayload = [];
15005 break;
15006 case 'textarea':
15007 lastProps = getHostProps$3(domElement, lastRawProps);
15008 nextProps = getHostProps$3(domElement, nextRawProps);
15009 updatePayload = [];
15010 break;
15011 default:
15012 lastProps = lastRawProps;
15013 nextProps = nextRawProps;
15014 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
15015 // TODO: This cast may not be sound for SVG, MathML or custom elements.
15016 trapClickOnNonInteractiveElement(domElement);
15017 }
15018 break;
15019 }
15020
15021 assertValidProps(tag, nextProps, getStack);
15022
15023 var propKey = void 0;
15024 var styleName = void 0;
15025 var styleUpdates = null;
15026 for (propKey in lastProps) {
15027 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
15028 continue;
15029 }
15030 if (propKey === STYLE) {
15031 var lastStyle = lastProps[propKey];
15032 for (styleName in lastStyle) {
15033 if (lastStyle.hasOwnProperty(styleName)) {
15034 if (!styleUpdates) {
15035 styleUpdates = {};
15036 }
15037 styleUpdates[styleName] = '';
15038 }
15039 }
15040 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
15041 // Noop. This is handled by the clear text mechanism.
15042 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
15043 // Noop
15044 } else if (propKey === AUTOFOCUS) {
15045 // Noop. It doesn't work on updates anyway.
15046 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15047 // This is a special case. If any listener updates we need to ensure
15048 // that the "current" fiber pointer gets updated so we need a commit
15049 // to update this element.
15050 if (!updatePayload) {
15051 updatePayload = [];
15052 }
15053 } else {
15054 // For all other deleted properties we add it to the queue. We use
15055 // the whitelist in the commit phase instead.
15056 (updatePayload = updatePayload || []).push(propKey, null);
15057 }
15058 }
15059 for (propKey in nextProps) {
15060 var nextProp = nextProps[propKey];
15061 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
15062 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
15063 continue;
15064 }
15065 if (propKey === STYLE) {
15066 {
15067 if (nextProp) {
15068 // Freeze the next style object so that we can assume it won't be
15069 // mutated. We have already warned for this in the past.
15070 Object.freeze(nextProp);
15071 }
15072 }
15073 if (lastProp) {
15074 // Unset styles on `lastProp` but not on `nextProp`.
15075 for (styleName in lastProp) {
15076 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
15077 if (!styleUpdates) {
15078 styleUpdates = {};
15079 }
15080 styleUpdates[styleName] = '';
15081 }
15082 }
15083 // Update styles that changed since `lastProp`.
15084 for (styleName in nextProp) {
15085 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
15086 if (!styleUpdates) {
15087 styleUpdates = {};
15088 }
15089 styleUpdates[styleName] = nextProp[styleName];
15090 }
15091 }
15092 } else {
15093 // Relies on `updateStylesByID` not mutating `styleUpdates`.
15094 if (!styleUpdates) {
15095 if (!updatePayload) {
15096 updatePayload = [];
15097 }
15098 updatePayload.push(propKey, styleUpdates);
15099 }
15100 styleUpdates = nextProp;
15101 }
15102 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
15103 var nextHtml = nextProp ? nextProp[HTML] : undefined;
15104 var lastHtml = lastProp ? lastProp[HTML] : undefined;
15105 if (nextHtml != null) {
15106 if (lastHtml !== nextHtml) {
15107 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
15108 }
15109 } else {
15110 // TODO: It might be too late to clear this if we have children
15111 // inserted already.
15112 }
15113 } else if (propKey === CHILDREN) {
15114 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
15115 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
15116 }
15117 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
15118 // Noop
15119 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15120 if (nextProp != null) {
15121 // We eagerly listen to this even though we haven't committed yet.
15122 if (true && typeof nextProp !== 'function') {
15123 warnForInvalidEventListener(propKey, nextProp);
15124 }
15125 ensureListeningTo(rootContainerElement, propKey);
15126 }
15127 if (!updatePayload && lastProp !== nextProp) {
15128 // This is a special case. If any listener updates we need to ensure
15129 // that the "current" props pointer gets updated so we need a commit
15130 // to update this element.
15131 updatePayload = [];
15132 }
15133 } else {
15134 // For any other property we always add it to the queue and then we
15135 // filter it out using the whitelist during the commit.
15136 (updatePayload = updatePayload || []).push(propKey, nextProp);
15137 }
15138 }
15139 if (styleUpdates) {
15140 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
15141 }
15142 return updatePayload;
15143}
15144
15145// Apply the diff.
15146function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
15147 // Update checked *before* name.
15148 // In the middle of an update, it is possible to have multiple checked.
15149 // When a checked radio tries to change name, browser makes another radio's checked false.
15150 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
15151 updateChecked(domElement, nextRawProps);
15152 }
15153
15154 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
15155 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
15156 // Apply the diff.
15157 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
15158
15159 // TODO: Ensure that an update gets scheduled if any of the special props
15160 // changed.
15161 switch (tag) {
15162 case 'input':
15163 // Update the wrapper around inputs *after* updating props. This has to
15164 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
15165 // raise warnings and prevent the new value from being assigned.
15166 updateWrapper(domElement, nextRawProps);
15167 break;
15168 case 'textarea':
15169 updateWrapper$1(domElement, nextRawProps);
15170 break;
15171 case 'select':
15172 // <select> value update needs to occur after <option> children
15173 // reconciliation
15174 postUpdateWrapper(domElement, nextRawProps);
15175 break;
15176 }
15177}
15178
15179function getPossibleStandardName(propName) {
15180 {
15181 var lowerCasedName = propName.toLowerCase();
15182 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
15183 return null;
15184 }
15185 return possibleStandardNames[lowerCasedName] || null;
15186 }
15187 return null;
15188}
15189
15190function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
15191 var isCustomComponentTag = void 0;
15192 var extraAttributeNames = void 0;
15193
15194 {
15195 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
15196 isCustomComponentTag = isCustomComponent(tag, rawProps);
15197 validatePropertiesInDevelopment(tag, rawProps);
15198 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
15199 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
15200 didWarnShadyDOM = true;
15201 }
15202 }
15203
15204 // TODO: Make sure that we check isMounted before firing any of these events.
15205 switch (tag) {
15206 case 'iframe':
15207 case 'object':
15208 trapBubbledEvent('topLoad', 'load', domElement);
15209 break;
15210 case 'video':
15211 case 'audio':
15212 // Create listener for each media event
15213 for (var event in mediaEventTypes) {
15214 if (mediaEventTypes.hasOwnProperty(event)) {
15215 trapBubbledEvent(event, mediaEventTypes[event], domElement);
15216 }
15217 }
15218 break;
15219 case 'source':
15220 trapBubbledEvent('topError', 'error', domElement);
15221 break;
15222 case 'img':
15223 case 'image':
15224 case 'link':
15225 trapBubbledEvent('topError', 'error', domElement);
15226 trapBubbledEvent('topLoad', 'load', domElement);
15227 break;
15228 case 'form':
15229 trapBubbledEvent('topReset', 'reset', domElement);
15230 trapBubbledEvent('topSubmit', 'submit', domElement);
15231 break;
15232 case 'details':
15233 trapBubbledEvent('topToggle', 'toggle', domElement);
15234 break;
15235 case 'input':
15236 initWrapperState(domElement, rawProps);
15237 trapBubbledEvent('topInvalid', 'invalid', domElement);
15238 // For controlled components we always need to ensure we're listening
15239 // to onChange. Even if there is no listener.
15240 ensureListeningTo(rootContainerElement, 'onChange');
15241 break;
15242 case 'option':
15243 validateProps(domElement, rawProps);
15244 break;
15245 case 'select':
15246 initWrapperState$1(domElement, rawProps);
15247 trapBubbledEvent('topInvalid', 'invalid', domElement);
15248 // For controlled components we always need to ensure we're listening
15249 // to onChange. Even if there is no listener.
15250 ensureListeningTo(rootContainerElement, 'onChange');
15251 break;
15252 case 'textarea':
15253 initWrapperState$2(domElement, rawProps);
15254 trapBubbledEvent('topInvalid', 'invalid', domElement);
15255 // For controlled components we always need to ensure we're listening
15256 // to onChange. Even if there is no listener.
15257 ensureListeningTo(rootContainerElement, 'onChange');
15258 break;
15259 }
15260
15261 assertValidProps(tag, rawProps, getStack);
15262
15263 {
15264 extraAttributeNames = new Set();
15265 var attributes = domElement.attributes;
15266 for (var i = 0; i < attributes.length; i++) {
15267 var name = attributes[i].name.toLowerCase();
15268 switch (name) {
15269 // Built-in SSR attribute is whitelisted
15270 case 'data-reactroot':
15271 break;
15272 // Controlled attributes are not validated
15273 // TODO: Only ignore them on controlled tags.
15274 case 'value':
15275 break;
15276 case 'checked':
15277 break;
15278 case 'selected':
15279 break;
15280 default:
15281 // Intentionally use the original name.
15282 // See discussion in https://github.com/facebook/react/pull/10676.
15283 extraAttributeNames.add(attributes[i].name);
15284 }
15285 }
15286 }
15287
15288 var updatePayload = null;
15289 for (var propKey in rawProps) {
15290 if (!rawProps.hasOwnProperty(propKey)) {
15291 continue;
15292 }
15293 var nextProp = rawProps[propKey];
15294 if (propKey === CHILDREN) {
15295 // For text content children we compare against textContent. This
15296 // might match additional HTML that is hidden when we read it using
15297 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
15298 // satisfies our requirement. Our requirement is not to produce perfect
15299 // HTML and attributes. Ideally we should preserve structure but it's
15300 // ok not to if the visible content is still enough to indicate what
15301 // even listeners these nodes might be wired up to.
15302 // TODO: Warn if there is more than a single textNode as a child.
15303 // TODO: Should we use domElement.firstChild.nodeValue to compare?
15304 if (typeof nextProp === 'string') {
15305 if (domElement.textContent !== nextProp) {
15306 if (true && !suppressHydrationWarning) {
15307 warnForTextDifference(domElement.textContent, nextProp);
15308 }
15309 updatePayload = [CHILDREN, nextProp];
15310 }
15311 } else if (typeof nextProp === 'number') {
15312 if (domElement.textContent !== '' + nextProp) {
15313 if (true && !suppressHydrationWarning) {
15314 warnForTextDifference(domElement.textContent, nextProp);
15315 }
15316 updatePayload = [CHILDREN, '' + nextProp];
15317 }
15318 }
15319 } else if (registrationNameModules.hasOwnProperty(propKey)) {
15320 if (nextProp != null) {
15321 if (true && typeof nextProp !== 'function') {
15322 warnForInvalidEventListener(propKey, nextProp);
15323 }
15324 ensureListeningTo(rootContainerElement, propKey);
15325 }
15326 } else if (true &&
15327 // Convince Flow we've calculated it (it's DEV-only in this method.)
15328 typeof isCustomComponentTag === 'boolean') {
15329 // Validate that the properties correspond to their expected values.
15330 var serverValue = void 0;
15331 var propertyInfo = getPropertyInfo(propKey);
15332 if (suppressHydrationWarning) {
15333 // Don't bother comparing. We're ignoring all these warnings.
15334 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
15335 // Controlled attributes are not validated
15336 // TODO: Only ignore them on controlled tags.
15337 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
15338 // Noop
15339 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
15340 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
15341 var serverHTML = domElement.innerHTML;
15342 var expectedHTML = normalizeHTML(domElement, rawHtml);
15343 if (expectedHTML !== serverHTML) {
15344 warnForPropDifference(propKey, serverHTML, expectedHTML);
15345 }
15346 } else if (propKey === STYLE) {
15347 // $FlowFixMe - Should be inferred as not undefined.
15348 extraAttributeNames['delete'](propKey);
15349 var expectedStyle = createDangerousStringForStyles(nextProp);
15350 serverValue = domElement.getAttribute('style');
15351 if (expectedStyle !== serverValue) {
15352 warnForPropDifference(propKey, serverValue, expectedStyle);
15353 }
15354 } else if (isCustomComponentTag) {
15355 // $FlowFixMe - Should be inferred as not undefined.
15356 extraAttributeNames['delete'](propKey.toLowerCase());
15357 serverValue = getValueForAttribute(domElement, propKey, nextProp);
15358
15359 if (nextProp !== serverValue) {
15360 warnForPropDifference(propKey, serverValue, nextProp);
15361 }
15362 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
15363 var isMismatchDueToBadCasing = false;
15364 if (propertyInfo !== null) {
15365 // $FlowFixMe - Should be inferred as not undefined.
15366 extraAttributeNames['delete'](propertyInfo.attributeName);
15367 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
15368 } else {
15369 var ownNamespace = parentNamespace;
15370 if (ownNamespace === HTML_NAMESPACE) {
15371 ownNamespace = getIntrinsicNamespace(tag);
15372 }
15373 if (ownNamespace === HTML_NAMESPACE) {
15374 // $FlowFixMe - Should be inferred as not undefined.
15375 extraAttributeNames['delete'](propKey.toLowerCase());
15376 } else {
15377 var standardName = getPossibleStandardName(propKey);
15378 if (standardName !== null && standardName !== propKey) {
15379 // If an SVG prop is supplied with bad casing, it will
15380 // be successfully parsed from HTML, but will produce a mismatch
15381 // (and would be incorrectly rendered on the client).
15382 // However, we already warn about bad casing elsewhere.
15383 // So we'll skip the misleading extra mismatch warning in this case.
15384 isMismatchDueToBadCasing = true;
15385 // $FlowFixMe - Should be inferred as not undefined.
15386 extraAttributeNames['delete'](standardName);
15387 }
15388 // $FlowFixMe - Should be inferred as not undefined.
15389 extraAttributeNames['delete'](propKey);
15390 }
15391 serverValue = getValueForAttribute(domElement, propKey, nextProp);
15392 }
15393
15394 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
15395 warnForPropDifference(propKey, serverValue, nextProp);
15396 }
15397 }
15398 }
15399 }
15400
15401 {
15402 // $FlowFixMe - Should be inferred as not undefined.
15403 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
15404 // $FlowFixMe - Should be inferred as not undefined.
15405 warnForExtraAttributes(extraAttributeNames);
15406 }
15407 }
15408
15409 switch (tag) {
15410 case 'input':
15411 // TODO: Make sure we check if this is still unmounted or do any clean
15412 // up necessary since we never stop tracking anymore.
15413 track(domElement);
15414 postMountWrapper(domElement, rawProps);
15415 break;
15416 case 'textarea':
15417 // TODO: Make sure we check if this is still unmounted or do any clean
15418 // up necessary since we never stop tracking anymore.
15419 track(domElement);
15420 postMountWrapper$3(domElement, rawProps);
15421 break;
15422 case 'select':
15423 case 'option':
15424 // For input and textarea we current always set the value property at
15425 // post mount to force it to diverge from attributes. However, for
15426 // option and select we don't quite do the same thing and select
15427 // is not resilient to the DOM state changing so we don't do that here.
15428 // TODO: Consider not doing this for input and textarea.
15429 break;
15430 default:
15431 if (typeof rawProps.onClick === 'function') {
15432 // TODO: This cast may not be sound for SVG, MathML or custom elements.
15433 trapClickOnNonInteractiveElement(domElement);
15434 }
15435 break;
15436 }
15437
15438 return updatePayload;
15439}
15440
15441function diffHydratedText$1(textNode, text) {
15442 var isDifferent = textNode.nodeValue !== text;
15443 return isDifferent;
15444}
15445
15446function warnForUnmatchedText$1(textNode, text) {
15447 {
15448 warnForTextDifference(textNode.nodeValue, text);
15449 }
15450}
15451
15452function warnForDeletedHydratableElement$1(parentNode, child) {
15453 {
15454 if (didWarnInvalidHydration) {
15455 return;
15456 }
15457 didWarnInvalidHydration = true;
15458 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
15459 }
15460}
15461
15462function warnForDeletedHydratableText$1(parentNode, child) {
15463 {
15464 if (didWarnInvalidHydration) {
15465 return;
15466 }
15467 didWarnInvalidHydration = true;
15468 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
15469 }
15470}
15471
15472function warnForInsertedHydratedElement$1(parentNode, tag, props) {
15473 {
15474 if (didWarnInvalidHydration) {
15475 return;
15476 }
15477 didWarnInvalidHydration = true;
15478 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
15479 }
15480}
15481
15482function warnForInsertedHydratedText$1(parentNode, text) {
15483 {
15484 if (text === '') {
15485 // We expect to insert empty text nodes since they're not represented in
15486 // the HTML.
15487 // TODO: Remove this special case if we can just avoid inserting empty
15488 // text nodes.
15489 return;
15490 }
15491 if (didWarnInvalidHydration) {
15492 return;
15493 }
15494 didWarnInvalidHydration = true;
15495 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
15496 }
15497}
15498
15499function restoreControlledState$1(domElement, tag, props) {
15500 switch (tag) {
15501 case 'input':
15502 restoreControlledState(domElement, props);
15503 return;
15504 case 'textarea':
15505 restoreControlledState$3(domElement, props);
15506 return;
15507 case 'select':
15508 restoreControlledState$2(domElement, props);
15509 return;
15510 }
15511}
15512
15513var ReactDOMFiberComponent = Object.freeze({
15514 createElement: createElement$1,
15515 createTextNode: createTextNode$1,
15516 setInitialProperties: setInitialProperties$1,
15517 diffProperties: diffProperties$1,
15518 updateProperties: updateProperties$1,
15519 diffHydratedProperties: diffHydratedProperties$1,
15520 diffHydratedText: diffHydratedText$1,
15521 warnForUnmatchedText: warnForUnmatchedText$1,
15522 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
15523 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
15524 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
15525 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
15526 restoreControlledState: restoreControlledState$1
15527});
15528
15529// TODO: direct imports like some-package/src/* are bad. Fix me.
15530var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
15531
15532var validateDOMNesting = emptyFunction_1;
15533
15534{
15535 // This validation code was written based on the HTML5 parsing spec:
15536 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
15537 //
15538 // Note: this does not catch all invalid nesting, nor does it try to (as it's
15539 // not clear what practical benefit doing so provides); instead, we warn only
15540 // for cases where the parser will give a parse tree differing from what React
15541 // intended. For example, <b><div></div></b> is invalid but we don't warn
15542 // because it still parses correctly; we do warn for other cases like nested
15543 // <p> tags where the beginning of the second element implicitly closes the
15544 // first, causing a confusing mess.
15545
15546 // https://html.spec.whatwg.org/multipage/syntax.html#special
15547 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'];
15548
15549 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
15550 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
15551
15552 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
15553 // TODO: Distinguish by namespace here -- for <title>, including it here
15554 // errs on the side of fewer warnings
15555 'foreignObject', 'desc', 'title'];
15556
15557 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
15558 var buttonScopeTags = inScopeTags.concat(['button']);
15559
15560 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
15561 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
15562
15563 var emptyAncestorInfo = {
15564 current: null,
15565
15566 formTag: null,
15567 aTagInScope: null,
15568 buttonTagInScope: null,
15569 nobrTagInScope: null,
15570 pTagInButtonScope: null,
15571
15572 listItemTagAutoclosing: null,
15573 dlItemTagAutoclosing: null
15574 };
15575
15576 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
15577 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
15578 var info = { tag: tag, instance: instance };
15579
15580 if (inScopeTags.indexOf(tag) !== -1) {
15581 ancestorInfo.aTagInScope = null;
15582 ancestorInfo.buttonTagInScope = null;
15583 ancestorInfo.nobrTagInScope = null;
15584 }
15585 if (buttonScopeTags.indexOf(tag) !== -1) {
15586 ancestorInfo.pTagInButtonScope = null;
15587 }
15588
15589 // See rules for 'li', 'dd', 'dt' start tags in
15590 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15591 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
15592 ancestorInfo.listItemTagAutoclosing = null;
15593 ancestorInfo.dlItemTagAutoclosing = null;
15594 }
15595
15596 ancestorInfo.current = info;
15597
15598 if (tag === 'form') {
15599 ancestorInfo.formTag = info;
15600 }
15601 if (tag === 'a') {
15602 ancestorInfo.aTagInScope = info;
15603 }
15604 if (tag === 'button') {
15605 ancestorInfo.buttonTagInScope = info;
15606 }
15607 if (tag === 'nobr') {
15608 ancestorInfo.nobrTagInScope = info;
15609 }
15610 if (tag === 'p') {
15611 ancestorInfo.pTagInButtonScope = info;
15612 }
15613 if (tag === 'li') {
15614 ancestorInfo.listItemTagAutoclosing = info;
15615 }
15616 if (tag === 'dd' || tag === 'dt') {
15617 ancestorInfo.dlItemTagAutoclosing = info;
15618 }
15619
15620 return ancestorInfo;
15621 };
15622
15623 /**
15624 * Returns whether
15625 */
15626 var isTagValidWithParent = function (tag, parentTag) {
15627 // First, let's check if we're in an unusual parsing mode...
15628 switch (parentTag) {
15629 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
15630 case 'select':
15631 return tag === 'option' || tag === 'optgroup' || tag === '#text';
15632 case 'optgroup':
15633 return tag === 'option' || tag === '#text';
15634 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
15635 // but
15636 case 'option':
15637 return tag === '#text';
15638 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
15639 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
15640 // No special behavior since these rules fall back to "in body" mode for
15641 // all except special table nodes which cause bad parsing behavior anyway.
15642
15643 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
15644 case 'tr':
15645 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
15646 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
15647 case 'tbody':
15648 case 'thead':
15649 case 'tfoot':
15650 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
15651 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
15652 case 'colgroup':
15653 return tag === 'col' || tag === 'template';
15654 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
15655 case 'table':
15656 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
15657 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
15658 case 'head':
15659 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
15660 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
15661 case 'html':
15662 return tag === 'head' || tag === 'body';
15663 case '#document':
15664 return tag === 'html';
15665 }
15666
15667 // Probably in the "in body" parsing mode, so we outlaw only tag combos
15668 // where the parsing rules cause implicit opens or closes to be added.
15669 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15670 switch (tag) {
15671 case 'h1':
15672 case 'h2':
15673 case 'h3':
15674 case 'h4':
15675 case 'h5':
15676 case 'h6':
15677 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
15678
15679 case 'rp':
15680 case 'rt':
15681 return impliedEndTags.indexOf(parentTag) === -1;
15682
15683 case 'body':
15684 case 'caption':
15685 case 'col':
15686 case 'colgroup':
15687 case 'frame':
15688 case 'head':
15689 case 'html':
15690 case 'tbody':
15691 case 'td':
15692 case 'tfoot':
15693 case 'th':
15694 case 'thead':
15695 case 'tr':
15696 // These tags are only valid with a few parents that have special child
15697 // parsing rules -- if we're down here, then none of those matched and
15698 // so we allow it only if we don't know what the parent is, as all other
15699 // cases are invalid.
15700 return parentTag == null;
15701 }
15702
15703 return true;
15704 };
15705
15706 /**
15707 * Returns whether
15708 */
15709 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
15710 switch (tag) {
15711 case 'address':
15712 case 'article':
15713 case 'aside':
15714 case 'blockquote':
15715 case 'center':
15716 case 'details':
15717 case 'dialog':
15718 case 'dir':
15719 case 'div':
15720 case 'dl':
15721 case 'fieldset':
15722 case 'figcaption':
15723 case 'figure':
15724 case 'footer':
15725 case 'header':
15726 case 'hgroup':
15727 case 'main':
15728 case 'menu':
15729 case 'nav':
15730 case 'ol':
15731 case 'p':
15732 case 'section':
15733 case 'summary':
15734 case 'ul':
15735 case 'pre':
15736 case 'listing':
15737 case 'table':
15738 case 'hr':
15739 case 'xmp':
15740 case 'h1':
15741 case 'h2':
15742 case 'h3':
15743 case 'h4':
15744 case 'h5':
15745 case 'h6':
15746 return ancestorInfo.pTagInButtonScope;
15747
15748 case 'form':
15749 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
15750
15751 case 'li':
15752 return ancestorInfo.listItemTagAutoclosing;
15753
15754 case 'dd':
15755 case 'dt':
15756 return ancestorInfo.dlItemTagAutoclosing;
15757
15758 case 'button':
15759 return ancestorInfo.buttonTagInScope;
15760
15761 case 'a':
15762 // Spec says something about storing a list of markers, but it sounds
15763 // equivalent to this check.
15764 return ancestorInfo.aTagInScope;
15765
15766 case 'nobr':
15767 return ancestorInfo.nobrTagInScope;
15768 }
15769
15770 return null;
15771 };
15772
15773 var didWarn = {};
15774
15775 validateDOMNesting = function (childTag, childText, ancestorInfo) {
15776 ancestorInfo = ancestorInfo || emptyAncestorInfo;
15777 var parentInfo = ancestorInfo.current;
15778 var parentTag = parentInfo && parentInfo.tag;
15779
15780 if (childText != null) {
15781 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
15782 childTag = '#text';
15783 }
15784
15785 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15786 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15787 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15788 if (!invalidParentOrAncestor) {
15789 return;
15790 }
15791
15792 var ancestorTag = invalidParentOrAncestor.tag;
15793 var addendum = getCurrentFiberStackAddendum$6();
15794
15795 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15796 if (didWarn[warnKey]) {
15797 return;
15798 }
15799 didWarn[warnKey] = true;
15800
15801 var tagDisplayName = childTag;
15802 var whitespaceInfo = '';
15803 if (childTag === '#text') {
15804 if (/\S/.test(childText)) {
15805 tagDisplayName = 'Text nodes';
15806 } else {
15807 tagDisplayName = 'Whitespace text nodes';
15808 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15809 }
15810 } else {
15811 tagDisplayName = '<' + childTag + '>';
15812 }
15813
15814 if (invalidParent) {
15815 var info = '';
15816 if (ancestorTag === 'table' && childTag === 'tr') {
15817 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15818 }
15819 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15820 } else {
15821 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15822 }
15823 };
15824
15825 // TODO: turn this into a named export
15826 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15827}
15828
15829var validateDOMNesting$1 = validateDOMNesting;
15830
15831// TODO: This type is shared between the reconciler and ReactDOM, but will
15832// eventually be lifted out to the renderer.
15833
15834// TODO: direct imports like some-package/src/* are bad. Fix me.
15835var createElement = createElement$1;
15836var createTextNode = createTextNode$1;
15837var setInitialProperties = setInitialProperties$1;
15838var diffProperties = diffProperties$1;
15839var updateProperties = updateProperties$1;
15840var diffHydratedProperties = diffHydratedProperties$1;
15841var diffHydratedText = diffHydratedText$1;
15842var warnForUnmatchedText = warnForUnmatchedText$1;
15843var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15844var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15845var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15846var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15847var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15848var precacheFiberNode = precacheFiberNode$1;
15849var updateFiberProps = updateFiberProps$1;
15850
15851
15852var SUPPRESS_HYDRATION_WARNING = void 0;
15853var topLevelUpdateWarnings = void 0;
15854var warnOnInvalidCallback = void 0;
15855var didWarnAboutUnstableCreatePortal = false;
15856
15857{
15858 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15859 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') {
15860 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');
15861 }
15862
15863 topLevelUpdateWarnings = function (container) {
15864 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15865 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15866 if (hostInstance) {
15867 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.');
15868 }
15869 }
15870
15871 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15872 var rootEl = getReactRootElementInContainer(container);
15873 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15874
15875 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.');
15876
15877 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.');
15878 };
15879
15880 warnOnInvalidCallback = function (callback, callerName) {
15881 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
15882 };
15883}
15884
15885injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
15886
15887var eventsEnabled = null;
15888var selectionInformation = null;
15889
15890function ReactBatch(root) {
15891 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
15892 this._expirationTime = expirationTime;
15893 this._root = root;
15894 this._next = null;
15895 this._callbacks = null;
15896 this._didComplete = false;
15897 this._hasChildren = false;
15898 this._children = null;
15899 this._defer = true;
15900}
15901ReactBatch.prototype.render = function (children) {
15902 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
15903 this._hasChildren = true;
15904 this._children = children;
15905 var internalRoot = this._root._internalRoot;
15906 var expirationTime = this._expirationTime;
15907 var work = new ReactWork();
15908 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
15909 return work;
15910};
15911ReactBatch.prototype.then = function (onComplete) {
15912 if (this._didComplete) {
15913 onComplete();
15914 return;
15915 }
15916 var callbacks = this._callbacks;
15917 if (callbacks === null) {
15918 callbacks = this._callbacks = [];
15919 }
15920 callbacks.push(onComplete);
15921};
15922ReactBatch.prototype.commit = function () {
15923 var internalRoot = this._root._internalRoot;
15924 var firstBatch = internalRoot.firstBatch;
15925 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15926
15927 if (!this._hasChildren) {
15928 // This batch is empty. Return.
15929 this._next = null;
15930 this._defer = false;
15931 return;
15932 }
15933
15934 var expirationTime = this._expirationTime;
15935
15936 // Ensure this is the first batch in the list.
15937 if (firstBatch !== this) {
15938 // This batch is not the earliest batch. We need to move it to the front.
15939 // Update its expiration time to be the expiration time of the earliest
15940 // batch, so that we can flush it without flushing the other batches.
15941 if (this._hasChildren) {
15942 expirationTime = this._expirationTime = firstBatch._expirationTime;
15943 // Rendering this batch again ensures its children will be the final state
15944 // when we flush (updates are processed in insertion order: last
15945 // update wins).
15946 // TODO: This forces a restart. Should we print a warning?
15947 this.render(this._children);
15948 }
15949
15950 // Remove the batch from the list.
15951 var previous = null;
15952 var batch = firstBatch;
15953 while (batch !== this) {
15954 previous = batch;
15955 batch = batch._next;
15956 }
15957 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15958 previous._next = batch._next;
15959
15960 // Add it to the front.
15961 this._next = firstBatch;
15962 firstBatch = internalRoot.firstBatch = this;
15963 }
15964
15965 // Synchronously flush all the work up to this batch's expiration time.
15966 this._defer = false;
15967 DOMRenderer.flushRoot(internalRoot, expirationTime);
15968
15969 // Pop the batch from the list.
15970 var next = this._next;
15971 this._next = null;
15972 firstBatch = internalRoot.firstBatch = next;
15973
15974 // Append the next earliest batch's children to the update queue.
15975 if (firstBatch !== null && firstBatch._hasChildren) {
15976 firstBatch.render(firstBatch._children);
15977 }
15978};
15979ReactBatch.prototype._onComplete = function () {
15980 if (this._didComplete) {
15981 return;
15982 }
15983 this._didComplete = true;
15984 var callbacks = this._callbacks;
15985 if (callbacks === null) {
15986 return;
15987 }
15988 // TODO: Error handling.
15989 for (var i = 0; i < callbacks.length; i++) {
15990 var _callback = callbacks[i];
15991 _callback();
15992 }
15993};
15994
15995function ReactWork() {
15996 this._callbacks = null;
15997 this._didCommit = false;
15998 // TODO: Avoid need to bind by replacing callbacks in the update queue with
15999 // list of Work objects.
16000 this._onCommit = this._onCommit.bind(this);
16001}
16002ReactWork.prototype.then = function (onCommit) {
16003 if (this._didCommit) {
16004 onCommit();
16005 return;
16006 }
16007 var callbacks = this._callbacks;
16008 if (callbacks === null) {
16009 callbacks = this._callbacks = [];
16010 }
16011 callbacks.push(onCommit);
16012};
16013ReactWork.prototype._onCommit = function () {
16014 if (this._didCommit) {
16015 return;
16016 }
16017 this._didCommit = true;
16018 var callbacks = this._callbacks;
16019 if (callbacks === null) {
16020 return;
16021 }
16022 // TODO: Error handling.
16023 for (var i = 0; i < callbacks.length; i++) {
16024 var _callback2 = callbacks[i];
16025 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
16026 _callback2();
16027 }
16028};
16029
16030function ReactRoot(container, isAsync, hydrate) {
16031 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
16032 this._internalRoot = root;
16033}
16034ReactRoot.prototype.render = function (children, callback) {
16035 var root = this._internalRoot;
16036 var work = new ReactWork();
16037 callback = callback === undefined ? null : callback;
16038 {
16039 warnOnInvalidCallback(callback, 'render');
16040 }
16041 if (callback !== null) {
16042 work.then(callback);
16043 }
16044 DOMRenderer.updateContainer(children, root, null, work._onCommit);
16045 return work;
16046};
16047ReactRoot.prototype.unmount = function (callback) {
16048 var root = this._internalRoot;
16049 var work = new ReactWork();
16050 callback = callback === undefined ? null : callback;
16051 {
16052 warnOnInvalidCallback(callback, 'render');
16053 }
16054 if (callback !== null) {
16055 work.then(callback);
16056 }
16057 DOMRenderer.updateContainer(null, root, null, work._onCommit);
16058 return work;
16059};
16060ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
16061 var root = this._internalRoot;
16062 var work = new ReactWork();
16063 callback = callback === undefined ? null : callback;
16064 {
16065 warnOnInvalidCallback(callback, 'render');
16066 }
16067 if (callback !== null) {
16068 work.then(callback);
16069 }
16070 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
16071 return work;
16072};
16073ReactRoot.prototype.createBatch = function () {
16074 var batch = new ReactBatch(this);
16075 var expirationTime = batch._expirationTime;
16076
16077 var internalRoot = this._internalRoot;
16078 var firstBatch = internalRoot.firstBatch;
16079 if (firstBatch === null) {
16080 internalRoot.firstBatch = batch;
16081 batch._next = null;
16082 } else {
16083 // Insert sorted by expiration time then insertion order
16084 var insertAfter = null;
16085 var insertBefore = firstBatch;
16086 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
16087 insertAfter = insertBefore;
16088 insertBefore = insertBefore._next;
16089 }
16090 batch._next = insertBefore;
16091 if (insertAfter !== null) {
16092 insertAfter._next = batch;
16093 }
16094 }
16095
16096 return batch;
16097};
16098
16099/**
16100 * True if the supplied DOM node is a valid node element.
16101 *
16102 * @param {?DOMElement} node The candidate DOM node.
16103 * @return {boolean} True if the DOM is a valid DOM node.
16104 * @internal
16105 */
16106function isValidContainer(node) {
16107 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 '));
16108}
16109
16110function getReactRootElementInContainer(container) {
16111 if (!container) {
16112 return null;
16113 }
16114
16115 if (container.nodeType === DOCUMENT_NODE) {
16116 return container.documentElement;
16117 } else {
16118 return container.firstChild;
16119 }
16120}
16121
16122function shouldHydrateDueToLegacyHeuristic(container) {
16123 var rootElement = getReactRootElementInContainer(container);
16124 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
16125}
16126
16127function shouldAutoFocusHostComponent(type, props) {
16128 switch (type) {
16129 case 'button':
16130 case 'input':
16131 case 'select':
16132 case 'textarea':
16133 return !!props.autoFocus;
16134 }
16135 return false;
16136}
16137
16138var DOMRenderer = reactReconciler({
16139 getRootHostContext: function (rootContainerInstance) {
16140 var type = void 0;
16141 var namespace = void 0;
16142 var nodeType = rootContainerInstance.nodeType;
16143 switch (nodeType) {
16144 case DOCUMENT_NODE:
16145 case DOCUMENT_FRAGMENT_NODE:
16146 {
16147 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
16148 var root = rootContainerInstance.documentElement;
16149 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
16150 break;
16151 }
16152 default:
16153 {
16154 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
16155 var ownNamespace = container.namespaceURI || null;
16156 type = container.tagName;
16157 namespace = getChildNamespace(ownNamespace, type);
16158 break;
16159 }
16160 }
16161 {
16162 var validatedTag = type.toLowerCase();
16163 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
16164 return { namespace: namespace, ancestorInfo: _ancestorInfo };
16165 }
16166 return namespace;
16167 },
16168 getChildHostContext: function (parentHostContext, type) {
16169 {
16170 var parentHostContextDev = parentHostContext;
16171 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
16172 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
16173 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
16174 }
16175 var parentNamespace = parentHostContext;
16176 return getChildNamespace(parentNamespace, type);
16177 },
16178 getPublicInstance: function (instance) {
16179 return instance;
16180 },
16181 prepareForCommit: function () {
16182 eventsEnabled = isEnabled();
16183 selectionInformation = getSelectionInformation();
16184 setEnabled(false);
16185 },
16186 resetAfterCommit: function () {
16187 restoreSelection(selectionInformation);
16188 selectionInformation = null;
16189 setEnabled(eventsEnabled);
16190 eventsEnabled = null;
16191 },
16192 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
16193 var parentNamespace = void 0;
16194 {
16195 // TODO: take namespace into account when validating.
16196 var hostContextDev = hostContext;
16197 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
16198 if (typeof props.children === 'string' || typeof props.children === 'number') {
16199 var string = '' + props.children;
16200 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
16201 validateDOMNesting$1(null, string, ownAncestorInfo);
16202 }
16203 parentNamespace = hostContextDev.namespace;
16204 }
16205 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
16206 precacheFiberNode(internalInstanceHandle, domElement);
16207 updateFiberProps(domElement, props);
16208 return domElement;
16209 },
16210 appendInitialChild: function (parentInstance, child) {
16211 parentInstance.appendChild(child);
16212 },
16213 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
16214 setInitialProperties(domElement, type, props, rootContainerInstance);
16215 return shouldAutoFocusHostComponent(type, props);
16216 },
16217 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
16218 {
16219 var hostContextDev = hostContext;
16220 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
16221 var string = '' + newProps.children;
16222 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
16223 validateDOMNesting$1(null, string, ownAncestorInfo);
16224 }
16225 }
16226 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
16227 },
16228 shouldSetTextContent: function (type, props) {
16229 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
16230 },
16231 shouldDeprioritizeSubtree: function (type, props) {
16232 return !!props.hidden;
16233 },
16234 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
16235 {
16236 var hostContextDev = hostContext;
16237 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
16238 }
16239 var textNode = createTextNode(text, rootContainerInstance);
16240 precacheFiberNode(internalInstanceHandle, textNode);
16241 return textNode;
16242 },
16243
16244
16245 now: now,
16246
16247 mutation: {
16248 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
16249 // Despite the naming that might imply otherwise, this method only
16250 // fires if there is an `Update` effect scheduled during mounting.
16251 // This happens if `finalizeInitialChildren` returns `true` (which it
16252 // does to implement the `autoFocus` attribute on the client). But
16253 // there are also other cases when this might happen (such as patching
16254 // up text content during hydration mismatch). So we'll check this again.
16255 if (shouldAutoFocusHostComponent(type, newProps)) {
16256 domElement.focus();
16257 }
16258 },
16259 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
16260 // Update the props handle so that we know which props are the ones with
16261 // with current event handlers.
16262 updateFiberProps(domElement, newProps);
16263 // Apply the diff to the DOM node.
16264 updateProperties(domElement, updatePayload, type, oldProps, newProps);
16265 },
16266 resetTextContent: function (domElement) {
16267 setTextContent(domElement, '');
16268 },
16269 commitTextUpdate: function (textInstance, oldText, newText) {
16270 textInstance.nodeValue = newText;
16271 },
16272 appendChild: function (parentInstance, child) {
16273 parentInstance.appendChild(child);
16274 },
16275 appendChildToContainer: function (container, child) {
16276 if (container.nodeType === COMMENT_NODE) {
16277 container.parentNode.insertBefore(child, container);
16278 } else {
16279 container.appendChild(child);
16280 }
16281 },
16282 insertBefore: function (parentInstance, child, beforeChild) {
16283 parentInstance.insertBefore(child, beforeChild);
16284 },
16285 insertInContainerBefore: function (container, child, beforeChild) {
16286 if (container.nodeType === COMMENT_NODE) {
16287 container.parentNode.insertBefore(child, beforeChild);
16288 } else {
16289 container.insertBefore(child, beforeChild);
16290 }
16291 },
16292 removeChild: function (parentInstance, child) {
16293 parentInstance.removeChild(child);
16294 },
16295 removeChildFromContainer: function (container, child) {
16296 if (container.nodeType === COMMENT_NODE) {
16297 container.parentNode.removeChild(child);
16298 } else {
16299 container.removeChild(child);
16300 }
16301 }
16302 },
16303
16304 hydration: {
16305 canHydrateInstance: function (instance, type, props) {
16306 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
16307 return null;
16308 }
16309 // This has now been refined to an element node.
16310 return instance;
16311 },
16312 canHydrateTextInstance: function (instance, text) {
16313 if (text === '' || instance.nodeType !== TEXT_NODE) {
16314 // Empty strings are not parsed by HTML so there won't be a correct match here.
16315 return null;
16316 }
16317 // This has now been refined to a text node.
16318 return instance;
16319 },
16320 getNextHydratableSibling: function (instance) {
16321 var node = instance.nextSibling;
16322 // Skip non-hydratable nodes.
16323 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
16324 node = node.nextSibling;
16325 }
16326 return node;
16327 },
16328 getFirstHydratableChild: function (parentInstance) {
16329 var next = parentInstance.firstChild;
16330 // Skip non-hydratable nodes.
16331 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
16332 next = next.nextSibling;
16333 }
16334 return next;
16335 },
16336 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
16337 precacheFiberNode(internalInstanceHandle, instance);
16338 // TODO: Possibly defer this until the commit phase where all the events
16339 // get attached.
16340 updateFiberProps(instance, props);
16341 var parentNamespace = void 0;
16342 {
16343 var hostContextDev = hostContext;
16344 parentNamespace = hostContextDev.namespace;
16345 }
16346 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
16347 },
16348 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
16349 precacheFiberNode(internalInstanceHandle, textInstance);
16350 return diffHydratedText(textInstance, text);
16351 },
16352 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
16353 {
16354 warnForUnmatchedText(textInstance, text);
16355 }
16356 },
16357 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
16358 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16359 warnForUnmatchedText(textInstance, text);
16360 }
16361 },
16362 didNotHydrateContainerInstance: function (parentContainer, instance) {
16363 {
16364 if (instance.nodeType === 1) {
16365 warnForDeletedHydratableElement(parentContainer, instance);
16366 } else {
16367 warnForDeletedHydratableText(parentContainer, instance);
16368 }
16369 }
16370 },
16371 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
16372 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16373 if (instance.nodeType === 1) {
16374 warnForDeletedHydratableElement(parentInstance, instance);
16375 } else {
16376 warnForDeletedHydratableText(parentInstance, instance);
16377 }
16378 }
16379 },
16380 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
16381 {
16382 warnForInsertedHydratedElement(parentContainer, type, props);
16383 }
16384 },
16385 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
16386 {
16387 warnForInsertedHydratedText(parentContainer, text);
16388 }
16389 },
16390 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
16391 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16392 warnForInsertedHydratedElement(parentInstance, type, props);
16393 }
16394 },
16395 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
16396 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
16397 warnForInsertedHydratedText(parentInstance, text);
16398 }
16399 }
16400 },
16401
16402 scheduleDeferredCallback: rIC,
16403 cancelDeferredCallback: cIC
16404});
16405
16406injection$3.injectRenderer(DOMRenderer);
16407
16408var warnedAboutHydrateAPI = false;
16409
16410function legacyCreateRootFromDOMContainer(container, forceHydrate) {
16411 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
16412 // First clear any existing content.
16413 if (!shouldHydrate) {
16414 var warned = false;
16415 var rootSibling = void 0;
16416 while (rootSibling = container.lastChild) {
16417 {
16418 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
16419 warned = true;
16420 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.');
16421 }
16422 }
16423 container.removeChild(rootSibling);
16424 }
16425 }
16426 {
16427 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
16428 warnedAboutHydrateAPI = true;
16429 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.');
16430 }
16431 }
16432 // Legacy roots are not async by default.
16433 var isAsync = false;
16434 return new ReactRoot(container, isAsync, shouldHydrate);
16435}
16436
16437function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
16438 // TODO: Ensure all entry points contain this check
16439 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
16440
16441 {
16442 topLevelUpdateWarnings(container);
16443 }
16444
16445 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
16446 // member of intersection type." Whyyyyyy.
16447 var root = container._reactRootContainer;
16448 if (!root) {
16449 // Initial mount
16450 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
16451 if (typeof callback === 'function') {
16452 var originalCallback = callback;
16453 callback = function () {
16454 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
16455 originalCallback.call(instance);
16456 };
16457 }
16458 // Initial mount should not be batched.
16459 DOMRenderer.unbatchedUpdates(function () {
16460 if (parentComponent != null) {
16461 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
16462 } else {
16463 root.render(children, callback);
16464 }
16465 });
16466 } else {
16467 if (typeof callback === 'function') {
16468 var _originalCallback = callback;
16469 callback = function () {
16470 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
16471 _originalCallback.call(instance);
16472 };
16473 }
16474 // Update
16475 if (parentComponent != null) {
16476 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
16477 } else {
16478 root.render(children, callback);
16479 }
16480 }
16481 return DOMRenderer.getPublicRootInstance(root._internalRoot);
16482}
16483
16484function createPortal(children, container) {
16485 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
16486
16487 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
16488 // TODO: pass ReactDOM portal implementation as third argument
16489 return createPortal$1(children, container, null, key);
16490}
16491
16492var ReactDOM = {
16493 createPortal: createPortal,
16494
16495 findDOMNode: function (componentOrElement) {
16496 {
16497 var owner = ReactCurrentOwner.current;
16498 if (owner !== null) {
16499 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
16500 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');
16501 owner.stateNode._warnedAboutRefsInRender = true;
16502 }
16503 }
16504 if (componentOrElement == null) {
16505 return null;
16506 }
16507 if (componentOrElement.nodeType === ELEMENT_NODE) {
16508 return componentOrElement;
16509 }
16510
16511 var inst = get(componentOrElement);
16512 if (inst) {
16513 return DOMRenderer.findHostInstance(inst);
16514 }
16515
16516 if (typeof componentOrElement.render === 'function') {
16517 invariant_1(false, 'Unable to find node on an unmounted component.');
16518 } else {
16519 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
16520 }
16521 },
16522 hydrate: function (element, container, callback) {
16523 // TODO: throw or warn if we couldn't hydrate?
16524 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
16525 },
16526 render: function (element, container, callback) {
16527 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
16528 },
16529 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
16530 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
16531 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
16532 },
16533 unmountComponentAtNode: function (container) {
16534 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
16535
16536 if (container._reactRootContainer) {
16537 {
16538 var rootEl = getReactRootElementInContainer(container);
16539 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
16540 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
16541 }
16542
16543 // Unmount should not be batched.
16544 DOMRenderer.unbatchedUpdates(function () {
16545 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
16546 container._reactRootContainer = null;
16547 });
16548 });
16549 // If you call unmountComponentAtNode twice in quick succession, you'll
16550 // get `true` twice. That's probably fine?
16551 return true;
16552 } else {
16553 {
16554 var _rootEl = getReactRootElementInContainer(container);
16555 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
16556
16557 // Check if the container itself is a React root node.
16558 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
16559
16560 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.');
16561 }
16562
16563 return false;
16564 }
16565 },
16566
16567
16568 // Temporary alias since we already shipped React 16 RC with it.
16569 // TODO: remove in React 17.
16570 unstable_createPortal: function () {
16571 if (!didWarnAboutUnstableCreatePortal) {
16572 didWarnAboutUnstableCreatePortal = true;
16573 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.');
16574 }
16575 return createPortal.apply(undefined, arguments);
16576 },
16577
16578
16579 unstable_batchedUpdates: DOMRenderer.batchedUpdates,
16580
16581 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
16582
16583 flushSync: DOMRenderer.flushSync,
16584
16585 unstable_flushControlled: DOMRenderer.flushControlled,
16586
16587 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
16588 // For TapEventPlugin which is popular in open source
16589 EventPluginHub: EventPluginHub,
16590 // Used by test-utils
16591 EventPluginRegistry: EventPluginRegistry,
16592 EventPropagators: EventPropagators,
16593 ReactControlledComponent: ReactControlledComponent,
16594 ReactDOMComponentTree: ReactDOMComponentTree,
16595 ReactDOMEventListener: ReactDOMEventListener
16596 }
16597};
16598
16599if (enableCreateRoot) {
16600 ReactDOM.createRoot = function createRoot(container, options) {
16601 var hydrate = options != null && options.hydrate === true;
16602 return new ReactRoot(container, true, hydrate);
16603 };
16604}
16605
16606var foundDevTools = DOMRenderer.injectIntoDevTools({
16607 findFiberByHostInstance: getClosestInstanceFromNode,
16608 bundleType: 1,
16609 version: ReactVersion,
16610 rendererPackageName: 'react-dom'
16611});
16612
16613{
16614 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
16615 // If we're in Chrome or Firefox, provide a download link if not installed.
16616 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
16617 var protocol = window.location.protocol;
16618 // Don't warn in exotic cases like chrome-extension://.
16619 if (/^(https?|file):$/.test(protocol)) {
16620 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');
16621 }
16622 }
16623 }
16624}
16625
16626
16627
16628var ReactDOM$2 = Object.freeze({
16629 default: ReactDOM
16630});
16631
16632var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
16633
16634// TODO: decide on the top-level export form.
16635// This is hacky but makes it work with both Rollup and Jest.
16636var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
16637
16638return reactDom;
16639
16640})));