· 8 years ago · Jan 19, 2018, 02:34 PM
1/** @license React v16.2.0
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 * Forked from fbjs/warning:
290 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
291 *
292 * Only change is we use console.warn instead of console.error,
293 * and do nothing when 'console' is not supported.
294 * This really simplifies the code.
295 * ---
296 * Similar to invariant but only logs a warning if the condition is not met.
297 * This can be used to log issues in development environments in critical
298 * paths. Removing the logging code for production environments will keep the
299 * same logic and follow the same code paths.
300 */
301
302var lowPriorityWarning = function () {};
303
304{
305 var printWarning = function (format) {
306 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
307 args[_key - 1] = arguments[_key];
308 }
309
310 var argIndex = 0;
311 var message = 'Warning: ' + format.replace(/%s/g, function () {
312 return args[argIndex++];
313 });
314 if (typeof console !== 'undefined') {
315 console.warn(message);
316 }
317 try {
318 // --- Welcome to debugging React ---
319 // This error was thrown as a convenience so that you can use this stack
320 // to find the callsite that caused this warning to fire.
321 throw new Error(message);
322 } catch (x) {}
323 };
324
325 lowPriorityWarning = function (condition, format) {
326 if (format === undefined) {
327 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
328 }
329 if (!condition) {
330 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
331 args[_key2 - 2] = arguments[_key2];
332 }
333
334 printWarning.apply(undefined, [format].concat(args));
335 }
336 };
337}
338
339var lowPriorityWarning$1 = lowPriorityWarning;
340
341var shouldWarnOnInjection = false;
342
343/**
344 * Injectable ordering of event plugins.
345 */
346var eventPluginOrder = null;
347
348/**
349 * Injectable mapping from names to event plugin modules.
350 */
351var namesToPlugins = {};
352
353function enableWarningOnInjection() {
354 shouldWarnOnInjection = true;
355}
356
357/**
358 * Recomputes the plugin list using the injected plugins and plugin ordering.
359 *
360 * @private
361 */
362function recomputePluginOrdering() {
363 if (!eventPluginOrder) {
364 // Wait until an `eventPluginOrder` is injected.
365 return;
366 }
367 for (var pluginName in namesToPlugins) {
368 var pluginModule = namesToPlugins[pluginName];
369 var pluginIndex = eventPluginOrder.indexOf(pluginName);
370 !(pluginIndex > -1) ? invariant_1(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
371 if (plugins[pluginIndex]) {
372 continue;
373 }
374 !pluginModule.extractEvents ? invariant_1(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
375 plugins[pluginIndex] = pluginModule;
376 var publishedEvents = pluginModule.eventTypes;
377 for (var eventName in publishedEvents) {
378 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant_1(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
379 }
380 }
381}
382
383/**
384 * Publishes an event so that it can be dispatched by the supplied plugin.
385 *
386 * @param {object} dispatchConfig Dispatch configuration for the event.
387 * @param {object} PluginModule Plugin publishing the event.
388 * @return {boolean} True if the event was successfully published.
389 * @private
390 */
391function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
392 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
393 eventNameDispatchConfigs[eventName] = dispatchConfig;
394
395 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
396 if (phasedRegistrationNames) {
397 for (var phaseName in phasedRegistrationNames) {
398 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
399 var phasedRegistrationName = phasedRegistrationNames[phaseName];
400 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
401 }
402 }
403 return true;
404 } else if (dispatchConfig.registrationName) {
405 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
406 return true;
407 }
408 return false;
409}
410
411/**
412 * Publishes a registration name that is used to identify dispatched events.
413 *
414 * @param {string} registrationName Registration name to add.
415 * @param {object} PluginModule Plugin publishing the event.
416 * @private
417 */
418function publishRegistrationName(registrationName, pluginModule, eventName) {
419 !!registrationNameModules[registrationName] ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
420 registrationNameModules[registrationName] = pluginModule;
421 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
422
423 {
424 var lowerCasedName = registrationName.toLowerCase();
425 possibleRegistrationNames[lowerCasedName] = registrationName;
426
427 if (registrationName === 'onDoubleClick') {
428 possibleRegistrationNames.ondblclick = registrationName;
429 }
430 }
431}
432
433/**
434 * Registers plugins so that they can extract and dispatch events.
435 *
436 * @see {EventPluginHub}
437 */
438
439/**
440 * Ordered list of injected plugins.
441 */
442var plugins = [];
443
444/**
445 * Mapping from event name to dispatch config
446 */
447var eventNameDispatchConfigs = {};
448
449/**
450 * Mapping from registration name to plugin module
451 */
452var registrationNameModules = {};
453
454/**
455 * Mapping from registration name to event name
456 */
457var registrationNameDependencies = {};
458
459/**
460 * Mapping from lowercase registration names to the properly cased version,
461 * used to warn in the case of missing event handlers. Available
462 * only in true.
463 * @type {Object}
464 */
465var possibleRegistrationNames = {};
466// Trust the developer to only use possibleRegistrationNames in true
467
468/**
469 * Injects an ordering of plugins (by plugin name). This allows the ordering
470 * to be decoupled from injection of the actual plugins so that ordering is
471 * always deterministic regardless of packaging, on-the-fly injection, etc.
472 *
473 * @param {array} InjectedEventPluginOrder
474 * @internal
475 * @see {EventPluginHub.injection.injectEventPluginOrder}
476 */
477function injectEventPluginOrder(injectedEventPluginOrder) {
478 !!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;
479 // Clone the ordering so it cannot be dynamically mutated.
480 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
481 recomputePluginOrdering();
482}
483
484/**
485 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
486 * in the ordering injected by `injectEventPluginOrder`.
487 *
488 * Plugins can be injected as part of page initialization or on-the-fly.
489 *
490 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
491 * @internal
492 * @see {EventPluginHub.injection.injectEventPluginsByName}
493 */
494function injectEventPluginsByName(injectedNamesToPlugins) {
495 {
496 if (shouldWarnOnInjection) {
497 var names = Object.keys(injectedNamesToPlugins).join(', ');
498 lowPriorityWarning$1(false, 'Injecting custom event plugins (%s) is deprecated ' + 'and will not work in React 17+. Please update your code ' + 'to not depend on React internals. The stack trace for this ' + 'warning should reveal the library that is using them. ' + 'See https://github.com/facebook/react/issues/11689 for a discussion.', names);
499 }
500 }
501
502 var isOrderingDirty = false;
503 for (var pluginName in injectedNamesToPlugins) {
504 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
505 continue;
506 }
507 var pluginModule = injectedNamesToPlugins[pluginName];
508 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
509 !!namesToPlugins[pluginName] ? invariant_1(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
510 namesToPlugins[pluginName] = pluginModule;
511 isOrderingDirty = true;
512 }
513 }
514 if (isOrderingDirty) {
515 recomputePluginOrdering();
516 }
517}
518
519var EventPluginRegistry = Object.freeze({
520 enableWarningOnInjection: enableWarningOnInjection,
521 plugins: plugins,
522 eventNameDispatchConfigs: eventNameDispatchConfigs,
523 registrationNameModules: registrationNameModules,
524 registrationNameDependencies: registrationNameDependencies,
525 possibleRegistrationNames: possibleRegistrationNames,
526 injectEventPluginOrder: injectEventPluginOrder,
527 injectEventPluginsByName: injectEventPluginsByName
528});
529
530/**
531 * Copyright (c) 2013-present, Facebook, Inc.
532 *
533 * This source code is licensed under the MIT license found in the
534 * LICENSE file in the root directory of this source tree.
535 *
536 *
537 */
538
539function makeEmptyFunction(arg) {
540 return function () {
541 return arg;
542 };
543}
544
545/**
546 * This function accepts and discards inputs; it has no side effects. This is
547 * primarily useful idiomatically for overridable function endpoints which
548 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
549 */
550var emptyFunction = function emptyFunction() {};
551
552emptyFunction.thatReturns = makeEmptyFunction;
553emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
554emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
555emptyFunction.thatReturnsNull = makeEmptyFunction(null);
556emptyFunction.thatReturnsThis = function () {
557 return this;
558};
559emptyFunction.thatReturnsArgument = function (arg) {
560 return arg;
561};
562
563var emptyFunction_1 = emptyFunction;
564
565/**
566 * Copyright (c) 2014-present, Facebook, Inc.
567 *
568 * This source code is licensed under the MIT license found in the
569 * LICENSE file in the root directory of this source tree.
570 *
571 */
572
573
574
575
576
577/**
578 * Similar to invariant but only logs a warning if the condition is not met.
579 * This can be used to log issues in development environments in critical
580 * paths. Removing the logging code for production environments will keep the
581 * same logic and follow the same code paths.
582 */
583
584var warning = emptyFunction_1;
585
586{
587 var printWarning$1 = function printWarning(format) {
588 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
589 args[_key - 1] = arguments[_key];
590 }
591
592 var argIndex = 0;
593 var message = 'Warning: ' + format.replace(/%s/g, function () {
594 return args[argIndex++];
595 });
596 if (typeof console !== 'undefined') {
597 console.error(message);
598 }
599 try {
600 // --- Welcome to debugging React ---
601 // This error was thrown as a convenience so that you can use this stack
602 // to find the callsite that caused this warning to fire.
603 throw new Error(message);
604 } catch (x) {}
605 };
606
607 warning = function warning(condition, format) {
608 if (format === undefined) {
609 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
610 }
611
612 if (format.indexOf('Failed Composite propType: ') === 0) {
613 return; // Ignore CompositeComponent proptype check.
614 }
615
616 if (!condition) {
617 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
618 args[_key2 - 2] = arguments[_key2];
619 }
620
621 printWarning$1.apply(undefined, [format].concat(args));
622 }
623 };
624}
625
626var warning_1 = warning;
627
628var getFiberCurrentPropsFromNode = null;
629var getInstanceFromNode = null;
630var getNodeFromInstance = null;
631
632var injection$1 = {
633 injectComponentTree: function (Injected) {
634 getFiberCurrentPropsFromNode = Injected.getFiberCurrentPropsFromNode;
635 getInstanceFromNode = Injected.getInstanceFromNode;
636 getNodeFromInstance = Injected.getNodeFromInstance;
637
638 {
639 warning_1(getNodeFromInstance && getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
640 }
641 }
642};
643
644
645
646
647
648
649var validateEventDispatches = void 0;
650{
651 validateEventDispatches = function (event) {
652 var dispatchListeners = event._dispatchListeners;
653 var dispatchInstances = event._dispatchInstances;
654
655 var listenersIsArr = Array.isArray(dispatchListeners);
656 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
657
658 var instancesIsArr = Array.isArray(dispatchInstances);
659 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
660
661 warning_1(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.');
662 };
663}
664
665/**
666 * Dispatch the event to the listener.
667 * @param {SyntheticEvent} event SyntheticEvent to handle
668 * @param {boolean} simulated If the event is simulated (changes exn behavior)
669 * @param {function} listener Application-level callback
670 * @param {*} inst Internal component instance
671 */
672function executeDispatch(event, simulated, listener, inst) {
673 var type = event.type || 'unknown-event';
674 event.currentTarget = getNodeFromInstance(inst);
675 ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
676 event.currentTarget = null;
677}
678
679/**
680 * Standard/simple iteration through an event's collected dispatches.
681 */
682function executeDispatchesInOrder(event, simulated) {
683 var dispatchListeners = event._dispatchListeners;
684 var dispatchInstances = event._dispatchInstances;
685 {
686 validateEventDispatches(event);
687 }
688 if (Array.isArray(dispatchListeners)) {
689 for (var i = 0; i < dispatchListeners.length; i++) {
690 if (event.isPropagationStopped()) {
691 break;
692 }
693 // Listeners and Instances are two parallel arrays that are always in sync.
694 executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
695 }
696 } else if (dispatchListeners) {
697 executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
698 }
699 event._dispatchListeners = null;
700 event._dispatchInstances = null;
701}
702
703/**
704 * @see executeDispatchesInOrderStopAtTrueImpl
705 */
706
707
708/**
709 * Execution of a "direct" dispatch - there must be at most one dispatch
710 * accumulated on the event or it is considered an error. It doesn't really make
711 * sense for an event with multiple dispatches (bubbled) to keep track of the
712 * return values at each dispatch execution, but it does tend to make sense when
713 * dealing with "direct" dispatches.
714 *
715 * @return {*} The return value of executing the single dispatch.
716 */
717
718
719/**
720 * @param {SyntheticEvent} event
721 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
722 */
723
724/**
725 * Accumulates items that must not be null or undefined into the first one. This
726 * is used to conserve memory by avoiding array allocations, and thus sacrifices
727 * API cleanness. Since `current` can be null before being passed in and not
728 * null after this function, make sure to assign it back to `current`:
729 *
730 * `a = accumulateInto(a, b);`
731 *
732 * This API should be sparingly used. Try `accumulate` for something cleaner.
733 *
734 * @return {*|array<*>} An accumulation of items.
735 */
736
737function accumulateInto(current, next) {
738 !(next != null) ? invariant_1(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
739
740 if (current == null) {
741 return next;
742 }
743
744 // Both are not empty. Warning: Never call x.concat(y) when you are not
745 // certain that x is an Array (x could be a string with concat method).
746 if (Array.isArray(current)) {
747 if (Array.isArray(next)) {
748 current.push.apply(current, next);
749 return current;
750 }
751 current.push(next);
752 return current;
753 }
754
755 if (Array.isArray(next)) {
756 // A bit too dangerous to mutate `next`.
757 return [current].concat(next);
758 }
759
760 return [current, next];
761}
762
763/**
764 * @param {array} arr an "accumulation" of items which is either an Array or
765 * a single item. Useful when paired with the `accumulate` module. This is a
766 * simple utility that allows us to reason about a collection of items, but
767 * handling the case when there is exactly one item (and we do not need to
768 * allocate an array).
769 * @param {function} cb Callback invoked with each element or a collection.
770 * @param {?} [scope] Scope used as `this` in a callback.
771 */
772function forEachAccumulated(arr, cb, scope) {
773 if (Array.isArray(arr)) {
774 arr.forEach(cb, scope);
775 } else if (arr) {
776 cb.call(scope, arr);
777 }
778}
779
780/**
781 * Internal queue of events that have accumulated their dispatches and are
782 * waiting to have their dispatches executed.
783 */
784var eventQueue = null;
785
786/**
787 * Dispatches an event and releases it back into the pool, unless persistent.
788 *
789 * @param {?object} event Synthetic event to be dispatched.
790 * @param {boolean} simulated If the event is simulated (changes exn behavior)
791 * @private
792 */
793var executeDispatchesAndRelease = function (event, simulated) {
794 if (event) {
795 executeDispatchesInOrder(event, simulated);
796
797 if (!event.isPersistent()) {
798 event.constructor.release(event);
799 }
800 }
801};
802var executeDispatchesAndReleaseSimulated = function (e) {
803 return executeDispatchesAndRelease(e, true);
804};
805var executeDispatchesAndReleaseTopLevel = function (e) {
806 return executeDispatchesAndRelease(e, false);
807};
808
809function isInteractive(tag) {
810 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
811}
812
813function shouldPreventMouseEvent(name, type, props) {
814 switch (name) {
815 case 'onClick':
816 case 'onClickCapture':
817 case 'onDoubleClick':
818 case 'onDoubleClickCapture':
819 case 'onMouseDown':
820 case 'onMouseDownCapture':
821 case 'onMouseMove':
822 case 'onMouseMoveCapture':
823 case 'onMouseUp':
824 case 'onMouseUpCapture':
825 return !!(props.disabled && isInteractive(type));
826 default:
827 return false;
828 }
829}
830
831/**
832 * This is a unified interface for event plugins to be installed and configured.
833 *
834 * Event plugins can implement the following properties:
835 *
836 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
837 * Required. When a top-level event is fired, this method is expected to
838 * extract synthetic events that will in turn be queued and dispatched.
839 *
840 * `eventTypes` {object}
841 * Optional, plugins that fire events must publish a mapping of registration
842 * names that are used to register listeners. Values of this mapping must
843 * be objects that contain `registrationName` or `phasedRegistrationNames`.
844 *
845 * `executeDispatch` {function(object, function, string)}
846 * Optional, allows plugins to override how an event gets dispatched. By
847 * default, the listener is simply invoked.
848 *
849 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
850 *
851 * @public
852 */
853
854/**
855 * Methods for injecting dependencies.
856 */
857var injection = {
858 /**
859 * @param {array} InjectedEventPluginOrder
860 * @public
861 */
862 injectEventPluginOrder: injectEventPluginOrder,
863
864 /**
865 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
866 */
867 injectEventPluginsByName: injectEventPluginsByName
868};
869
870/**
871 * @param {object} inst The instance, which is the source of events.
872 * @param {string} registrationName Name of listener (e.g. `onClick`).
873 * @return {?function} The stored callback.
874 */
875function getListener(inst, registrationName) {
876 var listener = void 0;
877
878 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
879 // live here; needs to be moved to a better place soon
880 var stateNode = inst.stateNode;
881 if (!stateNode) {
882 // Work in progress (ex: onload events in incremental mode).
883 return null;
884 }
885 var props = getFiberCurrentPropsFromNode(stateNode);
886 if (!props) {
887 // Work in progress.
888 return null;
889 }
890 listener = props[registrationName];
891 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
892 return null;
893 }
894 !(!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;
895 return listener;
896}
897
898/**
899 * Allows registered plugins an opportunity to extract events from top-level
900 * native browser events.
901 *
902 * @return {*} An accumulation of synthetic events.
903 * @internal
904 */
905function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
906 var events = null;
907 for (var i = 0; i < plugins.length; i++) {
908 // Not every plugin in the ordering may be loaded at runtime.
909 var possiblePlugin = plugins[i];
910 if (possiblePlugin) {
911 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
912 if (extractedEvents) {
913 events = accumulateInto(events, extractedEvents);
914 }
915 }
916 }
917 return events;
918}
919
920function runEventsInBatch(events, simulated) {
921 if (events !== null) {
922 eventQueue = accumulateInto(eventQueue, events);
923 }
924
925 // Set `eventQueue` to null before processing it so that we can tell if more
926 // events get enqueued while processing.
927 var processingEventQueue = eventQueue;
928 eventQueue = null;
929
930 if (!processingEventQueue) {
931 return;
932 }
933
934 if (simulated) {
935 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
936 } else {
937 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
938 }
939 !!eventQueue ? invariant_1(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
940 // This would be a good time to rethrow if any of the event handlers threw.
941 ReactErrorUtils.rethrowCaughtError();
942}
943
944function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
945 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
946 runEventsInBatch(events, false);
947}
948
949var EventPluginHub = Object.freeze({
950 injection: injection,
951 getListener: getListener,
952 runEventsInBatch: runEventsInBatch,
953 runExtractedEventsInBatch: runExtractedEventsInBatch
954});
955
956var IndeterminateComponent = 0; // Before we know whether it is functional or class
957var FunctionalComponent = 1;
958var ClassComponent = 2;
959var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
960var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
961var HostComponent = 5;
962var HostText = 6;
963var CallComponent = 7;
964var CallHandlerPhase = 8;
965var ReturnComponent = 9;
966var Fragment = 10;
967
968var randomKey = Math.random().toString(36).slice(2);
969var internalInstanceKey = '__reactInternalInstance$' + randomKey;
970var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
971
972function precacheFiberNode$1(hostInst, node) {
973 node[internalInstanceKey] = hostInst;
974}
975
976/**
977 * Given a DOM node, return the closest ReactDOMComponent or
978 * ReactDOMTextComponent instance ancestor.
979 */
980function getClosestInstanceFromNode(node) {
981 if (node[internalInstanceKey]) {
982 return node[internalInstanceKey];
983 }
984
985 while (!node[internalInstanceKey]) {
986 if (node.parentNode) {
987 node = node.parentNode;
988 } else {
989 // Top of the tree. This node must not be part of a React tree (or is
990 // unmounted, potentially).
991 return null;
992 }
993 }
994
995 var inst = node[internalInstanceKey];
996 if (inst.tag === HostComponent || inst.tag === HostText) {
997 // In Fiber, this will always be the deepest root.
998 return inst;
999 }
1000
1001 return null;
1002}
1003
1004/**
1005 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
1006 * instance, or null if the node was not rendered by this React.
1007 */
1008function getInstanceFromNode$1(node) {
1009 var inst = node[internalInstanceKey];
1010 if (inst) {
1011 if (inst.tag === HostComponent || inst.tag === HostText) {
1012 return inst;
1013 } else {
1014 return null;
1015 }
1016 }
1017 return null;
1018}
1019
1020/**
1021 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
1022 * DOM node.
1023 */
1024function getNodeFromInstance$1(inst) {
1025 if (inst.tag === HostComponent || inst.tag === HostText) {
1026 // In Fiber this, is just the state node right now. We assume it will be
1027 // a host component or host text.
1028 return inst.stateNode;
1029 }
1030
1031 // Without this first invariant, passing a non-DOM-component triggers the next
1032 // invariant for a missing parent, which is super confusing.
1033 invariant_1(false, 'getNodeFromInstance: Invalid argument.');
1034}
1035
1036function getFiberCurrentPropsFromNode$1(node) {
1037 return node[internalEventHandlersKey] || null;
1038}
1039
1040function updateFiberProps$1(node, props) {
1041 node[internalEventHandlersKey] = props;
1042}
1043
1044var ReactDOMComponentTree = Object.freeze({
1045 precacheFiberNode: precacheFiberNode$1,
1046 getClosestInstanceFromNode: getClosestInstanceFromNode,
1047 getInstanceFromNode: getInstanceFromNode$1,
1048 getNodeFromInstance: getNodeFromInstance$1,
1049 getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode$1,
1050 updateFiberProps: updateFiberProps$1
1051});
1052
1053function getParent(inst) {
1054 do {
1055 inst = inst['return'];
1056 // TODO: If this is a HostRoot we might want to bail out.
1057 // That is depending on if we want nested subtrees (layers) to bubble
1058 // events to their parent. We could also go through parentNode on the
1059 // host node but that wouldn't work for React Native and doesn't let us
1060 // do the portal feature.
1061 } while (inst && inst.tag !== HostComponent);
1062 if (inst) {
1063 return inst;
1064 }
1065 return null;
1066}
1067
1068/**
1069 * Return the lowest common ancestor of A and B, or null if they are in
1070 * different trees.
1071 */
1072function getLowestCommonAncestor(instA, instB) {
1073 var depthA = 0;
1074 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1075 depthA++;
1076 }
1077 var depthB = 0;
1078 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1079 depthB++;
1080 }
1081
1082 // If A is deeper, crawl up.
1083 while (depthA - depthB > 0) {
1084 instA = getParent(instA);
1085 depthA--;
1086 }
1087
1088 // If B is deeper, crawl up.
1089 while (depthB - depthA > 0) {
1090 instB = getParent(instB);
1091 depthB--;
1092 }
1093
1094 // Walk in lockstep until we find a match.
1095 var depth = depthA;
1096 while (depth--) {
1097 if (instA === instB || instA === instB.alternate) {
1098 return instA;
1099 }
1100 instA = getParent(instA);
1101 instB = getParent(instB);
1102 }
1103 return null;
1104}
1105
1106/**
1107 * Return if A is an ancestor of B.
1108 */
1109
1110
1111/**
1112 * Return the parent instance of the passed-in instance.
1113 */
1114function getParentInstance(inst) {
1115 return getParent(inst);
1116}
1117
1118/**
1119 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1120 */
1121function traverseTwoPhase(inst, fn, arg) {
1122 var path = [];
1123 while (inst) {
1124 path.push(inst);
1125 inst = getParent(inst);
1126 }
1127 var i = void 0;
1128 for (i = path.length; i-- > 0;) {
1129 fn(path[i], 'captured', arg);
1130 }
1131 for (i = 0; i < path.length; i++) {
1132 fn(path[i], 'bubbled', arg);
1133 }
1134}
1135
1136/**
1137 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1138 * should would receive a `mouseEnter` or `mouseLeave` event.
1139 *
1140 * Does not invoke the callback on the nearest common ancestor because nothing
1141 * "entered" or "left" that element.
1142 */
1143function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1144 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1145 var pathFrom = [];
1146 while (true) {
1147 if (!from) {
1148 break;
1149 }
1150 if (from === common) {
1151 break;
1152 }
1153 var alternate = from.alternate;
1154 if (alternate !== null && alternate === common) {
1155 break;
1156 }
1157 pathFrom.push(from);
1158 from = getParent(from);
1159 }
1160 var pathTo = [];
1161 while (true) {
1162 if (!to) {
1163 break;
1164 }
1165 if (to === common) {
1166 break;
1167 }
1168 var _alternate = to.alternate;
1169 if (_alternate !== null && _alternate === common) {
1170 break;
1171 }
1172 pathTo.push(to);
1173 to = getParent(to);
1174 }
1175 for (var i = 0; i < pathFrom.length; i++) {
1176 fn(pathFrom[i], 'bubbled', argFrom);
1177 }
1178 for (var _i = pathTo.length; _i-- > 0;) {
1179 fn(pathTo[_i], 'captured', argTo);
1180 }
1181}
1182
1183/**
1184 * Some event types have a notion of different registration names for different
1185 * "phases" of propagation. This finds listeners by a given phase.
1186 */
1187function listenerAtPhase(inst, event, propagationPhase) {
1188 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1189 return getListener(inst, registrationName);
1190}
1191
1192/**
1193 * A small set of propagation patterns, each of which will accept a small amount
1194 * of information, and generate a set of "dispatch ready event objects" - which
1195 * are sets of events that have already been annotated with a set of dispatched
1196 * listener functions/ids. The API is designed this way to discourage these
1197 * propagation strategies from actually executing the dispatches, since we
1198 * always want to collect the entire set of dispatches before executing even a
1199 * single one.
1200 */
1201
1202/**
1203 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1204 * here, allows us to not have to bind or create functions for each event.
1205 * Mutating the event's members allows us to not have to create a wrapping
1206 * "dispatch" object that pairs the event with the listener.
1207 */
1208function accumulateDirectionalDispatches(inst, phase, event) {
1209 {
1210 warning_1(inst, 'Dispatching inst must not be null');
1211 }
1212 var listener = listenerAtPhase(inst, event, phase);
1213 if (listener) {
1214 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1215 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1216 }
1217}
1218
1219/**
1220 * Collect dispatches (must be entirely collected before dispatching - see unit
1221 * tests). Lazily allocate the array to conserve memory. We must loop through
1222 * each event and perform the traversal for each one. We cannot perform a
1223 * single traversal for the entire collection of events because each event may
1224 * have a different target.
1225 */
1226function accumulateTwoPhaseDispatchesSingle(event) {
1227 if (event && event.dispatchConfig.phasedRegistrationNames) {
1228 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1229 }
1230}
1231
1232/**
1233 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
1234 */
1235function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
1236 if (event && event.dispatchConfig.phasedRegistrationNames) {
1237 var targetInst = event._targetInst;
1238 var parentInst = targetInst ? getParentInstance(targetInst) : null;
1239 traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
1240 }
1241}
1242
1243/**
1244 * Accumulates without regard to direction, does not look for phased
1245 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1246 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1247 */
1248function accumulateDispatches(inst, ignoredDirection, event) {
1249 if (inst && event && event.dispatchConfig.registrationName) {
1250 var registrationName = event.dispatchConfig.registrationName;
1251 var listener = getListener(inst, registrationName);
1252 if (listener) {
1253 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1254 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1255 }
1256 }
1257}
1258
1259/**
1260 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1261 * `dispatchMarker`.
1262 * @param {SyntheticEvent} event
1263 */
1264function accumulateDirectDispatchesSingle(event) {
1265 if (event && event.dispatchConfig.registrationName) {
1266 accumulateDispatches(event._targetInst, null, event);
1267 }
1268}
1269
1270function accumulateTwoPhaseDispatches(events) {
1271 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1272}
1273
1274function accumulateTwoPhaseDispatchesSkipTarget(events) {
1275 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
1276}
1277
1278function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1279 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1280}
1281
1282function accumulateDirectDispatches(events) {
1283 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1284}
1285
1286var EventPropagators = Object.freeze({
1287 accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
1288 accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
1289 accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
1290 accumulateDirectDispatches: accumulateDirectDispatches
1291});
1292
1293/**
1294 * Copyright (c) 2013-present, Facebook, Inc.
1295 *
1296 * This source code is licensed under the MIT license found in the
1297 * LICENSE file in the root directory of this source tree.
1298 *
1299 */
1300
1301
1302
1303var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1304
1305/**
1306 * Simple, lightweight module assisting with the detection and context of
1307 * Worker. Helps avoid circular dependencies and allows code to reason about
1308 * whether or not they are in a Worker, even if they never include the main
1309 * `ReactWorker` dependency.
1310 */
1311var ExecutionEnvironment = {
1312
1313 canUseDOM: canUseDOM,
1314
1315 canUseWorkers: typeof Worker !== 'undefined',
1316
1317 canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
1318
1319 canUseViewport: canUseDOM && !!window.screen,
1320
1321 isInWorker: !canUseDOM // For now, this is true - might change in the future.
1322
1323};
1324
1325var ExecutionEnvironment_1 = ExecutionEnvironment;
1326
1327var contentKey = null;
1328
1329/**
1330 * Gets the key used to access text content on a DOM node.
1331 *
1332 * @return {?string} Key used to access text content.
1333 * @internal
1334 */
1335function getTextContentAccessor() {
1336 if (!contentKey && ExecutionEnvironment_1.canUseDOM) {
1337 // Prefer textContent to innerText because many browsers support both but
1338 // SVG <text> elements don't support innerText even when <div> does.
1339 contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
1340 }
1341 return contentKey;
1342}
1343
1344/**
1345 * This helper object stores information about text content of a target node,
1346 * allowing comparison of content before and after a given event.
1347 *
1348 * Identify the node where selection currently begins, then observe
1349 * both its text content and its current position in the DOM. Since the
1350 * browser may natively replace the target node during composition, we can
1351 * use its position to find its replacement.
1352 *
1353 *
1354 */
1355var compositionState = {
1356 _root: null,
1357 _startText: null,
1358 _fallbackText: null
1359};
1360
1361function initialize(nativeEventTarget) {
1362 compositionState._root = nativeEventTarget;
1363 compositionState._startText = getText();
1364 return true;
1365}
1366
1367function reset() {
1368 compositionState._root = null;
1369 compositionState._startText = null;
1370 compositionState._fallbackText = null;
1371}
1372
1373function getData() {
1374 if (compositionState._fallbackText) {
1375 return compositionState._fallbackText;
1376 }
1377
1378 var start = void 0;
1379 var startValue = compositionState._startText;
1380 var startLength = startValue.length;
1381 var end = void 0;
1382 var endValue = getText();
1383 var endLength = endValue.length;
1384
1385 for (start = 0; start < startLength; start++) {
1386 if (startValue[start] !== endValue[start]) {
1387 break;
1388 }
1389 }
1390
1391 var minEnd = startLength - start;
1392 for (end = 1; end <= minEnd; end++) {
1393 if (startValue[startLength - end] !== endValue[endLength - end]) {
1394 break;
1395 }
1396 }
1397
1398 var sliceTail = end > 1 ? 1 - end : undefined;
1399 compositionState._fallbackText = endValue.slice(start, sliceTail);
1400 return compositionState._fallbackText;
1401}
1402
1403function getText() {
1404 if ('value' in compositionState._root) {
1405 return compositionState._root.value;
1406 }
1407 return compositionState._root[getTextContentAccessor()];
1408}
1409
1410var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1411
1412var _assign = ReactInternals.assign;
1413
1414/* eslint valid-typeof: 0 */
1415
1416var didWarnForAddedNewProperty = false;
1417var EVENT_POOL_SIZE = 10;
1418
1419var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
1420
1421/**
1422 * @interface Event
1423 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1424 */
1425var EventInterface = {
1426 type: null,
1427 target: null,
1428 // currentTarget is set when dispatching; no use in copying it here
1429 currentTarget: emptyFunction_1.thatReturnsNull,
1430 eventPhase: null,
1431 bubbles: null,
1432 cancelable: null,
1433 timeStamp: function (event) {
1434 return event.timeStamp || Date.now();
1435 },
1436 defaultPrevented: null,
1437 isTrusted: null
1438};
1439
1440/**
1441 * Synthetic events are dispatched by event plugins, typically in response to a
1442 * top-level event delegation handler.
1443 *
1444 * These systems should generally use pooling to reduce the frequency of garbage
1445 * collection. The system should check `isPersistent` to determine whether the
1446 * event should be released into the pool after being dispatched. Users that
1447 * need a persisted event should invoke `persist`.
1448 *
1449 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1450 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1451 * DOM interface; custom application-specific events can also subclass this.
1452 *
1453 * @param {object} dispatchConfig Configuration used to dispatch this event.
1454 * @param {*} targetInst Marker identifying the event target.
1455 * @param {object} nativeEvent Native browser event.
1456 * @param {DOMEventTarget} nativeEventTarget Target node.
1457 */
1458function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1459 {
1460 // these have a getter/setter for warnings
1461 delete this.nativeEvent;
1462 delete this.preventDefault;
1463 delete this.stopPropagation;
1464 }
1465
1466 this.dispatchConfig = dispatchConfig;
1467 this._targetInst = targetInst;
1468 this.nativeEvent = nativeEvent;
1469
1470 var Interface = this.constructor.Interface;
1471 for (var propName in Interface) {
1472 if (!Interface.hasOwnProperty(propName)) {
1473 continue;
1474 }
1475 {
1476 delete this[propName]; // this has a getter/setter for warnings
1477 }
1478 var normalize = Interface[propName];
1479 if (normalize) {
1480 this[propName] = normalize(nativeEvent);
1481 } else {
1482 if (propName === 'target') {
1483 this.target = nativeEventTarget;
1484 } else {
1485 this[propName] = nativeEvent[propName];
1486 }
1487 }
1488 }
1489
1490 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1491 if (defaultPrevented) {
1492 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1493 } else {
1494 this.isDefaultPrevented = emptyFunction_1.thatReturnsFalse;
1495 }
1496 this.isPropagationStopped = emptyFunction_1.thatReturnsFalse;
1497 return this;
1498}
1499
1500_assign(SyntheticEvent.prototype, {
1501 preventDefault: function () {
1502 this.defaultPrevented = true;
1503 var event = this.nativeEvent;
1504 if (!event) {
1505 return;
1506 }
1507
1508 if (event.preventDefault) {
1509 event.preventDefault();
1510 } else if (typeof event.returnValue !== 'unknown') {
1511 event.returnValue = false;
1512 }
1513 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1514 },
1515
1516 stopPropagation: function () {
1517 var event = this.nativeEvent;
1518 if (!event) {
1519 return;
1520 }
1521
1522 if (event.stopPropagation) {
1523 event.stopPropagation();
1524 } else if (typeof event.cancelBubble !== 'unknown') {
1525 // The ChangeEventPlugin registers a "propertychange" event for
1526 // IE. This event does not support bubbling or cancelling, and
1527 // any references to cancelBubble throw "Member not found". A
1528 // typeof check of "unknown" circumvents this issue (and is also
1529 // IE specific).
1530 event.cancelBubble = true;
1531 }
1532
1533 this.isPropagationStopped = emptyFunction_1.thatReturnsTrue;
1534 },
1535
1536 /**
1537 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1538 * them back into the pool. This allows a way to hold onto a reference that
1539 * won't be added back into the pool.
1540 */
1541 persist: function () {
1542 this.isPersistent = emptyFunction_1.thatReturnsTrue;
1543 },
1544
1545 /**
1546 * Checks if this event should be released back into the pool.
1547 *
1548 * @return {boolean} True if this should not be released, false otherwise.
1549 */
1550 isPersistent: emptyFunction_1.thatReturnsFalse,
1551
1552 /**
1553 * `PooledClass` looks for `destructor` on each instance it releases.
1554 */
1555 destructor: function () {
1556 var Interface = this.constructor.Interface;
1557 for (var propName in Interface) {
1558 {
1559 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1560 }
1561 }
1562 for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
1563 this[shouldBeReleasedProperties[i]] = null;
1564 }
1565 {
1566 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1567 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction_1));
1568 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction_1));
1569 }
1570 }
1571});
1572
1573SyntheticEvent.Interface = EventInterface;
1574
1575/**
1576 * Helper to reduce boilerplate when creating subclasses.
1577 */
1578SyntheticEvent.extend = function (Interface) {
1579 var Super = this;
1580
1581 var E = function () {};
1582 E.prototype = Super.prototype;
1583 var prototype = new E();
1584
1585 function Class() {
1586 return Super.apply(this, arguments);
1587 }
1588 _assign(prototype, Class.prototype);
1589 Class.prototype = prototype;
1590 Class.prototype.constructor = Class;
1591
1592 Class.Interface = _assign({}, Super.Interface, Interface);
1593 Class.extend = Super.extend;
1594 addEventPoolingTo(Class);
1595
1596 return Class;
1597};
1598
1599/** Proxying after everything set on SyntheticEvent
1600 * to resolve Proxy issue on some WebKit browsers
1601 * in which some Event properties are set to undefined (GH#10010)
1602 */
1603{
1604 var isProxySupported = typeof Proxy === 'function' &&
1605 // https://github.com/facebook/react/issues/12011
1606 !Object.isSealed(new Proxy({}, {}));
1607
1608 if (isProxySupported) {
1609 /*eslint-disable no-func-assign */
1610 SyntheticEvent = new Proxy(SyntheticEvent, {
1611 construct: function (target, args) {
1612 return this.apply(target, Object.create(target.prototype), args);
1613 },
1614 apply: function (constructor, that, args) {
1615 return new Proxy(constructor.apply(that, args), {
1616 set: function (target, prop, value) {
1617 if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
1618 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.');
1619 didWarnForAddedNewProperty = true;
1620 }
1621 target[prop] = value;
1622 return true;
1623 }
1624 });
1625 }
1626 });
1627 /*eslint-enable no-func-assign */
1628 }
1629}
1630
1631addEventPoolingTo(SyntheticEvent);
1632
1633/**
1634 * Helper to nullify syntheticEvent instance properties when destructing
1635 *
1636 * @param {String} propName
1637 * @param {?object} getVal
1638 * @return {object} defineProperty object
1639 */
1640function getPooledWarningPropertyDefinition(propName, getVal) {
1641 var isFunction = typeof getVal === 'function';
1642 return {
1643 configurable: true,
1644 set: set,
1645 get: get
1646 };
1647
1648 function set(val) {
1649 var action = isFunction ? 'setting the method' : 'setting the property';
1650 warn(action, 'This is effectively a no-op');
1651 return val;
1652 }
1653
1654 function get() {
1655 var action = isFunction ? 'accessing the method' : 'accessing the property';
1656 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1657 warn(action, result);
1658 return getVal;
1659 }
1660
1661 function warn(action, result) {
1662 var warningCondition = false;
1663 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);
1664 }
1665}
1666
1667function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1668 var EventConstructor = this;
1669 if (EventConstructor.eventPool.length) {
1670 var instance = EventConstructor.eventPool.pop();
1671 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1672 return instance;
1673 }
1674 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1675}
1676
1677function releasePooledEvent(event) {
1678 var EventConstructor = this;
1679 !(event instanceof EventConstructor) ? invariant_1(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1680 event.destructor();
1681 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1682 EventConstructor.eventPool.push(event);
1683 }
1684}
1685
1686function addEventPoolingTo(EventConstructor) {
1687 EventConstructor.eventPool = [];
1688 EventConstructor.getPooled = getPooledEvent;
1689 EventConstructor.release = releasePooledEvent;
1690}
1691
1692var SyntheticEvent$1 = SyntheticEvent;
1693
1694/**
1695 * @interface Event
1696 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1697 */
1698var SyntheticCompositionEvent = SyntheticEvent$1.extend({
1699 data: null
1700});
1701
1702/**
1703 * @interface Event
1704 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1705 * /#events-inputevents
1706 */
1707var SyntheticInputEvent = SyntheticEvent$1.extend({
1708 data: null
1709});
1710
1711var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1712var START_KEYCODE = 229;
1713
1714var canUseCompositionEvent = ExecutionEnvironment_1.canUseDOM && 'CompositionEvent' in window;
1715
1716var documentMode = null;
1717if (ExecutionEnvironment_1.canUseDOM && 'documentMode' in document) {
1718 documentMode = document.documentMode;
1719}
1720
1721// Webkit offers a very useful `textInput` event that can be used to
1722// directly represent `beforeInput`. The IE `textinput` event is not as
1723// useful, so we don't use it.
1724var canUseTextInputEvent = ExecutionEnvironment_1.canUseDOM && 'TextEvent' in window && !documentMode;
1725
1726// In IE9+, we have access to composition events, but the data supplied
1727// by the native compositionend event may be incorrect. Japanese ideographic
1728// spaces, for instance (\u3000) are not recorded correctly.
1729var useFallbackCompositionData = ExecutionEnvironment_1.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1730
1731var SPACEBAR_CODE = 32;
1732var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1733
1734// Events and their corresponding property names.
1735var eventTypes = {
1736 beforeInput: {
1737 phasedRegistrationNames: {
1738 bubbled: 'onBeforeInput',
1739 captured: 'onBeforeInputCapture'
1740 },
1741 dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste']
1742 },
1743 compositionEnd: {
1744 phasedRegistrationNames: {
1745 bubbled: 'onCompositionEnd',
1746 captured: 'onCompositionEndCapture'
1747 },
1748 dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1749 },
1750 compositionStart: {
1751 phasedRegistrationNames: {
1752 bubbled: 'onCompositionStart',
1753 captured: 'onCompositionStartCapture'
1754 },
1755 dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1756 },
1757 compositionUpdate: {
1758 phasedRegistrationNames: {
1759 bubbled: 'onCompositionUpdate',
1760 captured: 'onCompositionUpdateCapture'
1761 },
1762 dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1763 }
1764};
1765
1766// Track whether we've ever handled a keypress on the space key.
1767var hasSpaceKeypress = false;
1768
1769/**
1770 * Return whether a native keypress event is assumed to be a command.
1771 * This is required because Firefox fires `keypress` events for key commands
1772 * (cut, copy, select-all, etc.) even though no character is inserted.
1773 */
1774function isKeypressCommand(nativeEvent) {
1775 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1776 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1777 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1778}
1779
1780/**
1781 * Translate native top level events into event types.
1782 *
1783 * @param {string} topLevelType
1784 * @return {object}
1785 */
1786function getCompositionEventType(topLevelType) {
1787 switch (topLevelType) {
1788 case 'topCompositionStart':
1789 return eventTypes.compositionStart;
1790 case 'topCompositionEnd':
1791 return eventTypes.compositionEnd;
1792 case 'topCompositionUpdate':
1793 return eventTypes.compositionUpdate;
1794 }
1795}
1796
1797/**
1798 * Does our fallback best-guess model think this event signifies that
1799 * composition has begun?
1800 *
1801 * @param {string} topLevelType
1802 * @param {object} nativeEvent
1803 * @return {boolean}
1804 */
1805function isFallbackCompositionStart(topLevelType, nativeEvent) {
1806 return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
1807}
1808
1809/**
1810 * Does our fallback mode think that this event is the end of composition?
1811 *
1812 * @param {string} topLevelType
1813 * @param {object} nativeEvent
1814 * @return {boolean}
1815 */
1816function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1817 switch (topLevelType) {
1818 case 'topKeyUp':
1819 // Command keys insert or clear IME input.
1820 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1821 case 'topKeyDown':
1822 // Expect IME keyCode on each keydown. If we get any other
1823 // code we must have exited earlier.
1824 return nativeEvent.keyCode !== START_KEYCODE;
1825 case 'topKeyPress':
1826 case 'topMouseDown':
1827 case 'topBlur':
1828 // Events are not possible without cancelling IME.
1829 return true;
1830 default:
1831 return false;
1832 }
1833}
1834
1835/**
1836 * Google Input Tools provides composition data via a CustomEvent,
1837 * with the `data` property populated in the `detail` object. If this
1838 * is available on the event object, use it. If not, this is a plain
1839 * composition event and we have nothing special to extract.
1840 *
1841 * @param {object} nativeEvent
1842 * @return {?string}
1843 */
1844function getDataFromCustomEvent(nativeEvent) {
1845 var detail = nativeEvent.detail;
1846 if (typeof detail === 'object' && 'data' in detail) {
1847 return detail.data;
1848 }
1849 return null;
1850}
1851
1852// Track the current IME composition status, if any.
1853var isComposing = false;
1854
1855/**
1856 * @return {?object} A SyntheticCompositionEvent.
1857 */
1858function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1859 var eventType = void 0;
1860 var fallbackData = void 0;
1861
1862 if (canUseCompositionEvent) {
1863 eventType = getCompositionEventType(topLevelType);
1864 } else if (!isComposing) {
1865 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1866 eventType = eventTypes.compositionStart;
1867 }
1868 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1869 eventType = eventTypes.compositionEnd;
1870 }
1871
1872 if (!eventType) {
1873 return null;
1874 }
1875
1876 if (useFallbackCompositionData) {
1877 // The current composition is stored statically and must not be
1878 // overwritten while composition continues.
1879 if (!isComposing && eventType === eventTypes.compositionStart) {
1880 isComposing = initialize(nativeEventTarget);
1881 } else if (eventType === eventTypes.compositionEnd) {
1882 if (isComposing) {
1883 fallbackData = getData();
1884 }
1885 }
1886 }
1887
1888 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1889
1890 if (fallbackData) {
1891 // Inject data generated from fallback path into the synthetic event.
1892 // This matches the property of native CompositionEventInterface.
1893 event.data = fallbackData;
1894 } else {
1895 var customData = getDataFromCustomEvent(nativeEvent);
1896 if (customData !== null) {
1897 event.data = customData;
1898 }
1899 }
1900
1901 accumulateTwoPhaseDispatches(event);
1902 return event;
1903}
1904
1905/**
1906 * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
1907 * @param {object} nativeEvent Native browser event.
1908 * @return {?string} The string corresponding to this `beforeInput` event.
1909 */
1910function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1911 switch (topLevelType) {
1912 case 'topCompositionEnd':
1913 return getDataFromCustomEvent(nativeEvent);
1914 case 'topKeyPress':
1915 /**
1916 * If native `textInput` events are available, our goal is to make
1917 * use of them. However, there is a special case: the spacebar key.
1918 * In Webkit, preventing default on a spacebar `textInput` event
1919 * cancels character insertion, but it *also* causes the browser
1920 * to fall back to its default spacebar behavior of scrolling the
1921 * page.
1922 *
1923 * Tracking at:
1924 * https://code.google.com/p/chromium/issues/detail?id=355103
1925 *
1926 * To avoid this issue, use the keypress event as if no `textInput`
1927 * event is available.
1928 */
1929 var which = nativeEvent.which;
1930 if (which !== SPACEBAR_CODE) {
1931 return null;
1932 }
1933
1934 hasSpaceKeypress = true;
1935 return SPACEBAR_CHAR;
1936
1937 case 'topTextInput':
1938 // Record the characters to be added to the DOM.
1939 var chars = nativeEvent.data;
1940
1941 // If it's a spacebar character, assume that we have already handled
1942 // it at the keypress level and bail immediately. Android Chrome
1943 // doesn't give us keycodes, so we need to blacklist it.
1944 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1945 return null;
1946 }
1947
1948 return chars;
1949
1950 default:
1951 // For other native event types, do nothing.
1952 return null;
1953 }
1954}
1955
1956/**
1957 * For browsers that do not provide the `textInput` event, extract the
1958 * appropriate string to use for SyntheticInputEvent.
1959 *
1960 * @param {string} topLevelType Record from `BrowserEventConstants`.
1961 * @param {object} nativeEvent Native browser event.
1962 * @return {?string} The fallback string for this `beforeInput` event.
1963 */
1964function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1965 // If we are currently composing (IME) and using a fallback to do so,
1966 // try to extract the composed characters from the fallback object.
1967 // If composition event is available, we extract a string only at
1968 // compositionevent, otherwise extract it at fallback events.
1969 if (isComposing) {
1970 if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1971 var chars = getData();
1972 reset();
1973 isComposing = false;
1974 return chars;
1975 }
1976 return null;
1977 }
1978
1979 switch (topLevelType) {
1980 case 'topPaste':
1981 // If a paste event occurs after a keypress, throw out the input
1982 // chars. Paste events should not lead to BeforeInput events.
1983 return null;
1984 case 'topKeyPress':
1985 /**
1986 * As of v27, Firefox may fire keypress events even when no character
1987 * will be inserted. A few possibilities:
1988 *
1989 * - `which` is `0`. Arrow keys, Esc key, etc.
1990 *
1991 * - `which` is the pressed key code, but no char is available.
1992 * Ex: 'AltGr + d` in Polish. There is no modified character for
1993 * this key combination and no character is inserted into the
1994 * document, but FF fires the keypress for char code `100` anyway.
1995 * No `input` event will occur.
1996 *
1997 * - `which` is the pressed key code, but a command combination is
1998 * being used. Ex: `Cmd+C`. No character is inserted, and no
1999 * `input` event will occur.
2000 */
2001 if (!isKeypressCommand(nativeEvent)) {
2002 // IE fires the `keypress` event when a user types an emoji via
2003 // Touch keyboard of Windows. In such a case, the `char` property
2004 // holds an emoji character like `\uD83D\uDE0A`. Because its length
2005 // is 2, the property `which` does not represent an emoji correctly.
2006 // In such a case, we directly return the `char` property instead of
2007 // using `which`.
2008 if (nativeEvent.char && nativeEvent.char.length > 1) {
2009 return nativeEvent.char;
2010 } else if (nativeEvent.which) {
2011 return String.fromCharCode(nativeEvent.which);
2012 }
2013 }
2014 return null;
2015 case 'topCompositionEnd':
2016 return useFallbackCompositionData ? null : nativeEvent.data;
2017 default:
2018 return null;
2019 }
2020}
2021
2022/**
2023 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2024 * `textInput` or fallback behavior.
2025 *
2026 * @return {?object} A SyntheticInputEvent.
2027 */
2028function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2029 var chars = void 0;
2030
2031 if (canUseTextInputEvent) {
2032 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2033 } else {
2034 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2035 }
2036
2037 // If no characters are being inserted, no BeforeInput event should
2038 // be fired.
2039 if (!chars) {
2040 return null;
2041 }
2042
2043 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2044
2045 event.data = chars;
2046 accumulateTwoPhaseDispatches(event);
2047 return event;
2048}
2049
2050/**
2051 * Create an `onBeforeInput` event to match
2052 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2053 *
2054 * This event plugin is based on the native `textInput` event
2055 * available in Chrome, Safari, Opera, and IE. This event fires after
2056 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2057 *
2058 * `beforeInput` is spec'd but not implemented in any browsers, and
2059 * the `input` event does not provide any useful information about what has
2060 * actually been added, contrary to the spec. Thus, `textInput` is the best
2061 * available event to identify the characters that have actually been inserted
2062 * into the target node.
2063 *
2064 * This plugin is also responsible for emitting `composition` events, thus
2065 * allowing us to share composition fallback code for both `beforeInput` and
2066 * `composition` event types.
2067 */
2068var BeforeInputEventPlugin = {
2069 eventTypes: eventTypes,
2070
2071 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2072 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2073
2074 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2075
2076 if (composition === null) {
2077 return beforeInput;
2078 }
2079
2080 if (beforeInput === null) {
2081 return composition;
2082 }
2083
2084 return [composition, beforeInput];
2085 }
2086};
2087
2088// Use to restore controlled state after a change event has fired.
2089
2090var fiberHostComponent = null;
2091
2092var ReactControlledComponentInjection = {
2093 injectFiberControlledHostComponent: function (hostComponentImpl) {
2094 // The fiber implementation doesn't use dynamic dispatch so we need to
2095 // inject the implementation.
2096 fiberHostComponent = hostComponentImpl;
2097 }
2098};
2099
2100var restoreTarget = null;
2101var restoreQueue = null;
2102
2103function restoreStateOfTarget(target) {
2104 // We perform this translation at the end of the event loop so that we
2105 // always receive the correct fiber here
2106 var internalInstance = getInstanceFromNode(target);
2107 if (!internalInstance) {
2108 // Unmounted
2109 return;
2110 }
2111 !(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;
2112 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2113 fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props);
2114}
2115
2116var injection$2 = ReactControlledComponentInjection;
2117
2118function enqueueStateRestore(target) {
2119 if (restoreTarget) {
2120 if (restoreQueue) {
2121 restoreQueue.push(target);
2122 } else {
2123 restoreQueue = [target];
2124 }
2125 } else {
2126 restoreTarget = target;
2127 }
2128}
2129
2130function restoreStateIfNeeded() {
2131 if (!restoreTarget) {
2132 return;
2133 }
2134 var target = restoreTarget;
2135 var queuedTargets = restoreQueue;
2136 restoreTarget = null;
2137 restoreQueue = null;
2138
2139 restoreStateOfTarget(target);
2140 if (queuedTargets) {
2141 for (var i = 0; i < queuedTargets.length; i++) {
2142 restoreStateOfTarget(queuedTargets[i]);
2143 }
2144 }
2145}
2146
2147var ReactControlledComponent = Object.freeze({
2148 injection: injection$2,
2149 enqueueStateRestore: enqueueStateRestore,
2150 restoreStateIfNeeded: restoreStateIfNeeded
2151});
2152
2153// Used as a way to call batchedUpdates when we don't have a reference to
2154// the renderer. Such as when we're dispatching events or if third party
2155// libraries need to call batchedUpdates. Eventually, this API will go away when
2156// everything is batched by default. We'll then have a similar API to opt-out of
2157// scheduled work and instead do synchronous work.
2158
2159// Defaults
2160var fiberBatchedUpdates = function (fn, bookkeeping) {
2161 return fn(bookkeeping);
2162};
2163
2164var isNestingBatched = false;
2165function batchedUpdates(fn, bookkeeping) {
2166 if (isNestingBatched) {
2167 // If we are currently inside another batch, we need to wait until it
2168 // fully completes before restoring state. Therefore, we add the target to
2169 // a queue of work.
2170 return fiberBatchedUpdates(fn, bookkeeping);
2171 }
2172 isNestingBatched = true;
2173 try {
2174 return fiberBatchedUpdates(fn, bookkeeping);
2175 } finally {
2176 // Here we wait until all updates have propagated, which is important
2177 // when using controlled components within layers:
2178 // https://github.com/facebook/react/issues/1698
2179 // Then we restore state of any controlled component.
2180 isNestingBatched = false;
2181 restoreStateIfNeeded();
2182 }
2183}
2184
2185var ReactGenericBatchingInjection = {
2186 injectFiberBatchedUpdates: function (_batchedUpdates) {
2187 fiberBatchedUpdates = _batchedUpdates;
2188 }
2189};
2190
2191var injection$3 = ReactGenericBatchingInjection;
2192
2193/**
2194 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2195 */
2196var supportedInputTypes = {
2197 color: true,
2198 date: true,
2199 datetime: true,
2200 'datetime-local': true,
2201 email: true,
2202 month: true,
2203 number: true,
2204 password: true,
2205 range: true,
2206 search: true,
2207 tel: true,
2208 text: true,
2209 time: true,
2210 url: true,
2211 week: true
2212};
2213
2214function isTextInputElement(elem) {
2215 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2216
2217 if (nodeName === 'input') {
2218 return !!supportedInputTypes[elem.type];
2219 }
2220
2221 if (nodeName === 'textarea') {
2222 return true;
2223 }
2224
2225 return false;
2226}
2227
2228/**
2229 * HTML nodeType values that represent the type of the node
2230 */
2231
2232var ELEMENT_NODE = 1;
2233var TEXT_NODE = 3;
2234var COMMENT_NODE = 8;
2235var DOCUMENT_NODE = 9;
2236var DOCUMENT_FRAGMENT_NODE = 11;
2237
2238/**
2239 * Gets the target node from a native browser event by accounting for
2240 * inconsistencies in browser DOM APIs.
2241 *
2242 * @param {object} nativeEvent Native browser event.
2243 * @return {DOMEventTarget} Target node.
2244 */
2245function getEventTarget(nativeEvent) {
2246 var target = nativeEvent.target || window;
2247
2248 // Normalize SVG <use> element events #4963
2249 if (target.correspondingUseElement) {
2250 target = target.correspondingUseElement;
2251 }
2252
2253 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2254 // @see http://www.quirksmode.org/js/events_properties.html
2255 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2256}
2257
2258/**
2259 * Checks if an event is supported in the current execution environment.
2260 *
2261 * NOTE: This will not work correctly for non-generic events such as `change`,
2262 * `reset`, `load`, `error`, and `select`.
2263 *
2264 * Borrows from Modernizr.
2265 *
2266 * @param {string} eventNameSuffix Event name, e.g. "click".
2267 * @param {?boolean} capture Check if the capture phase is supported.
2268 * @return {boolean} True if the event is supported.
2269 * @internal
2270 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2271 */
2272function isEventSupported(eventNameSuffix, capture) {
2273 if (!ExecutionEnvironment_1.canUseDOM || capture && !('addEventListener' in document)) {
2274 return false;
2275 }
2276
2277 var eventName = 'on' + eventNameSuffix;
2278 var isSupported = eventName in document;
2279
2280 if (!isSupported) {
2281 var element = document.createElement('div');
2282 element.setAttribute(eventName, 'return;');
2283 isSupported = typeof element[eventName] === 'function';
2284 }
2285
2286 return isSupported;
2287}
2288
2289function isCheckable(elem) {
2290 var type = elem.type;
2291 var nodeName = elem.nodeName;
2292 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2293}
2294
2295function getTracker(node) {
2296 return node._valueTracker;
2297}
2298
2299function detachTracker(node) {
2300 node._valueTracker = null;
2301}
2302
2303function getValueFromNode(node) {
2304 var value = '';
2305 if (!node) {
2306 return value;
2307 }
2308
2309 if (isCheckable(node)) {
2310 value = node.checked ? 'true' : 'false';
2311 } else {
2312 value = node.value;
2313 }
2314
2315 return value;
2316}
2317
2318function trackValueOnNode(node) {
2319 var valueField = isCheckable(node) ? 'checked' : 'value';
2320 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2321
2322 var currentValue = '' + node[valueField];
2323
2324 // if someone has already defined a value or Safari, then bail
2325 // and don't track value will cause over reporting of changes,
2326 // but it's better then a hard failure
2327 // (needed for certain tests that spyOn input values and Safari)
2328 if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2329 return;
2330 }
2331
2332 Object.defineProperty(node, valueField, {
2333 configurable: true,
2334 get: function () {
2335 return descriptor.get.call(this);
2336 },
2337 set: function (value) {
2338 currentValue = '' + value;
2339 descriptor.set.call(this, value);
2340 }
2341 });
2342 // We could've passed this the first time
2343 // but it triggers a bug in IE11 and Edge 14/15.
2344 // Calling defineProperty() again should be equivalent.
2345 // https://github.com/facebook/react/issues/11768
2346 Object.defineProperty(node, valueField, {
2347 enumerable: descriptor.enumerable
2348 });
2349
2350 var tracker = {
2351 getValue: function () {
2352 return currentValue;
2353 },
2354 setValue: function (value) {
2355 currentValue = '' + value;
2356 },
2357 stopTracking: function () {
2358 detachTracker(node);
2359 delete node[valueField];
2360 }
2361 };
2362 return tracker;
2363}
2364
2365function track(node) {
2366 if (getTracker(node)) {
2367 return;
2368 }
2369
2370 // TODO: Once it's just Fiber we can move this to node._wrapperState
2371 node._valueTracker = trackValueOnNode(node);
2372}
2373
2374function updateValueIfChanged(node) {
2375 if (!node) {
2376 return false;
2377 }
2378
2379 var tracker = getTracker(node);
2380 // if there is no tracker at this point it's unlikely
2381 // that trying again will succeed
2382 if (!tracker) {
2383 return true;
2384 }
2385
2386 var lastValue = tracker.getValue();
2387 var nextValue = getValueFromNode(node);
2388 if (nextValue !== lastValue) {
2389 tracker.setValue(nextValue);
2390 return true;
2391 }
2392 return false;
2393}
2394
2395var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2396
2397var ReactCurrentOwner = ReactInternals$1.ReactCurrentOwner;
2398var ReactDebugCurrentFrame = ReactInternals$1.ReactDebugCurrentFrame;
2399
2400var describeComponentFrame = function (name, source, ownerName) {
2401 return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
2402};
2403
2404// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2405// nor polyfill, then a plain number is used for performance.
2406var hasSymbol = typeof Symbol === 'function' && Symbol['for'];
2407
2408var REACT_ELEMENT_TYPE = hasSymbol ? Symbol['for']('react.element') : 0xeac7;
2409var REACT_CALL_TYPE = hasSymbol ? Symbol['for']('react.call') : 0xeac8;
2410var REACT_RETURN_TYPE = hasSymbol ? Symbol['for']('react.return') : 0xeac9;
2411var REACT_PORTAL_TYPE = hasSymbol ? Symbol['for']('react.portal') : 0xeaca;
2412var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb;
2413
2414var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2415var FAUX_ITERATOR_SYMBOL = '@@iterator';
2416
2417function getIteratorFn(maybeIterable) {
2418 if (maybeIterable === null || typeof maybeIterable === 'undefined') {
2419 return null;
2420 }
2421 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2422 if (typeof maybeIterator === 'function') {
2423 return maybeIterator;
2424 }
2425 return null;
2426}
2427
2428function getComponentName(fiber) {
2429 var type = fiber.type;
2430
2431 if (typeof type === 'function') {
2432 return type.displayName || type.name;
2433 }
2434 if (typeof type === 'string') {
2435 return type;
2436 }
2437 switch (type) {
2438 case REACT_FRAGMENT_TYPE:
2439 return 'ReactFragment';
2440 case REACT_PORTAL_TYPE:
2441 return 'ReactPortal';
2442 case REACT_CALL_TYPE:
2443 return 'ReactCall';
2444 case REACT_RETURN_TYPE:
2445 return 'ReactReturn';
2446 }
2447 return null;
2448}
2449
2450function describeFiber(fiber) {
2451 switch (fiber.tag) {
2452 case IndeterminateComponent:
2453 case FunctionalComponent:
2454 case ClassComponent:
2455 case HostComponent:
2456 var owner = fiber._debugOwner;
2457 var source = fiber._debugSource;
2458 var name = getComponentName(fiber);
2459 var ownerName = null;
2460 if (owner) {
2461 ownerName = getComponentName(owner);
2462 }
2463 return describeComponentFrame(name, source, ownerName);
2464 default:
2465 return '';
2466 }
2467}
2468
2469// This function can only be called with a work-in-progress fiber and
2470// only during begin or complete phase. Do not call it under any other
2471// circumstances.
2472function getStackAddendumByWorkInProgressFiber(workInProgress) {
2473 var info = '';
2474 var node = workInProgress;
2475 do {
2476 info += describeFiber(node);
2477 // Otherwise this return pointer might point to the wrong tree:
2478 node = node['return'];
2479 } while (node);
2480 return info;
2481}
2482
2483function getCurrentFiberOwnerName$1() {
2484 {
2485 var fiber = ReactDebugCurrentFiber.current;
2486 if (fiber === null) {
2487 return null;
2488 }
2489 var owner = fiber._debugOwner;
2490 if (owner !== null && typeof owner !== 'undefined') {
2491 return getComponentName(owner);
2492 }
2493 }
2494 return null;
2495}
2496
2497function getCurrentFiberStackAddendum$1() {
2498 {
2499 var fiber = ReactDebugCurrentFiber.current;
2500 if (fiber === null) {
2501 return null;
2502 }
2503 // Safe because if current fiber exists, we are reconciling,
2504 // and it is guaranteed to be the work-in-progress version.
2505 return getStackAddendumByWorkInProgressFiber(fiber);
2506 }
2507 return null;
2508}
2509
2510function resetCurrentFiber() {
2511 ReactDebugCurrentFrame.getCurrentStack = null;
2512 ReactDebugCurrentFiber.current = null;
2513 ReactDebugCurrentFiber.phase = null;
2514}
2515
2516function setCurrentFiber(fiber) {
2517 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1;
2518 ReactDebugCurrentFiber.current = fiber;
2519 ReactDebugCurrentFiber.phase = null;
2520}
2521
2522function setCurrentPhase(phase) {
2523 ReactDebugCurrentFiber.phase = phase;
2524}
2525
2526var ReactDebugCurrentFiber = {
2527 current: null,
2528 phase: null,
2529 resetCurrentFiber: resetCurrentFiber,
2530 setCurrentFiber: setCurrentFiber,
2531 setCurrentPhase: setCurrentPhase,
2532 getCurrentFiberOwnerName: getCurrentFiberOwnerName$1,
2533 getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1
2534};
2535
2536// A reserved attribute.
2537// It is handled by React separately and shouldn't be written to the DOM.
2538var RESERVED = 0;
2539
2540// A simple string attribute.
2541// Attributes that aren't in the whitelist are presumed to have this type.
2542var STRING = 1;
2543
2544// A string attribute that accepts booleans in React. In HTML, these are called
2545// "enumerated" attributes with "true" and "false" as possible values.
2546// When true, it should be set to a "true" string.
2547// When false, it should be set to a "false" string.
2548var BOOLEANISH_STRING = 2;
2549
2550// A real boolean attribute.
2551// When true, it should be present (set either to an empty string or its name).
2552// When false, it should be omitted.
2553var BOOLEAN = 3;
2554
2555// An attribute that can be used as a flag as well as with a value.
2556// When true, it should be present (set either to an empty string or its name).
2557// When false, it should be omitted.
2558// For any other value, should be present with that value.
2559var OVERLOADED_BOOLEAN = 4;
2560
2561// An attribute that must be numeric or parse as a numeric.
2562// When falsy, it should be removed.
2563var NUMERIC = 5;
2564
2565// An attribute that must be positive numeric or parse as a positive numeric.
2566// When falsy, it should be removed.
2567var POSITIVE_NUMERIC = 6;
2568
2569/* eslint-disable max-len */
2570var 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';
2571/* eslint-enable max-len */
2572var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2573
2574
2575var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2576var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2577
2578var illegalAttributeNameCache = {};
2579var validatedAttributeNameCache = {};
2580
2581function isAttributeNameSafe(attributeName) {
2582 if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
2583 return true;
2584 }
2585 if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
2586 return false;
2587 }
2588 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2589 validatedAttributeNameCache[attributeName] = true;
2590 return true;
2591 }
2592 illegalAttributeNameCache[attributeName] = true;
2593 {
2594 warning_1(false, 'Invalid attribute name: `%s`', attributeName);
2595 }
2596 return false;
2597}
2598
2599function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2600 if (propertyInfo !== null) {
2601 return propertyInfo.type === RESERVED;
2602 }
2603 if (isCustomComponentTag) {
2604 return false;
2605 }
2606 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2607 return true;
2608 }
2609 return false;
2610}
2611
2612function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2613 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2614 return false;
2615 }
2616 switch (typeof value) {
2617 case 'function':
2618 // $FlowIssue symbol is perfectly valid here
2619 case 'symbol':
2620 // eslint-disable-line
2621 return true;
2622 case 'boolean':
2623 {
2624 if (isCustomComponentTag) {
2625 return false;
2626 }
2627 if (propertyInfo !== null) {
2628 return !propertyInfo.acceptsBooleans;
2629 } else {
2630 var prefix = name.toLowerCase().slice(0, 5);
2631 return prefix !== 'data-' && prefix !== 'aria-';
2632 }
2633 }
2634 default:
2635 return false;
2636 }
2637}
2638
2639function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2640 if (value === null || typeof value === 'undefined') {
2641 return true;
2642 }
2643 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2644 return true;
2645 }
2646 if (propertyInfo !== null) {
2647 switch (propertyInfo.type) {
2648 case BOOLEAN:
2649 return !value;
2650 case OVERLOADED_BOOLEAN:
2651 return value === false;
2652 case NUMERIC:
2653 return isNaN(value);
2654 case POSITIVE_NUMERIC:
2655 return isNaN(value) || value < 1;
2656 }
2657 }
2658 return false;
2659}
2660
2661function getPropertyInfo(name) {
2662 return properties.hasOwnProperty(name) ? properties[name] : null;
2663}
2664
2665function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2666 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2667 this.attributeName = attributeName;
2668 this.attributeNamespace = attributeNamespace;
2669 this.mustUseProperty = mustUseProperty;
2670 this.propertyName = name;
2671 this.type = type;
2672}
2673
2674// When adding attributes to this list, be sure to also add them to
2675// the `possibleStandardNames` module to ensure casing and incorrect
2676// name warnings.
2677var properties = {};
2678
2679// These props are reserved by React. They shouldn't be written to the DOM.
2680['children', 'dangerouslySetInnerHTML',
2681// TODO: This prevents the assignment of defaultValue to regular
2682// elements (not just inputs). Now that ReactDOMInput assigns to the
2683// defaultValue property -- do we need this?
2684'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2685 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2686 name, // attributeName
2687 null);
2688});
2689
2690// A few React string attributes have a different name.
2691// This is a mapping from React prop names to the attribute names.
2692new Map([['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']]).forEach(function (attributeName, name) {
2693 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2694 attributeName, // attributeName
2695 null);
2696});
2697
2698// These are "enumerated" HTML attributes that accept "true" and "false".
2699// In React, we let users pass `true` and `false` even though technically
2700// these aren't boolean attributes (they are coerced to strings).
2701['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2702 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2703 name.toLowerCase(), // attributeName
2704 null);
2705});
2706
2707// These are "enumerated" SVG attributes that accept "true" and "false".
2708// In React, we let users pass `true` and `false` even though technically
2709// these aren't boolean attributes (they are coerced to strings).
2710// Since these are SVG attributes, their attribute names are case-sensitive.
2711['autoReverse', 'externalResourcesRequired', 'preserveAlpha'].forEach(function (name) {
2712 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2713 name, // attributeName
2714 null);
2715});
2716
2717// These are HTML boolean attributes.
2718['allowFullScreen', 'async',
2719// Note: there is a special case that prevents it from being written to the DOM
2720// on the client side because the browsers are inconsistent. Instead we call focus().
2721'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2722// Microdata
2723'itemScope'].forEach(function (name) {
2724 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2725 name.toLowerCase(), // attributeName
2726 null);
2727});
2728
2729// These are the few React props that we set as DOM properties
2730// rather than attributes. These are all booleans.
2731['checked',
2732// Note: `option.selected` is not updated if `select.multiple` is
2733// disabled with `removeAttribute`. We have special logic for handling this.
2734'multiple', 'muted', 'selected'].forEach(function (name) {
2735 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2736 name.toLowerCase(), // attributeName
2737 null);
2738});
2739
2740// These are HTML attributes that are "overloaded booleans": they behave like
2741// booleans, but can also accept a string value.
2742['capture', 'download'].forEach(function (name) {
2743 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2744 name.toLowerCase(), // attributeName
2745 null);
2746});
2747
2748// These are HTML attributes that must be positive numbers.
2749['cols', 'rows', 'size', 'span'].forEach(function (name) {
2750 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2751 name.toLowerCase(), // attributeName
2752 null);
2753});
2754
2755// These are HTML attributes that must be numbers.
2756['rowSpan', 'start'].forEach(function (name) {
2757 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2758 name.toLowerCase(), // attributeName
2759 null);
2760});
2761
2762var CAMELIZE = /[\-\:]([a-z])/g;
2763var capitalize = function (token) {
2764 return token[1].toUpperCase();
2765};
2766
2767// This is a list of all SVG attributes that need special casing, namespacing,
2768// or boolean value assignment. Regular attributes that just accept strings
2769// and have the same names are omitted, just like in the HTML whitelist.
2770// Some of these attributes can be hard to find. This list was created by
2771// scrapping the MDN documentation.
2772['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) {
2773 var name = attributeName.replace(CAMELIZE, capitalize);
2774 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2775 attributeName, null);
2776});
2777
2778// String SVG attributes with the xlink namespace.
2779['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2780 var name = attributeName.replace(CAMELIZE, capitalize);
2781 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2782 attributeName, 'http://www.w3.org/1999/xlink');
2783});
2784
2785// String SVG attributes with the xml namespace.
2786['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2787 var name = attributeName.replace(CAMELIZE, capitalize);
2788 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2789 attributeName, 'http://www.w3.org/XML/1998/namespace');
2790});
2791
2792// Special case: this attribute exists both in HTML and SVG.
2793// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2794// its React `tabIndex` name, like we do for attributes that exist only in HTML.
2795properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2796'tabindex', // attributeName
2797null);
2798
2799/**
2800 * Get the value for a property on a node. Only used in DEV for SSR validation.
2801 * The "expected" argument is used as a hint of what the expected value is.
2802 * Some properties have multiple equivalent values.
2803 */
2804function getValueForProperty(node, name, expected, propertyInfo) {
2805 {
2806 if (propertyInfo.mustUseProperty) {
2807 var propertyName = propertyInfo.propertyName;
2808
2809 return node[propertyName];
2810 } else {
2811 var attributeName = propertyInfo.attributeName;
2812
2813 var stringValue = null;
2814
2815 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2816 if (node.hasAttribute(attributeName)) {
2817 var value = node.getAttribute(attributeName);
2818 if (value === '') {
2819 return true;
2820 }
2821 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2822 return value;
2823 }
2824 if (value === '' + expected) {
2825 return expected;
2826 }
2827 return value;
2828 }
2829 } else if (node.hasAttribute(attributeName)) {
2830 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2831 // We had an attribute but shouldn't have had one, so read it
2832 // for the error message.
2833 return node.getAttribute(attributeName);
2834 }
2835 if (propertyInfo.type === BOOLEAN) {
2836 // If this was a boolean, it doesn't matter what the value is
2837 // the fact that we have it is the same as the expected.
2838 return expected;
2839 }
2840 // Even if this property uses a namespace we use getAttribute
2841 // because we assume its namespaced name is the same as our config.
2842 // To use getAttributeNS we need the local name which we don't have
2843 // in our config atm.
2844 stringValue = node.getAttribute(attributeName);
2845 }
2846
2847 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2848 return stringValue === null ? expected : stringValue;
2849 } else if (stringValue === '' + expected) {
2850 return expected;
2851 } else {
2852 return stringValue;
2853 }
2854 }
2855 }
2856}
2857
2858/**
2859 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2860 * The third argument is used as a hint of what the expected value is. Some
2861 * attributes have multiple equivalent values.
2862 */
2863function getValueForAttribute(node, name, expected) {
2864 {
2865 if (!isAttributeNameSafe(name)) {
2866 return;
2867 }
2868 if (!node.hasAttribute(name)) {
2869 return expected === undefined ? undefined : null;
2870 }
2871 var value = node.getAttribute(name);
2872 if (value === '' + expected) {
2873 return expected;
2874 }
2875 return value;
2876 }
2877}
2878
2879/**
2880 * Sets the value for a property on a node.
2881 *
2882 * @param {DOMElement} node
2883 * @param {string} name
2884 * @param {*} value
2885 */
2886function setValueForProperty(node, name, value, isCustomComponentTag) {
2887 var propertyInfo = getPropertyInfo(name);
2888 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2889 return;
2890 }
2891 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2892 value = null;
2893 }
2894 // If the prop isn't in the special list, treat it as a simple attribute.
2895 if (isCustomComponentTag || propertyInfo === null) {
2896 if (isAttributeNameSafe(name)) {
2897 var _attributeName = name;
2898 if (value === null) {
2899 node.removeAttribute(_attributeName);
2900 } else {
2901 node.setAttribute(_attributeName, '' + value);
2902 }
2903 }
2904 return;
2905 }
2906 var mustUseProperty = propertyInfo.mustUseProperty;
2907
2908 if (mustUseProperty) {
2909 var propertyName = propertyInfo.propertyName;
2910
2911 if (value === null) {
2912 var type = propertyInfo.type;
2913
2914 node[propertyName] = type === BOOLEAN ? false : '';
2915 } else {
2916 // Contrary to `setAttribute`, object properties are properly
2917 // `toString`ed by IE8/9.
2918 node[propertyName] = value;
2919 }
2920 return;
2921 }
2922 // The rest are treated as attributes with special cases.
2923 var attributeName = propertyInfo.attributeName,
2924 attributeNamespace = propertyInfo.attributeNamespace;
2925
2926 if (value === null) {
2927 node.removeAttribute(attributeName);
2928 } else {
2929 var _type = propertyInfo.type;
2930
2931 var attributeValue = void 0;
2932 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
2933 attributeValue = '';
2934 } else {
2935 // `setAttribute` with objects becomes only `[object]` in IE8/9,
2936 // ('' + value) makes it output the correct toString()-value.
2937 attributeValue = '' + value;
2938 }
2939 if (attributeNamespace) {
2940 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
2941 } else {
2942 node.setAttribute(attributeName, attributeValue);
2943 }
2944 }
2945}
2946
2947/**
2948 * Copyright (c) 2013-present, Facebook, Inc.
2949 *
2950 * This source code is licensed under the MIT license found in the
2951 * LICENSE file in the root directory of this source tree.
2952 */
2953
2954
2955
2956var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
2957
2958var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
2959
2960/**
2961 * Copyright (c) 2013-present, Facebook, Inc.
2962 *
2963 * This source code is licensed under the MIT license found in the
2964 * LICENSE file in the root directory of this source tree.
2965 */
2966
2967
2968
2969{
2970 var invariant$2 = invariant_1;
2971 var warning$2 = warning_1;
2972 var ReactPropTypesSecret = ReactPropTypesSecret_1;
2973 var loggedTypeFailures = {};
2974}
2975
2976/**
2977 * Assert that the values match with the type specs.
2978 * Error messages are memorized and will only be shown once.
2979 *
2980 * @param {object} typeSpecs Map of name to a ReactPropType
2981 * @param {object} values Runtime values that need to be type-checked
2982 * @param {string} location e.g. "prop", "context", "child context"
2983 * @param {string} componentName Name of the component for error messages.
2984 * @param {?Function} getStack Returns the component stack.
2985 * @private
2986 */
2987function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
2988 {
2989 for (var typeSpecName in typeSpecs) {
2990 if (typeSpecs.hasOwnProperty(typeSpecName)) {
2991 var error;
2992 // Prop type validation may throw. In case they do, we don't want to
2993 // fail the render phase where it didn't fail before. So we log it.
2994 // After these have been cleaned up, we'll let them throw.
2995 try {
2996 // This is intentionally an invariant that gets caught. It's the same
2997 // behavior as without this statement except with a better message.
2998 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]);
2999 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
3000 } catch (ex) {
3001 error = ex;
3002 }
3003 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);
3004 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
3005 // Only monitor this failure once because there tends to be a lot of the
3006 // same error.
3007 loggedTypeFailures[error.message] = true;
3008
3009 var stack = getStack ? getStack() : '';
3010
3011 warning$2(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
3012 }
3013 }
3014 }
3015 }
3016}
3017
3018var checkPropTypes_1 = checkPropTypes;
3019
3020var ReactControlledValuePropTypes = {
3021 checkPropTypes: null
3022};
3023
3024{
3025 var hasReadOnlyValue = {
3026 button: true,
3027 checkbox: true,
3028 image: true,
3029 hidden: true,
3030 radio: true,
3031 reset: true,
3032 submit: true
3033 };
3034
3035 var propTypes = {
3036 value: function (props, propName, componentName) {
3037 if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
3038 return null;
3039 }
3040 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`.');
3041 },
3042 checked: function (props, propName, componentName) {
3043 if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
3044 return null;
3045 }
3046 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`.');
3047 }
3048 };
3049
3050 /**
3051 * Provide a linked `value` attribute for controlled forms. You should not use
3052 * this outside of the ReactDOM controlled form components.
3053 */
3054 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) {
3055 checkPropTypes_1(propTypes, props, 'prop', tagName, getStack);
3056 };
3057}
3058
3059// TODO: direct imports like some-package/src/* are bad. Fix me.
3060var getCurrentFiberOwnerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
3061var getCurrentFiberStackAddendum = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
3062
3063var didWarnValueDefaultValue = false;
3064var didWarnCheckedDefaultChecked = false;
3065var didWarnControlledToUncontrolled = false;
3066var didWarnUncontrolledToControlled = false;
3067
3068function isControlled(props) {
3069 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3070 return usesChecked ? props.checked != null : props.value != null;
3071}
3072
3073/**
3074 * Implements an <input> host component that allows setting these optional
3075 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3076 *
3077 * If `checked` or `value` are not supplied (or null/undefined), user actions
3078 * that affect the checked state or value will trigger updates to the element.
3079 *
3080 * If they are supplied (and not null/undefined), the rendered element will not
3081 * trigger updates to the element. Instead, the props must change in order for
3082 * the rendered element to be updated.
3083 *
3084 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3085 * with an empty value (or `defaultValue`).
3086 *
3087 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3088 */
3089
3090function getHostProps(element, props) {
3091 var node = element;
3092 var checked = props.checked;
3093
3094 var hostProps = _assign({}, props, {
3095 defaultChecked: undefined,
3096 defaultValue: undefined,
3097 value: undefined,
3098 checked: checked != null ? checked : node._wrapperState.initialChecked
3099 });
3100
3101 return hostProps;
3102}
3103
3104function initWrapperState(element, props) {
3105 {
3106 ReactControlledValuePropTypes.checkPropTypes('input', props, getCurrentFiberStackAddendum);
3107
3108 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3109 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);
3110 didWarnCheckedDefaultChecked = true;
3111 }
3112 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3113 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);
3114 didWarnValueDefaultValue = true;
3115 }
3116 }
3117
3118 var node = element;
3119 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3120
3121 node._wrapperState = {
3122 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3123 initialValue: getSafeValue(props.value != null ? props.value : defaultValue),
3124 controlled: isControlled(props)
3125 };
3126}
3127
3128function updateChecked(element, props) {
3129 var node = element;
3130 var checked = props.checked;
3131 if (checked != null) {
3132 setValueForProperty(node, 'checked', checked, false);
3133 }
3134}
3135
3136function updateWrapper(element, props) {
3137 var node = element;
3138 {
3139 var _controlled = isControlled(props);
3140
3141 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3142 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());
3143 didWarnUncontrolledToControlled = true;
3144 }
3145 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3146 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());
3147 didWarnControlledToUncontrolled = true;
3148 }
3149 }
3150
3151 updateChecked(element, props);
3152
3153 var value = getSafeValue(props.value);
3154
3155 if (value != null) {
3156 if (props.type === 'number') {
3157 if (value === 0 && node.value === '' ||
3158 // eslint-disable-next-line
3159 node.value != value) {
3160 node.value = '' + value;
3161 }
3162 } else if (node.value !== '' + value) {
3163 node.value = '' + value;
3164 }
3165 }
3166
3167 if (props.hasOwnProperty('value')) {
3168 setDefaultValue(node, props.type, value);
3169 } else if (props.hasOwnProperty('defaultValue')) {
3170 setDefaultValue(node, props.type, getSafeValue(props.defaultValue));
3171 }
3172
3173 if (props.checked == null && props.defaultChecked != null) {
3174 node.defaultChecked = !!props.defaultChecked;
3175 }
3176}
3177
3178function postMountWrapper(element, props) {
3179 var node = element;
3180
3181 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3182 // Do not assign value if it is already set. This prevents user text input
3183 // from being lost during SSR hydration.
3184 if (node.value === '') {
3185 node.value = '' + node._wrapperState.initialValue;
3186 }
3187
3188 // value must be assigned before defaultValue. This fixes an issue where the
3189 // visually displayed value of date inputs disappears on mobile Safari and Chrome:
3190 // https://github.com/facebook/react/issues/7233
3191 node.defaultValue = '' + node._wrapperState.initialValue;
3192 }
3193
3194 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3195 // this is needed to work around a chrome bug where setting defaultChecked
3196 // will sometimes influence the value of checked (even after detachment).
3197 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3198 // We need to temporarily unset name to avoid disrupting radio button groups.
3199 var name = node.name;
3200 if (name !== '') {
3201 node.name = '';
3202 }
3203 node.defaultChecked = !node.defaultChecked;
3204 node.defaultChecked = !node.defaultChecked;
3205 if (name !== '') {
3206 node.name = name;
3207 }
3208}
3209
3210function restoreControlledState(element, props) {
3211 var node = element;
3212 updateWrapper(node, props);
3213 updateNamedCousins(node, props);
3214}
3215
3216function updateNamedCousins(rootNode, props) {
3217 var name = props.name;
3218 if (props.type === 'radio' && name != null) {
3219 var queryRoot = rootNode;
3220
3221 while (queryRoot.parentNode) {
3222 queryRoot = queryRoot.parentNode;
3223 }
3224
3225 // If `rootNode.form` was non-null, then we could try `form.elements`,
3226 // but that sometimes behaves strangely in IE8. We could also try using
3227 // `form.getElementsByName`, but that will only return direct children
3228 // and won't include inputs that use the HTML5 `form=` attribute. Since
3229 // the input might not even be in a form. It might not even be in the
3230 // document. Let's just use the local `querySelectorAll` to ensure we don't
3231 // miss anything.
3232 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3233
3234 for (var i = 0; i < group.length; i++) {
3235 var otherNode = group[i];
3236 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3237 continue;
3238 }
3239 // This will throw if radio buttons rendered by different copies of React
3240 // and the same name are rendered into the same form (same as #1939).
3241 // That's probably okay; we don't support it just as we don't support
3242 // mixing React radio buttons with non-React ones.
3243 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3244 !otherProps ? invariant_1(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3245
3246 // We need update the tracked value on the named cousin since the value
3247 // was changed but the input saw no event or value set
3248 updateValueIfChanged(otherNode);
3249
3250 // If this is a controlled radio button group, forcing the input that
3251 // was previously checked to update will cause it to be come re-checked
3252 // as appropriate.
3253 updateWrapper(otherNode, otherProps);
3254 }
3255 }
3256}
3257
3258// In Chrome, assigning defaultValue to certain input types triggers input validation.
3259// For number inputs, the display value loses trailing decimal points. For email inputs,
3260// Chrome raises "The specified value <x> is not a valid email address".
3261//
3262// Here we check to see if the defaultValue has actually changed, avoiding these problems
3263// when the user is inputting text
3264//
3265// https://github.com/facebook/react/issues/7253
3266function setDefaultValue(node, type, value) {
3267 if (
3268 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3269 type !== 'number' || node.ownerDocument.activeElement !== node) {
3270 if (value == null) {
3271 node.defaultValue = '' + node._wrapperState.initialValue;
3272 } else if (node.defaultValue !== '' + value) {
3273 node.defaultValue = '' + value;
3274 }
3275 }
3276}
3277
3278function getSafeValue(value) {
3279 switch (typeof value) {
3280 case 'boolean':
3281 case 'number':
3282 case 'object':
3283 case 'string':
3284 case 'undefined':
3285 return value;
3286 default:
3287 // function, symbol are assigned as empty strings
3288 return '';
3289 }
3290}
3291
3292var eventTypes$1 = {
3293 change: {
3294 phasedRegistrationNames: {
3295 bubbled: 'onChange',
3296 captured: 'onChangeCapture'
3297 },
3298 dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange']
3299 }
3300};
3301
3302function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3303 var event = SyntheticEvent$1.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3304 event.type = 'change';
3305 // Flag this event loop as needing state restore.
3306 enqueueStateRestore(target);
3307 accumulateTwoPhaseDispatches(event);
3308 return event;
3309}
3310/**
3311 * For IE shims
3312 */
3313var activeElement = null;
3314var activeElementInst = null;
3315
3316/**
3317 * SECTION: handle `change` event
3318 */
3319function shouldUseChangeEvent(elem) {
3320 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3321 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3322}
3323
3324function manualDispatchChangeEvent(nativeEvent) {
3325 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3326
3327 // If change and propertychange bubbled, we'd just bind to it like all the
3328 // other events and have it go through ReactBrowserEventEmitter. Since it
3329 // doesn't, we manually listen for the events and so we have to enqueue and
3330 // process the abstract event manually.
3331 //
3332 // Batching is necessary here in order to ensure that all event handlers run
3333 // before the next rerender (including event handlers attached to ancestor
3334 // elements instead of directly on the input). Without this, controlled
3335 // components don't work properly in conjunction with event bubbling because
3336 // the component is rerendered and the value reverted before all the event
3337 // handlers can run. See https://github.com/facebook/react/issues/708.
3338 batchedUpdates(runEventInBatch, event);
3339}
3340
3341function runEventInBatch(event) {
3342 runEventsInBatch(event, false);
3343}
3344
3345function getInstIfValueChanged(targetInst) {
3346 var targetNode = getNodeFromInstance$1(targetInst);
3347 if (updateValueIfChanged(targetNode)) {
3348 return targetInst;
3349 }
3350}
3351
3352function getTargetInstForChangeEvent(topLevelType, targetInst) {
3353 if (topLevelType === 'topChange') {
3354 return targetInst;
3355 }
3356}
3357
3358/**
3359 * SECTION: handle `input` event
3360 */
3361var isInputEventSupported = false;
3362if (ExecutionEnvironment_1.canUseDOM) {
3363 // IE9 claims to support the input event but fails to trigger it when
3364 // deleting text, so we ignore its input events.
3365 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3366}
3367
3368/**
3369 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3370 * and override the value property so that we can distinguish user events from
3371 * value changes in JS.
3372 */
3373function startWatchingForValueChange(target, targetInst) {
3374 activeElement = target;
3375 activeElementInst = targetInst;
3376 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3377}
3378
3379/**
3380 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3381 * if any exists.
3382 */
3383function stopWatchingForValueChange() {
3384 if (!activeElement) {
3385 return;
3386 }
3387 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3388 activeElement = null;
3389 activeElementInst = null;
3390}
3391
3392/**
3393 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3394 * the value of the active element has changed.
3395 */
3396function handlePropertyChange(nativeEvent) {
3397 if (nativeEvent.propertyName !== 'value') {
3398 return;
3399 }
3400 if (getInstIfValueChanged(activeElementInst)) {
3401 manualDispatchChangeEvent(nativeEvent);
3402 }
3403}
3404
3405function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3406 if (topLevelType === 'topFocus') {
3407 // In IE9, propertychange fires for most input events but is buggy and
3408 // doesn't fire when text is deleted, but conveniently, selectionchange
3409 // appears to fire in all of the remaining cases so we catch those and
3410 // forward the event if the value has changed
3411 // In either case, we don't want to call the event handler if the value
3412 // is changed from JS so we redefine a setter for `.value` that updates
3413 // our activeElementValue variable, allowing us to ignore those changes
3414 //
3415 // stopWatching() should be a noop here but we call it just in case we
3416 // missed a blur event somehow.
3417 stopWatchingForValueChange();
3418 startWatchingForValueChange(target, targetInst);
3419 } else if (topLevelType === 'topBlur') {
3420 stopWatchingForValueChange();
3421 }
3422}
3423
3424// For IE8 and IE9.
3425function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3426 if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') {
3427 // On the selectionchange event, the target is just document which isn't
3428 // helpful for us so just check activeElement instead.
3429 //
3430 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3431 // propertychange on the first input event after setting `value` from a
3432 // script and fires only keydown, keypress, keyup. Catching keyup usually
3433 // gets it and catching keydown lets us fire an event for the first
3434 // keystroke if user does a key repeat (it'll be a little delayed: right
3435 // before the second keystroke). Other input methods (e.g., paste) seem to
3436 // fire selectionchange normally.
3437 return getInstIfValueChanged(activeElementInst);
3438 }
3439}
3440
3441/**
3442 * SECTION: handle `click` event
3443 */
3444function shouldUseClickEvent(elem) {
3445 // Use the `click` event to detect changes to checkbox and radio inputs.
3446 // This approach works across all browsers, whereas `change` does not fire
3447 // until `blur` in IE8.
3448 var nodeName = elem.nodeName;
3449 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3450}
3451
3452function getTargetInstForClickEvent(topLevelType, targetInst) {
3453 if (topLevelType === 'topClick') {
3454 return getInstIfValueChanged(targetInst);
3455 }
3456}
3457
3458function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3459 if (topLevelType === 'topInput' || topLevelType === 'topChange') {
3460 return getInstIfValueChanged(targetInst);
3461 }
3462}
3463
3464function handleControlledInputBlur(inst, node) {
3465 // TODO: In IE, inst is occasionally null. Why?
3466 if (inst == null) {
3467 return;
3468 }
3469
3470 // Fiber and ReactDOM keep wrapper state in separate places
3471 var state = inst._wrapperState || node._wrapperState;
3472
3473 if (!state || !state.controlled || node.type !== 'number') {
3474 return;
3475 }
3476
3477 // If controlled, assign the value attribute to the current value on blur
3478 setDefaultValue(node, 'number', node.value);
3479}
3480
3481/**
3482 * This plugin creates an `onChange` event that normalizes change events
3483 * across form elements. This event fires at a time when it's possible to
3484 * change the element's value without seeing a flicker.
3485 *
3486 * Supported elements are:
3487 * - input (see `isTextInputElement`)
3488 * - textarea
3489 * - select
3490 */
3491var ChangeEventPlugin = {
3492 eventTypes: eventTypes$1,
3493
3494 _isInputEventSupported: isInputEventSupported,
3495
3496 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3497 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3498
3499 var getTargetInstFunc = void 0,
3500 handleEventFunc = void 0;
3501 if (shouldUseChangeEvent(targetNode)) {
3502 getTargetInstFunc = getTargetInstForChangeEvent;
3503 } else if (isTextInputElement(targetNode)) {
3504 if (isInputEventSupported) {
3505 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3506 } else {
3507 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3508 handleEventFunc = handleEventsForInputEventPolyfill;
3509 }
3510 } else if (shouldUseClickEvent(targetNode)) {
3511 getTargetInstFunc = getTargetInstForClickEvent;
3512 }
3513
3514 if (getTargetInstFunc) {
3515 var inst = getTargetInstFunc(topLevelType, targetInst);
3516 if (inst) {
3517 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3518 return event;
3519 }
3520 }
3521
3522 if (handleEventFunc) {
3523 handleEventFunc(topLevelType, targetNode, targetInst);
3524 }
3525
3526 // When blurring, set the value attribute for number inputs
3527 if (topLevelType === 'topBlur') {
3528 handleControlledInputBlur(targetInst, targetNode);
3529 }
3530 }
3531};
3532
3533/**
3534 * Module that is injectable into `EventPluginHub`, that specifies a
3535 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3536 * plugins, without having to package every one of them. This is better than
3537 * having plugins be ordered in the same order that they are injected because
3538 * that ordering would be influenced by the packaging order.
3539 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3540 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3541 */
3542var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3543
3544var SyntheticUIEvent = SyntheticEvent$1.extend({
3545 view: null,
3546 detail: null
3547});
3548
3549/**
3550 * Translation from modifier key to the associated property in the event.
3551 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3552 */
3553
3554var modifierKeyToProp = {
3555 Alt: 'altKey',
3556 Control: 'ctrlKey',
3557 Meta: 'metaKey',
3558 Shift: 'shiftKey'
3559};
3560
3561// IE8 does not implement getModifierState so we simply map it to the only
3562// modifier keys exposed by the event itself, does not support Lock-keys.
3563// Currently, all major browsers except Chrome seems to support Lock-keys.
3564function modifierStateGetter(keyArg) {
3565 var syntheticEvent = this;
3566 var nativeEvent = syntheticEvent.nativeEvent;
3567 if (nativeEvent.getModifierState) {
3568 return nativeEvent.getModifierState(keyArg);
3569 }
3570 var keyProp = modifierKeyToProp[keyArg];
3571 return keyProp ? !!nativeEvent[keyProp] : false;
3572}
3573
3574function getEventModifierState(nativeEvent) {
3575 return modifierStateGetter;
3576}
3577
3578/**
3579 * @interface MouseEvent
3580 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3581 */
3582var SyntheticMouseEvent = SyntheticUIEvent.extend({
3583 screenX: null,
3584 screenY: null,
3585 clientX: null,
3586 clientY: null,
3587 pageX: null,
3588 pageY: null,
3589 ctrlKey: null,
3590 shiftKey: null,
3591 altKey: null,
3592 metaKey: null,
3593 getModifierState: getEventModifierState,
3594 button: null,
3595 buttons: null,
3596 relatedTarget: function (event) {
3597 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3598 }
3599});
3600
3601var eventTypes$2 = {
3602 mouseEnter: {
3603 registrationName: 'onMouseEnter',
3604 dependencies: ['topMouseOut', 'topMouseOver']
3605 },
3606 mouseLeave: {
3607 registrationName: 'onMouseLeave',
3608 dependencies: ['topMouseOut', 'topMouseOver']
3609 }
3610};
3611
3612var EnterLeaveEventPlugin = {
3613 eventTypes: eventTypes$2,
3614
3615 /**
3616 * For almost every interaction we care about, there will be both a top-level
3617 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3618 * we do not extract duplicate events. However, moving the mouse into the
3619 * browser from outside will not fire a `mouseout` event. In this case, we use
3620 * the `mouseover` top-level event.
3621 */
3622 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3623 if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3624 return null;
3625 }
3626 if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') {
3627 // Must not be a mouse in or mouse out - ignoring.
3628 return null;
3629 }
3630
3631 var win = void 0;
3632 if (nativeEventTarget.window === nativeEventTarget) {
3633 // `nativeEventTarget` is probably a window object.
3634 win = nativeEventTarget;
3635 } else {
3636 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3637 var doc = nativeEventTarget.ownerDocument;
3638 if (doc) {
3639 win = doc.defaultView || doc.parentWindow;
3640 } else {
3641 win = window;
3642 }
3643 }
3644
3645 var from = void 0;
3646 var to = void 0;
3647 if (topLevelType === 'topMouseOut') {
3648 from = targetInst;
3649 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
3650 to = related ? getClosestInstanceFromNode(related) : null;
3651 } else {
3652 // Moving to a node from outside the window.
3653 from = null;
3654 to = targetInst;
3655 }
3656
3657 if (from === to) {
3658 // Nothing pertains to our managed components.
3659 return null;
3660 }
3661
3662 var fromNode = from == null ? win : getNodeFromInstance$1(from);
3663 var toNode = to == null ? win : getNodeFromInstance$1(to);
3664
3665 var leave = SyntheticMouseEvent.getPooled(eventTypes$2.mouseLeave, from, nativeEvent, nativeEventTarget);
3666 leave.type = 'mouseleave';
3667 leave.target = fromNode;
3668 leave.relatedTarget = toNode;
3669
3670 var enter = SyntheticMouseEvent.getPooled(eventTypes$2.mouseEnter, to, nativeEvent, nativeEventTarget);
3671 enter.type = 'mouseenter';
3672 enter.target = toNode;
3673 enter.relatedTarget = fromNode;
3674
3675 accumulateEnterLeaveDispatches(leave, enter, from, to);
3676
3677 return [leave, enter];
3678 }
3679};
3680
3681/**
3682 * Copyright (c) 2013-present, Facebook, Inc.
3683 *
3684 * This source code is licensed under the MIT license found in the
3685 * LICENSE file in the root directory of this source tree.
3686 *
3687 * @typechecks
3688 */
3689
3690/* eslint-disable fb-www/typeof-undefined */
3691
3692/**
3693 * Same as document.activeElement but wraps in a try-catch block. In IE it is
3694 * not safe to call document.activeElement if there is nothing focused.
3695 *
3696 * The activeElement will be null only if the document or document body is not
3697 * yet defined.
3698 *
3699 * @param {?DOMDocument} doc Defaults to current document.
3700 * @return {?DOMElement}
3701 */
3702function getActiveElement(doc) /*?DOMElement*/{
3703 doc = doc || (typeof document !== 'undefined' ? document : undefined);
3704 if (typeof doc === 'undefined') {
3705 return null;
3706 }
3707 try {
3708 return doc.activeElement || doc.body;
3709 } catch (e) {
3710 return doc.body;
3711 }
3712}
3713
3714var getActiveElement_1 = getActiveElement;
3715
3716/**
3717 * Copyright (c) 2013-present, Facebook, Inc.
3718 *
3719 * This source code is licensed under the MIT license found in the
3720 * LICENSE file in the root directory of this source tree.
3721 *
3722 * @typechecks
3723 *
3724 */
3725
3726/*eslint-disable no-self-compare */
3727
3728
3729
3730var hasOwnProperty = Object.prototype.hasOwnProperty;
3731
3732/**
3733 * inlined Object.is polyfill to avoid requiring consumers ship their own
3734 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3735 */
3736function is(x, y) {
3737 // SameValue algorithm
3738 if (x === y) {
3739 // Steps 1-5, 7-10
3740 // Steps 6.b-6.e: +0 != -0
3741 // Added the nonzero y check to make Flow happy, but it is redundant
3742 return x !== 0 || y !== 0 || 1 / x === 1 / y;
3743 } else {
3744 // Step 6.a: NaN == NaN
3745 return x !== x && y !== y;
3746 }
3747}
3748
3749/**
3750 * Performs equality by iterating through keys on an object and returning false
3751 * when any key has values which are not strictly equal between the arguments.
3752 * Returns true when the values of all keys are strictly equal.
3753 */
3754function shallowEqual(objA, objB) {
3755 if (is(objA, objB)) {
3756 return true;
3757 }
3758
3759 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3760 return false;
3761 }
3762
3763 var keysA = Object.keys(objA);
3764 var keysB = Object.keys(objB);
3765
3766 if (keysA.length !== keysB.length) {
3767 return false;
3768 }
3769
3770 // Test for A's keys different from B.
3771 for (var i = 0; i < keysA.length; i++) {
3772 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3773 return false;
3774 }
3775 }
3776
3777 return true;
3778}
3779
3780var shallowEqual_1 = shallowEqual;
3781
3782/**
3783 * `ReactInstanceMap` maintains a mapping from a public facing stateful
3784 * instance (key) and the internal representation (value). This allows public
3785 * methods to accept the user facing instance as an argument and map them back
3786 * to internal methods.
3787 *
3788 * Note that this module is currently shared and assumed to be stateless.
3789 * If this becomes an actual Map, that will break.
3790 */
3791
3792/**
3793 * This API should be called `delete` but we'd have to make sure to always
3794 * transform these to strings for IE support. When this transform is fully
3795 * supported we can rename it.
3796 */
3797
3798
3799function get(key) {
3800 return key._reactInternalFiber;
3801}
3802
3803function has(key) {
3804 return key._reactInternalFiber !== undefined;
3805}
3806
3807function set(key, value) {
3808 key._reactInternalFiber = value;
3809}
3810
3811// Don't change these two values:
3812var NoEffect = 0;
3813var PerformedWork = 1;
3814
3815// You can change the rest (and add more).
3816var Placement = 2;
3817var Update = 4;
3818var PlacementAndUpdate = 6;
3819var Deletion = 8;
3820var ContentReset = 16;
3821var Callback = 32;
3822var Err = 64;
3823var Ref = 128;
3824
3825var MOUNTING = 1;
3826var MOUNTED = 2;
3827var UNMOUNTED = 3;
3828
3829function isFiberMountedImpl(fiber) {
3830 var node = fiber;
3831 if (!fiber.alternate) {
3832 // If there is no alternate, this might be a new tree that isn't inserted
3833 // yet. If it is, then it will have a pending insertion effect on it.
3834 if ((node.effectTag & Placement) !== NoEffect) {
3835 return MOUNTING;
3836 }
3837 while (node['return']) {
3838 node = node['return'];
3839 if ((node.effectTag & Placement) !== NoEffect) {
3840 return MOUNTING;
3841 }
3842 }
3843 } else {
3844 while (node['return']) {
3845 node = node['return'];
3846 }
3847 }
3848 if (node.tag === HostRoot) {
3849 // TODO: Check if this was a nested HostRoot when used with
3850 // renderContainerIntoSubtree.
3851 return MOUNTED;
3852 }
3853 // If we didn't hit the root, that means that we're in an disconnected tree
3854 // that has been unmounted.
3855 return UNMOUNTED;
3856}
3857
3858function isFiberMounted(fiber) {
3859 return isFiberMountedImpl(fiber) === MOUNTED;
3860}
3861
3862function isMounted(component) {
3863 {
3864 var owner = ReactCurrentOwner.current;
3865 if (owner !== null && owner.tag === ClassComponent) {
3866 var ownerFiber = owner;
3867 var instance = ownerFiber.stateNode;
3868 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');
3869 instance._warnedAboutRefsInRender = true;
3870 }
3871 }
3872
3873 var fiber = get(component);
3874 if (!fiber) {
3875 return false;
3876 }
3877 return isFiberMountedImpl(fiber) === MOUNTED;
3878}
3879
3880function assertIsMounted(fiber) {
3881 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3882}
3883
3884function findCurrentFiberUsingSlowPath(fiber) {
3885 var alternate = fiber.alternate;
3886 if (!alternate) {
3887 // If there is no alternate, then we only need to check if it is mounted.
3888 var state = isFiberMountedImpl(fiber);
3889 !(state !== UNMOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3890 if (state === MOUNTING) {
3891 return null;
3892 }
3893 return fiber;
3894 }
3895 // If we have two possible branches, we'll walk backwards up to the root
3896 // to see what path the root points to. On the way we may hit one of the
3897 // special cases and we'll deal with them.
3898 var a = fiber;
3899 var b = alternate;
3900 while (true) {
3901 var parentA = a['return'];
3902 var parentB = parentA ? parentA.alternate : null;
3903 if (!parentA || !parentB) {
3904 // We're at the root.
3905 break;
3906 }
3907
3908 // If both copies of the parent fiber point to the same child, we can
3909 // assume that the child is current. This happens when we bailout on low
3910 // priority: the bailed out fiber's child reuses the current child.
3911 if (parentA.child === parentB.child) {
3912 var child = parentA.child;
3913 while (child) {
3914 if (child === a) {
3915 // We've determined that A is the current branch.
3916 assertIsMounted(parentA);
3917 return fiber;
3918 }
3919 if (child === b) {
3920 // We've determined that B is the current branch.
3921 assertIsMounted(parentA);
3922 return alternate;
3923 }
3924 child = child.sibling;
3925 }
3926 // We should never have an alternate for any mounting node. So the only
3927 // way this could possibly happen is if this was unmounted, if at all.
3928 invariant_1(false, 'Unable to find node on an unmounted component.');
3929 }
3930
3931 if (a['return'] !== b['return']) {
3932 // The return pointer of A and the return pointer of B point to different
3933 // fibers. We assume that return pointers never criss-cross, so A must
3934 // belong to the child set of A.return, and B must belong to the child
3935 // set of B.return.
3936 a = parentA;
3937 b = parentB;
3938 } else {
3939 // The return pointers point to the same fiber. We'll have to use the
3940 // default, slow path: scan the child sets of each parent alternate to see
3941 // which child belongs to which set.
3942 //
3943 // Search parent A's child set
3944 var didFindChild = false;
3945 var _child = parentA.child;
3946 while (_child) {
3947 if (_child === a) {
3948 didFindChild = true;
3949 a = parentA;
3950 b = parentB;
3951 break;
3952 }
3953 if (_child === b) {
3954 didFindChild = true;
3955 b = parentA;
3956 a = parentB;
3957 break;
3958 }
3959 _child = _child.sibling;
3960 }
3961 if (!didFindChild) {
3962 // Search parent B's child set
3963 _child = parentB.child;
3964 while (_child) {
3965 if (_child === a) {
3966 didFindChild = true;
3967 a = parentB;
3968 b = parentA;
3969 break;
3970 }
3971 if (_child === b) {
3972 didFindChild = true;
3973 b = parentB;
3974 a = parentA;
3975 break;
3976 }
3977 _child = _child.sibling;
3978 }
3979 !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;
3980 }
3981 }
3982
3983 !(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;
3984 }
3985 // If the root is not a host container, we're in a disconnected tree. I.e.
3986 // unmounted.
3987 !(a.tag === HostRoot) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3988 if (a.stateNode.current === a) {
3989 // We've determined that A is the current branch.
3990 return fiber;
3991 }
3992 // Otherwise B has to be current branch.
3993 return alternate;
3994}
3995
3996function findCurrentHostFiber(parent) {
3997 var currentParent = findCurrentFiberUsingSlowPath(parent);
3998 if (!currentParent) {
3999 return null;
4000 }
4001
4002 // Next we'll drill down this component to find the first HostComponent/Text.
4003 var node = currentParent;
4004 while (true) {
4005 if (node.tag === HostComponent || node.tag === HostText) {
4006 return node;
4007 } else if (node.child) {
4008 node.child['return'] = node;
4009 node = node.child;
4010 continue;
4011 }
4012 if (node === currentParent) {
4013 return null;
4014 }
4015 while (!node.sibling) {
4016 if (!node['return'] || node['return'] === currentParent) {
4017 return null;
4018 }
4019 node = node['return'];
4020 }
4021 node.sibling['return'] = node['return'];
4022 node = node.sibling;
4023 }
4024 // Flow needs the return null here, but ESLint complains about it.
4025 // eslint-disable-next-line no-unreachable
4026 return null;
4027}
4028
4029function findCurrentHostFiberWithNoPortals(parent) {
4030 var currentParent = findCurrentFiberUsingSlowPath(parent);
4031 if (!currentParent) {
4032 return null;
4033 }
4034
4035 // Next we'll drill down this component to find the first HostComponent/Text.
4036 var node = currentParent;
4037 while (true) {
4038 if (node.tag === HostComponent || node.tag === HostText) {
4039 return node;
4040 } else if (node.child && node.tag !== HostPortal) {
4041 node.child['return'] = node;
4042 node = node.child;
4043 continue;
4044 }
4045 if (node === currentParent) {
4046 return null;
4047 }
4048 while (!node.sibling) {
4049 if (!node['return'] || node['return'] === currentParent) {
4050 return null;
4051 }
4052 node = node['return'];
4053 }
4054 node.sibling['return'] = node['return'];
4055 node = node.sibling;
4056 }
4057 // Flow needs the return null here, but ESLint complains about it.
4058 // eslint-disable-next-line no-unreachable
4059 return null;
4060}
4061
4062function addEventBubbleListener(element, eventType, listener) {
4063 element.addEventListener(eventType, listener, false);
4064}
4065
4066function addEventCaptureListener(element, eventType, listener) {
4067 element.addEventListener(eventType, listener, true);
4068}
4069
4070var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4071var callbackBookkeepingPool = [];
4072
4073/**
4074 * Find the deepest React component completely containing the root of the
4075 * passed-in instance (for use when entire React trees are nested within each
4076 * other). If React trees are not nested, returns null.
4077 */
4078function findRootContainerNode(inst) {
4079 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4080 // traversal, but caching is difficult to do correctly without using a
4081 // mutation observer to listen for all DOM changes.
4082 while (inst['return']) {
4083 inst = inst['return'];
4084 }
4085 if (inst.tag !== HostRoot) {
4086 // This can happen if we're in a detached tree.
4087 return null;
4088 }
4089 return inst.stateNode.containerInfo;
4090}
4091
4092// Used to store ancestor hierarchy in top level callback
4093function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4094 if (callbackBookkeepingPool.length) {
4095 var instance = callbackBookkeepingPool.pop();
4096 instance.topLevelType = topLevelType;
4097 instance.nativeEvent = nativeEvent;
4098 instance.targetInst = targetInst;
4099 return instance;
4100 }
4101 return {
4102 topLevelType: topLevelType,
4103 nativeEvent: nativeEvent,
4104 targetInst: targetInst,
4105 ancestors: []
4106 };
4107}
4108
4109function releaseTopLevelCallbackBookKeeping(instance) {
4110 instance.topLevelType = null;
4111 instance.nativeEvent = null;
4112 instance.targetInst = null;
4113 instance.ancestors.length = 0;
4114 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4115 callbackBookkeepingPool.push(instance);
4116 }
4117}
4118
4119function handleTopLevel(bookKeeping) {
4120 var targetInst = bookKeeping.targetInst;
4121
4122 // Loop through the hierarchy, in case there's any nested components.
4123 // It's important that we build the array of ancestors before calling any
4124 // event handlers, because event handlers can modify the DOM, leading to
4125 // inconsistencies with ReactMount's node cache. See #1105.
4126 var ancestor = targetInst;
4127 do {
4128 if (!ancestor) {
4129 bookKeeping.ancestors.push(ancestor);
4130 break;
4131 }
4132 var root = findRootContainerNode(ancestor);
4133 if (!root) {
4134 break;
4135 }
4136 bookKeeping.ancestors.push(ancestor);
4137 ancestor = getClosestInstanceFromNode(root);
4138 } while (ancestor);
4139
4140 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4141 targetInst = bookKeeping.ancestors[i];
4142 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4143 }
4144}
4145
4146// TODO: can we stop exporting these?
4147var _enabled = true;
4148
4149function setEnabled(enabled) {
4150 _enabled = !!enabled;
4151}
4152
4153function isEnabled() {
4154 return _enabled;
4155}
4156
4157/**
4158 * Traps top-level events by using event bubbling.
4159 *
4160 * @param {string} topLevelType Record from `BrowserEventConstants`.
4161 * @param {string} handlerBaseName Event name (e.g. "click").
4162 * @param {object} element Element on which to attach listener.
4163 * @return {?object} An object with a remove function which will forcefully
4164 * remove the listener.
4165 * @internal
4166 */
4167function trapBubbledEvent(topLevelType, handlerBaseName, element) {
4168 if (!element) {
4169 return null;
4170 }
4171 addEventBubbleListener(element, handlerBaseName, dispatchEvent.bind(null, topLevelType));
4172}
4173
4174/**
4175 * Traps a top-level event by using event capturing.
4176 *
4177 * @param {string} topLevelType Record from `BrowserEventConstants`.
4178 * @param {string} handlerBaseName Event name (e.g. "click").
4179 * @param {object} element Element on which to attach listener.
4180 * @return {?object} An object with a remove function which will forcefully
4181 * remove the listener.
4182 * @internal
4183 */
4184function trapCapturedEvent(topLevelType, handlerBaseName, element) {
4185 if (!element) {
4186 return null;
4187 }
4188 addEventCaptureListener(element, handlerBaseName, dispatchEvent.bind(null, topLevelType));
4189}
4190
4191function dispatchEvent(topLevelType, nativeEvent) {
4192 if (!_enabled) {
4193 return;
4194 }
4195
4196 var nativeEventTarget = getEventTarget(nativeEvent);
4197 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4198 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4199 // If we get an event (ex: img onload) before committing that
4200 // component's mount, ignore it for now (that is, treat it as if it was an
4201 // event on a non-React tree). We might also consider queueing events and
4202 // dispatching them after the mount.
4203 targetInst = null;
4204 }
4205
4206 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4207
4208 try {
4209 // Event queue being processed in the same cycle allows
4210 // `preventDefault`.
4211 batchedUpdates(handleTopLevel, bookKeeping);
4212 } finally {
4213 releaseTopLevelCallbackBookKeeping(bookKeeping);
4214 }
4215}
4216
4217var ReactDOMEventListener = Object.freeze({
4218 get _enabled () { return _enabled; },
4219 setEnabled: setEnabled,
4220 isEnabled: isEnabled,
4221 trapBubbledEvent: trapBubbledEvent,
4222 trapCapturedEvent: trapCapturedEvent,
4223 dispatchEvent: dispatchEvent
4224});
4225
4226/**
4227 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4228 *
4229 * @param {string} styleProp
4230 * @param {string} eventName
4231 * @returns {object}
4232 */
4233function makePrefixMap(styleProp, eventName) {
4234 var prefixes = {};
4235
4236 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4237 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4238 prefixes['Moz' + styleProp] = 'moz' + eventName;
4239 prefixes['ms' + styleProp] = 'MS' + eventName;
4240 prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
4241
4242 return prefixes;
4243}
4244
4245/**
4246 * A list of event names to a configurable list of vendor prefixes.
4247 */
4248var vendorPrefixes = {
4249 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4250 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4251 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4252 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4253};
4254
4255/**
4256 * Event names that have already been detected and prefixed (if applicable).
4257 */
4258var prefixedEventNames = {};
4259
4260/**
4261 * Element to check for prefixes on.
4262 */
4263var style = {};
4264
4265/**
4266 * Bootstrap if a DOM exists.
4267 */
4268if (ExecutionEnvironment_1.canUseDOM) {
4269 style = document.createElement('div').style;
4270
4271 // On some platforms, in particular some releases of Android 4.x,
4272 // the un-prefixed "animation" and "transition" properties are defined on the
4273 // style object but the events that fire will still be prefixed, so we need
4274 // to check if the un-prefixed events are usable, and if not remove them from the map.
4275 if (!('AnimationEvent' in window)) {
4276 delete vendorPrefixes.animationend.animation;
4277 delete vendorPrefixes.animationiteration.animation;
4278 delete vendorPrefixes.animationstart.animation;
4279 }
4280
4281 // Same as above
4282 if (!('TransitionEvent' in window)) {
4283 delete vendorPrefixes.transitionend.transition;
4284 }
4285}
4286
4287/**
4288 * Attempts to determine the correct vendor prefixed event name.
4289 *
4290 * @param {string} eventName
4291 * @returns {string}
4292 */
4293function getVendorPrefixedEventName(eventName) {
4294 if (prefixedEventNames[eventName]) {
4295 return prefixedEventNames[eventName];
4296 } else if (!vendorPrefixes[eventName]) {
4297 return eventName;
4298 }
4299
4300 var prefixMap = vendorPrefixes[eventName];
4301
4302 for (var styleProp in prefixMap) {
4303 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
4304 return prefixedEventNames[eventName] = prefixMap[styleProp];
4305 }
4306 }
4307
4308 return eventName;
4309}
4310
4311/**
4312 * Types of raw signals from the browser caught at the top level.
4313 *
4314 * For events like 'submit' or audio/video events which don't consistently
4315 * bubble (which we trap at a lower node than `document`), binding
4316 * at `document` would cause duplicate events so we don't include them here.
4317 */
4318var topLevelTypes = {
4319 topAnimationEnd: getVendorPrefixedEventName('animationend'),
4320 topAnimationIteration: getVendorPrefixedEventName('animationiteration'),
4321 topAnimationStart: getVendorPrefixedEventName('animationstart'),
4322 topBlur: 'blur',
4323 topCancel: 'cancel',
4324 topChange: 'change',
4325 topClick: 'click',
4326 topClose: 'close',
4327 topCompositionEnd: 'compositionend',
4328 topCompositionStart: 'compositionstart',
4329 topCompositionUpdate: 'compositionupdate',
4330 topContextMenu: 'contextmenu',
4331 topCopy: 'copy',
4332 topCut: 'cut',
4333 topDoubleClick: 'dblclick',
4334 topDrag: 'drag',
4335 topDragEnd: 'dragend',
4336 topDragEnter: 'dragenter',
4337 topDragExit: 'dragexit',
4338 topDragLeave: 'dragleave',
4339 topDragOver: 'dragover',
4340 topDragStart: 'dragstart',
4341 topDrop: 'drop',
4342 topFocus: 'focus',
4343 topInput: 'input',
4344 topKeyDown: 'keydown',
4345 topKeyPress: 'keypress',
4346 topKeyUp: 'keyup',
4347 topLoad: 'load',
4348 topLoadStart: 'loadstart',
4349 topMouseDown: 'mousedown',
4350 topMouseMove: 'mousemove',
4351 topMouseOut: 'mouseout',
4352 topMouseOver: 'mouseover',
4353 topMouseUp: 'mouseup',
4354 topPaste: 'paste',
4355 topScroll: 'scroll',
4356 topSelectionChange: 'selectionchange',
4357 topTextInput: 'textInput',
4358 topToggle: 'toggle',
4359 topTouchCancel: 'touchcancel',
4360 topTouchEnd: 'touchend',
4361 topTouchMove: 'touchmove',
4362 topTouchStart: 'touchstart',
4363 topTransitionEnd: getVendorPrefixedEventName('transitionend'),
4364 topWheel: 'wheel'
4365};
4366
4367// There are so many media events, it makes sense to just
4368// maintain a list of them. Note these aren't technically
4369// "top-level" since they don't bubble. We should come up
4370// with a better naming convention if we come to refactoring
4371// the event system.
4372var mediaEventTypes = {
4373 topAbort: 'abort',
4374 topCanPlay: 'canplay',
4375 topCanPlayThrough: 'canplaythrough',
4376 topDurationChange: 'durationchange',
4377 topEmptied: 'emptied',
4378 topEncrypted: 'encrypted',
4379 topEnded: 'ended',
4380 topError: 'error',
4381 topLoadedData: 'loadeddata',
4382 topLoadedMetadata: 'loadedmetadata',
4383 topLoadStart: 'loadstart',
4384 topPause: 'pause',
4385 topPlay: 'play',
4386 topPlaying: 'playing',
4387 topProgress: 'progress',
4388 topRateChange: 'ratechange',
4389 topSeeked: 'seeked',
4390 topSeeking: 'seeking',
4391 topStalled: 'stalled',
4392 topSuspend: 'suspend',
4393 topTimeUpdate: 'timeupdate',
4394 topVolumeChange: 'volumechange',
4395 topWaiting: 'waiting'
4396};
4397
4398/**
4399 * Summary of `ReactBrowserEventEmitter` event handling:
4400 *
4401 * - Top-level delegation is used to trap most native browser events. This
4402 * may only occur in the main thread and is the responsibility of
4403 * ReactDOMEventListener, which is injected and can therefore support
4404 * pluggable event sources. This is the only work that occurs in the main
4405 * thread.
4406 *
4407 * - We normalize and de-duplicate events to account for browser quirks. This
4408 * may be done in the worker thread.
4409 *
4410 * - Forward these native events (with the associated top-level type used to
4411 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4412 * to extract any synthetic events.
4413 *
4414 * - The `EventPluginHub` will then process each event by annotating them with
4415 * "dispatches", a sequence of listeners and IDs that care about that event.
4416 *
4417 * - The `EventPluginHub` then dispatches the events.
4418 *
4419 * Overview of React and the event system:
4420 *
4421 * +------------+ .
4422 * | DOM | .
4423 * +------------+ .
4424 * | .
4425 * v .
4426 * +------------+ .
4427 * | ReactEvent | .
4428 * | Listener | .
4429 * +------------+ . +-----------+
4430 * | . +--------+|SimpleEvent|
4431 * | . | |Plugin |
4432 * +-----|------+ . v +-----------+
4433 * | | | . +--------------+ +------------+
4434 * | +-----------.--->|EventPluginHub| | Event |
4435 * | | . | | +-----------+ | Propagators|
4436 * | ReactEvent | . | | |TapEvent | |------------|
4437 * | Emitter | . | |<---+|Plugin | |other plugin|
4438 * | | . | | +-----------+ | utilities |
4439 * | +-----------.--->| | +------------+
4440 * | | | . +--------------+
4441 * +-----|------+ . ^ +-----------+
4442 * | . | |Enter/Leave|
4443 * + . +-------+|Plugin |
4444 * +-------------+ . +-----------+
4445 * | application | .
4446 * |-------------| .
4447 * | | .
4448 * | | .
4449 * +-------------+ .
4450 * .
4451 * React Core . General Purpose Event Plugin System
4452 */
4453
4454var alreadyListeningTo = {};
4455var reactTopListenersCounter = 0;
4456
4457/**
4458 * To ensure no conflicts with other potential React instances on the page
4459 */
4460var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4461
4462function getListeningForDocument(mountAt) {
4463 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4464 // directly.
4465 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4466 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4467 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4468 }
4469 return alreadyListeningTo[mountAt[topListenersIDKey]];
4470}
4471
4472/**
4473 * We listen for bubbled touch events on the document object.
4474 *
4475 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4476 * mounting `onmousemove` events at some node that was not the document
4477 * element. The symptoms were that if your mouse is not moving over something
4478 * contained within that mount point (for example on the background) the
4479 * top-level listeners for `onmousemove` won't be called. However, if you
4480 * register the `mousemove` on the document object, then it will of course
4481 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4482 * top-level listeners to the document object only, at least for these
4483 * movement types of events and possibly all events.
4484 *
4485 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4486 *
4487 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
4488 * they bubble to document.
4489 *
4490 * @param {string} registrationName Name of listener (e.g. `onClick`).
4491 * @param {object} contentDocumentHandle Document which owns the container
4492 */
4493function listenTo(registrationName, contentDocumentHandle) {
4494 var mountAt = contentDocumentHandle;
4495 var isListening = getListeningForDocument(mountAt);
4496 var dependencies = registrationNameDependencies[registrationName];
4497
4498 for (var i = 0; i < dependencies.length; i++) {
4499 var dependency = dependencies[i];
4500 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4501 if (dependency === 'topScroll') {
4502 trapCapturedEvent('topScroll', 'scroll', mountAt);
4503 } else if (dependency === 'topFocus' || dependency === 'topBlur') {
4504 trapCapturedEvent('topFocus', 'focus', mountAt);
4505 trapCapturedEvent('topBlur', 'blur', mountAt);
4506
4507 // to make sure blur and focus event listeners are only attached once
4508 isListening.topBlur = true;
4509 isListening.topFocus = true;
4510 } else if (dependency === 'topCancel') {
4511 if (isEventSupported('cancel', true)) {
4512 trapCapturedEvent('topCancel', 'cancel', mountAt);
4513 }
4514 isListening.topCancel = true;
4515 } else if (dependency === 'topClose') {
4516 if (isEventSupported('close', true)) {
4517 trapCapturedEvent('topClose', 'close', mountAt);
4518 }
4519 isListening.topClose = true;
4520 } else if (topLevelTypes.hasOwnProperty(dependency)) {
4521 trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
4522 }
4523
4524 isListening[dependency] = true;
4525 }
4526 }
4527}
4528
4529function isListeningToAllDependencies(registrationName, mountAt) {
4530 var isListening = getListeningForDocument(mountAt);
4531 var dependencies = registrationNameDependencies[registrationName];
4532 for (var i = 0; i < dependencies.length; i++) {
4533 var dependency = dependencies[i];
4534 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4535 return false;
4536 }
4537 }
4538 return true;
4539}
4540
4541/**
4542 * Copyright (c) 2013-present, Facebook, Inc.
4543 *
4544 * This source code is licensed under the MIT license found in the
4545 * LICENSE file in the root directory of this source tree.
4546 *
4547 * @typechecks
4548 */
4549
4550/**
4551 * @param {*} object The object to check.
4552 * @return {boolean} Whether or not the object is a DOM node.
4553 */
4554function isNode(object) {
4555 var doc = object ? object.ownerDocument || object : document;
4556 var defaultView = doc.defaultView || window;
4557 return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
4558}
4559
4560var isNode_1 = isNode;
4561
4562/**
4563 * Copyright (c) 2013-present, Facebook, Inc.
4564 *
4565 * This source code is licensed under the MIT license found in the
4566 * LICENSE file in the root directory of this source tree.
4567 *
4568 * @typechecks
4569 */
4570
4571
4572
4573/**
4574 * @param {*} object The object to check.
4575 * @return {boolean} Whether or not the object is a DOM text node.
4576 */
4577function isTextNode(object) {
4578 return isNode_1(object) && object.nodeType == 3;
4579}
4580
4581var isTextNode_1 = isTextNode;
4582
4583/**
4584 * Copyright (c) 2013-present, Facebook, Inc.
4585 *
4586 * This source code is licensed under the MIT license found in the
4587 * LICENSE file in the root directory of this source tree.
4588 *
4589 *
4590 */
4591
4592
4593
4594/*eslint-disable no-bitwise */
4595
4596/**
4597 * Checks if a given DOM node contains or is another DOM node.
4598 */
4599function containsNode(outerNode, innerNode) {
4600 if (!outerNode || !innerNode) {
4601 return false;
4602 } else if (outerNode === innerNode) {
4603 return true;
4604 } else if (isTextNode_1(outerNode)) {
4605 return false;
4606 } else if (isTextNode_1(innerNode)) {
4607 return containsNode(outerNode, innerNode.parentNode);
4608 } else if ('contains' in outerNode) {
4609 return outerNode.contains(innerNode);
4610 } else if (outerNode.compareDocumentPosition) {
4611 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
4612 } else {
4613 return false;
4614 }
4615}
4616
4617var containsNode_1 = containsNode;
4618
4619/**
4620 * Given any node return the first leaf node without children.
4621 *
4622 * @param {DOMElement|DOMTextNode} node
4623 * @return {DOMElement|DOMTextNode}
4624 */
4625function getLeafNode(node) {
4626 while (node && node.firstChild) {
4627 node = node.firstChild;
4628 }
4629 return node;
4630}
4631
4632/**
4633 * Get the next sibling within a container. This will walk up the
4634 * DOM if a node's siblings have been exhausted.
4635 *
4636 * @param {DOMElement|DOMTextNode} node
4637 * @return {?DOMElement|DOMTextNode}
4638 */
4639function getSiblingNode(node) {
4640 while (node) {
4641 if (node.nextSibling) {
4642 return node.nextSibling;
4643 }
4644 node = node.parentNode;
4645 }
4646}
4647
4648/**
4649 * Get object describing the nodes which contain characters at offset.
4650 *
4651 * @param {DOMElement|DOMTextNode} root
4652 * @param {number} offset
4653 * @return {?object}
4654 */
4655function getNodeForCharacterOffset(root, offset) {
4656 var node = getLeafNode(root);
4657 var nodeStart = 0;
4658 var nodeEnd = 0;
4659
4660 while (node) {
4661 if (node.nodeType === TEXT_NODE) {
4662 nodeEnd = nodeStart + node.textContent.length;
4663
4664 if (nodeStart <= offset && nodeEnd >= offset) {
4665 return {
4666 node: node,
4667 offset: offset - nodeStart
4668 };
4669 }
4670
4671 nodeStart = nodeEnd;
4672 }
4673
4674 node = getLeafNode(getSiblingNode(node));
4675 }
4676}
4677
4678/**
4679 * @param {DOMElement} outerNode
4680 * @return {?object}
4681 */
4682function getOffsets(outerNode) {
4683 var selection = window.getSelection && window.getSelection();
4684
4685 if (!selection || selection.rangeCount === 0) {
4686 return null;
4687 }
4688
4689 var anchorNode = selection.anchorNode,
4690 anchorOffset = selection.anchorOffset,
4691 focusNode = selection.focusNode,
4692 focusOffset = selection.focusOffset;
4693
4694 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
4695 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
4696 // expose properties, triggering a "Permission denied error" if any of its
4697 // properties are accessed. The only seemingly possible way to avoid erroring
4698 // is to access a property that typically works for non-anonymous divs and
4699 // catch any error that may otherwise arise. See
4700 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
4701
4702 try {
4703 /* eslint-disable no-unused-expressions */
4704 anchorNode.nodeType;
4705 focusNode.nodeType;
4706 /* eslint-enable no-unused-expressions */
4707 } catch (e) {
4708 return null;
4709 }
4710
4711 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
4712}
4713
4714/**
4715 * Returns {start, end} where `start` is the character/codepoint index of
4716 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
4717 * `end` is the index of (focusNode, focusOffset).
4718 *
4719 * Returns null if you pass in garbage input but we should probably just crash.
4720 *
4721 * Exported only for testing.
4722 */
4723function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
4724 var length = 0;
4725 var start = -1;
4726 var end = -1;
4727 var indexWithinAnchor = 0;
4728 var indexWithinFocus = 0;
4729 var node = outerNode;
4730 var parentNode = null;
4731
4732 outer: while (true) {
4733 var next = null;
4734
4735 while (true) {
4736 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
4737 start = length + anchorOffset;
4738 }
4739 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
4740 end = length + focusOffset;
4741 }
4742
4743 if (node.nodeType === TEXT_NODE) {
4744 length += node.nodeValue.length;
4745 }
4746
4747 if ((next = node.firstChild) === null) {
4748 break;
4749 }
4750 // Moving from `node` to its first child `next`.
4751 parentNode = node;
4752 node = next;
4753 }
4754
4755 while (true) {
4756 if (node === outerNode) {
4757 // If `outerNode` has children, this is always the second time visiting
4758 // it. If it has no children, this is still the first loop, and the only
4759 // valid selection is anchorNode and focusNode both equal to this node
4760 // and both offsets 0, in which case we will have handled above.
4761 break outer;
4762 }
4763 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
4764 start = length;
4765 }
4766 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
4767 end = length;
4768 }
4769 if ((next = node.nextSibling) !== null) {
4770 break;
4771 }
4772 node = parentNode;
4773 parentNode = node.parentNode;
4774 }
4775
4776 // Moving from `node` to its next sibling `next`.
4777 node = next;
4778 }
4779
4780 if (start === -1 || end === -1) {
4781 // This should never happen. (Would happen if the anchor/focus nodes aren't
4782 // actually inside the passed-in node.)
4783 return null;
4784 }
4785
4786 return {
4787 start: start,
4788 end: end
4789 };
4790}
4791
4792/**
4793 * In modern non-IE browsers, we can support both forward and backward
4794 * selections.
4795 *
4796 * Note: IE10+ supports the Selection object, but it does not support
4797 * the `extend` method, which means that even in modern IE, it's not possible
4798 * to programmatically create a backward selection. Thus, for all IE
4799 * versions, we use the old IE API to create our selections.
4800 *
4801 * @param {DOMElement|DOMTextNode} node
4802 * @param {object} offsets
4803 */
4804function setOffsets(node, offsets) {
4805 if (!window.getSelection) {
4806 return;
4807 }
4808
4809 var selection = window.getSelection();
4810 var length = node[getTextContentAccessor()].length;
4811 var start = Math.min(offsets.start, length);
4812 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
4813
4814 // IE 11 uses modern selection, but doesn't support the extend method.
4815 // Flip backward selections, so we can set with a single range.
4816 if (!selection.extend && start > end) {
4817 var temp = end;
4818 end = start;
4819 start = temp;
4820 }
4821
4822 var startMarker = getNodeForCharacterOffset(node, start);
4823 var endMarker = getNodeForCharacterOffset(node, end);
4824
4825 if (startMarker && endMarker) {
4826 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
4827 return;
4828 }
4829 var range = document.createRange();
4830 range.setStart(startMarker.node, startMarker.offset);
4831 selection.removeAllRanges();
4832
4833 if (start > end) {
4834 selection.addRange(range);
4835 selection.extend(endMarker.node, endMarker.offset);
4836 } else {
4837 range.setEnd(endMarker.node, endMarker.offset);
4838 selection.addRange(range);
4839 }
4840 }
4841}
4842
4843function isInDocument(node) {
4844 return containsNode_1(document.documentElement, node);
4845}
4846
4847/**
4848 * @ReactInputSelection: React input selection module. Based on Selection.js,
4849 * but modified to be suitable for react and has a couple of bug fixes (doesn't
4850 * assume buttons have range selections allowed).
4851 * Input selection module for React.
4852 */
4853
4854function hasSelectionCapabilities(elem) {
4855 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
4856 return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
4857}
4858
4859function getSelectionInformation() {
4860 var focusedElem = getActiveElement_1();
4861 return {
4862 focusedElem: focusedElem,
4863 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
4864 };
4865}
4866
4867/**
4868 * @restoreSelection: If any selection information was potentially lost,
4869 * restore it. This is useful when performing operations that could remove dom
4870 * nodes and place them back in, resulting in focus being lost.
4871 */
4872function restoreSelection(priorSelectionInformation) {
4873 var curFocusedElem = getActiveElement_1();
4874 var priorFocusedElem = priorSelectionInformation.focusedElem;
4875 var priorSelectionRange = priorSelectionInformation.selectionRange;
4876 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
4877 if (hasSelectionCapabilities(priorFocusedElem)) {
4878 setSelection(priorFocusedElem, priorSelectionRange);
4879 }
4880
4881 // Focusing a node can change the scroll position, which is undesirable
4882 var ancestors = [];
4883 var ancestor = priorFocusedElem;
4884 while (ancestor = ancestor.parentNode) {
4885 if (ancestor.nodeType === ELEMENT_NODE) {
4886 ancestors.push({
4887 element: ancestor,
4888 left: ancestor.scrollLeft,
4889 top: ancestor.scrollTop
4890 });
4891 }
4892 }
4893
4894 priorFocusedElem.focus();
4895
4896 for (var i = 0; i < ancestors.length; i++) {
4897 var info = ancestors[i];
4898 info.element.scrollLeft = info.left;
4899 info.element.scrollTop = info.top;
4900 }
4901 }
4902}
4903
4904/**
4905 * @getSelection: Gets the selection bounds of a focused textarea, input or
4906 * contentEditable node.
4907 * -@input: Look up selection bounds of this input
4908 * -@return {start: selectionStart, end: selectionEnd}
4909 */
4910function getSelection$1(input) {
4911 var selection = void 0;
4912
4913 if ('selectionStart' in input) {
4914 // Modern browser with input or textarea.
4915 selection = {
4916 start: input.selectionStart,
4917 end: input.selectionEnd
4918 };
4919 } else {
4920 // Content editable or old IE textarea.
4921 selection = getOffsets(input);
4922 }
4923
4924 return selection || { start: 0, end: 0 };
4925}
4926
4927/**
4928 * @setSelection: Sets the selection bounds of a textarea or input and focuses
4929 * the input.
4930 * -@input Set selection bounds of this input or textarea
4931 * -@offsets Object of same form that is returned from get*
4932 */
4933function setSelection(input, offsets) {
4934 var start = offsets.start,
4935 end = offsets.end;
4936
4937 if (end === undefined) {
4938 end = start;
4939 }
4940
4941 if ('selectionStart' in input) {
4942 input.selectionStart = start;
4943 input.selectionEnd = Math.min(end, input.value.length);
4944 } else {
4945 setOffsets(input, offsets);
4946 }
4947}
4948
4949var skipSelectionChangeEvent = ExecutionEnvironment_1.canUseDOM && 'documentMode' in document && document.documentMode <= 11;
4950
4951var eventTypes$3 = {
4952 select: {
4953 phasedRegistrationNames: {
4954 bubbled: 'onSelect',
4955 captured: 'onSelectCapture'
4956 },
4957 dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange']
4958 }
4959};
4960
4961var activeElement$1 = null;
4962var activeElementInst$1 = null;
4963var lastSelection = null;
4964var mouseDown = false;
4965
4966/**
4967 * Get an object which is a unique representation of the current selection.
4968 *
4969 * The return value will not be consistent across nodes or browsers, but
4970 * two identical selections on the same node will return identical objects.
4971 *
4972 * @param {DOMElement} node
4973 * @return {object}
4974 */
4975function getSelection(node) {
4976 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
4977 return {
4978 start: node.selectionStart,
4979 end: node.selectionEnd
4980 };
4981 } else if (window.getSelection) {
4982 var selection = window.getSelection();
4983 return {
4984 anchorNode: selection.anchorNode,
4985 anchorOffset: selection.anchorOffset,
4986 focusNode: selection.focusNode,
4987 focusOffset: selection.focusOffset
4988 };
4989 }
4990}
4991
4992/**
4993 * Poll selection to see whether it's changed.
4994 *
4995 * @param {object} nativeEvent
4996 * @return {?SyntheticEvent}
4997 */
4998function constructSelectEvent(nativeEvent, nativeEventTarget) {
4999 // Ensure we have the right element, and that the user is not dragging a
5000 // selection (this matches native `select` event behavior). In HTML5, select
5001 // fires only on input and textarea thus if there's no focused element we
5002 // won't dispatch.
5003 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement_1()) {
5004 return null;
5005 }
5006
5007 // Only fire when selection has actually changed.
5008 var currentSelection = getSelection(activeElement$1);
5009 if (!lastSelection || !shallowEqual_1(lastSelection, currentSelection)) {
5010 lastSelection = currentSelection;
5011
5012 var syntheticEvent = SyntheticEvent$1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5013
5014 syntheticEvent.type = 'select';
5015 syntheticEvent.target = activeElement$1;
5016
5017 accumulateTwoPhaseDispatches(syntheticEvent);
5018
5019 return syntheticEvent;
5020 }
5021
5022 return null;
5023}
5024
5025/**
5026 * This plugin creates an `onSelect` event that normalizes select events
5027 * across form elements.
5028 *
5029 * Supported elements are:
5030 * - input (see `isTextInputElement`)
5031 * - textarea
5032 * - contentEditable
5033 *
5034 * This differs from native browser implementations in the following ways:
5035 * - Fires on contentEditable fields as well as inputs.
5036 * - Fires for collapsed selection.
5037 * - Fires after user input.
5038 */
5039var SelectEventPlugin = {
5040 eventTypes: eventTypes$3,
5041
5042 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5043 var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE ? nativeEventTarget : nativeEventTarget.ownerDocument;
5044 // Track whether all listeners exists for this plugin. If none exist, we do
5045 // not extract events. See #3639.
5046 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5047 return null;
5048 }
5049
5050 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5051
5052 switch (topLevelType) {
5053 // Track the input node that has focus.
5054 case 'topFocus':
5055 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5056 activeElement$1 = targetNode;
5057 activeElementInst$1 = targetInst;
5058 lastSelection = null;
5059 }
5060 break;
5061 case 'topBlur':
5062 activeElement$1 = null;
5063 activeElementInst$1 = null;
5064 lastSelection = null;
5065 break;
5066 // Don't fire the event while the user is dragging. This matches the
5067 // semantics of the native select event.
5068 case 'topMouseDown':
5069 mouseDown = true;
5070 break;
5071 case 'topContextMenu':
5072 case 'topMouseUp':
5073 mouseDown = false;
5074 return constructSelectEvent(nativeEvent, nativeEventTarget);
5075 // Chrome and IE fire non-standard event when selection is changed (and
5076 // sometimes when it hasn't). IE's event fires out of order with respect
5077 // to key and input events on deletion, so we discard it.
5078 //
5079 // Firefox doesn't support selectionchange, so check selection status
5080 // after each key entry. The selection changes after keydown and before
5081 // keyup, but we check on keydown as well in the case of holding down a
5082 // key, when multiple keydown events are fired but only one keyup is.
5083 // This is also our approach for IE handling, for the reason above.
5084 case 'topSelectionChange':
5085 if (skipSelectionChangeEvent) {
5086 break;
5087 }
5088 // falls through
5089 case 'topKeyDown':
5090 case 'topKeyUp':
5091 return constructSelectEvent(nativeEvent, nativeEventTarget);
5092 }
5093
5094 return null;
5095 }
5096};
5097
5098/**
5099 * @interface Event
5100 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
5101 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
5102 */
5103var SyntheticAnimationEvent = SyntheticEvent$1.extend({
5104 animationName: null,
5105 elapsedTime: null,
5106 pseudoElement: null
5107});
5108
5109/**
5110 * @interface Event
5111 * @see http://www.w3.org/TR/clipboard-apis/
5112 */
5113var SyntheticClipboardEvent = SyntheticEvent$1.extend({
5114 clipboardData: function (event) {
5115 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
5116 }
5117});
5118
5119/**
5120 * @interface FocusEvent
5121 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5122 */
5123var SyntheticFocusEvent = SyntheticUIEvent.extend({
5124 relatedTarget: null
5125});
5126
5127/**
5128 * `charCode` represents the actual "character code" and is safe to use with
5129 * `String.fromCharCode`. As such, only keys that correspond to printable
5130 * characters produce a valid `charCode`, the only exception to this is Enter.
5131 * The Tab-key is considered non-printable and does not have a `charCode`,
5132 * presumably because it does not produce a tab-character in browsers.
5133 *
5134 * @param {object} nativeEvent Native browser event.
5135 * @return {number} Normalized `charCode` property.
5136 */
5137function getEventCharCode(nativeEvent) {
5138 var charCode = void 0;
5139 var keyCode = nativeEvent.keyCode;
5140
5141 if ('charCode' in nativeEvent) {
5142 charCode = nativeEvent.charCode;
5143
5144 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
5145 if (charCode === 0 && keyCode === 13) {
5146 charCode = 13;
5147 }
5148 } else {
5149 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
5150 charCode = keyCode;
5151 }
5152
5153 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
5154 // report Enter as charCode 10 when ctrl is pressed.
5155 if (charCode === 10) {
5156 charCode = 13;
5157 }
5158
5159 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
5160 // Must not discard the (non-)printable Enter-key.
5161 if (charCode >= 32 || charCode === 13) {
5162 return charCode;
5163 }
5164
5165 return 0;
5166}
5167
5168/**
5169 * Normalization of deprecated HTML5 `key` values
5170 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5171 */
5172var normalizeKey = {
5173 Esc: 'Escape',
5174 Spacebar: ' ',
5175 Left: 'ArrowLeft',
5176 Up: 'ArrowUp',
5177 Right: 'ArrowRight',
5178 Down: 'ArrowDown',
5179 Del: 'Delete',
5180 Win: 'OS',
5181 Menu: 'ContextMenu',
5182 Apps: 'ContextMenu',
5183 Scroll: 'ScrollLock',
5184 MozPrintableKey: 'Unidentified'
5185};
5186
5187/**
5188 * Translation from legacy `keyCode` to HTML5 `key`
5189 * Only special keys supported, all others depend on keyboard layout or browser
5190 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5191 */
5192var translateToKey = {
5193 '8': 'Backspace',
5194 '9': 'Tab',
5195 '12': 'Clear',
5196 '13': 'Enter',
5197 '16': 'Shift',
5198 '17': 'Control',
5199 '18': 'Alt',
5200 '19': 'Pause',
5201 '20': 'CapsLock',
5202 '27': 'Escape',
5203 '32': ' ',
5204 '33': 'PageUp',
5205 '34': 'PageDown',
5206 '35': 'End',
5207 '36': 'Home',
5208 '37': 'ArrowLeft',
5209 '38': 'ArrowUp',
5210 '39': 'ArrowRight',
5211 '40': 'ArrowDown',
5212 '45': 'Insert',
5213 '46': 'Delete',
5214 '112': 'F1',
5215 '113': 'F2',
5216 '114': 'F3',
5217 '115': 'F4',
5218 '116': 'F5',
5219 '117': 'F6',
5220 '118': 'F7',
5221 '119': 'F8',
5222 '120': 'F9',
5223 '121': 'F10',
5224 '122': 'F11',
5225 '123': 'F12',
5226 '144': 'NumLock',
5227 '145': 'ScrollLock',
5228 '224': 'Meta'
5229};
5230
5231/**
5232 * @param {object} nativeEvent Native browser event.
5233 * @return {string} Normalized `key` property.
5234 */
5235function getEventKey(nativeEvent) {
5236 if (nativeEvent.key) {
5237 // Normalize inconsistent values reported by browsers due to
5238 // implementations of a working draft specification.
5239
5240 // FireFox implements `key` but returns `MozPrintableKey` for all
5241 // printable characters (normalized to `Unidentified`), ignore it.
5242 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
5243 if (key !== 'Unidentified') {
5244 return key;
5245 }
5246 }
5247
5248 // Browser does not implement `key`, polyfill as much of it as we can.
5249 if (nativeEvent.type === 'keypress') {
5250 var charCode = getEventCharCode(nativeEvent);
5251
5252 // The enter-key is technically both printable and non-printable and can
5253 // thus be captured by `keypress`, no other non-printable key should.
5254 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
5255 }
5256 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
5257 // While user keyboard layout determines the actual meaning of each
5258 // `keyCode` value, almost all function keys have a universal value.
5259 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
5260 }
5261 return '';
5262}
5263
5264/**
5265 * @interface KeyboardEvent
5266 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5267 */
5268var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
5269 key: getEventKey,
5270 location: null,
5271 ctrlKey: null,
5272 shiftKey: null,
5273 altKey: null,
5274 metaKey: null,
5275 repeat: null,
5276 locale: null,
5277 getModifierState: getEventModifierState,
5278 // Legacy Interface
5279 charCode: function (event) {
5280 // `charCode` is the result of a KeyPress event and represents the value of
5281 // the actual printable character.
5282
5283 // KeyPress is deprecated, but its replacement is not yet final and not
5284 // implemented in any major browser. Only KeyPress has charCode.
5285 if (event.type === 'keypress') {
5286 return getEventCharCode(event);
5287 }
5288 return 0;
5289 },
5290 keyCode: function (event) {
5291 // `keyCode` is the result of a KeyDown/Up event and represents the value of
5292 // physical keyboard key.
5293
5294 // The actual meaning of the value depends on the users' keyboard layout
5295 // which cannot be detected. Assuming that it is a US keyboard layout
5296 // provides a surprisingly accurate mapping for US and European users.
5297 // Due to this, it is left to the user to implement at this time.
5298 if (event.type === 'keydown' || event.type === 'keyup') {
5299 return event.keyCode;
5300 }
5301 return 0;
5302 },
5303 which: function (event) {
5304 // `which` is an alias for either `keyCode` or `charCode` depending on the
5305 // type of the event.
5306 if (event.type === 'keypress') {
5307 return getEventCharCode(event);
5308 }
5309 if (event.type === 'keydown' || event.type === 'keyup') {
5310 return event.keyCode;
5311 }
5312 return 0;
5313 }
5314});
5315
5316/**
5317 * @interface DragEvent
5318 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5319 */
5320var SyntheticDragEvent = SyntheticMouseEvent.extend({
5321 dataTransfer: null
5322});
5323
5324/**
5325 * @interface TouchEvent
5326 * @see http://www.w3.org/TR/touch-events/
5327 */
5328var SyntheticTouchEvent = SyntheticUIEvent.extend({
5329 touches: null,
5330 targetTouches: null,
5331 changedTouches: null,
5332 altKey: null,
5333 metaKey: null,
5334 ctrlKey: null,
5335 shiftKey: null,
5336 getModifierState: getEventModifierState
5337});
5338
5339/**
5340 * @interface Event
5341 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
5342 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
5343 */
5344var SyntheticTransitionEvent = SyntheticEvent$1.extend({
5345 propertyName: null,
5346 elapsedTime: null,
5347 pseudoElement: null
5348});
5349
5350/**
5351 * @interface WheelEvent
5352 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5353 */
5354var SyntheticWheelEvent = SyntheticMouseEvent.extend({
5355 deltaX: function (event) {
5356 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
5357 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
5358 },
5359 deltaY: function (event) {
5360 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
5361 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
5362 'wheelDelta' in event ? -event.wheelDelta : 0;
5363 },
5364
5365 deltaZ: null,
5366
5367 // Browsers without "deltaMode" is reporting in raw wheel delta where one
5368 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
5369 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
5370 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
5371 deltaMode: null
5372});
5373
5374/**
5375 * Turns
5376 * ['abort', ...]
5377 * into
5378 * eventTypes = {
5379 * 'abort': {
5380 * phasedRegistrationNames: {
5381 * bubbled: 'onAbort',
5382 * captured: 'onAbortCapture',
5383 * },
5384 * dependencies: ['topAbort'],
5385 * },
5386 * ...
5387 * };
5388 * topLevelEventsToDispatchConfig = {
5389 * 'topAbort': { sameConfig }
5390 * };
5391 */
5392var eventTypes$4 = {};
5393var topLevelEventsToDispatchConfig = {};
5394['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'toggle', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) {
5395 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5396 var onEvent = 'on' + capitalizedEvent;
5397 var topEvent = 'top' + capitalizedEvent;
5398
5399 var type = {
5400 phasedRegistrationNames: {
5401 bubbled: onEvent,
5402 captured: onEvent + 'Capture'
5403 },
5404 dependencies: [topEvent]
5405 };
5406 eventTypes$4[event] = type;
5407 topLevelEventsToDispatchConfig[topEvent] = type;
5408});
5409
5410// Only used in DEV for exhaustiveness validation.
5411var 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'];
5412
5413var SimpleEventPlugin = {
5414 eventTypes: eventTypes$4,
5415
5416 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5417 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
5418 if (!dispatchConfig) {
5419 return null;
5420 }
5421 var EventConstructor = void 0;
5422 switch (topLevelType) {
5423 case 'topKeyPress':
5424 // Firefox creates a keypress event for function keys too. This removes
5425 // the unwanted keypress events. Enter is however both printable and
5426 // non-printable. One would expect Tab to be as well (but it isn't).
5427 if (getEventCharCode(nativeEvent) === 0) {
5428 return null;
5429 }
5430 /* falls through */
5431 case 'topKeyDown':
5432 case 'topKeyUp':
5433 EventConstructor = SyntheticKeyboardEvent;
5434 break;
5435 case 'topBlur':
5436 case 'topFocus':
5437 EventConstructor = SyntheticFocusEvent;
5438 break;
5439 case 'topClick':
5440 // Firefox creates a click event on right mouse clicks. This removes the
5441 // unwanted click events.
5442 if (nativeEvent.button === 2) {
5443 return null;
5444 }
5445 /* falls through */
5446 case 'topDoubleClick':
5447 case 'topMouseDown':
5448 case 'topMouseMove':
5449 case 'topMouseUp':
5450 // TODO: Disabled elements should not respond to mouse events
5451 /* falls through */
5452 case 'topMouseOut':
5453 case 'topMouseOver':
5454 case 'topContextMenu':
5455 EventConstructor = SyntheticMouseEvent;
5456 break;
5457 case 'topDrag':
5458 case 'topDragEnd':
5459 case 'topDragEnter':
5460 case 'topDragExit':
5461 case 'topDragLeave':
5462 case 'topDragOver':
5463 case 'topDragStart':
5464 case 'topDrop':
5465 EventConstructor = SyntheticDragEvent;
5466 break;
5467 case 'topTouchCancel':
5468 case 'topTouchEnd':
5469 case 'topTouchMove':
5470 case 'topTouchStart':
5471 EventConstructor = SyntheticTouchEvent;
5472 break;
5473 case 'topAnimationEnd':
5474 case 'topAnimationIteration':
5475 case 'topAnimationStart':
5476 EventConstructor = SyntheticAnimationEvent;
5477 break;
5478 case 'topTransitionEnd':
5479 EventConstructor = SyntheticTransitionEvent;
5480 break;
5481 case 'topScroll':
5482 EventConstructor = SyntheticUIEvent;
5483 break;
5484 case 'topWheel':
5485 EventConstructor = SyntheticWheelEvent;
5486 break;
5487 case 'topCopy':
5488 case 'topCut':
5489 case 'topPaste':
5490 EventConstructor = SyntheticClipboardEvent;
5491 break;
5492 default:
5493 {
5494 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
5495 warning_1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
5496 }
5497 }
5498 // HTML Events
5499 // @see http://www.w3.org/TR/html5/index.html#events-0
5500 EventConstructor = SyntheticEvent$1;
5501 break;
5502 }
5503 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
5504 accumulateTwoPhaseDispatches(event);
5505 return event;
5506 }
5507};
5508
5509/**
5510 * Inject modules for resolving DOM hierarchy and plugin ordering.
5511 */
5512injection.injectEventPluginOrder(DOMEventPluginOrder);
5513injection$1.injectComponentTree(ReactDOMComponentTree);
5514
5515/**
5516 * Some important event plugins included by default (without having to require
5517 * them).
5518 */
5519injection.injectEventPluginsByName({
5520 SimpleEventPlugin: SimpleEventPlugin,
5521 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5522 ChangeEventPlugin: ChangeEventPlugin,
5523 SelectEventPlugin: SelectEventPlugin,
5524 BeforeInputEventPlugin: BeforeInputEventPlugin
5525});
5526
5527/**
5528 * Copyright (c) 2013-present, Facebook, Inc.
5529 *
5530 * This source code is licensed under the MIT license found in the
5531 * LICENSE file in the root directory of this source tree.
5532 *
5533 */
5534
5535
5536
5537var emptyObject = {};
5538
5539{
5540 Object.freeze(emptyObject);
5541}
5542
5543var emptyObject_1 = emptyObject;
5544
5545var valueStack = [];
5546
5547var fiberStack = void 0;
5548
5549{
5550 fiberStack = [];
5551}
5552
5553var index = -1;
5554
5555function createCursor(defaultValue) {
5556 return {
5557 current: defaultValue
5558 };
5559}
5560
5561
5562
5563function pop(cursor, fiber) {
5564 if (index < 0) {
5565 {
5566 warning_1(false, 'Unexpected pop.');
5567 }
5568 return;
5569 }
5570
5571 {
5572 if (fiber !== fiberStack[index]) {
5573 warning_1(false, 'Unexpected Fiber popped.');
5574 }
5575 }
5576
5577 cursor.current = valueStack[index];
5578
5579 valueStack[index] = null;
5580
5581 {
5582 fiberStack[index] = null;
5583 }
5584
5585 index--;
5586}
5587
5588function push(cursor, value, fiber) {
5589 index++;
5590
5591 valueStack[index] = cursor.current;
5592
5593 {
5594 fiberStack[index] = fiber;
5595 }
5596
5597 cursor.current = value;
5598}
5599
5600function reset$1() {
5601 while (index > -1) {
5602 valueStack[index] = null;
5603
5604 {
5605 fiberStack[index] = null;
5606 }
5607
5608 index--;
5609 }
5610}
5611
5612var enableAsyncSubtreeAPI = true;
5613// Exports ReactDOM.createRoot
5614var enableCreateRoot = false;
5615var enableUserTimingAPI = true;
5616
5617// Mutating mode (React DOM, React ART, React Native):
5618var enableMutatingReconciler = true;
5619// Experimental noop mode (currently unused):
5620var enableNoopReconciler = false;
5621// Experimental persistent mode (CS):
5622var enablePersistentReconciler = false;
5623
5624// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
5625var debugRenderPhaseSideEffects = false;
5626
5627// Only used in www builds.
5628
5629// Prefix measurements so that it's possible to filter them.
5630// Longer prefixes are hard to read in DevTools.
5631var reactEmoji = '\u269B';
5632var warningEmoji = '\u26D4';
5633var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
5634
5635// Keep track of current fiber so that we know the path to unwind on pause.
5636// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5637var currentFiber = null;
5638// If we're in the middle of user code, which fiber and method is it?
5639// Reusing `currentFiber` would be confusing for this because user code fiber
5640// can change during commit phase too, but we don't need to unwind it (since
5641// lifecycles in the commit phase don't resemble a tree).
5642var currentPhase = null;
5643var currentPhaseFiber = null;
5644// Did lifecycle hook schedule an update? This is often a performance problem,
5645// so we will keep track of it, and include it in the report.
5646// Track commits caused by cascading updates.
5647var isCommitting = false;
5648var hasScheduledUpdateInCurrentCommit = false;
5649var hasScheduledUpdateInCurrentPhase = false;
5650var commitCountInCurrentWorkLoop = 0;
5651var effectCountInCurrentCommit = 0;
5652var isWaitingForCallback = false;
5653// During commits, we only show a measurement once per method name
5654// to avoid stretch the commit phase with measurement overhead.
5655var labelsInCurrentCommit = new Set();
5656
5657var formatMarkName = function (markName) {
5658 return reactEmoji + ' ' + markName;
5659};
5660
5661var formatLabel = function (label, warning) {
5662 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
5663 var suffix = warning ? ' Warning: ' + warning : '';
5664 return '' + prefix + label + suffix;
5665};
5666
5667var beginMark = function (markName) {
5668 performance.mark(formatMarkName(markName));
5669};
5670
5671var clearMark = function (markName) {
5672 performance.clearMarks(formatMarkName(markName));
5673};
5674
5675var endMark = function (label, markName, warning) {
5676 var formattedMarkName = formatMarkName(markName);
5677 var formattedLabel = formatLabel(label, warning);
5678 try {
5679 performance.measure(formattedLabel, formattedMarkName);
5680 } catch (err) {}
5681 // If previous mark was missing for some reason, this will throw.
5682 // This could only happen if React crashed in an unexpected place earlier.
5683 // Don't pile on with more errors.
5684
5685 // Clear marks immediately to avoid growing buffer.
5686 performance.clearMarks(formattedMarkName);
5687 performance.clearMeasures(formattedLabel);
5688};
5689
5690var getFiberMarkName = function (label, debugID) {
5691 return label + ' (#' + debugID + ')';
5692};
5693
5694var getFiberLabel = function (componentName, isMounted, phase) {
5695 if (phase === null) {
5696 // These are composite component total time measurements.
5697 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
5698 } else {
5699 // Composite component methods.
5700 return componentName + '.' + phase;
5701 }
5702};
5703
5704var beginFiberMark = function (fiber, phase) {
5705 var componentName = getComponentName(fiber) || 'Unknown';
5706 var debugID = fiber._debugID;
5707 var isMounted = fiber.alternate !== null;
5708 var label = getFiberLabel(componentName, isMounted, phase);
5709
5710 if (isCommitting && labelsInCurrentCommit.has(label)) {
5711 // During the commit phase, we don't show duplicate labels because
5712 // there is a fixed overhead for every measurement, and we don't
5713 // want to stretch the commit phase beyond necessary.
5714 return false;
5715 }
5716 labelsInCurrentCommit.add(label);
5717
5718 var markName = getFiberMarkName(label, debugID);
5719 beginMark(markName);
5720 return true;
5721};
5722
5723var clearFiberMark = function (fiber, phase) {
5724 var componentName = getComponentName(fiber) || 'Unknown';
5725 var debugID = fiber._debugID;
5726 var isMounted = fiber.alternate !== null;
5727 var label = getFiberLabel(componentName, isMounted, phase);
5728 var markName = getFiberMarkName(label, debugID);
5729 clearMark(markName);
5730};
5731
5732var endFiberMark = function (fiber, phase, warning) {
5733 var componentName = getComponentName(fiber) || 'Unknown';
5734 var debugID = fiber._debugID;
5735 var isMounted = fiber.alternate !== null;
5736 var label = getFiberLabel(componentName, isMounted, phase);
5737 var markName = getFiberMarkName(label, debugID);
5738 endMark(label, markName, warning);
5739};
5740
5741var shouldIgnoreFiber = function (fiber) {
5742 // Host components should be skipped in the timeline.
5743 // We could check typeof fiber.type, but does this work with RN?
5744 switch (fiber.tag) {
5745 case HostRoot:
5746 case HostComponent:
5747 case HostText:
5748 case HostPortal:
5749 case CallComponent:
5750 case ReturnComponent:
5751 case Fragment:
5752 return true;
5753 default:
5754 return false;
5755 }
5756};
5757
5758var clearPendingPhaseMeasurement = function () {
5759 if (currentPhase !== null && currentPhaseFiber !== null) {
5760 clearFiberMark(currentPhaseFiber, currentPhase);
5761 }
5762 currentPhaseFiber = null;
5763 currentPhase = null;
5764 hasScheduledUpdateInCurrentPhase = false;
5765};
5766
5767var pauseTimers = function () {
5768 // Stops all currently active measurements so that they can be resumed
5769 // if we continue in a later deferred loop from the same unit of work.
5770 var fiber = currentFiber;
5771 while (fiber) {
5772 if (fiber._debugIsCurrentlyTiming) {
5773 endFiberMark(fiber, null, null);
5774 }
5775 fiber = fiber['return'];
5776 }
5777};
5778
5779var resumeTimersRecursively = function (fiber) {
5780 if (fiber['return'] !== null) {
5781 resumeTimersRecursively(fiber['return']);
5782 }
5783 if (fiber._debugIsCurrentlyTiming) {
5784 beginFiberMark(fiber, null);
5785 }
5786};
5787
5788var resumeTimers = function () {
5789 // Resumes all measurements that were active during the last deferred loop.
5790 if (currentFiber !== null) {
5791 resumeTimersRecursively(currentFiber);
5792 }
5793};
5794
5795function recordEffect() {
5796 if (enableUserTimingAPI) {
5797 effectCountInCurrentCommit++;
5798 }
5799}
5800
5801function recordScheduleUpdate() {
5802 if (enableUserTimingAPI) {
5803 if (isCommitting) {
5804 hasScheduledUpdateInCurrentCommit = true;
5805 }
5806 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
5807 hasScheduledUpdateInCurrentPhase = true;
5808 }
5809 }
5810}
5811
5812function startRequestCallbackTimer() {
5813 if (enableUserTimingAPI) {
5814 if (supportsUserTiming && !isWaitingForCallback) {
5815 isWaitingForCallback = true;
5816 beginMark('(Waiting for async callback...)');
5817 }
5818 }
5819}
5820
5821function stopRequestCallbackTimer(didExpire) {
5822 if (enableUserTimingAPI) {
5823 if (supportsUserTiming) {
5824 isWaitingForCallback = false;
5825 var warning = didExpire ? 'React was blocked by main thread' : null;
5826 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
5827 }
5828 }
5829}
5830
5831function startWorkTimer(fiber) {
5832 if (enableUserTimingAPI) {
5833 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5834 return;
5835 }
5836 // If we pause, this is the fiber to unwind from.
5837 currentFiber = fiber;
5838 if (!beginFiberMark(fiber, null)) {
5839 return;
5840 }
5841 fiber._debugIsCurrentlyTiming = true;
5842 }
5843}
5844
5845function cancelWorkTimer(fiber) {
5846 if (enableUserTimingAPI) {
5847 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5848 return;
5849 }
5850 // Remember we shouldn't complete measurement for this fiber.
5851 // Otherwise flamechart will be deep even for small updates.
5852 fiber._debugIsCurrentlyTiming = false;
5853 clearFiberMark(fiber, null);
5854 }
5855}
5856
5857function stopWorkTimer(fiber) {
5858 if (enableUserTimingAPI) {
5859 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5860 return;
5861 }
5862 // If we pause, its parent is the fiber to unwind from.
5863 currentFiber = fiber['return'];
5864 if (!fiber._debugIsCurrentlyTiming) {
5865 return;
5866 }
5867 fiber._debugIsCurrentlyTiming = false;
5868 endFiberMark(fiber, null, null);
5869 }
5870}
5871
5872function stopFailedWorkTimer(fiber) {
5873 if (enableUserTimingAPI) {
5874 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5875 return;
5876 }
5877 // If we pause, its parent is the fiber to unwind from.
5878 currentFiber = fiber['return'];
5879 if (!fiber._debugIsCurrentlyTiming) {
5880 return;
5881 }
5882 fiber._debugIsCurrentlyTiming = false;
5883 var warning = 'An error was thrown inside this error boundary';
5884 endFiberMark(fiber, null, warning);
5885 }
5886}
5887
5888function startPhaseTimer(fiber, phase) {
5889 if (enableUserTimingAPI) {
5890 if (!supportsUserTiming) {
5891 return;
5892 }
5893 clearPendingPhaseMeasurement();
5894 if (!beginFiberMark(fiber, phase)) {
5895 return;
5896 }
5897 currentPhaseFiber = fiber;
5898 currentPhase = phase;
5899 }
5900}
5901
5902function stopPhaseTimer() {
5903 if (enableUserTimingAPI) {
5904 if (!supportsUserTiming) {
5905 return;
5906 }
5907 if (currentPhase !== null && currentPhaseFiber !== null) {
5908 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
5909 endFiberMark(currentPhaseFiber, currentPhase, warning);
5910 }
5911 currentPhase = null;
5912 currentPhaseFiber = null;
5913 }
5914}
5915
5916function startWorkLoopTimer(nextUnitOfWork) {
5917 if (enableUserTimingAPI) {
5918 currentFiber = nextUnitOfWork;
5919 if (!supportsUserTiming) {
5920 return;
5921 }
5922 commitCountInCurrentWorkLoop = 0;
5923 // This is top level call.
5924 // Any other measurements are performed within.
5925 beginMark('(React Tree Reconciliation)');
5926 // Resume any measurements that were in progress during the last loop.
5927 resumeTimers();
5928 }
5929}
5930
5931function stopWorkLoopTimer(interruptedBy) {
5932 if (enableUserTimingAPI) {
5933 if (!supportsUserTiming) {
5934 return;
5935 }
5936 var warning = null;
5937 if (interruptedBy !== null) {
5938 if (interruptedBy.tag === HostRoot) {
5939 warning = 'A top-level update interrupted the previous render';
5940 } else {
5941 var componentName = getComponentName(interruptedBy) || 'Unknown';
5942 warning = 'An update to ' + componentName + ' interrupted the previous render';
5943 }
5944 } else if (commitCountInCurrentWorkLoop > 1) {
5945 warning = 'There were cascading updates';
5946 }
5947 commitCountInCurrentWorkLoop = 0;
5948 // Pause any measurements until the next loop.
5949 pauseTimers();
5950 endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning);
5951 }
5952}
5953
5954function startCommitTimer() {
5955 if (enableUserTimingAPI) {
5956 if (!supportsUserTiming) {
5957 return;
5958 }
5959 isCommitting = true;
5960 hasScheduledUpdateInCurrentCommit = false;
5961 labelsInCurrentCommit.clear();
5962 beginMark('(Committing Changes)');
5963 }
5964}
5965
5966function stopCommitTimer() {
5967 if (enableUserTimingAPI) {
5968 if (!supportsUserTiming) {
5969 return;
5970 }
5971
5972 var warning = null;
5973 if (hasScheduledUpdateInCurrentCommit) {
5974 warning = 'Lifecycle hook scheduled a cascading update';
5975 } else if (commitCountInCurrentWorkLoop > 0) {
5976 warning = 'Caused by a cascading update in earlier commit';
5977 }
5978 hasScheduledUpdateInCurrentCommit = false;
5979 commitCountInCurrentWorkLoop++;
5980 isCommitting = false;
5981 labelsInCurrentCommit.clear();
5982
5983 endMark('(Committing Changes)', '(Committing Changes)', warning);
5984 }
5985}
5986
5987function startCommitHostEffectsTimer() {
5988 if (enableUserTimingAPI) {
5989 if (!supportsUserTiming) {
5990 return;
5991 }
5992 effectCountInCurrentCommit = 0;
5993 beginMark('(Committing Host Effects)');
5994 }
5995}
5996
5997function stopCommitHostEffectsTimer() {
5998 if (enableUserTimingAPI) {
5999 if (!supportsUserTiming) {
6000 return;
6001 }
6002 var count = effectCountInCurrentCommit;
6003 effectCountInCurrentCommit = 0;
6004 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
6005 }
6006}
6007
6008function startCommitLifeCyclesTimer() {
6009 if (enableUserTimingAPI) {
6010 if (!supportsUserTiming) {
6011 return;
6012 }
6013 effectCountInCurrentCommit = 0;
6014 beginMark('(Calling Lifecycle Methods)');
6015 }
6016}
6017
6018function stopCommitLifeCyclesTimer() {
6019 if (enableUserTimingAPI) {
6020 if (!supportsUserTiming) {
6021 return;
6022 }
6023 var count = effectCountInCurrentCommit;
6024 effectCountInCurrentCommit = 0;
6025 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
6026 }
6027}
6028
6029var warnedAboutMissingGetChildContext = void 0;
6030
6031{
6032 warnedAboutMissingGetChildContext = {};
6033}
6034
6035// A cursor to the current merged context object on the stack.
6036var contextStackCursor = createCursor(emptyObject_1);
6037// A cursor to a boolean indicating whether the context has changed.
6038var didPerformWorkStackCursor = createCursor(false);
6039// Keep track of the previous context object that was on the stack.
6040// We use this to get access to the parent context after we have already
6041// pushed the next context provider, and now need to merge their contexts.
6042var previousContext = emptyObject_1;
6043
6044function getUnmaskedContext(workInProgress) {
6045 var hasOwnContext = isContextProvider(workInProgress);
6046 if (hasOwnContext) {
6047 // If the fiber is a context provider itself, when we read its context
6048 // we have already pushed its own child context on the stack. A context
6049 // provider should not "see" its own child context. Therefore we read the
6050 // previous (parent) context instead for a context provider.
6051 return previousContext;
6052 }
6053 return contextStackCursor.current;
6054}
6055
6056function cacheContext(workInProgress, unmaskedContext, maskedContext) {
6057 var instance = workInProgress.stateNode;
6058 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
6059 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
6060}
6061
6062function getMaskedContext(workInProgress, unmaskedContext) {
6063 var type = workInProgress.type;
6064 var contextTypes = type.contextTypes;
6065 if (!contextTypes) {
6066 return emptyObject_1;
6067 }
6068
6069 // Avoid recreating masked context unless unmasked context has changed.
6070 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
6071 // This may trigger infinite loops if componentWillReceiveProps calls setState.
6072 var instance = workInProgress.stateNode;
6073 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
6074 return instance.__reactInternalMemoizedMaskedChildContext;
6075 }
6076
6077 var context = {};
6078 for (var key in contextTypes) {
6079 context[key] = unmaskedContext[key];
6080 }
6081
6082 {
6083 var name = getComponentName(workInProgress) || 'Unknown';
6084 checkPropTypes_1(contextTypes, context, 'context', name, ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6085 }
6086
6087 // Cache unmasked context so we can avoid recreating masked context unless necessary.
6088 // Context is created before the class component is instantiated so check for instance.
6089 if (instance) {
6090 cacheContext(workInProgress, unmaskedContext, context);
6091 }
6092
6093 return context;
6094}
6095
6096function hasContextChanged() {
6097 return didPerformWorkStackCursor.current;
6098}
6099
6100function isContextConsumer(fiber) {
6101 return fiber.tag === ClassComponent && fiber.type.contextTypes != null;
6102}
6103
6104function isContextProvider(fiber) {
6105 return fiber.tag === ClassComponent && fiber.type.childContextTypes != null;
6106}
6107
6108function popContextProvider(fiber) {
6109 if (!isContextProvider(fiber)) {
6110 return;
6111 }
6112
6113 pop(didPerformWorkStackCursor, fiber);
6114 pop(contextStackCursor, fiber);
6115}
6116
6117function popTopLevelContextObject(fiber) {
6118 pop(didPerformWorkStackCursor, fiber);
6119 pop(contextStackCursor, fiber);
6120}
6121
6122function pushTopLevelContextObject(fiber, context, didChange) {
6123 !(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;
6124
6125 push(contextStackCursor, context, fiber);
6126 push(didPerformWorkStackCursor, didChange, fiber);
6127}
6128
6129function processChildContext(fiber, parentContext) {
6130 var instance = fiber.stateNode;
6131 var childContextTypes = fiber.type.childContextTypes;
6132
6133 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
6134 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
6135 if (typeof instance.getChildContext !== 'function') {
6136 {
6137 var componentName = getComponentName(fiber) || 'Unknown';
6138
6139 if (!warnedAboutMissingGetChildContext[componentName]) {
6140 warnedAboutMissingGetChildContext[componentName] = true;
6141 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);
6142 }
6143 }
6144 return parentContext;
6145 }
6146
6147 var childContext = void 0;
6148 {
6149 ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
6150 }
6151 startPhaseTimer(fiber, 'getChildContext');
6152 childContext = instance.getChildContext();
6153 stopPhaseTimer();
6154 {
6155 ReactDebugCurrentFiber.setCurrentPhase(null);
6156 }
6157 for (var contextKey in childContext) {
6158 !(contextKey in childContextTypes) ? invariant_1(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(fiber) || 'Unknown', contextKey) : void 0;
6159 }
6160 {
6161 var name = getComponentName(fiber) || 'Unknown';
6162 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
6163 // In practice, there is one case in which we won't get a stack. It's when
6164 // somebody calls unstable_renderSubtreeIntoContainer() and we process
6165 // context from the parent component instance. The stack will be missing
6166 // because it's outside of the reconciliation, and so the pointer has not
6167 // been set. This is rare and doesn't matter. We'll also remove that API.
6168 ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6169 }
6170
6171 return _assign({}, parentContext, childContext);
6172}
6173
6174function pushContextProvider(workInProgress) {
6175 if (!isContextProvider(workInProgress)) {
6176 return false;
6177 }
6178
6179 var instance = workInProgress.stateNode;
6180 // We push the context as early as possible to ensure stack integrity.
6181 // If the instance does not exist yet, we will push null at first,
6182 // and replace it on the stack later when invalidating the context.
6183 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject_1;
6184
6185 // Remember the parent context so we can merge with it later.
6186 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
6187 previousContext = contextStackCursor.current;
6188 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
6189 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
6190
6191 return true;
6192}
6193
6194function invalidateContextProvider(workInProgress, didChange) {
6195 var instance = workInProgress.stateNode;
6196 !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;
6197
6198 if (didChange) {
6199 // Merge parent and own context.
6200 // Skip this if we're not updating due to sCU.
6201 // This avoids unnecessarily recomputing memoized values.
6202 var mergedContext = processChildContext(workInProgress, previousContext);
6203 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
6204
6205 // Replace the old (or empty) context with the new one.
6206 // It is important to unwind the context in the reverse order.
6207 pop(didPerformWorkStackCursor, workInProgress);
6208 pop(contextStackCursor, workInProgress);
6209 // Now push the new context and mark that it has changed.
6210 push(contextStackCursor, mergedContext, workInProgress);
6211 push(didPerformWorkStackCursor, didChange, workInProgress);
6212 } else {
6213 pop(didPerformWorkStackCursor, workInProgress);
6214 push(didPerformWorkStackCursor, didChange, workInProgress);
6215 }
6216}
6217
6218function resetContext() {
6219 previousContext = emptyObject_1;
6220 contextStackCursor.current = emptyObject_1;
6221 didPerformWorkStackCursor.current = false;
6222}
6223
6224function findCurrentUnmaskedContext(fiber) {
6225 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
6226 // makes sense elsewhere
6227 !(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;
6228
6229 var node = fiber;
6230 while (node.tag !== HostRoot) {
6231 if (isContextProvider(node)) {
6232 return node.stateNode.__reactInternalMemoizedMergedChildContext;
6233 }
6234 var parent = node['return'];
6235 !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;
6236 node = parent;
6237 }
6238 return node.stateNode.context;
6239}
6240
6241var NoWork = 0; // TODO: Use an opaque type once ESLint et al support the syntax
6242
6243var Sync = 1;
6244var Never = 2147483647; // Max int32: Math.pow(2, 31) - 1
6245
6246var UNIT_SIZE = 10;
6247var MAGIC_NUMBER_OFFSET = 2;
6248
6249// 1 unit of expiration time represents 10ms.
6250function msToExpirationTime(ms) {
6251 // Always add an offset so that we don't clash with the magic number for NoWork.
6252 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET;
6253}
6254
6255function expirationTimeToMs(expirationTime) {
6256 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE;
6257}
6258
6259function ceiling(num, precision) {
6260 return ((num / precision | 0) + 1) * precision;
6261}
6262
6263function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6264 return ceiling(currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
6265}
6266
6267var NoContext = 0;
6268var AsyncUpdates = 1;
6269
6270var hasBadMapPolyfill = void 0;
6271
6272{
6273 hasBadMapPolyfill = false;
6274 try {
6275 var nonExtensibleObject = Object.preventExtensions({});
6276 var testMap = new Map([[nonExtensibleObject, null]]);
6277 var testSet = new Set([nonExtensibleObject]);
6278 // This is necessary for Rollup to not consider these unused.
6279 // https://github.com/rollup/rollup/issues/1771
6280 // TODO: we can remove these if Rollup fixes the bug.
6281 testMap.set(0, 0);
6282 testSet.add(0);
6283 } catch (e) {
6284 // TODO: Consider warning about bad polyfills
6285 hasBadMapPolyfill = true;
6286 }
6287}
6288
6289// A Fiber is work on a Component that needs to be done or was done. There can
6290// be more than one per component.
6291
6292
6293var debugCounter = void 0;
6294
6295{
6296 debugCounter = 1;
6297}
6298
6299function FiberNode(tag, pendingProps, key, internalContextTag) {
6300 // Instance
6301 this.tag = tag;
6302 this.key = key;
6303 this.type = null;
6304 this.stateNode = null;
6305
6306 // Fiber
6307 this['return'] = null;
6308 this.child = null;
6309 this.sibling = null;
6310 this.index = 0;
6311
6312 this.ref = null;
6313
6314 this.pendingProps = pendingProps;
6315 this.memoizedProps = null;
6316 this.updateQueue = null;
6317 this.memoizedState = null;
6318
6319 this.internalContextTag = internalContextTag;
6320
6321 // Effects
6322 this.effectTag = NoEffect;
6323 this.nextEffect = null;
6324
6325 this.firstEffect = null;
6326 this.lastEffect = null;
6327
6328 this.expirationTime = NoWork;
6329
6330 this.alternate = null;
6331
6332 {
6333 this._debugID = debugCounter++;
6334 this._debugSource = null;
6335 this._debugOwner = null;
6336 this._debugIsCurrentlyTiming = false;
6337 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
6338 Object.preventExtensions(this);
6339 }
6340 }
6341}
6342
6343// This is a constructor function, rather than a POJO constructor, still
6344// please ensure we do the following:
6345// 1) Nobody should add any instance methods on this. Instance methods can be
6346// more difficult to predict when they get optimized and they are almost
6347// never inlined properly in static compilers.
6348// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
6349// always know when it is a fiber.
6350// 3) We might want to experiment with using numeric keys since they are easier
6351// to optimize in a non-JIT environment.
6352// 4) We can easily go from a constructor to a createFiber object literal if that
6353// is faster.
6354// 5) It should be easy to port this to a C struct and keep a C implementation
6355// compatible.
6356var createFiber = function (tag, pendingProps, key, internalContextTag) {
6357 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
6358 return new FiberNode(tag, pendingProps, key, internalContextTag);
6359};
6360
6361function shouldConstruct(Component) {
6362 return !!(Component.prototype && Component.prototype.isReactComponent);
6363}
6364
6365// This is used to create an alternate fiber to do work on.
6366function createWorkInProgress(current, pendingProps, expirationTime) {
6367 var workInProgress = current.alternate;
6368 if (workInProgress === null) {
6369 // We use a double buffering pooling technique because we know that we'll
6370 // only ever need at most two versions of a tree. We pool the "other" unused
6371 // node that we're free to reuse. This is lazily created to avoid allocating
6372 // extra objects for things that are never updated. It also allow us to
6373 // reclaim the extra memory if needed.
6374 workInProgress = createFiber(current.tag, pendingProps, current.key, current.internalContextTag);
6375 workInProgress.type = current.type;
6376 workInProgress.stateNode = current.stateNode;
6377
6378 {
6379 // DEV-only fields
6380 workInProgress._debugID = current._debugID;
6381 workInProgress._debugSource = current._debugSource;
6382 workInProgress._debugOwner = current._debugOwner;
6383 }
6384
6385 workInProgress.alternate = current;
6386 current.alternate = workInProgress;
6387 } else {
6388 workInProgress.pendingProps = pendingProps;
6389
6390 // We already have an alternate.
6391 // Reset the effect tag.
6392 workInProgress.effectTag = NoEffect;
6393
6394 // The effect list is no longer valid.
6395 workInProgress.nextEffect = null;
6396 workInProgress.firstEffect = null;
6397 workInProgress.lastEffect = null;
6398 }
6399
6400 workInProgress.expirationTime = expirationTime;
6401
6402 workInProgress.child = current.child;
6403 workInProgress.memoizedProps = current.memoizedProps;
6404 workInProgress.memoizedState = current.memoizedState;
6405 workInProgress.updateQueue = current.updateQueue;
6406
6407 // These will be overridden during the parent's reconciliation
6408 workInProgress.sibling = current.sibling;
6409 workInProgress.index = current.index;
6410 workInProgress.ref = current.ref;
6411
6412 return workInProgress;
6413}
6414
6415function createHostRootFiber(isAsync) {
6416 var internalContextTag = isAsync ? AsyncUpdates : NoContext;
6417 return createFiber(HostRoot, null, null, internalContextTag);
6418}
6419
6420function createFiberFromElement(element, internalContextTag, expirationTime) {
6421 var owner = null;
6422 {
6423 owner = element._owner;
6424 }
6425
6426 var fiber = void 0;
6427 var type = element.type;
6428 var key = element.key;
6429 var pendingProps = element.props;
6430 if (typeof type === 'function') {
6431 fiber = shouldConstruct(type) ? createFiber(ClassComponent, pendingProps, key, internalContextTag) : createFiber(IndeterminateComponent, pendingProps, key, internalContextTag);
6432 fiber.type = type;
6433 } else if (typeof type === 'string') {
6434 fiber = createFiber(HostComponent, pendingProps, key, internalContextTag);
6435 fiber.type = type;
6436 } else {
6437 switch (type) {
6438 case REACT_FRAGMENT_TYPE:
6439 return createFiberFromFragment(pendingProps.children, internalContextTag, expirationTime, key);
6440 case REACT_CALL_TYPE:
6441 fiber = createFiber(CallComponent, pendingProps, key, internalContextTag);
6442 fiber.type = REACT_CALL_TYPE;
6443 break;
6444 case REACT_RETURN_TYPE:
6445 fiber = createFiber(ReturnComponent, pendingProps, key, internalContextTag);
6446 fiber.type = REACT_RETURN_TYPE;
6447 break;
6448 default:
6449 {
6450 if (typeof type === 'object' && type !== null && typeof type.tag === 'number') {
6451 // Currently assumed to be a continuation and therefore is a
6452 // fiber already.
6453 // TODO: The yield system is currently broken for updates in some
6454 // cases. The reified yield stores a fiber, but we don't know which
6455 // fiber that is; the current or a workInProgress? When the
6456 // continuation gets rendered here we don't know if we can reuse that
6457 // fiber or if we need to clone it. There is probably a clever way to
6458 // restructure this.
6459 fiber = type;
6460 fiber.pendingProps = pendingProps;
6461 } else {
6462 var info = '';
6463 {
6464 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
6465 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.';
6466 }
6467 var ownerName = owner ? getComponentName(owner) : null;
6468 if (ownerName) {
6469 info += '\n\nCheck the render method of `' + ownerName + '`.';
6470 }
6471 }
6472 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);
6473 }
6474 }
6475 }
6476 }
6477
6478 {
6479 fiber._debugSource = element._source;
6480 fiber._debugOwner = element._owner;
6481 }
6482
6483 fiber.expirationTime = expirationTime;
6484
6485 return fiber;
6486}
6487
6488function createFiberFromFragment(elements, internalContextTag, expirationTime, key) {
6489 var fiber = createFiber(Fragment, elements, key, internalContextTag);
6490 fiber.expirationTime = expirationTime;
6491 return fiber;
6492}
6493
6494function createFiberFromText(content, internalContextTag, expirationTime) {
6495 var fiber = createFiber(HostText, content, null, internalContextTag);
6496 fiber.expirationTime = expirationTime;
6497 return fiber;
6498}
6499
6500function createFiberFromHostInstanceForDeletion() {
6501 var fiber = createFiber(HostComponent, null, null, NoContext);
6502 fiber.type = 'DELETED';
6503 return fiber;
6504}
6505
6506function createFiberFromPortal(portal, internalContextTag, expirationTime) {
6507 var pendingProps = portal.children !== null ? portal.children : [];
6508 var fiber = createFiber(HostPortal, pendingProps, portal.key, internalContextTag);
6509 fiber.expirationTime = expirationTime;
6510 fiber.stateNode = {
6511 containerInfo: portal.containerInfo,
6512 pendingChildren: null, // Used by persistent updates
6513 implementation: portal.implementation
6514 };
6515 return fiber;
6516}
6517
6518// TODO: This should be lifted into the renderer.
6519
6520
6521function createFiberRoot(containerInfo, isAsync, hydrate) {
6522 // Cyclic construction. This cheats the type system right now because
6523 // stateNode is any.
6524 var uninitializedFiber = createHostRootFiber(isAsync);
6525 var root = {
6526 current: uninitializedFiber,
6527 containerInfo: containerInfo,
6528 pendingChildren: null,
6529 remainingExpirationTime: NoWork,
6530 isReadyForCommit: false,
6531 finishedWork: null,
6532 context: null,
6533 pendingContext: null,
6534 hydrate: hydrate,
6535 firstBatch: null,
6536 nextScheduledRoot: null
6537 };
6538 uninitializedFiber.stateNode = root;
6539 return root;
6540}
6541
6542var onCommitFiberRoot = null;
6543var onCommitFiberUnmount = null;
6544var hasLoggedError = false;
6545
6546function catchErrors(fn) {
6547 return function (arg) {
6548 try {
6549 return fn(arg);
6550 } catch (err) {
6551 if (true && !hasLoggedError) {
6552 hasLoggedError = true;
6553 warning_1(false, 'React DevTools encountered an error: %s', err);
6554 }
6555 }
6556 };
6557}
6558
6559function injectInternals(internals) {
6560 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
6561 // No DevTools
6562 return false;
6563 }
6564 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
6565 if (hook.isDisabled) {
6566 // This isn't a real property on the hook, but it can be set to opt out
6567 // of DevTools integration and associated warnings and logs.
6568 // https://github.com/facebook/react/issues/3877
6569 return true;
6570 }
6571 if (!hook.supportsFiber) {
6572 {
6573 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');
6574 }
6575 // DevTools exists, even though it doesn't support Fiber.
6576 return true;
6577 }
6578 try {
6579 var rendererID = hook.inject(internals);
6580 // We have successfully injected, so now it is safe to set up hooks.
6581 onCommitFiberRoot = catchErrors(function (root) {
6582 return hook.onCommitFiberRoot(rendererID, root);
6583 });
6584 onCommitFiberUnmount = catchErrors(function (fiber) {
6585 return hook.onCommitFiberUnmount(rendererID, fiber);
6586 });
6587 } catch (err) {
6588 // Catch all errors because it is unsafe to throw during initialization.
6589 {
6590 warning_1(false, 'React DevTools encountered an error: %s.', err);
6591 }
6592 }
6593 // DevTools exists
6594 return true;
6595}
6596
6597function onCommitRoot(root) {
6598 if (typeof onCommitFiberRoot === 'function') {
6599 onCommitFiberRoot(root);
6600 }
6601}
6602
6603function onCommitUnmount(fiber) {
6604 if (typeof onCommitFiberUnmount === 'function') {
6605 onCommitFiberUnmount(fiber);
6606 }
6607}
6608
6609var didWarnUpdateInsideUpdate = void 0;
6610
6611{
6612 didWarnUpdateInsideUpdate = false;
6613}
6614
6615// Callbacks are not validated until invocation
6616
6617
6618// Singly linked-list of updates. When an update is scheduled, it is added to
6619// the queue of the current fiber and the work-in-progress fiber. The two queues
6620// are separate but they share a persistent structure.
6621//
6622// During reconciliation, updates are removed from the work-in-progress fiber,
6623// but they remain on the current fiber. That ensures that if a work-in-progress
6624// is aborted, the aborted updates are recovered by cloning from current.
6625//
6626// The work-in-progress queue is always a subset of the current queue.
6627//
6628// When the tree is committed, the work-in-progress becomes the current.
6629
6630
6631function createUpdateQueue(baseState) {
6632 var queue = {
6633 baseState: baseState,
6634 expirationTime: NoWork,
6635 first: null,
6636 last: null,
6637 callbackList: null,
6638 hasForceUpdate: false,
6639 isInitialized: false
6640 };
6641 {
6642 queue.isProcessing = false;
6643 }
6644 return queue;
6645}
6646
6647function insertUpdateIntoQueue(queue, update) {
6648 // Append the update to the end of the list.
6649 if (queue.last === null) {
6650 // Queue is empty
6651 queue.first = queue.last = update;
6652 } else {
6653 queue.last.next = update;
6654 queue.last = update;
6655 }
6656 if (queue.expirationTime === NoWork || queue.expirationTime > update.expirationTime) {
6657 queue.expirationTime = update.expirationTime;
6658 }
6659}
6660
6661function insertUpdateIntoFiber(fiber, update) {
6662 // We'll have at least one and at most two distinct update queues.
6663 var alternateFiber = fiber.alternate;
6664 var queue1 = fiber.updateQueue;
6665 if (queue1 === null) {
6666 // TODO: We don't know what the base state will be until we begin work.
6667 // It depends on which fiber is the next current. Initialize with an empty
6668 // base state, then set to the memoizedState when rendering. Not super
6669 // happy with this approach.
6670 queue1 = fiber.updateQueue = createUpdateQueue(null);
6671 }
6672
6673 var queue2 = void 0;
6674 if (alternateFiber !== null) {
6675 queue2 = alternateFiber.updateQueue;
6676 if (queue2 === null) {
6677 queue2 = alternateFiber.updateQueue = createUpdateQueue(null);
6678 }
6679 } else {
6680 queue2 = null;
6681 }
6682 queue2 = queue2 !== queue1 ? queue2 : null;
6683
6684 // Warn if an update is scheduled from inside an updater function.
6685 {
6686 if ((queue1.isProcessing || queue2 !== null && queue2.isProcessing) && !didWarnUpdateInsideUpdate) {
6687 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.');
6688 didWarnUpdateInsideUpdate = true;
6689 }
6690 }
6691
6692 // If there's only one queue, add the update to that queue and exit.
6693 if (queue2 === null) {
6694 insertUpdateIntoQueue(queue1, update);
6695 return;
6696 }
6697
6698 // If either queue is empty, we need to add to both queues.
6699 if (queue1.last === null || queue2.last === null) {
6700 insertUpdateIntoQueue(queue1, update);
6701 insertUpdateIntoQueue(queue2, update);
6702 return;
6703 }
6704
6705 // If both lists are not empty, the last update is the same for both lists
6706 // because of structural sharing. So, we should only append to one of
6707 // the lists.
6708 insertUpdateIntoQueue(queue1, update);
6709 // But we still need to update the `last` pointer of queue2.
6710 queue2.last = update;
6711}
6712
6713function getUpdateExpirationTime(fiber) {
6714 if (fiber.tag !== ClassComponent && fiber.tag !== HostRoot) {
6715 return NoWork;
6716 }
6717 var updateQueue = fiber.updateQueue;
6718 if (updateQueue === null) {
6719 return NoWork;
6720 }
6721 return updateQueue.expirationTime;
6722}
6723
6724function getStateFromUpdate(update, instance, prevState, props) {
6725 var partialState = update.partialState;
6726 if (typeof partialState === 'function') {
6727 var updateFn = partialState;
6728
6729 // Invoke setState callback an extra time to help detect side-effects.
6730 if (debugRenderPhaseSideEffects) {
6731 updateFn.call(instance, prevState, props);
6732 }
6733
6734 return updateFn.call(instance, prevState, props);
6735 } else {
6736 return partialState;
6737 }
6738}
6739
6740function processUpdateQueue(current, workInProgress, queue, instance, props, renderExpirationTime) {
6741 if (current !== null && current.updateQueue === queue) {
6742 // We need to create a work-in-progress queue, by cloning the current queue.
6743 var currentQueue = queue;
6744 queue = workInProgress.updateQueue = {
6745 baseState: currentQueue.baseState,
6746 expirationTime: currentQueue.expirationTime,
6747 first: currentQueue.first,
6748 last: currentQueue.last,
6749 isInitialized: currentQueue.isInitialized,
6750 // These fields are no longer valid because they were already committed.
6751 // Reset them.
6752 callbackList: null,
6753 hasForceUpdate: false
6754 };
6755 }
6756
6757 {
6758 // Set this flag so we can warn if setState is called inside the update
6759 // function of another setState.
6760 queue.isProcessing = true;
6761 }
6762
6763 // Reset the remaining expiration time. If we skip over any updates, we'll
6764 // increase this accordingly.
6765 queue.expirationTime = NoWork;
6766
6767 // TODO: We don't know what the base state will be until we begin work.
6768 // It depends on which fiber is the next current. Initialize with an empty
6769 // base state, then set to the memoizedState when rendering. Not super
6770 // happy with this approach.
6771 var state = void 0;
6772 if (queue.isInitialized) {
6773 state = queue.baseState;
6774 } else {
6775 state = queue.baseState = workInProgress.memoizedState;
6776 queue.isInitialized = true;
6777 }
6778 var dontMutatePrevState = true;
6779 var update = queue.first;
6780 var didSkip = false;
6781 while (update !== null) {
6782 var updateExpirationTime = update.expirationTime;
6783 if (updateExpirationTime > renderExpirationTime) {
6784 // This update does not have sufficient priority. Skip it.
6785 var remainingExpirationTime = queue.expirationTime;
6786 if (remainingExpirationTime === NoWork || remainingExpirationTime > updateExpirationTime) {
6787 // Update the remaining expiration time.
6788 queue.expirationTime = updateExpirationTime;
6789 }
6790 if (!didSkip) {
6791 didSkip = true;
6792 queue.baseState = state;
6793 }
6794 // Continue to the next update.
6795 update = update.next;
6796 continue;
6797 }
6798
6799 // This update does have sufficient priority.
6800
6801 // If no previous updates were skipped, drop this update from the queue by
6802 // advancing the head of the list.
6803 if (!didSkip) {
6804 queue.first = update.next;
6805 if (queue.first === null) {
6806 queue.last = null;
6807 }
6808 }
6809
6810 // Process the update
6811 var _partialState = void 0;
6812 if (update.isReplace) {
6813 state = getStateFromUpdate(update, instance, state, props);
6814 dontMutatePrevState = true;
6815 } else {
6816 _partialState = getStateFromUpdate(update, instance, state, props);
6817 if (_partialState) {
6818 if (dontMutatePrevState) {
6819 // $FlowFixMe: Idk how to type this properly.
6820 state = _assign({}, state, _partialState);
6821 } else {
6822 state = _assign(state, _partialState);
6823 }
6824 dontMutatePrevState = false;
6825 }
6826 }
6827 if (update.isForced) {
6828 queue.hasForceUpdate = true;
6829 }
6830 if (update.callback !== null) {
6831 // Append to list of callbacks.
6832 var _callbackList = queue.callbackList;
6833 if (_callbackList === null) {
6834 _callbackList = queue.callbackList = [];
6835 }
6836 _callbackList.push(update);
6837 }
6838 update = update.next;
6839 }
6840
6841 if (queue.callbackList !== null) {
6842 workInProgress.effectTag |= Callback;
6843 } else if (queue.first === null && !queue.hasForceUpdate) {
6844 // The queue is empty. We can reset it.
6845 workInProgress.updateQueue = null;
6846 }
6847
6848 if (!didSkip) {
6849 didSkip = true;
6850 queue.baseState = state;
6851 }
6852
6853 {
6854 // No longer processing.
6855 queue.isProcessing = false;
6856 }
6857
6858 return state;
6859}
6860
6861function commitCallbacks(queue, context) {
6862 var callbackList = queue.callbackList;
6863 if (callbackList === null) {
6864 return;
6865 }
6866 // Set the list to null to make sure they don't get called more than once.
6867 queue.callbackList = null;
6868 for (var i = 0; i < callbackList.length; i++) {
6869 var update = callbackList[i];
6870 var _callback = update.callback;
6871 // This update might be processed again. Clear the callback so it's only
6872 // called once.
6873 update.callback = null;
6874 !(typeof _callback === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0;
6875 _callback.call(context);
6876 }
6877}
6878
6879var fakeInternalInstance = {};
6880var isArray = Array.isArray;
6881
6882var didWarnAboutStateAssignmentForComponent = void 0;
6883var warnOnInvalidCallback$1 = void 0;
6884
6885{
6886 var didWarnOnInvalidCallback = {};
6887 didWarnAboutStateAssignmentForComponent = {};
6888
6889 warnOnInvalidCallback$1 = function (callback, callerName) {
6890 if (callback === null || typeof callback === 'function') {
6891 return;
6892 }
6893 var key = callerName + '_' + callback;
6894 if (!didWarnOnInvalidCallback[key]) {
6895 warning_1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
6896 didWarnOnInvalidCallback[key] = true;
6897 }
6898 };
6899
6900 // This is so gross but it's at least non-critical and can be removed if
6901 // it causes problems. This is meant to give a nicer error message for
6902 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
6903 // ...)) which otherwise throws a "_processChildContext is not a function"
6904 // exception.
6905 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
6906 enumerable: false,
6907 value: function () {
6908 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).');
6909 }
6910 });
6911 Object.freeze(fakeInternalInstance);
6912}
6913
6914var ReactFiberClassComponent = function (scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState) {
6915 // Class component state updater
6916 var updater = {
6917 isMounted: isMounted,
6918 enqueueSetState: function (instance, partialState, callback) {
6919 var fiber = get(instance);
6920 callback = callback === undefined ? null : callback;
6921 {
6922 warnOnInvalidCallback$1(callback, 'setState');
6923 }
6924 var expirationTime = computeExpirationForFiber(fiber);
6925 var update = {
6926 expirationTime: expirationTime,
6927 partialState: partialState,
6928 callback: callback,
6929 isReplace: false,
6930 isForced: false,
6931 nextCallback: null,
6932 next: null
6933 };
6934 insertUpdateIntoFiber(fiber, update);
6935 scheduleWork(fiber, expirationTime);
6936 },
6937 enqueueReplaceState: function (instance, state, callback) {
6938 var fiber = get(instance);
6939 callback = callback === undefined ? null : callback;
6940 {
6941 warnOnInvalidCallback$1(callback, 'replaceState');
6942 }
6943 var expirationTime = computeExpirationForFiber(fiber);
6944 var update = {
6945 expirationTime: expirationTime,
6946 partialState: state,
6947 callback: callback,
6948 isReplace: true,
6949 isForced: false,
6950 nextCallback: null,
6951 next: null
6952 };
6953 insertUpdateIntoFiber(fiber, update);
6954 scheduleWork(fiber, expirationTime);
6955 },
6956 enqueueForceUpdate: function (instance, callback) {
6957 var fiber = get(instance);
6958 callback = callback === undefined ? null : callback;
6959 {
6960 warnOnInvalidCallback$1(callback, 'forceUpdate');
6961 }
6962 var expirationTime = computeExpirationForFiber(fiber);
6963 var update = {
6964 expirationTime: expirationTime,
6965 partialState: null,
6966 callback: callback,
6967 isReplace: false,
6968 isForced: true,
6969 nextCallback: null,
6970 next: null
6971 };
6972 insertUpdateIntoFiber(fiber, update);
6973 scheduleWork(fiber, expirationTime);
6974 }
6975 };
6976
6977 function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
6978 if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) {
6979 // If the workInProgress already has an Update effect, return true
6980 return true;
6981 }
6982
6983 var instance = workInProgress.stateNode;
6984 var type = workInProgress.type;
6985 if (typeof instance.shouldComponentUpdate === 'function') {
6986 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
6987 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext);
6988 stopPhaseTimer();
6989
6990 // Simulate an async bailout/interruption by invoking lifecycle twice.
6991 if (debugRenderPhaseSideEffects) {
6992 instance.shouldComponentUpdate(newProps, newState, newContext);
6993 }
6994
6995 {
6996 warning_1(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(workInProgress) || 'Unknown');
6997 }
6998
6999 return shouldUpdate;
7000 }
7001
7002 if (type.prototype && type.prototype.isPureReactComponent) {
7003 return !shallowEqual_1(oldProps, newProps) || !shallowEqual_1(oldState, newState);
7004 }
7005
7006 return true;
7007 }
7008
7009 function checkClassInstance(workInProgress) {
7010 var instance = workInProgress.stateNode;
7011 var type = workInProgress.type;
7012 {
7013 var name = getComponentName(workInProgress);
7014 var renderPresent = instance.render;
7015
7016 if (!renderPresent) {
7017 if (type.prototype && typeof type.prototype.render === 'function') {
7018 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
7019 } else {
7020 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
7021 }
7022 }
7023
7024 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
7025 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);
7026 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
7027 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);
7028 var noInstancePropTypes = !instance.propTypes;
7029 warning_1(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
7030 var noInstanceContextTypes = !instance.contextTypes;
7031 warning_1(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
7032 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
7033 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);
7034 if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
7035 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');
7036 }
7037 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
7038 warning_1(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
7039 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
7040 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);
7041 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
7042 warning_1(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
7043 var hasMutatedProps = instance.props !== workInProgress.pendingProps;
7044 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);
7045 var noInstanceDefaultProps = !instance.defaultProps;
7046 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);
7047 }
7048
7049 var state = instance.state;
7050 if (state && (typeof state !== 'object' || isArray(state))) {
7051 warning_1(false, '%s.state: must be set to an object or null', getComponentName(workInProgress));
7052 }
7053 if (typeof instance.getChildContext === 'function') {
7054 warning_1(typeof workInProgress.type.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', getComponentName(workInProgress));
7055 }
7056 }
7057
7058 function resetInputPointers(workInProgress, instance) {
7059 instance.props = workInProgress.memoizedProps;
7060 instance.state = workInProgress.memoizedState;
7061 }
7062
7063 function adoptClassInstance(workInProgress, instance) {
7064 instance.updater = updater;
7065 workInProgress.stateNode = instance;
7066 // The instance needs access to the fiber so that it can schedule updates
7067 set(instance, workInProgress);
7068 {
7069 instance._reactInternalInstance = fakeInternalInstance;
7070 }
7071 }
7072
7073 function constructClassInstance(workInProgress, props) {
7074 var ctor = workInProgress.type;
7075 var unmaskedContext = getUnmaskedContext(workInProgress);
7076 var needsContext = isContextConsumer(workInProgress);
7077 var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject_1;
7078 var instance = new ctor(props, context);
7079 adoptClassInstance(workInProgress, instance);
7080
7081 // Cache unmasked context so we can avoid recreating masked context unless necessary.
7082 // ReactFiberContext usually updates this cache but can't for newly-created instances.
7083 if (needsContext) {
7084 cacheContext(workInProgress, unmaskedContext, context);
7085 }
7086
7087 return instance;
7088 }
7089
7090 function callComponentWillMount(workInProgress, instance) {
7091 startPhaseTimer(workInProgress, 'componentWillMount');
7092 var oldState = instance.state;
7093 instance.componentWillMount();
7094 stopPhaseTimer();
7095
7096 if (oldState !== instance.state) {
7097 {
7098 warning_1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress));
7099 }
7100 updater.enqueueReplaceState(instance, instance.state, null);
7101 }
7102 }
7103
7104 function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) {
7105 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7106 var oldState = instance.state;
7107 instance.componentWillReceiveProps(newProps, newContext);
7108 stopPhaseTimer();
7109
7110 // Simulate an async bailout/interruption by invoking lifecycle twice.
7111 if (debugRenderPhaseSideEffects) {
7112 instance.componentWillReceiveProps(newProps, newContext);
7113 }
7114
7115 if (instance.state !== oldState) {
7116 {
7117 var componentName = getComponentName(workInProgress) || 'Component';
7118 if (!didWarnAboutStateAssignmentForComponent[componentName]) {
7119 warning_1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
7120 didWarnAboutStateAssignmentForComponent[componentName] = true;
7121 }
7122 }
7123 updater.enqueueReplaceState(instance, instance.state, null);
7124 }
7125 }
7126
7127 // Invokes the mount life-cycles on a previously never rendered instance.
7128 function mountClassInstance(workInProgress, renderExpirationTime) {
7129 var current = workInProgress.alternate;
7130
7131 {
7132 checkClassInstance(workInProgress);
7133 }
7134
7135 var instance = workInProgress.stateNode;
7136 var state = instance.state || null;
7137 var props = workInProgress.pendingProps;
7138 var unmaskedContext = getUnmaskedContext(workInProgress);
7139
7140 instance.props = props;
7141 instance.state = workInProgress.memoizedState = state;
7142 instance.refs = emptyObject_1;
7143 instance.context = getMaskedContext(workInProgress, unmaskedContext);
7144
7145 if (enableAsyncSubtreeAPI && workInProgress.type != null && workInProgress.type.prototype != null && workInProgress.type.prototype.unstable_isAsyncReactComponent === true) {
7146 workInProgress.internalContextTag |= AsyncUpdates;
7147 }
7148
7149 if (typeof instance.componentWillMount === 'function') {
7150 callComponentWillMount(workInProgress, instance);
7151 // If we had additional state updates during this life-cycle, let's
7152 // process them now.
7153 var updateQueue = workInProgress.updateQueue;
7154 if (updateQueue !== null) {
7155 instance.state = processUpdateQueue(current, workInProgress, updateQueue, instance, props, renderExpirationTime);
7156 }
7157 }
7158 if (typeof instance.componentDidMount === 'function') {
7159 workInProgress.effectTag |= Update;
7160 }
7161 }
7162
7163 // Called on a preexisting class instance. Returns false if a resumed render
7164 // could be reused.
7165 // function resumeMountClassInstance(
7166 // workInProgress: Fiber,
7167 // priorityLevel: PriorityLevel,
7168 // ): boolean {
7169 // const instance = workInProgress.stateNode;
7170 // resetInputPointers(workInProgress, instance);
7171
7172 // let newState = workInProgress.memoizedState;
7173 // let newProps = workInProgress.pendingProps;
7174 // if (!newProps) {
7175 // // If there isn't any new props, then we'll reuse the memoized props.
7176 // // This could be from already completed work.
7177 // newProps = workInProgress.memoizedProps;
7178 // invariant(
7179 // newProps != null,
7180 // 'There should always be pending or memoized props. This error is ' +
7181 // 'likely caused by a bug in React. Please file an issue.',
7182 // );
7183 // }
7184 // const newUnmaskedContext = getUnmaskedContext(workInProgress);
7185 // const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7186
7187 // const oldContext = instance.context;
7188 // const oldProps = workInProgress.memoizedProps;
7189
7190 // if (
7191 // typeof instance.componentWillReceiveProps === 'function' &&
7192 // (oldProps !== newProps || oldContext !== newContext)
7193 // ) {
7194 // callComponentWillReceiveProps(
7195 // workInProgress,
7196 // instance,
7197 // newProps,
7198 // newContext,
7199 // );
7200 // }
7201
7202 // // Process the update queue before calling shouldComponentUpdate
7203 // const updateQueue = workInProgress.updateQueue;
7204 // if (updateQueue !== null) {
7205 // newState = processUpdateQueue(
7206 // workInProgress,
7207 // updateQueue,
7208 // instance,
7209 // newState,
7210 // newProps,
7211 // priorityLevel,
7212 // );
7213 // }
7214
7215 // // TODO: Should we deal with a setState that happened after the last
7216 // // componentWillMount and before this componentWillMount? Probably
7217 // // unsupported anyway.
7218
7219 // if (
7220 // !checkShouldComponentUpdate(
7221 // workInProgress,
7222 // workInProgress.memoizedProps,
7223 // newProps,
7224 // workInProgress.memoizedState,
7225 // newState,
7226 // newContext,
7227 // )
7228 // ) {
7229 // // Update the existing instance's state, props, and context pointers even
7230 // // though we're bailing out.
7231 // instance.props = newProps;
7232 // instance.state = newState;
7233 // instance.context = newContext;
7234 // return false;
7235 // }
7236
7237 // // Update the input pointers now so that they are correct when we call
7238 // // componentWillMount
7239 // instance.props = newProps;
7240 // instance.state = newState;
7241 // instance.context = newContext;
7242
7243 // if (typeof instance.componentWillMount === 'function') {
7244 // callComponentWillMount(workInProgress, instance);
7245 // // componentWillMount may have called setState. Process the update queue.
7246 // const newUpdateQueue = workInProgress.updateQueue;
7247 // if (newUpdateQueue !== null) {
7248 // newState = processUpdateQueue(
7249 // workInProgress,
7250 // newUpdateQueue,
7251 // instance,
7252 // newState,
7253 // newProps,
7254 // priorityLevel,
7255 // );
7256 // }
7257 // }
7258
7259 // if (typeof instance.componentDidMount === 'function') {
7260 // workInProgress.effectTag |= Update;
7261 // }
7262
7263 // instance.state = newState;
7264
7265 // return true;
7266 // }
7267
7268 // Invokes the update life-cycles and returns false if it shouldn't rerender.
7269 function updateClassInstance(current, workInProgress, renderExpirationTime) {
7270 var instance = workInProgress.stateNode;
7271 resetInputPointers(workInProgress, instance);
7272
7273 var oldProps = workInProgress.memoizedProps;
7274 var newProps = workInProgress.pendingProps;
7275 var oldContext = instance.context;
7276 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7277 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7278
7279 // Note: During these life-cycles, instance.props/instance.state are what
7280 // ever the previously attempted to render - not the "current". However,
7281 // during componentDidUpdate we pass the "current" props.
7282
7283 if (typeof instance.componentWillReceiveProps === 'function' && (oldProps !== newProps || oldContext !== newContext)) {
7284 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7285 }
7286
7287 // Compute the next state using the memoized state and the update queue.
7288 var oldState = workInProgress.memoizedState;
7289 // TODO: Previous state can be null.
7290 var newState = void 0;
7291 if (workInProgress.updateQueue !== null) {
7292 newState = processUpdateQueue(current, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7293 } else {
7294 newState = oldState;
7295 }
7296
7297 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7298 // If an update was already in progress, we should schedule an Update
7299 // effect even though we're bailing out, so that cWU/cDU are called.
7300 if (typeof instance.componentDidUpdate === 'function') {
7301 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7302 workInProgress.effectTag |= Update;
7303 }
7304 }
7305 return false;
7306 }
7307
7308 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7309
7310 if (shouldUpdate) {
7311 if (typeof instance.componentWillUpdate === 'function') {
7312 startPhaseTimer(workInProgress, 'componentWillUpdate');
7313 instance.componentWillUpdate(newProps, newState, newContext);
7314 stopPhaseTimer();
7315
7316 // Simulate an async bailout/interruption by invoking lifecycle twice.
7317 if (debugRenderPhaseSideEffects) {
7318 instance.componentWillUpdate(newProps, newState, newContext);
7319 }
7320 }
7321 if (typeof instance.componentDidUpdate === 'function') {
7322 workInProgress.effectTag |= Update;
7323 }
7324 } else {
7325 // If an update was already in progress, we should schedule an Update
7326 // effect even though we're bailing out, so that cWU/cDU are called.
7327 if (typeof instance.componentDidUpdate === 'function') {
7328 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7329 workInProgress.effectTag |= Update;
7330 }
7331 }
7332
7333 // If shouldComponentUpdate returned false, we should still update the
7334 // memoized props/state to indicate that this work can be reused.
7335 memoizeProps(workInProgress, newProps);
7336 memoizeState(workInProgress, newState);
7337 }
7338
7339 // Update the existing instance's state, props, and context pointers even
7340 // if shouldComponentUpdate returns false.
7341 instance.props = newProps;
7342 instance.state = newState;
7343 instance.context = newContext;
7344
7345 return shouldUpdate;
7346 }
7347
7348 return {
7349 adoptClassInstance: adoptClassInstance,
7350 constructClassInstance: constructClassInstance,
7351 mountClassInstance: mountClassInstance,
7352 // resumeMountClassInstance,
7353 updateClassInstance: updateClassInstance
7354 };
7355};
7356
7357var getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
7358
7359
7360var didWarnAboutMaps = void 0;
7361var ownerHasKeyUseWarning = void 0;
7362var ownerHasFunctionTypeWarning = void 0;
7363var warnForMissingKey = function (child) {};
7364
7365{
7366 didWarnAboutMaps = false;
7367 /**
7368 * Warn if there's no key explicitly set on dynamic arrays of children or
7369 * object keys are not valid. This allows us to keep track of children between
7370 * updates.
7371 */
7372 ownerHasKeyUseWarning = {};
7373 ownerHasFunctionTypeWarning = {};
7374
7375 warnForMissingKey = function (child) {
7376 if (child === null || typeof child !== 'object') {
7377 return;
7378 }
7379 if (!child._store || child._store.validated || child.key != null) {
7380 return;
7381 }
7382 !(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;
7383 child._store.validated = true;
7384
7385 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() || '');
7386 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
7387 return;
7388 }
7389 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
7390
7391 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());
7392 };
7393}
7394
7395var isArray$1 = Array.isArray;
7396
7397function coerceRef(current, element) {
7398 var mixedRef = element.ref;
7399 if (mixedRef !== null && typeof mixedRef !== 'function') {
7400 if (element._owner) {
7401 var owner = element._owner;
7402 var inst = void 0;
7403 if (owner) {
7404 var ownerFiber = owner;
7405 !(ownerFiber.tag === ClassComponent) ? invariant_1(false, 'Stateless function components cannot have refs.') : void 0;
7406 inst = ownerFiber.stateNode;
7407 }
7408 !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;
7409 var stringRef = '' + mixedRef;
7410 // Check if previous string ref matches new string ref
7411 if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
7412 return current.ref;
7413 }
7414 var ref = function (value) {
7415 var refs = inst.refs === emptyObject_1 ? inst.refs = {} : inst.refs;
7416 if (value === null) {
7417 delete refs[stringRef];
7418 } else {
7419 refs[stringRef] = value;
7420 }
7421 };
7422 ref._stringRef = stringRef;
7423 return ref;
7424 } else {
7425 !(typeof mixedRef === 'string') ? invariant_1(false, 'Expected ref to be a function or a string.') : void 0;
7426 !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;
7427 }
7428 }
7429 return mixedRef;
7430}
7431
7432function throwOnInvalidObjectType(returnFiber, newChild) {
7433 if (returnFiber.type !== 'textarea') {
7434 var addendum = '';
7435 {
7436 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$2() || '');
7437 }
7438 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);
7439 }
7440}
7441
7442function warnOnFunctionType() {
7443 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() || '');
7444
7445 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
7446 return;
7447 }
7448 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
7449
7450 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() || '');
7451}
7452
7453// This wrapper function exists because I expect to clone the code in each path
7454// to be able to optimize each path individually by branching early. This needs
7455// a compiler or we can do it manually. Helpers that don't need this branching
7456// live outside of this function.
7457function ChildReconciler(shouldTrackSideEffects) {
7458 function deleteChild(returnFiber, childToDelete) {
7459 if (!shouldTrackSideEffects) {
7460 // Noop.
7461 return;
7462 }
7463 // Deletions are added in reversed order so we add it to the front.
7464 // At this point, the return fiber's effect list is empty except for
7465 // deletions, so we can just append the deletion to the list. The remaining
7466 // effects aren't added until the complete phase. Once we implement
7467 // resuming, this may not be true.
7468 var last = returnFiber.lastEffect;
7469 if (last !== null) {
7470 last.nextEffect = childToDelete;
7471 returnFiber.lastEffect = childToDelete;
7472 } else {
7473 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7474 }
7475 childToDelete.nextEffect = null;
7476 childToDelete.effectTag = Deletion;
7477 }
7478
7479 function deleteRemainingChildren(returnFiber, currentFirstChild) {
7480 if (!shouldTrackSideEffects) {
7481 // Noop.
7482 return null;
7483 }
7484
7485 // TODO: For the shouldClone case, this could be micro-optimized a bit by
7486 // assuming that after the first child we've already added everything.
7487 var childToDelete = currentFirstChild;
7488 while (childToDelete !== null) {
7489 deleteChild(returnFiber, childToDelete);
7490 childToDelete = childToDelete.sibling;
7491 }
7492 return null;
7493 }
7494
7495 function mapRemainingChildren(returnFiber, currentFirstChild) {
7496 // Add the remaining children to a temporary map so that we can find them by
7497 // keys quickly. Implicit (null) keys get added to this set with their index
7498 var existingChildren = new Map();
7499
7500 var existingChild = currentFirstChild;
7501 while (existingChild !== null) {
7502 if (existingChild.key !== null) {
7503 existingChildren.set(existingChild.key, existingChild);
7504 } else {
7505 existingChildren.set(existingChild.index, existingChild);
7506 }
7507 existingChild = existingChild.sibling;
7508 }
7509 return existingChildren;
7510 }
7511
7512 function useFiber(fiber, pendingProps, expirationTime) {
7513 // We currently set sibling to null and index to 0 here because it is easy
7514 // to forget to do before returning it. E.g. for the single child case.
7515 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
7516 clone.index = 0;
7517 clone.sibling = null;
7518 return clone;
7519 }
7520
7521 function placeChild(newFiber, lastPlacedIndex, newIndex) {
7522 newFiber.index = newIndex;
7523 if (!shouldTrackSideEffects) {
7524 // Noop.
7525 return lastPlacedIndex;
7526 }
7527 var current = newFiber.alternate;
7528 if (current !== null) {
7529 var oldIndex = current.index;
7530 if (oldIndex < lastPlacedIndex) {
7531 // This is a move.
7532 newFiber.effectTag = Placement;
7533 return lastPlacedIndex;
7534 } else {
7535 // This item can stay in place.
7536 return oldIndex;
7537 }
7538 } else {
7539 // This is an insertion.
7540 newFiber.effectTag = Placement;
7541 return lastPlacedIndex;
7542 }
7543 }
7544
7545 function placeSingleChild(newFiber) {
7546 // This is simpler for the single child case. We only need to do a
7547 // placement for inserting new children.
7548 if (shouldTrackSideEffects && newFiber.alternate === null) {
7549 newFiber.effectTag = Placement;
7550 }
7551 return newFiber;
7552 }
7553
7554 function updateTextNode(returnFiber, current, textContent, expirationTime) {
7555 if (current === null || current.tag !== HostText) {
7556 // Insert
7557 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
7558 created['return'] = returnFiber;
7559 return created;
7560 } else {
7561 // Update
7562 var existing = useFiber(current, textContent, expirationTime);
7563 existing['return'] = returnFiber;
7564 return existing;
7565 }
7566 }
7567
7568 function updateElement(returnFiber, current, element, expirationTime) {
7569 if (current !== null && current.type === element.type) {
7570 // Move based on index
7571 var existing = useFiber(current, element.props, expirationTime);
7572 existing.ref = coerceRef(current, element);
7573 existing['return'] = returnFiber;
7574 {
7575 existing._debugSource = element._source;
7576 existing._debugOwner = element._owner;
7577 }
7578 return existing;
7579 } else {
7580 // Insert
7581 var created = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
7582 created.ref = coerceRef(current, element);
7583 created['return'] = returnFiber;
7584 return created;
7585 }
7586 }
7587
7588 function updatePortal(returnFiber, current, portal, expirationTime) {
7589 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
7590 // Insert
7591 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
7592 created['return'] = returnFiber;
7593 return created;
7594 } else {
7595 // Update
7596 var existing = useFiber(current, portal.children || [], expirationTime);
7597 existing['return'] = returnFiber;
7598 return existing;
7599 }
7600 }
7601
7602 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
7603 if (current === null || current.tag !== Fragment) {
7604 // Insert
7605 var created = createFiberFromFragment(fragment, returnFiber.internalContextTag, expirationTime, key);
7606 created['return'] = returnFiber;
7607 return created;
7608 } else {
7609 // Update
7610 var existing = useFiber(current, fragment, expirationTime);
7611 existing['return'] = returnFiber;
7612 return existing;
7613 }
7614 }
7615
7616 function createChild(returnFiber, newChild, expirationTime) {
7617 if (typeof newChild === 'string' || typeof newChild === 'number') {
7618 // Text nodes don't have keys. If the previous node is implicitly keyed
7619 // we can continue to replace it without aborting even if it is not a text
7620 // node.
7621 var created = createFiberFromText('' + newChild, returnFiber.internalContextTag, expirationTime);
7622 created['return'] = returnFiber;
7623 return created;
7624 }
7625
7626 if (typeof newChild === 'object' && newChild !== null) {
7627 switch (newChild.$$typeof) {
7628 case REACT_ELEMENT_TYPE:
7629 {
7630 var _created = createFiberFromElement(newChild, returnFiber.internalContextTag, expirationTime);
7631 _created.ref = coerceRef(null, newChild);
7632 _created['return'] = returnFiber;
7633 return _created;
7634 }
7635 case REACT_PORTAL_TYPE:
7636 {
7637 var _created2 = createFiberFromPortal(newChild, returnFiber.internalContextTag, expirationTime);
7638 _created2['return'] = returnFiber;
7639 return _created2;
7640 }
7641 }
7642
7643 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7644 var _created3 = createFiberFromFragment(newChild, returnFiber.internalContextTag, expirationTime, null);
7645 _created3['return'] = returnFiber;
7646 return _created3;
7647 }
7648
7649 throwOnInvalidObjectType(returnFiber, newChild);
7650 }
7651
7652 {
7653 if (typeof newChild === 'function') {
7654 warnOnFunctionType();
7655 }
7656 }
7657
7658 return null;
7659 }
7660
7661 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
7662 // Update the fiber if the keys match, otherwise return null.
7663
7664 var key = oldFiber !== null ? oldFiber.key : null;
7665
7666 if (typeof newChild === 'string' || typeof newChild === 'number') {
7667 // Text nodes don't have keys. If the previous node is implicitly keyed
7668 // we can continue to replace it without aborting even if it is not a text
7669 // node.
7670 if (key !== null) {
7671 return null;
7672 }
7673 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
7674 }
7675
7676 if (typeof newChild === 'object' && newChild !== null) {
7677 switch (newChild.$$typeof) {
7678 case REACT_ELEMENT_TYPE:
7679 {
7680 if (newChild.key === key) {
7681 if (newChild.type === REACT_FRAGMENT_TYPE) {
7682 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
7683 }
7684 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
7685 } else {
7686 return null;
7687 }
7688 }
7689 case REACT_PORTAL_TYPE:
7690 {
7691 if (newChild.key === key) {
7692 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
7693 } else {
7694 return null;
7695 }
7696 }
7697 }
7698
7699 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7700 if (key !== null) {
7701 return null;
7702 }
7703
7704 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
7705 }
7706
7707 throwOnInvalidObjectType(returnFiber, newChild);
7708 }
7709
7710 {
7711 if (typeof newChild === 'function') {
7712 warnOnFunctionType();
7713 }
7714 }
7715
7716 return null;
7717 }
7718
7719 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
7720 if (typeof newChild === 'string' || typeof newChild === 'number') {
7721 // Text nodes don't have keys, so we neither have to check the old nor
7722 // new node for the key. If both are text nodes, they match.
7723 var matchedFiber = existingChildren.get(newIdx) || null;
7724 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
7725 }
7726
7727 if (typeof newChild === 'object' && newChild !== null) {
7728 switch (newChild.$$typeof) {
7729 case REACT_ELEMENT_TYPE:
7730 {
7731 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7732 if (newChild.type === REACT_FRAGMENT_TYPE) {
7733 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
7734 }
7735 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
7736 }
7737 case REACT_PORTAL_TYPE:
7738 {
7739 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7740 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
7741 }
7742 }
7743
7744 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7745 var _matchedFiber3 = existingChildren.get(newIdx) || null;
7746 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
7747 }
7748
7749 throwOnInvalidObjectType(returnFiber, newChild);
7750 }
7751
7752 {
7753 if (typeof newChild === 'function') {
7754 warnOnFunctionType();
7755 }
7756 }
7757
7758 return null;
7759 }
7760
7761 /**
7762 * Warns if there is a duplicate or missing key
7763 */
7764 function warnOnInvalidKey(child, knownKeys) {
7765 {
7766 if (typeof child !== 'object' || child === null) {
7767 return knownKeys;
7768 }
7769 switch (child.$$typeof) {
7770 case REACT_ELEMENT_TYPE:
7771 case REACT_PORTAL_TYPE:
7772 warnForMissingKey(child);
7773 var key = child.key;
7774 if (typeof key !== 'string') {
7775 break;
7776 }
7777 if (knownKeys === null) {
7778 knownKeys = new Set();
7779 knownKeys.add(key);
7780 break;
7781 }
7782 if (!knownKeys.has(key)) {
7783 knownKeys.add(key);
7784 break;
7785 }
7786 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());
7787 break;
7788 default:
7789 break;
7790 }
7791 }
7792 return knownKeys;
7793 }
7794
7795 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
7796 // This algorithm can't optimize by searching from boths ends since we
7797 // don't have backpointers on fibers. I'm trying to see how far we can get
7798 // with that model. If it ends up not being worth the tradeoffs, we can
7799 // add it later.
7800
7801 // Even with a two ended optimization, we'd want to optimize for the case
7802 // where there are few changes and brute force the comparison instead of
7803 // going for the Map. It'd like to explore hitting that path first in
7804 // forward-only mode and only go for the Map once we notice that we need
7805 // lots of look ahead. This doesn't handle reversal as well as two ended
7806 // search but that's unusual. Besides, for the two ended optimization to
7807 // work on Iterables, we'd need to copy the whole set.
7808
7809 // In this first iteration, we'll just live with hitting the bad case
7810 // (adding everything to a Map) in for every insert/move.
7811
7812 // If you change this code, also update reconcileChildrenIterator() which
7813 // uses the same algorithm.
7814
7815 {
7816 // First, validate keys.
7817 var knownKeys = null;
7818 for (var i = 0; i < newChildren.length; i++) {
7819 var child = newChildren[i];
7820 knownKeys = warnOnInvalidKey(child, knownKeys);
7821 }
7822 }
7823
7824 var resultingFirstChild = null;
7825 var previousNewFiber = null;
7826
7827 var oldFiber = currentFirstChild;
7828 var lastPlacedIndex = 0;
7829 var newIdx = 0;
7830 var nextOldFiber = null;
7831 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
7832 if (oldFiber.index > newIdx) {
7833 nextOldFiber = oldFiber;
7834 oldFiber = null;
7835 } else {
7836 nextOldFiber = oldFiber.sibling;
7837 }
7838 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
7839 if (newFiber === null) {
7840 // TODO: This breaks on empty slots like null children. That's
7841 // unfortunate because it triggers the slow path all the time. We need
7842 // a better way to communicate whether this was a miss or null,
7843 // boolean, undefined, etc.
7844 if (oldFiber === null) {
7845 oldFiber = nextOldFiber;
7846 }
7847 break;
7848 }
7849 if (shouldTrackSideEffects) {
7850 if (oldFiber && newFiber.alternate === null) {
7851 // We matched the slot, but we didn't reuse the existing fiber, so we
7852 // need to delete the existing child.
7853 deleteChild(returnFiber, oldFiber);
7854 }
7855 }
7856 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
7857 if (previousNewFiber === null) {
7858 // TODO: Move out of the loop. This only happens for the first run.
7859 resultingFirstChild = newFiber;
7860 } else {
7861 // TODO: Defer siblings if we're not at the right index for this slot.
7862 // I.e. if we had null values before, then we want to defer this
7863 // for each null value. However, we also don't want to call updateSlot
7864 // with the previous one.
7865 previousNewFiber.sibling = newFiber;
7866 }
7867 previousNewFiber = newFiber;
7868 oldFiber = nextOldFiber;
7869 }
7870
7871 if (newIdx === newChildren.length) {
7872 // We've reached the end of the new children. We can delete the rest.
7873 deleteRemainingChildren(returnFiber, oldFiber);
7874 return resultingFirstChild;
7875 }
7876
7877 if (oldFiber === null) {
7878 // If we don't have any more existing children we can choose a fast path
7879 // since the rest will all be insertions.
7880 for (; newIdx < newChildren.length; newIdx++) {
7881 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
7882 if (!_newFiber) {
7883 continue;
7884 }
7885 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
7886 if (previousNewFiber === null) {
7887 // TODO: Move out of the loop. This only happens for the first run.
7888 resultingFirstChild = _newFiber;
7889 } else {
7890 previousNewFiber.sibling = _newFiber;
7891 }
7892 previousNewFiber = _newFiber;
7893 }
7894 return resultingFirstChild;
7895 }
7896
7897 // Add all children to a key map for quick lookups.
7898 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
7899
7900 // Keep scanning and use the map to restore deleted items as moves.
7901 for (; newIdx < newChildren.length; newIdx++) {
7902 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
7903 if (_newFiber2) {
7904 if (shouldTrackSideEffects) {
7905 if (_newFiber2.alternate !== null) {
7906 // The new fiber is a work in progress, but if there exists a
7907 // current, that means that we reused the fiber. We need to delete
7908 // it from the child list so that we don't add it to the deletion
7909 // list.
7910 existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key);
7911 }
7912 }
7913 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
7914 if (previousNewFiber === null) {
7915 resultingFirstChild = _newFiber2;
7916 } else {
7917 previousNewFiber.sibling = _newFiber2;
7918 }
7919 previousNewFiber = _newFiber2;
7920 }
7921 }
7922
7923 if (shouldTrackSideEffects) {
7924 // Any existing children that weren't consumed above were deleted. We need
7925 // to add them to the deletion list.
7926 existingChildren.forEach(function (child) {
7927 return deleteChild(returnFiber, child);
7928 });
7929 }
7930
7931 return resultingFirstChild;
7932 }
7933
7934 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
7935 // This is the same implementation as reconcileChildrenArray(),
7936 // but using the iterator instead.
7937
7938 var iteratorFn = getIteratorFn(newChildrenIterable);
7939 !(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;
7940
7941 {
7942 // Warn about using Maps as children
7943 if (typeof newChildrenIterable.entries === 'function') {
7944 var possibleMap = newChildrenIterable;
7945 if (possibleMap.entries === iteratorFn) {
7946 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());
7947 didWarnAboutMaps = true;
7948 }
7949 }
7950
7951 // First, validate keys.
7952 // We'll get a different iterator later for the main pass.
7953 var _newChildren = iteratorFn.call(newChildrenIterable);
7954 if (_newChildren) {
7955 var knownKeys = null;
7956 var _step = _newChildren.next();
7957 for (; !_step.done; _step = _newChildren.next()) {
7958 var child = _step.value;
7959 knownKeys = warnOnInvalidKey(child, knownKeys);
7960 }
7961 }
7962 }
7963
7964 var newChildren = iteratorFn.call(newChildrenIterable);
7965 !(newChildren != null) ? invariant_1(false, 'An iterable object provided no iterator.') : void 0;
7966
7967 var resultingFirstChild = null;
7968 var previousNewFiber = null;
7969
7970 var oldFiber = currentFirstChild;
7971 var lastPlacedIndex = 0;
7972 var newIdx = 0;
7973 var nextOldFiber = null;
7974
7975 var step = newChildren.next();
7976 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
7977 if (oldFiber.index > newIdx) {
7978 nextOldFiber = oldFiber;
7979 oldFiber = null;
7980 } else {
7981 nextOldFiber = oldFiber.sibling;
7982 }
7983 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
7984 if (newFiber === null) {
7985 // TODO: This breaks on empty slots like null children. That's
7986 // unfortunate because it triggers the slow path all the time. We need
7987 // a better way to communicate whether this was a miss or null,
7988 // boolean, undefined, etc.
7989 if (!oldFiber) {
7990 oldFiber = nextOldFiber;
7991 }
7992 break;
7993 }
7994 if (shouldTrackSideEffects) {
7995 if (oldFiber && newFiber.alternate === null) {
7996 // We matched the slot, but we didn't reuse the existing fiber, so we
7997 // need to delete the existing child.
7998 deleteChild(returnFiber, oldFiber);
7999 }
8000 }
8001 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8002 if (previousNewFiber === null) {
8003 // TODO: Move out of the loop. This only happens for the first run.
8004 resultingFirstChild = newFiber;
8005 } else {
8006 // TODO: Defer siblings if we're not at the right index for this slot.
8007 // I.e. if we had null values before, then we want to defer this
8008 // for each null value. However, we also don't want to call updateSlot
8009 // with the previous one.
8010 previousNewFiber.sibling = newFiber;
8011 }
8012 previousNewFiber = newFiber;
8013 oldFiber = nextOldFiber;
8014 }
8015
8016 if (step.done) {
8017 // We've reached the end of the new children. We can delete the rest.
8018 deleteRemainingChildren(returnFiber, oldFiber);
8019 return resultingFirstChild;
8020 }
8021
8022 if (oldFiber === null) {
8023 // If we don't have any more existing children we can choose a fast path
8024 // since the rest will all be insertions.
8025 for (; !step.done; newIdx++, step = newChildren.next()) {
8026 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
8027 if (_newFiber3 === null) {
8028 continue;
8029 }
8030 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
8031 if (previousNewFiber === null) {
8032 // TODO: Move out of the loop. This only happens for the first run.
8033 resultingFirstChild = _newFiber3;
8034 } else {
8035 previousNewFiber.sibling = _newFiber3;
8036 }
8037 previousNewFiber = _newFiber3;
8038 }
8039 return resultingFirstChild;
8040 }
8041
8042 // Add all children to a key map for quick lookups.
8043 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8044
8045 // Keep scanning and use the map to restore deleted items as moves.
8046 for (; !step.done; newIdx++, step = newChildren.next()) {
8047 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
8048 if (_newFiber4 !== null) {
8049 if (shouldTrackSideEffects) {
8050 if (_newFiber4.alternate !== null) {
8051 // The new fiber is a work in progress, but if there exists a
8052 // current, that means that we reused the fiber. We need to delete
8053 // it from the child list so that we don't add it to the deletion
8054 // list.
8055 existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key);
8056 }
8057 }
8058 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
8059 if (previousNewFiber === null) {
8060 resultingFirstChild = _newFiber4;
8061 } else {
8062 previousNewFiber.sibling = _newFiber4;
8063 }
8064 previousNewFiber = _newFiber4;
8065 }
8066 }
8067
8068 if (shouldTrackSideEffects) {
8069 // Any existing children that weren't consumed above were deleted. We need
8070 // to add them to the deletion list.
8071 existingChildren.forEach(function (child) {
8072 return deleteChild(returnFiber, child);
8073 });
8074 }
8075
8076 return resultingFirstChild;
8077 }
8078
8079 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
8080 // There's no need to check for keys on text nodes since we don't have a
8081 // way to define them.
8082 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
8083 // We already have an existing node so let's just update it and delete
8084 // the rest.
8085 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
8086 var existing = useFiber(currentFirstChild, textContent, expirationTime);
8087 existing['return'] = returnFiber;
8088 return existing;
8089 }
8090 // The existing first child is not a text node so we need to create one
8091 // and delete the existing ones.
8092 deleteRemainingChildren(returnFiber, currentFirstChild);
8093 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
8094 created['return'] = returnFiber;
8095 return created;
8096 }
8097
8098 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
8099 var key = element.key;
8100 var child = currentFirstChild;
8101 while (child !== null) {
8102 // TODO: If key === null and child.key === null, then this only applies to
8103 // the first item in the list.
8104 if (child.key === key) {
8105 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) {
8106 deleteRemainingChildren(returnFiber, child.sibling);
8107 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
8108 existing.ref = coerceRef(child, element);
8109 existing['return'] = returnFiber;
8110 {
8111 existing._debugSource = element._source;
8112 existing._debugOwner = element._owner;
8113 }
8114 return existing;
8115 } else {
8116 deleteRemainingChildren(returnFiber, child);
8117 break;
8118 }
8119 } else {
8120 deleteChild(returnFiber, child);
8121 }
8122 child = child.sibling;
8123 }
8124
8125 if (element.type === REACT_FRAGMENT_TYPE) {
8126 var created = createFiberFromFragment(element.props.children, returnFiber.internalContextTag, expirationTime, element.key);
8127 created['return'] = returnFiber;
8128 return created;
8129 } else {
8130 var _created4 = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
8131 _created4.ref = coerceRef(currentFirstChild, element);
8132 _created4['return'] = returnFiber;
8133 return _created4;
8134 }
8135 }
8136
8137 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
8138 var key = portal.key;
8139 var child = currentFirstChild;
8140 while (child !== null) {
8141 // TODO: If key === null and child.key === null, then this only applies to
8142 // the first item in the list.
8143 if (child.key === key) {
8144 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
8145 deleteRemainingChildren(returnFiber, child.sibling);
8146 var existing = useFiber(child, portal.children || [], expirationTime);
8147 existing['return'] = returnFiber;
8148 return existing;
8149 } else {
8150 deleteRemainingChildren(returnFiber, child);
8151 break;
8152 }
8153 } else {
8154 deleteChild(returnFiber, child);
8155 }
8156 child = child.sibling;
8157 }
8158
8159 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
8160 created['return'] = returnFiber;
8161 return created;
8162 }
8163
8164 // This API will tag the children with the side-effect of the reconciliation
8165 // itself. They will be added to the side-effect list as we pass through the
8166 // children and the parent.
8167 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
8168 // This function is not recursive.
8169 // If the top level item is an array, we treat it as a set of children,
8170 // not as a fragment. Nested arrays on the other hand will be treated as
8171 // fragment nodes. Recursion happens at the normal flow.
8172
8173 // Handle top level unkeyed fragments as if they were arrays.
8174 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
8175 // We treat the ambiguous cases above the same.
8176 if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
8177 newChild = newChild.props.children;
8178 }
8179
8180 // Handle object types
8181 var isObject = typeof newChild === 'object' && newChild !== null;
8182
8183 if (isObject) {
8184 switch (newChild.$$typeof) {
8185 case REACT_ELEMENT_TYPE:
8186 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
8187 case REACT_PORTAL_TYPE:
8188 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
8189 }
8190 }
8191
8192 if (typeof newChild === 'string' || typeof newChild === 'number') {
8193 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
8194 }
8195
8196 if (isArray$1(newChild)) {
8197 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
8198 }
8199
8200 if (getIteratorFn(newChild)) {
8201 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
8202 }
8203
8204 if (isObject) {
8205 throwOnInvalidObjectType(returnFiber, newChild);
8206 }
8207
8208 {
8209 if (typeof newChild === 'function') {
8210 warnOnFunctionType();
8211 }
8212 }
8213 if (typeof newChild === 'undefined') {
8214 // If the new child is undefined, and the return fiber is a composite
8215 // component, throw an error. If Fiber return types are disabled,
8216 // we already threw above.
8217 switch (returnFiber.tag) {
8218 case ClassComponent:
8219 {
8220 {
8221 var instance = returnFiber.stateNode;
8222 if (instance.render._isMockFunction) {
8223 // We allow auto-mocks to proceed as if they're returning null.
8224 break;
8225 }
8226 }
8227 }
8228 // Intentionally fall through to the next case, which handles both
8229 // functions and classes
8230 // eslint-disable-next-lined no-fallthrough
8231 case FunctionalComponent:
8232 {
8233 var Component = returnFiber.type;
8234 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');
8235 }
8236 }
8237 }
8238
8239 // Remaining cases are all treated as empty.
8240 return deleteRemainingChildren(returnFiber, currentFirstChild);
8241 }
8242
8243 return reconcileChildFibers;
8244}
8245
8246var reconcileChildFibers = ChildReconciler(true);
8247var mountChildFibers = ChildReconciler(false);
8248
8249function cloneChildFibers(current, workInProgress) {
8250 !(current === null || workInProgress.child === current.child) ? invariant_1(false, 'Resuming work not yet implemented.') : void 0;
8251
8252 if (workInProgress.child === null) {
8253 return;
8254 }
8255
8256 var currentChild = workInProgress.child;
8257 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8258 workInProgress.child = newChild;
8259
8260 newChild['return'] = workInProgress;
8261 while (currentChild.sibling !== null) {
8262 currentChild = currentChild.sibling;
8263 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8264 newChild['return'] = workInProgress;
8265 }
8266 newChild.sibling = null;
8267}
8268
8269var warnedAboutStatelessRefs = void 0;
8270var didWarnAboutBadClass = void 0;
8271
8272{
8273 warnedAboutStatelessRefs = {};
8274 didWarnAboutBadClass = {};
8275}
8276
8277var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber) {
8278 var shouldSetTextContent = config.shouldSetTextContent,
8279 shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree;
8280 var pushHostContext = hostContext.pushHostContext,
8281 pushHostContainer = hostContext.pushHostContainer;
8282 var enterHydrationState = hydrationContext.enterHydrationState,
8283 resetHydrationState = hydrationContext.resetHydrationState,
8284 tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance;
8285
8286 var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState),
8287 adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance,
8288 constructClassInstance = _ReactFiberClassCompo.constructClassInstance,
8289 mountClassInstance = _ReactFiberClassCompo.mountClassInstance,
8290 updateClassInstance = _ReactFiberClassCompo.updateClassInstance;
8291
8292 // TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
8293
8294
8295 function reconcileChildren(current, workInProgress, nextChildren) {
8296 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, workInProgress.expirationTime);
8297 }
8298
8299 function reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime) {
8300 if (current === null) {
8301 // If this is a fresh new component that hasn't been rendered yet, we
8302 // won't update its child set by applying minimal side-effects. Instead,
8303 // we will add them all to the child before it gets rendered. That means
8304 // we can optimize this reconciliation pass by not tracking side-effects.
8305 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8306 } else {
8307 // If the current child is the same as the work in progress, it means that
8308 // we haven't yet started any work on these children. Therefore, we use
8309 // the clone algorithm to create a copy of all the current children.
8310
8311 // If we had any progressed work already, that is invalid at this point so
8312 // let's throw it out.
8313 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8314 }
8315 }
8316
8317 function updateFragment(current, workInProgress) {
8318 var nextChildren = workInProgress.pendingProps;
8319 if (hasContextChanged()) {
8320 // Normally we can bail out on props equality but if context has changed
8321 // we don't do the bailout and we have to reuse existing props instead.
8322 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
8323 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8324 }
8325 reconcileChildren(current, workInProgress, nextChildren);
8326 memoizeProps(workInProgress, nextChildren);
8327 return workInProgress.child;
8328 }
8329
8330 function markRef(current, workInProgress) {
8331 var ref = workInProgress.ref;
8332 if (ref !== null && (!current || current.ref !== ref)) {
8333 // Schedule a Ref effect
8334 workInProgress.effectTag |= Ref;
8335 }
8336 }
8337
8338 function updateFunctionalComponent(current, workInProgress) {
8339 var fn = workInProgress.type;
8340 var nextProps = workInProgress.pendingProps;
8341
8342 if (hasContextChanged()) {
8343 // Normally we can bail out on props equality but if context has changed
8344 // we don't do the bailout and we have to reuse existing props instead.
8345 } else {
8346 if (workInProgress.memoizedProps === nextProps) {
8347 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8348 }
8349 // TODO: consider bringing fn.shouldComponentUpdate() back.
8350 // It used to be here.
8351 }
8352
8353 var unmaskedContext = getUnmaskedContext(workInProgress);
8354 var context = getMaskedContext(workInProgress, unmaskedContext);
8355
8356 var nextChildren = void 0;
8357
8358 {
8359 ReactCurrentOwner.current = workInProgress;
8360 ReactDebugCurrentFiber.setCurrentPhase('render');
8361 nextChildren = fn(nextProps, context);
8362 ReactDebugCurrentFiber.setCurrentPhase(null);
8363 }
8364 // React DevTools reads this flag.
8365 workInProgress.effectTag |= PerformedWork;
8366 reconcileChildren(current, workInProgress, nextChildren);
8367 memoizeProps(workInProgress, nextProps);
8368 return workInProgress.child;
8369 }
8370
8371 function updateClassComponent(current, workInProgress, renderExpirationTime) {
8372 // Push context providers early to prevent context stack mismatches.
8373 // During mounting we don't know the child context yet as the instance doesn't exist.
8374 // We will invalidate the child context in finishClassComponent() right after rendering.
8375 var hasContext = pushContextProvider(workInProgress);
8376
8377 var shouldUpdate = void 0;
8378 if (current === null) {
8379 if (!workInProgress.stateNode) {
8380 // In the initial pass we might need to construct the instance.
8381 constructClassInstance(workInProgress, workInProgress.pendingProps);
8382 mountClassInstance(workInProgress, renderExpirationTime);
8383
8384 // Simulate an async bailout/interruption by invoking lifecycle twice.
8385 // We do this here rather than inside of ReactFiberClassComponent,
8386 // To more realistically simulate the interruption behavior of async,
8387 // Which would never call componentWillMount() twice on the same instance.
8388 if (debugRenderPhaseSideEffects) {
8389 constructClassInstance(workInProgress, workInProgress.pendingProps);
8390 mountClassInstance(workInProgress, renderExpirationTime);
8391 }
8392
8393 shouldUpdate = true;
8394 } else {
8395 invariant_1(false, 'Resuming work not yet implemented.');
8396 // In a resume, we'll already have an instance we can reuse.
8397 // shouldUpdate = resumeMountClassInstance(workInProgress, renderExpirationTime);
8398 }
8399 } else {
8400 shouldUpdate = updateClassInstance(current, workInProgress, renderExpirationTime);
8401 }
8402 return finishClassComponent(current, workInProgress, shouldUpdate, hasContext);
8403 }
8404
8405 function finishClassComponent(current, workInProgress, shouldUpdate, hasContext) {
8406 // Refs should update even if shouldComponentUpdate returns false
8407 markRef(current, workInProgress);
8408
8409 if (!shouldUpdate) {
8410 // Context providers should defer to sCU for rendering
8411 if (hasContext) {
8412 invalidateContextProvider(workInProgress, false);
8413 }
8414
8415 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8416 }
8417
8418 var instance = workInProgress.stateNode;
8419
8420 // Rerender
8421 ReactCurrentOwner.current = workInProgress;
8422 var nextChildren = void 0;
8423 {
8424 ReactDebugCurrentFiber.setCurrentPhase('render');
8425 nextChildren = instance.render();
8426 if (debugRenderPhaseSideEffects) {
8427 instance.render();
8428 }
8429 ReactDebugCurrentFiber.setCurrentPhase(null);
8430 }
8431 // React DevTools reads this flag.
8432 workInProgress.effectTag |= PerformedWork;
8433 reconcileChildren(current, workInProgress, nextChildren);
8434 // Memoize props and state using the values we just used to render.
8435 // TODO: Restructure so we never read values from the instance.
8436 memoizeState(workInProgress, instance.state);
8437 memoizeProps(workInProgress, instance.props);
8438
8439 // The context might have changed so we need to recalculate it.
8440 if (hasContext) {
8441 invalidateContextProvider(workInProgress, true);
8442 }
8443
8444 return workInProgress.child;
8445 }
8446
8447 function pushHostRootContext(workInProgress) {
8448 var root = workInProgress.stateNode;
8449 if (root.pendingContext) {
8450 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8451 } else if (root.context) {
8452 // Should always be set
8453 pushTopLevelContextObject(workInProgress, root.context, false);
8454 }
8455 pushHostContainer(workInProgress, root.containerInfo);
8456 }
8457
8458 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8459 pushHostRootContext(workInProgress);
8460 var updateQueue = workInProgress.updateQueue;
8461 if (updateQueue !== null) {
8462 var prevState = workInProgress.memoizedState;
8463 var state = processUpdateQueue(current, workInProgress, updateQueue, null, null, renderExpirationTime);
8464 if (prevState === state) {
8465 // If the state is the same as before, that's a bailout because we had
8466 // no work that expires at this time.
8467 resetHydrationState();
8468 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8469 }
8470 var element = state.element;
8471 var root = workInProgress.stateNode;
8472 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
8473 // If we don't have any current children this might be the first pass.
8474 // We always try to hydrate. If this isn't a hydration pass there won't
8475 // be any children to hydrate which is effectively the same thing as
8476 // not hydrating.
8477
8478 // This is a bit of a hack. We track the host root as a placement to
8479 // know that we're currently in a mounting state. That way isMounted
8480 // works as expected. We must reset this before committing.
8481 // TODO: Delete this when we delete isMounted and findDOMNode.
8482 workInProgress.effectTag |= Placement;
8483
8484 // Ensure that children mount into this root without tracking
8485 // side-effects. This ensures that we don't store Placement effects on
8486 // nodes that will be hydrated.
8487 workInProgress.child = mountChildFibers(workInProgress, null, element, renderExpirationTime);
8488 } else {
8489 // Otherwise reset hydration state in case we aborted and resumed another
8490 // root.
8491 resetHydrationState();
8492 reconcileChildren(current, workInProgress, element);
8493 }
8494 memoizeState(workInProgress, state);
8495 return workInProgress.child;
8496 }
8497 resetHydrationState();
8498 // If there is no update queue, that's a bailout because the root has no props.
8499 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8500 }
8501
8502 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8503 pushHostContext(workInProgress);
8504
8505 if (current === null) {
8506 tryToClaimNextHydratableInstance(workInProgress);
8507 }
8508
8509 var type = workInProgress.type;
8510 var memoizedProps = workInProgress.memoizedProps;
8511 var nextProps = workInProgress.pendingProps;
8512 var prevProps = current !== null ? current.memoizedProps : null;
8513
8514 if (hasContextChanged()) {
8515 // Normally we can bail out on props equality but if context has changed
8516 // we don't do the bailout and we have to reuse existing props instead.
8517 } else if (memoizedProps === nextProps) {
8518 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8519 }
8520
8521 var nextChildren = nextProps.children;
8522 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8523
8524 if (isDirectTextChild) {
8525 // We special case a direct text child of a host node. This is a common
8526 // case. We won't handle it as a reified child. We will instead handle
8527 // this in the host environment that also have access to this prop. That
8528 // avoids allocating another HostText fiber and traversing it.
8529 nextChildren = null;
8530 } else if (prevProps && shouldSetTextContent(type, prevProps)) {
8531 // If we're switching from a direct text child to a normal child, or to
8532 // empty, we need to schedule the text content to be reset.
8533 workInProgress.effectTag |= ContentReset;
8534 }
8535
8536 markRef(current, workInProgress);
8537
8538 // Check the host config to see if the children are offscreen/hidden.
8539 if (renderExpirationTime !== Never && workInProgress.internalContextTag & AsyncUpdates && shouldDeprioritizeSubtree(type, nextProps)) {
8540 // Down-prioritize the children.
8541 workInProgress.expirationTime = Never;
8542 // Bailout and come back to this fiber later.
8543 return null;
8544 }
8545
8546 reconcileChildren(current, workInProgress, nextChildren);
8547 memoizeProps(workInProgress, nextProps);
8548 return workInProgress.child;
8549 }
8550
8551 function updateHostText(current, workInProgress) {
8552 if (current === null) {
8553 tryToClaimNextHydratableInstance(workInProgress);
8554 }
8555 var nextProps = workInProgress.pendingProps;
8556 memoizeProps(workInProgress, nextProps);
8557 // Nothing to do here. This is terminal. We'll do the completion step
8558 // immediately after.
8559 return null;
8560 }
8561
8562 function mountIndeterminateComponent(current, workInProgress, renderExpirationTime) {
8563 !(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;
8564 var fn = workInProgress.type;
8565 var props = workInProgress.pendingProps;
8566 var unmaskedContext = getUnmaskedContext(workInProgress);
8567 var context = getMaskedContext(workInProgress, unmaskedContext);
8568
8569 var value = void 0;
8570
8571 {
8572 if (fn.prototype && typeof fn.prototype.render === 'function') {
8573 var componentName = getComponentName(workInProgress) || 'Unknown';
8574
8575 if (!didWarnAboutBadClass[componentName]) {
8576 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);
8577 didWarnAboutBadClass[componentName] = true;
8578 }
8579 }
8580 ReactCurrentOwner.current = workInProgress;
8581 value = fn(props, context);
8582 }
8583 // React DevTools reads this flag.
8584 workInProgress.effectTag |= PerformedWork;
8585
8586 if (typeof value === 'object' && value !== null && typeof value.render === 'function') {
8587 // Proceed under the assumption that this is a class instance
8588 workInProgress.tag = ClassComponent;
8589
8590 // Push context providers early to prevent context stack mismatches.
8591 // During mounting we don't know the child context yet as the instance doesn't exist.
8592 // We will invalidate the child context in finishClassComponent() right after rendering.
8593 var hasContext = pushContextProvider(workInProgress);
8594 adoptClassInstance(workInProgress, value);
8595 mountClassInstance(workInProgress, renderExpirationTime);
8596 return finishClassComponent(current, workInProgress, true, hasContext);
8597 } else {
8598 // Proceed under the assumption that this is a functional component
8599 workInProgress.tag = FunctionalComponent;
8600 {
8601 var Component = workInProgress.type;
8602
8603 if (Component) {
8604 warning_1(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component');
8605 }
8606 if (workInProgress.ref !== null) {
8607 var info = '';
8608 var ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
8609 if (ownerName) {
8610 info += '\n\nCheck the render method of `' + ownerName + '`.';
8611 }
8612
8613 var warningKey = ownerName || workInProgress._debugID || '';
8614 var debugSource = workInProgress._debugSource;
8615 if (debugSource) {
8616 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8617 }
8618 if (!warnedAboutStatelessRefs[warningKey]) {
8619 warnedAboutStatelessRefs[warningKey] = true;
8620 warning_1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber.getCurrentFiberStackAddendum());
8621 }
8622 }
8623 }
8624 reconcileChildren(current, workInProgress, value);
8625 memoizeProps(workInProgress, props);
8626 return workInProgress.child;
8627 }
8628 }
8629
8630 function updateCallComponent(current, workInProgress, renderExpirationTime) {
8631 var nextProps = workInProgress.pendingProps;
8632 if (hasContextChanged()) {
8633 // Normally we can bail out on props equality but if context has changed
8634 // we don't do the bailout and we have to reuse existing props instead.
8635 } else if (workInProgress.memoizedProps === nextProps) {
8636 nextProps = workInProgress.memoizedProps;
8637 // TODO: When bailing out, we might need to return the stateNode instead
8638 // of the child. To check it for work.
8639 // return bailoutOnAlreadyFinishedWork(current, workInProgress);
8640 }
8641
8642 var nextChildren = nextProps.children;
8643
8644 // The following is a fork of reconcileChildrenAtExpirationTime but using
8645 // stateNode to store the child.
8646 if (current === null) {
8647 workInProgress.stateNode = mountChildFibers(workInProgress, workInProgress.stateNode, nextChildren, renderExpirationTime);
8648 } else {
8649 workInProgress.stateNode = reconcileChildFibers(workInProgress, current.stateNode, nextChildren, renderExpirationTime);
8650 }
8651
8652 memoizeProps(workInProgress, nextProps);
8653 // This doesn't take arbitrary time so we could synchronously just begin
8654 // eagerly do the work of workInProgress.child as an optimization.
8655 return workInProgress.stateNode;
8656 }
8657
8658 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8659 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8660 var nextChildren = workInProgress.pendingProps;
8661 if (hasContextChanged()) {
8662 // Normally we can bail out on props equality but if context has changed
8663 // we don't do the bailout and we have to reuse existing props instead.
8664 } else if (workInProgress.memoizedProps === nextChildren) {
8665 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8666 }
8667
8668 if (current === null) {
8669 // Portals are special because we don't append the children during mount
8670 // but at commit. Therefore we need to track insertions which the normal
8671 // flow doesn't do during mount. This doesn't happen at the root because
8672 // the root always starts with a "current" with a null child.
8673 // TODO: Consider unifying this with how the root works.
8674 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8675 memoizeProps(workInProgress, nextChildren);
8676 } else {
8677 reconcileChildren(current, workInProgress, nextChildren);
8678 memoizeProps(workInProgress, nextChildren);
8679 }
8680 return workInProgress.child;
8681 }
8682
8683 /*
8684 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
8685 let child = firstChild;
8686 do {
8687 // Ensure that the first and last effect of the parent corresponds
8688 // to the children's first and last effect.
8689 if (!returnFiber.firstEffect) {
8690 returnFiber.firstEffect = child.firstEffect;
8691 }
8692 if (child.lastEffect) {
8693 if (returnFiber.lastEffect) {
8694 returnFiber.lastEffect.nextEffect = child.firstEffect;
8695 }
8696 returnFiber.lastEffect = child.lastEffect;
8697 }
8698 } while (child = child.sibling);
8699 }
8700 */
8701
8702 function bailoutOnAlreadyFinishedWork(current, workInProgress) {
8703 cancelWorkTimer(workInProgress);
8704
8705 // TODO: We should ideally be able to bail out early if the children have no
8706 // more work to do. However, since we don't have a separation of this
8707 // Fiber's priority and its children yet - we don't know without doing lots
8708 // of the same work we do anyway. Once we have that separation we can just
8709 // bail out here if the children has no more work at this priority level.
8710 // if (workInProgress.priorityOfChildren <= priorityLevel) {
8711 // // If there are side-effects in these children that have not yet been
8712 // // committed we need to ensure that they get properly transferred up.
8713 // if (current && current.child !== workInProgress.child) {
8714 // reuseChildrenEffects(workInProgress, child);
8715 // }
8716 // return null;
8717 // }
8718
8719 cloneChildFibers(current, workInProgress);
8720 return workInProgress.child;
8721 }
8722
8723 function bailoutOnLowPriority(current, workInProgress) {
8724 cancelWorkTimer(workInProgress);
8725
8726 // TODO: Handle HostComponent tags here as well and call pushHostContext()?
8727 // See PR 8590 discussion for context
8728 switch (workInProgress.tag) {
8729 case HostRoot:
8730 pushHostRootContext(workInProgress);
8731 break;
8732 case ClassComponent:
8733 pushContextProvider(workInProgress);
8734 break;
8735 case HostPortal:
8736 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8737 break;
8738 }
8739 // TODO: What if this is currently in progress?
8740 // How can that happen? How is this not being cloned?
8741 return null;
8742 }
8743
8744 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead
8745 function memoizeProps(workInProgress, nextProps) {
8746 workInProgress.memoizedProps = nextProps;
8747 }
8748
8749 function memoizeState(workInProgress, nextState) {
8750 workInProgress.memoizedState = nextState;
8751 // Don't reset the updateQueue, in case there are pending updates. Resetting
8752 // is handled by processUpdateQueue.
8753 }
8754
8755 function beginWork(current, workInProgress, renderExpirationTime) {
8756 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8757 return bailoutOnLowPriority(current, workInProgress);
8758 }
8759
8760 switch (workInProgress.tag) {
8761 case IndeterminateComponent:
8762 return mountIndeterminateComponent(current, workInProgress, renderExpirationTime);
8763 case FunctionalComponent:
8764 return updateFunctionalComponent(current, workInProgress);
8765 case ClassComponent:
8766 return updateClassComponent(current, workInProgress, renderExpirationTime);
8767 case HostRoot:
8768 return updateHostRoot(current, workInProgress, renderExpirationTime);
8769 case HostComponent:
8770 return updateHostComponent(current, workInProgress, renderExpirationTime);
8771 case HostText:
8772 return updateHostText(current, workInProgress);
8773 case CallHandlerPhase:
8774 // This is a restart. Reset the tag to the initial phase.
8775 workInProgress.tag = CallComponent;
8776 // Intentionally fall through since this is now the same.
8777 case CallComponent:
8778 return updateCallComponent(current, workInProgress, renderExpirationTime);
8779 case ReturnComponent:
8780 // A return component is just a placeholder, we can just run through the
8781 // next one immediately.
8782 return null;
8783 case HostPortal:
8784 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8785 case Fragment:
8786 return updateFragment(current, workInProgress);
8787 default:
8788 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8789 }
8790 }
8791
8792 function beginFailedWork(current, workInProgress, renderExpirationTime) {
8793 // Push context providers here to avoid a push/pop context mismatch.
8794 switch (workInProgress.tag) {
8795 case ClassComponent:
8796 pushContextProvider(workInProgress);
8797 break;
8798 case HostRoot:
8799 pushHostRootContext(workInProgress);
8800 break;
8801 default:
8802 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
8803 }
8804
8805 // Add an error effect so we can handle the error during the commit phase
8806 workInProgress.effectTag |= Err;
8807
8808 // This is a weird case where we do "resume" work ? work that failed on
8809 // our first attempt. Because we no longer have a notion of "progressed
8810 // deletions," reset the child to the current child to make sure we delete
8811 // it again. TODO: Find a better way to handle this, perhaps during a more
8812 // general overhaul of error handling.
8813 if (current === null) {
8814 workInProgress.child = null;
8815 } else if (workInProgress.child !== current.child) {
8816 workInProgress.child = current.child;
8817 }
8818
8819 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8820 return bailoutOnLowPriority(current, workInProgress);
8821 }
8822
8823 // If we don't bail out, we're going be recomputing our children so we need
8824 // to drop our effect list.
8825 workInProgress.firstEffect = null;
8826 workInProgress.lastEffect = null;
8827
8828 // Unmount the current children as if the component rendered null
8829 var nextChildren = null;
8830 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime);
8831
8832 if (workInProgress.tag === ClassComponent) {
8833 var instance = workInProgress.stateNode;
8834 workInProgress.memoizedProps = instance.props;
8835 workInProgress.memoizedState = instance.state;
8836 }
8837
8838 return workInProgress.child;
8839 }
8840
8841 return {
8842 beginWork: beginWork,
8843 beginFailedWork: beginFailedWork
8844 };
8845};
8846
8847var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) {
8848 var createInstance = config.createInstance,
8849 createTextInstance = config.createTextInstance,
8850 appendInitialChild = config.appendInitialChild,
8851 finalizeInitialChildren = config.finalizeInitialChildren,
8852 prepareUpdate = config.prepareUpdate,
8853 mutation = config.mutation,
8854 persistence = config.persistence;
8855 var getRootHostContainer = hostContext.getRootHostContainer,
8856 popHostContext = hostContext.popHostContext,
8857 getHostContext = hostContext.getHostContext,
8858 popHostContainer = hostContext.popHostContainer;
8859 var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance,
8860 prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance,
8861 popHydrationState = hydrationContext.popHydrationState;
8862
8863
8864 function markUpdate(workInProgress) {
8865 // Tag the fiber with an update effect. This turns a Placement into
8866 // an UpdateAndPlacement.
8867 workInProgress.effectTag |= Update;
8868 }
8869
8870 function markRef(workInProgress) {
8871 workInProgress.effectTag |= Ref;
8872 }
8873
8874 function appendAllReturns(returns, workInProgress) {
8875 var node = workInProgress.stateNode;
8876 if (node) {
8877 node['return'] = workInProgress;
8878 }
8879 while (node !== null) {
8880 if (node.tag === HostComponent || node.tag === HostText || node.tag === HostPortal) {
8881 invariant_1(false, 'A call cannot have host component children.');
8882 } else if (node.tag === ReturnComponent) {
8883 returns.push(node.pendingProps.value);
8884 } else if (node.child !== null) {
8885 node.child['return'] = node;
8886 node = node.child;
8887 continue;
8888 }
8889 while (node.sibling === null) {
8890 if (node['return'] === null || node['return'] === workInProgress) {
8891 return;
8892 }
8893 node = node['return'];
8894 }
8895 node.sibling['return'] = node['return'];
8896 node = node.sibling;
8897 }
8898 }
8899
8900 function moveCallToHandlerPhase(current, workInProgress, renderExpirationTime) {
8901 var props = workInProgress.memoizedProps;
8902 !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;
8903
8904 // First step of the call has completed. Now we need to do the second.
8905 // TODO: It would be nice to have a multi stage call represented by a
8906 // single component, or at least tail call optimize nested ones. Currently
8907 // that requires additional fields that we don't want to add to the fiber.
8908 // So this requires nested handlers.
8909 // Note: This doesn't mutate the alternate node. I don't think it needs to
8910 // since this stage is reset for every pass.
8911 workInProgress.tag = CallHandlerPhase;
8912
8913 // Build up the returns.
8914 // TODO: Compare this to a generator or opaque helpers like Children.
8915 var returns = [];
8916 appendAllReturns(returns, workInProgress);
8917 var fn = props.handler;
8918 var childProps = props.props;
8919 var nextChildren = fn(childProps, returns);
8920
8921 var currentFirstChild = current !== null ? current.child : null;
8922 workInProgress.child = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, renderExpirationTime);
8923 return workInProgress.child;
8924 }
8925
8926 function appendAllChildren(parent, workInProgress) {
8927 // We only have the top Fiber that was created but we need recurse down its
8928 // children to find all the terminal nodes.
8929 var node = workInProgress.child;
8930 while (node !== null) {
8931 if (node.tag === HostComponent || node.tag === HostText) {
8932 appendInitialChild(parent, node.stateNode);
8933 } else if (node.tag === HostPortal) {
8934 // If we have a portal child, then we don't want to traverse
8935 // down its children. Instead, we'll get insertions from each child in
8936 // the portal directly.
8937 } else if (node.child !== null) {
8938 node.child['return'] = node;
8939 node = node.child;
8940 continue;
8941 }
8942 if (node === workInProgress) {
8943 return;
8944 }
8945 while (node.sibling === null) {
8946 if (node['return'] === null || node['return'] === workInProgress) {
8947 return;
8948 }
8949 node = node['return'];
8950 }
8951 node.sibling['return'] = node['return'];
8952 node = node.sibling;
8953 }
8954 }
8955
8956 var updateHostContainer = void 0;
8957 var updateHostComponent = void 0;
8958 var updateHostText = void 0;
8959 if (mutation) {
8960 if (enableMutatingReconciler) {
8961 // Mutation mode
8962 updateHostContainer = function (workInProgress) {
8963 // Noop
8964 };
8965 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
8966 // TODO: Type this specific to this type of component.
8967 workInProgress.updateQueue = updatePayload;
8968 // If the update payload indicates that there is a change or if there
8969 // is a new ref we mark this as an update. All the work is done in commitWork.
8970 if (updatePayload) {
8971 markUpdate(workInProgress);
8972 }
8973 };
8974 updateHostText = function (current, workInProgress, oldText, newText) {
8975 // If the text differs, mark it as an update. All the work in done in commitWork.
8976 if (oldText !== newText) {
8977 markUpdate(workInProgress);
8978 }
8979 };
8980 } else {
8981 invariant_1(false, 'Mutating reconciler is disabled.');
8982 }
8983 } else if (persistence) {
8984 if (enablePersistentReconciler) {
8985 // Persistent host tree mode
8986 var cloneInstance = persistence.cloneInstance,
8987 createContainerChildSet = persistence.createContainerChildSet,
8988 appendChildToContainerChildSet = persistence.appendChildToContainerChildSet,
8989 finalizeContainerChildren = persistence.finalizeContainerChildren;
8990
8991 // An unfortunate fork of appendAllChildren because we have two different parent types.
8992
8993 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) {
8994 // We only have the top Fiber that was created but we need recurse down its
8995 // children to find all the terminal nodes.
8996 var node = workInProgress.child;
8997 while (node !== null) {
8998 if (node.tag === HostComponent || node.tag === HostText) {
8999 appendChildToContainerChildSet(containerChildSet, node.stateNode);
9000 } else if (node.tag === HostPortal) {
9001 // If we have a portal child, then we don't want to traverse
9002 // down its children. Instead, we'll get insertions from each child in
9003 // the portal directly.
9004 } else if (node.child !== null) {
9005 node.child['return'] = node;
9006 node = node.child;
9007 continue;
9008 }
9009 if (node === workInProgress) {
9010 return;
9011 }
9012 while (node.sibling === null) {
9013 if (node['return'] === null || node['return'] === workInProgress) {
9014 return;
9015 }
9016 node = node['return'];
9017 }
9018 node.sibling['return'] = node['return'];
9019 node = node.sibling;
9020 }
9021 };
9022 updateHostContainer = function (workInProgress) {
9023 var portalOrRoot = workInProgress.stateNode;
9024 var childrenUnchanged = workInProgress.firstEffect === null;
9025 if (childrenUnchanged) {
9026 // No changes, just reuse the existing instance.
9027 } else {
9028 var container = portalOrRoot.containerInfo;
9029 var newChildSet = createContainerChildSet(container);
9030 if (finalizeContainerChildren(container, newChildSet)) {
9031 markUpdate(workInProgress);
9032 }
9033 portalOrRoot.pendingChildren = newChildSet;
9034 // If children might have changed, we have to add them all to the set.
9035 appendAllChildrenToContainer(newChildSet, workInProgress);
9036 // Schedule an update on the container to swap out the container.
9037 markUpdate(workInProgress);
9038 }
9039 };
9040 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9041 // If there are no effects associated with this node, then none of our children had any updates.
9042 // This guarantees that we can reuse all of them.
9043 var childrenUnchanged = workInProgress.firstEffect === null;
9044 var currentInstance = current.stateNode;
9045 if (childrenUnchanged && updatePayload === null) {
9046 // No changes, just reuse the existing instance.
9047 // Note that this might release a previous clone.
9048 workInProgress.stateNode = currentInstance;
9049 } else {
9050 var recyclableInstance = workInProgress.stateNode;
9051 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9052 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9053 markUpdate(workInProgress);
9054 }
9055 workInProgress.stateNode = newInstance;
9056 if (childrenUnchanged) {
9057 // If there are no other effects in this tree, we need to flag this node as having one.
9058 // Even though we're not going to use it for anything.
9059 // Otherwise parents won't know that there are new children to propagate upwards.
9060 markUpdate(workInProgress);
9061 } else {
9062 // If children might have changed, we have to add them all to the set.
9063 appendAllChildren(newInstance, workInProgress);
9064 }
9065 }
9066 };
9067 updateHostText = function (current, workInProgress, oldText, newText) {
9068 if (oldText !== newText) {
9069 // If the text content differs, we'll create a new text instance for it.
9070 var rootContainerInstance = getRootHostContainer();
9071 var currentHostContext = getHostContext();
9072 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9073 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9074 // This lets the parents know that at least one of their children has changed.
9075 markUpdate(workInProgress);
9076 }
9077 };
9078 } else {
9079 invariant_1(false, 'Persistent reconciler is disabled.');
9080 }
9081 } else {
9082 if (enableNoopReconciler) {
9083 // No host operations
9084 updateHostContainer = function (workInProgress) {
9085 // Noop
9086 };
9087 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9088 // Noop
9089 };
9090 updateHostText = function (current, workInProgress, oldText, newText) {
9091 // Noop
9092 };
9093 } else {
9094 invariant_1(false, 'Noop reconciler is disabled.');
9095 }
9096 }
9097
9098 function completeWork(current, workInProgress, renderExpirationTime) {
9099 var newProps = workInProgress.pendingProps;
9100 switch (workInProgress.tag) {
9101 case FunctionalComponent:
9102 return null;
9103 case ClassComponent:
9104 {
9105 // We are leaving this subtree, so pop context if any.
9106 popContextProvider(workInProgress);
9107 return null;
9108 }
9109 case HostRoot:
9110 {
9111 popHostContainer(workInProgress);
9112 popTopLevelContextObject(workInProgress);
9113 var fiberRoot = workInProgress.stateNode;
9114 if (fiberRoot.pendingContext) {
9115 fiberRoot.context = fiberRoot.pendingContext;
9116 fiberRoot.pendingContext = null;
9117 }
9118
9119 if (current === null || current.child === null) {
9120 // If we hydrated, pop so that we can delete any remaining children
9121 // that weren't hydrated.
9122 popHydrationState(workInProgress);
9123 // This resets the hacky state to fix isMounted before committing.
9124 // TODO: Delete this when we delete isMounted and findDOMNode.
9125 workInProgress.effectTag &= ~Placement;
9126 }
9127 updateHostContainer(workInProgress);
9128 return null;
9129 }
9130 case HostComponent:
9131 {
9132 popHostContext(workInProgress);
9133 var rootContainerInstance = getRootHostContainer();
9134 var type = workInProgress.type;
9135 if (current !== null && workInProgress.stateNode != null) {
9136 // If we have an alternate, that means this is an update and we need to
9137 // schedule a side-effect to do the updates.
9138 var oldProps = current.memoizedProps;
9139 // If we get updated because one of our children updated, we don't
9140 // have newProps so we'll have to reuse them.
9141 // TODO: Split the update API as separate for the props vs. children.
9142 // Even better would be if children weren't special cased at all tho.
9143 var instance = workInProgress.stateNode;
9144 var currentHostContext = getHostContext();
9145 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9146
9147 updateHostComponent(current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9148
9149 if (current.ref !== workInProgress.ref) {
9150 markRef(workInProgress);
9151 }
9152 } else {
9153 if (!newProps) {
9154 !(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;
9155 // This can happen when we abort work.
9156 return null;
9157 }
9158
9159 var _currentHostContext = getHostContext();
9160 // TODO: Move createInstance to beginWork and keep it on a context
9161 // "stack" as the parent. Then append children as we go in beginWork
9162 // or completeWork depending on we want to add then top->down or
9163 // bottom->up. Top->down is faster in IE11.
9164 var wasHydrated = popHydrationState(workInProgress);
9165 if (wasHydrated) {
9166 // TODO: Move this and createInstance step into the beginPhase
9167 // to consolidate.
9168 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) {
9169 // If changes to the hydrated node needs to be applied at the
9170 // commit-phase we mark this as such.
9171 markUpdate(workInProgress);
9172 }
9173 } else {
9174 var _instance = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress);
9175
9176 appendAllChildren(_instance, workInProgress);
9177
9178 // Certain renderers require commit-time effects for initial mount.
9179 // (eg DOM renderer supports auto-focus for certain elements).
9180 // Make sure such renderers get scheduled for later work.
9181 if (finalizeInitialChildren(_instance, type, newProps, rootContainerInstance, _currentHostContext)) {
9182 markUpdate(workInProgress);
9183 }
9184 workInProgress.stateNode = _instance;
9185 }
9186
9187 if (workInProgress.ref !== null) {
9188 // If there is a ref on a host node we need to schedule a callback
9189 markRef(workInProgress);
9190 }
9191 }
9192 return null;
9193 }
9194 case HostText:
9195 {
9196 var newText = newProps;
9197 if (current && workInProgress.stateNode != null) {
9198 var oldText = current.memoizedProps;
9199 // If we have an alternate, that means this is an update and we need
9200 // to schedule a side-effect to do the updates.
9201 updateHostText(current, workInProgress, oldText, newText);
9202 } else {
9203 if (typeof newText !== 'string') {
9204 !(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;
9205 // This can happen when we abort work.
9206 return null;
9207 }
9208 var _rootContainerInstance = getRootHostContainer();
9209 var _currentHostContext2 = getHostContext();
9210 var _wasHydrated = popHydrationState(workInProgress);
9211 if (_wasHydrated) {
9212 if (prepareToHydrateHostTextInstance(workInProgress)) {
9213 markUpdate(workInProgress);
9214 }
9215 } else {
9216 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress);
9217 }
9218 }
9219 return null;
9220 }
9221 case CallComponent:
9222 return moveCallToHandlerPhase(current, workInProgress, renderExpirationTime);
9223 case CallHandlerPhase:
9224 // Reset the tag to now be a first phase call.
9225 workInProgress.tag = CallComponent;
9226 return null;
9227 case ReturnComponent:
9228 // Does nothing.
9229 return null;
9230 case Fragment:
9231 return null;
9232 case HostPortal:
9233 popHostContainer(workInProgress);
9234 updateHostContainer(workInProgress);
9235 return null;
9236 // Error cases
9237 case IndeterminateComponent:
9238 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.');
9239 // eslint-disable-next-line no-fallthrough
9240 default:
9241 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9242 }
9243 }
9244
9245 return {
9246 completeWork: completeWork
9247 };
9248};
9249
9250var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback;
9251var hasCaughtError$1 = ReactErrorUtils.hasCaughtError;
9252var clearCaughtError$1 = ReactErrorUtils.clearCaughtError;
9253
9254
9255var ReactFiberCommitWork = function (config, captureError) {
9256 var getPublicInstance = config.getPublicInstance,
9257 mutation = config.mutation,
9258 persistence = config.persistence;
9259
9260
9261 var callComponentWillUnmountWithTimer = function (current, instance) {
9262 startPhaseTimer(current, 'componentWillUnmount');
9263 instance.props = current.memoizedProps;
9264 instance.state = current.memoizedState;
9265 instance.componentWillUnmount();
9266 stopPhaseTimer();
9267 };
9268
9269 // Capture errors so they don't interrupt unmounting.
9270 function safelyCallComponentWillUnmount(current, instance) {
9271 {
9272 invokeGuardedCallback$3(null, callComponentWillUnmountWithTimer, null, current, instance);
9273 if (hasCaughtError$1()) {
9274 var unmountError = clearCaughtError$1();
9275 captureError(current, unmountError);
9276 }
9277 }
9278 }
9279
9280 function safelyDetachRef(current) {
9281 var ref = current.ref;
9282 if (ref !== null) {
9283 {
9284 invokeGuardedCallback$3(null, ref, null, null);
9285 if (hasCaughtError$1()) {
9286 var refError = clearCaughtError$1();
9287 captureError(current, refError);
9288 }
9289 }
9290 }
9291 }
9292
9293 function commitLifeCycles(current, finishedWork) {
9294 switch (finishedWork.tag) {
9295 case ClassComponent:
9296 {
9297 var instance = finishedWork.stateNode;
9298 if (finishedWork.effectTag & Update) {
9299 if (current === null) {
9300 startPhaseTimer(finishedWork, 'componentDidMount');
9301 instance.props = finishedWork.memoizedProps;
9302 instance.state = finishedWork.memoizedState;
9303 instance.componentDidMount();
9304 stopPhaseTimer();
9305 } else {
9306 var prevProps = current.memoizedProps;
9307 var prevState = current.memoizedState;
9308 startPhaseTimer(finishedWork, 'componentDidUpdate');
9309 instance.props = finishedWork.memoizedProps;
9310 instance.state = finishedWork.memoizedState;
9311 instance.componentDidUpdate(prevProps, prevState);
9312 stopPhaseTimer();
9313 }
9314 }
9315 var updateQueue = finishedWork.updateQueue;
9316 if (updateQueue !== null) {
9317 commitCallbacks(updateQueue, instance);
9318 }
9319 return;
9320 }
9321 case HostRoot:
9322 {
9323 var _updateQueue = finishedWork.updateQueue;
9324 if (_updateQueue !== null) {
9325 var _instance = finishedWork.child !== null ? finishedWork.child.stateNode : null;
9326 commitCallbacks(_updateQueue, _instance);
9327 }
9328 return;
9329 }
9330 case HostComponent:
9331 {
9332 var _instance2 = finishedWork.stateNode;
9333
9334 // Renderers may schedule work to be done after host components are mounted
9335 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9336 // These effects should only be committed when components are first mounted,
9337 // aka when there is no current/alternate.
9338 if (current === null && finishedWork.effectTag & Update) {
9339 var type = finishedWork.type;
9340 var props = finishedWork.memoizedProps;
9341 commitMount(_instance2, type, props, finishedWork);
9342 }
9343
9344 return;
9345 }
9346 case HostText:
9347 {
9348 // We have no life-cycles associated with text.
9349 return;
9350 }
9351 case HostPortal:
9352 {
9353 // We have no life-cycles associated with portals.
9354 return;
9355 }
9356 default:
9357 {
9358 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.');
9359 }
9360 }
9361 }
9362
9363 function commitAttachRef(finishedWork) {
9364 var ref = finishedWork.ref;
9365 if (ref !== null) {
9366 var instance = finishedWork.stateNode;
9367 switch (finishedWork.tag) {
9368 case HostComponent:
9369 ref(getPublicInstance(instance));
9370 break;
9371 default:
9372 ref(instance);
9373 }
9374 }
9375 }
9376
9377 function commitDetachRef(current) {
9378 var currentRef = current.ref;
9379 if (currentRef !== null) {
9380 currentRef(null);
9381 }
9382 }
9383
9384 // User-originating errors (lifecycles and refs) should not interrupt
9385 // deletion, so don't let them throw. Host-originating errors should
9386 // interrupt deletion, so it's okay
9387 function commitUnmount(current) {
9388 if (typeof onCommitUnmount === 'function') {
9389 onCommitUnmount(current);
9390 }
9391
9392 switch (current.tag) {
9393 case ClassComponent:
9394 {
9395 safelyDetachRef(current);
9396 var instance = current.stateNode;
9397 if (typeof instance.componentWillUnmount === 'function') {
9398 safelyCallComponentWillUnmount(current, instance);
9399 }
9400 return;
9401 }
9402 case HostComponent:
9403 {
9404 safelyDetachRef(current);
9405 return;
9406 }
9407 case CallComponent:
9408 {
9409 commitNestedUnmounts(current.stateNode);
9410 return;
9411 }
9412 case HostPortal:
9413 {
9414 // TODO: this is recursive.
9415 // We are also not using this parent because
9416 // the portal will get pushed immediately.
9417 if (enableMutatingReconciler && mutation) {
9418 unmountHostComponents(current);
9419 } else if (enablePersistentReconciler && persistence) {
9420 emptyPortalContainer(current);
9421 }
9422 return;
9423 }
9424 }
9425 }
9426
9427 function commitNestedUnmounts(root) {
9428 // While we're inside a removed host node we don't want to call
9429 // removeChild on the inner nodes because they're removed by the top
9430 // call anyway. We also want to call componentWillUnmount on all
9431 // composites before this host node is removed from the tree. Therefore
9432 var node = root;
9433 while (true) {
9434 commitUnmount(node);
9435 // Visit children because they may contain more composite or host nodes.
9436 // Skip portals because commitUnmount() currently visits them recursively.
9437 if (node.child !== null && (
9438 // If we use mutation we drill down into portals using commitUnmount above.
9439 // If we don't use mutation we drill down into portals here instead.
9440 !mutation || node.tag !== HostPortal)) {
9441 node.child['return'] = node;
9442 node = node.child;
9443 continue;
9444 }
9445 if (node === root) {
9446 return;
9447 }
9448 while (node.sibling === null) {
9449 if (node['return'] === null || node['return'] === root) {
9450 return;
9451 }
9452 node = node['return'];
9453 }
9454 node.sibling['return'] = node['return'];
9455 node = node.sibling;
9456 }
9457 }
9458
9459 function detachFiber(current) {
9460 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9461 // should clear the child pointer of the parent alternate to let this
9462 // get GC:ed but we don't know which for sure which parent is the current
9463 // one so we'll settle for GC:ing the subtree of this child. This child
9464 // itself will be GC:ed when the parent updates the next time.
9465 current['return'] = null;
9466 current.child = null;
9467 if (current.alternate) {
9468 current.alternate.child = null;
9469 current.alternate['return'] = null;
9470 }
9471 }
9472
9473 var emptyPortalContainer = void 0;
9474
9475 if (!mutation) {
9476 var commitContainer = void 0;
9477 if (persistence) {
9478 var replaceContainerChildren = persistence.replaceContainerChildren,
9479 createContainerChildSet = persistence.createContainerChildSet;
9480
9481 emptyPortalContainer = function (current) {
9482 var portal = current.stateNode;
9483 var containerInfo = portal.containerInfo;
9484
9485 var emptyChildSet = createContainerChildSet(containerInfo);
9486 replaceContainerChildren(containerInfo, emptyChildSet);
9487 };
9488 commitContainer = function (finishedWork) {
9489 switch (finishedWork.tag) {
9490 case ClassComponent:
9491 {
9492 return;
9493 }
9494 case HostComponent:
9495 {
9496 return;
9497 }
9498 case HostText:
9499 {
9500 return;
9501 }
9502 case HostRoot:
9503 case HostPortal:
9504 {
9505 var portalOrRoot = finishedWork.stateNode;
9506 var containerInfo = portalOrRoot.containerInfo,
9507 _pendingChildren = portalOrRoot.pendingChildren;
9508
9509 replaceContainerChildren(containerInfo, _pendingChildren);
9510 return;
9511 }
9512 default:
9513 {
9514 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.');
9515 }
9516 }
9517 };
9518 } else {
9519 commitContainer = function (finishedWork) {
9520 // Noop
9521 };
9522 }
9523 if (enablePersistentReconciler || enableNoopReconciler) {
9524 return {
9525 commitResetTextContent: function (finishedWork) {},
9526 commitPlacement: function (finishedWork) {},
9527 commitDeletion: function (current) {
9528 // Detach refs and call componentWillUnmount() on the whole subtree.
9529 commitNestedUnmounts(current);
9530 detachFiber(current);
9531 },
9532 commitWork: function (current, finishedWork) {
9533 commitContainer(finishedWork);
9534 },
9535
9536 commitLifeCycles: commitLifeCycles,
9537 commitAttachRef: commitAttachRef,
9538 commitDetachRef: commitDetachRef
9539 };
9540 } else if (persistence) {
9541 invariant_1(false, 'Persistent reconciler is disabled.');
9542 } else {
9543 invariant_1(false, 'Noop reconciler is disabled.');
9544 }
9545 }
9546 var commitMount = mutation.commitMount,
9547 commitUpdate = mutation.commitUpdate,
9548 resetTextContent = mutation.resetTextContent,
9549 commitTextUpdate = mutation.commitTextUpdate,
9550 appendChild = mutation.appendChild,
9551 appendChildToContainer = mutation.appendChildToContainer,
9552 insertBefore = mutation.insertBefore,
9553 insertInContainerBefore = mutation.insertInContainerBefore,
9554 removeChild = mutation.removeChild,
9555 removeChildFromContainer = mutation.removeChildFromContainer;
9556
9557
9558 function getHostParentFiber(fiber) {
9559 var parent = fiber['return'];
9560 while (parent !== null) {
9561 if (isHostParent(parent)) {
9562 return parent;
9563 }
9564 parent = parent['return'];
9565 }
9566 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9567 }
9568
9569 function isHostParent(fiber) {
9570 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9571 }
9572
9573 function getHostSibling(fiber) {
9574 // We're going to search forward into the tree until we find a sibling host
9575 // node. Unfortunately, if multiple insertions are done in a row we have to
9576 // search past them. This leads to exponential search for the next sibling.
9577 var node = fiber;
9578 siblings: while (true) {
9579 // If we didn't find anything, let's try the next sibling.
9580 while (node.sibling === null) {
9581 if (node['return'] === null || isHostParent(node['return'])) {
9582 // If we pop out of the root or hit the parent the fiber we are the
9583 // last sibling.
9584 return null;
9585 }
9586 node = node['return'];
9587 }
9588 node.sibling['return'] = node['return'];
9589 node = node.sibling;
9590 while (node.tag !== HostComponent && node.tag !== HostText) {
9591 // If it is not host node and, we might have a host node inside it.
9592 // Try to search down until we find one.
9593 if (node.effectTag & Placement) {
9594 // If we don't have a child, try the siblings instead.
9595 continue siblings;
9596 }
9597 // If we don't have a child, try the siblings instead.
9598 // We also skip portals because they are not part of this host tree.
9599 if (node.child === null || node.tag === HostPortal) {
9600 continue siblings;
9601 } else {
9602 node.child['return'] = node;
9603 node = node.child;
9604 }
9605 }
9606 // Check if this host node is stable or about to be placed.
9607 if (!(node.effectTag & Placement)) {
9608 // Found it!
9609 return node.stateNode;
9610 }
9611 }
9612 }
9613
9614 function commitPlacement(finishedWork) {
9615 // Recursively insert all host nodes into the parent.
9616 var parentFiber = getHostParentFiber(finishedWork);
9617 var parent = void 0;
9618 var isContainer = void 0;
9619 switch (parentFiber.tag) {
9620 case HostComponent:
9621 parent = parentFiber.stateNode;
9622 isContainer = false;
9623 break;
9624 case HostRoot:
9625 parent = parentFiber.stateNode.containerInfo;
9626 isContainer = true;
9627 break;
9628 case HostPortal:
9629 parent = parentFiber.stateNode.containerInfo;
9630 isContainer = true;
9631 break;
9632 default:
9633 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9634 }
9635 if (parentFiber.effectTag & ContentReset) {
9636 // Reset the text content of the parent before doing any insertions
9637 resetTextContent(parent);
9638 // Clear ContentReset from the effect tag
9639 parentFiber.effectTag &= ~ContentReset;
9640 }
9641
9642 var before = getHostSibling(finishedWork);
9643 // We only have the top Fiber that was inserted but we need recurse down its
9644 // children to find all the terminal nodes.
9645 var node = finishedWork;
9646 while (true) {
9647 if (node.tag === HostComponent || node.tag === HostText) {
9648 if (before) {
9649 if (isContainer) {
9650 insertInContainerBefore(parent, node.stateNode, before);
9651 } else {
9652 insertBefore(parent, node.stateNode, before);
9653 }
9654 } else {
9655 if (isContainer) {
9656 appendChildToContainer(parent, node.stateNode);
9657 } else {
9658 appendChild(parent, node.stateNode);
9659 }
9660 }
9661 } else if (node.tag === HostPortal) {
9662 // If the insertion itself is a portal, then we don't want to traverse
9663 // down its children. Instead, we'll get insertions from each child in
9664 // the portal directly.
9665 } else if (node.child !== null) {
9666 node.child['return'] = node;
9667 node = node.child;
9668 continue;
9669 }
9670 if (node === finishedWork) {
9671 return;
9672 }
9673 while (node.sibling === null) {
9674 if (node['return'] === null || node['return'] === finishedWork) {
9675 return;
9676 }
9677 node = node['return'];
9678 }
9679 node.sibling['return'] = node['return'];
9680 node = node.sibling;
9681 }
9682 }
9683
9684 function unmountHostComponents(current) {
9685 // We only have the top Fiber that was inserted but we need recurse down its
9686 var node = current;
9687
9688 // Each iteration, currentParent is populated with node's host parent if not
9689 // currentParentIsValid.
9690 var currentParentIsValid = false;
9691 var currentParent = void 0;
9692 var currentParentIsContainer = void 0;
9693
9694 while (true) {
9695 if (!currentParentIsValid) {
9696 var parent = node['return'];
9697 findParent: while (true) {
9698 !(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;
9699 switch (parent.tag) {
9700 case HostComponent:
9701 currentParent = parent.stateNode;
9702 currentParentIsContainer = false;
9703 break findParent;
9704 case HostRoot:
9705 currentParent = parent.stateNode.containerInfo;
9706 currentParentIsContainer = true;
9707 break findParent;
9708 case HostPortal:
9709 currentParent = parent.stateNode.containerInfo;
9710 currentParentIsContainer = true;
9711 break findParent;
9712 }
9713 parent = parent['return'];
9714 }
9715 currentParentIsValid = true;
9716 }
9717
9718 if (node.tag === HostComponent || node.tag === HostText) {
9719 commitNestedUnmounts(node);
9720 // After all the children have unmounted, it is now safe to remove the
9721 // node from the tree.
9722 if (currentParentIsContainer) {
9723 removeChildFromContainer(currentParent, node.stateNode);
9724 } else {
9725 removeChild(currentParent, node.stateNode);
9726 }
9727 // Don't visit children because we already visited them.
9728 } else if (node.tag === HostPortal) {
9729 // When we go into a portal, it becomes the parent to remove from.
9730 // We will reassign it back when we pop the portal on the way up.
9731 currentParent = node.stateNode.containerInfo;
9732 // Visit children because portals might contain host components.
9733 if (node.child !== null) {
9734 node.child['return'] = node;
9735 node = node.child;
9736 continue;
9737 }
9738 } else {
9739 commitUnmount(node);
9740 // Visit children because we may find more host components below.
9741 if (node.child !== null) {
9742 node.child['return'] = node;
9743 node = node.child;
9744 continue;
9745 }
9746 }
9747 if (node === current) {
9748 return;
9749 }
9750 while (node.sibling === null) {
9751 if (node['return'] === null || node['return'] === current) {
9752 return;
9753 }
9754 node = node['return'];
9755 if (node.tag === HostPortal) {
9756 // When we go out of the portal, we need to restore the parent.
9757 // Since we don't keep a stack of them, we will search for it.
9758 currentParentIsValid = false;
9759 }
9760 }
9761 node.sibling['return'] = node['return'];
9762 node = node.sibling;
9763 }
9764 }
9765
9766 function commitDeletion(current) {
9767 // Recursively delete all host nodes from the parent.
9768 // Detach refs and call componentWillUnmount() on the whole subtree.
9769 unmountHostComponents(current);
9770 detachFiber(current);
9771 }
9772
9773 function commitWork(current, finishedWork) {
9774 switch (finishedWork.tag) {
9775 case ClassComponent:
9776 {
9777 return;
9778 }
9779 case HostComponent:
9780 {
9781 var instance = finishedWork.stateNode;
9782 if (instance != null) {
9783 // Commit the work prepared earlier.
9784 var newProps = finishedWork.memoizedProps;
9785 // For hydration we reuse the update path but we treat the oldProps
9786 // as the newProps. The updatePayload will contain the real change in
9787 // this case.
9788 var oldProps = current !== null ? current.memoizedProps : newProps;
9789 var type = finishedWork.type;
9790 // TODO: Type the updateQueue to be specific to host components.
9791 var updatePayload = finishedWork.updateQueue;
9792 finishedWork.updateQueue = null;
9793 if (updatePayload !== null) {
9794 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
9795 }
9796 }
9797 return;
9798 }
9799 case HostText:
9800 {
9801 !(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;
9802 var textInstance = finishedWork.stateNode;
9803 var newText = finishedWork.memoizedProps;
9804 // For hydration we reuse the update path but we treat the oldProps
9805 // as the newProps. The updatePayload will contain the real change in
9806 // this case.
9807 var oldText = current !== null ? current.memoizedProps : newText;
9808 commitTextUpdate(textInstance, oldText, newText);
9809 return;
9810 }
9811 case HostRoot:
9812 {
9813 return;
9814 }
9815 default:
9816 {
9817 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.');
9818 }
9819 }
9820 }
9821
9822 function commitResetTextContent(current) {
9823 resetTextContent(current.stateNode);
9824 }
9825
9826 if (enableMutatingReconciler) {
9827 return {
9828 commitResetTextContent: commitResetTextContent,
9829 commitPlacement: commitPlacement,
9830 commitDeletion: commitDeletion,
9831 commitWork: commitWork,
9832 commitLifeCycles: commitLifeCycles,
9833 commitAttachRef: commitAttachRef,
9834 commitDetachRef: commitDetachRef
9835 };
9836 } else {
9837 invariant_1(false, 'Mutating reconciler is disabled.');
9838 }
9839};
9840
9841var NO_CONTEXT = {};
9842
9843var ReactFiberHostContext = function (config) {
9844 var getChildHostContext = config.getChildHostContext,
9845 getRootHostContext = config.getRootHostContext;
9846
9847
9848 var contextStackCursor = createCursor(NO_CONTEXT);
9849 var contextFiberStackCursor = createCursor(NO_CONTEXT);
9850 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
9851
9852 function requiredContext(c) {
9853 !(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;
9854 return c;
9855 }
9856
9857 function getRootHostContainer() {
9858 var rootInstance = requiredContext(rootInstanceStackCursor.current);
9859 return rootInstance;
9860 }
9861
9862 function pushHostContainer(fiber, nextRootInstance) {
9863 // Push current root instance onto the stack;
9864 // This allows us to reset root when portals are popped.
9865 push(rootInstanceStackCursor, nextRootInstance, fiber);
9866
9867 var nextRootContext = getRootHostContext(nextRootInstance);
9868
9869 // Track the context and the Fiber that provided it.
9870 // This enables us to pop only Fibers that provide unique contexts.
9871 push(contextFiberStackCursor, fiber, fiber);
9872 push(contextStackCursor, nextRootContext, fiber);
9873 }
9874
9875 function popHostContainer(fiber) {
9876 pop(contextStackCursor, fiber);
9877 pop(contextFiberStackCursor, fiber);
9878 pop(rootInstanceStackCursor, fiber);
9879 }
9880
9881 function getHostContext() {
9882 var context = requiredContext(contextStackCursor.current);
9883 return context;
9884 }
9885
9886 function pushHostContext(fiber) {
9887 var rootInstance = requiredContext(rootInstanceStackCursor.current);
9888 var context = requiredContext(contextStackCursor.current);
9889 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
9890
9891 // Don't push this Fiber's context unless it's unique.
9892 if (context === nextContext) {
9893 return;
9894 }
9895
9896 // Track the context and the Fiber that provided it.
9897 // This enables us to pop only Fibers that provide unique contexts.
9898 push(contextFiberStackCursor, fiber, fiber);
9899 push(contextStackCursor, nextContext, fiber);
9900 }
9901
9902 function popHostContext(fiber) {
9903 // Do not pop unless this Fiber provided the current context.
9904 // pushHostContext() only pushes Fibers that provide unique contexts.
9905 if (contextFiberStackCursor.current !== fiber) {
9906 return;
9907 }
9908
9909 pop(contextStackCursor, fiber);
9910 pop(contextFiberStackCursor, fiber);
9911 }
9912
9913 function resetHostContainer() {
9914 contextStackCursor.current = NO_CONTEXT;
9915 rootInstanceStackCursor.current = NO_CONTEXT;
9916 }
9917
9918 return {
9919 getHostContext: getHostContext,
9920 getRootHostContainer: getRootHostContainer,
9921 popHostContainer: popHostContainer,
9922 popHostContext: popHostContext,
9923 pushHostContainer: pushHostContainer,
9924 pushHostContext: pushHostContext,
9925 resetHostContainer: resetHostContainer
9926 };
9927};
9928
9929var ReactFiberHydrationContext = function (config) {
9930 var shouldSetTextContent = config.shouldSetTextContent,
9931 hydration = config.hydration;
9932
9933 // If this doesn't have hydration mode.
9934
9935 if (!hydration) {
9936 return {
9937 enterHydrationState: function () {
9938 return false;
9939 },
9940 resetHydrationState: function () {},
9941 tryToClaimNextHydratableInstance: function () {},
9942 prepareToHydrateHostInstance: function () {
9943 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
9944 },
9945 prepareToHydrateHostTextInstance: function () {
9946 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
9947 },
9948 popHydrationState: function (fiber) {
9949 return false;
9950 }
9951 };
9952 }
9953
9954 var canHydrateInstance = hydration.canHydrateInstance,
9955 canHydrateTextInstance = hydration.canHydrateTextInstance,
9956 getNextHydratableSibling = hydration.getNextHydratableSibling,
9957 getFirstHydratableChild = hydration.getFirstHydratableChild,
9958 hydrateInstance = hydration.hydrateInstance,
9959 hydrateTextInstance = hydration.hydrateTextInstance,
9960 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
9961 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
9962 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
9963 didNotHydrateInstance = hydration.didNotHydrateInstance,
9964 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
9965 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
9966 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
9967 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
9968
9969 // The deepest Fiber on the stack involved in a hydration context.
9970 // This may have been an insertion or a hydration.
9971
9972 var hydrationParentFiber = null;
9973 var nextHydratableInstance = null;
9974 var isHydrating = false;
9975
9976 function enterHydrationState(fiber) {
9977 var parentInstance = fiber.stateNode.containerInfo;
9978 nextHydratableInstance = getFirstHydratableChild(parentInstance);
9979 hydrationParentFiber = fiber;
9980 isHydrating = true;
9981 return true;
9982 }
9983
9984 function deleteHydratableInstance(returnFiber, instance) {
9985 {
9986 switch (returnFiber.tag) {
9987 case HostRoot:
9988 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
9989 break;
9990 case HostComponent:
9991 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
9992 break;
9993 }
9994 }
9995
9996 var childToDelete = createFiberFromHostInstanceForDeletion();
9997 childToDelete.stateNode = instance;
9998 childToDelete['return'] = returnFiber;
9999 childToDelete.effectTag = Deletion;
10000
10001 // This might seem like it belongs on progressedFirstDeletion. However,
10002 // these children are not part of the reconciliation list of children.
10003 // Even if we abort and rereconcile the children, that will try to hydrate
10004 // again and the nodes are still in the host tree so these will be
10005 // recreated.
10006 if (returnFiber.lastEffect !== null) {
10007 returnFiber.lastEffect.nextEffect = childToDelete;
10008 returnFiber.lastEffect = childToDelete;
10009 } else {
10010 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
10011 }
10012 }
10013
10014 function insertNonHydratedInstance(returnFiber, fiber) {
10015 fiber.effectTag |= Placement;
10016 {
10017 switch (returnFiber.tag) {
10018 case HostRoot:
10019 {
10020 var parentContainer = returnFiber.stateNode.containerInfo;
10021 switch (fiber.tag) {
10022 case HostComponent:
10023 var type = fiber.type;
10024 var props = fiber.pendingProps;
10025 didNotFindHydratableContainerInstance(parentContainer, type, props);
10026 break;
10027 case HostText:
10028 var text = fiber.pendingProps;
10029 didNotFindHydratableContainerTextInstance(parentContainer, text);
10030 break;
10031 }
10032 break;
10033 }
10034 case HostComponent:
10035 {
10036 var parentType = returnFiber.type;
10037 var parentProps = returnFiber.memoizedProps;
10038 var parentInstance = returnFiber.stateNode;
10039 switch (fiber.tag) {
10040 case HostComponent:
10041 var _type = fiber.type;
10042 var _props = fiber.pendingProps;
10043 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
10044 break;
10045 case HostText:
10046 var _text = fiber.pendingProps;
10047 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
10048 break;
10049 }
10050 break;
10051 }
10052 default:
10053 return;
10054 }
10055 }
10056 }
10057
10058 function tryHydrate(fiber, nextInstance) {
10059 switch (fiber.tag) {
10060 case HostComponent:
10061 {
10062 var type = fiber.type;
10063 var props = fiber.pendingProps;
10064 var instance = canHydrateInstance(nextInstance, type, props);
10065 if (instance !== null) {
10066 fiber.stateNode = instance;
10067 return true;
10068 }
10069 return false;
10070 }
10071 case HostText:
10072 {
10073 var text = fiber.pendingProps;
10074 var textInstance = canHydrateTextInstance(nextInstance, text);
10075 if (textInstance !== null) {
10076 fiber.stateNode = textInstance;
10077 return true;
10078 }
10079 return false;
10080 }
10081 default:
10082 return false;
10083 }
10084 }
10085
10086 function tryToClaimNextHydratableInstance(fiber) {
10087 if (!isHydrating) {
10088 return;
10089 }
10090 var nextInstance = nextHydratableInstance;
10091 if (!nextInstance) {
10092 // Nothing to hydrate. Make it an insertion.
10093 insertNonHydratedInstance(hydrationParentFiber, fiber);
10094 isHydrating = false;
10095 hydrationParentFiber = fiber;
10096 return;
10097 }
10098 if (!tryHydrate(fiber, nextInstance)) {
10099 // If we can't hydrate this instance let's try the next one.
10100 // We use this as a heuristic. It's based on intuition and not data so it
10101 // might be flawed or unnecessary.
10102 nextInstance = getNextHydratableSibling(nextInstance);
10103 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
10104 // Nothing to hydrate. Make it an insertion.
10105 insertNonHydratedInstance(hydrationParentFiber, fiber);
10106 isHydrating = false;
10107 hydrationParentFiber = fiber;
10108 return;
10109 }
10110 // We matched the next one, we'll now assume that the first one was
10111 // superfluous and we'll delete it. Since we can't eagerly delete it
10112 // we'll have to schedule a deletion. To do that, this node needs a dummy
10113 // fiber associated with it.
10114 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
10115 }
10116 hydrationParentFiber = fiber;
10117 nextHydratableInstance = getFirstHydratableChild(nextInstance);
10118 }
10119
10120 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
10121 var instance = fiber.stateNode;
10122 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
10123 // TODO: Type this specific to this type of component.
10124 fiber.updateQueue = updatePayload;
10125 // If the update payload indicates that there is a change or if there
10126 // is a new ref we mark this as an update.
10127 if (updatePayload !== null) {
10128 return true;
10129 }
10130 return false;
10131 }
10132
10133 function prepareToHydrateHostTextInstance(fiber) {
10134 var textInstance = fiber.stateNode;
10135 var textContent = fiber.memoizedProps;
10136 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
10137 {
10138 if (shouldUpdate) {
10139 // We assume that prepareToHydrateHostTextInstance is called in a context where the
10140 // hydration parent is the parent host component of this host text.
10141 var returnFiber = hydrationParentFiber;
10142 if (returnFiber !== null) {
10143 switch (returnFiber.tag) {
10144 case HostRoot:
10145 {
10146 var parentContainer = returnFiber.stateNode.containerInfo;
10147 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
10148 break;
10149 }
10150 case HostComponent:
10151 {
10152 var parentType = returnFiber.type;
10153 var parentProps = returnFiber.memoizedProps;
10154 var parentInstance = returnFiber.stateNode;
10155 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
10156 break;
10157 }
10158 }
10159 }
10160 }
10161 }
10162 return shouldUpdate;
10163 }
10164
10165 function popToNextHostParent(fiber) {
10166 var parent = fiber['return'];
10167 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
10168 parent = parent['return'];
10169 }
10170 hydrationParentFiber = parent;
10171 }
10172
10173 function popHydrationState(fiber) {
10174 if (fiber !== hydrationParentFiber) {
10175 // We're deeper than the current hydration context, inside an inserted
10176 // tree.
10177 return false;
10178 }
10179 if (!isHydrating) {
10180 // If we're not currently hydrating but we're in a hydration context, then
10181 // we were an insertion and now need to pop up reenter hydration of our
10182 // siblings.
10183 popToNextHostParent(fiber);
10184 isHydrating = true;
10185 return false;
10186 }
10187
10188 var type = fiber.type;
10189
10190 // If we have any remaining hydratable nodes, we need to delete them now.
10191 // We only do this deeper than head and body since they tend to have random
10192 // other nodes in them. We also ignore components with pure text content in
10193 // side of them.
10194 // TODO: Better heuristic.
10195 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
10196 var nextInstance = nextHydratableInstance;
10197 while (nextInstance) {
10198 deleteHydratableInstance(fiber, nextInstance);
10199 nextInstance = getNextHydratableSibling(nextInstance);
10200 }
10201 }
10202
10203 popToNextHostParent(fiber);
10204 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
10205 return true;
10206 }
10207
10208 function resetHydrationState() {
10209 hydrationParentFiber = null;
10210 nextHydratableInstance = null;
10211 isHydrating = false;
10212 }
10213
10214 return {
10215 enterHydrationState: enterHydrationState,
10216 resetHydrationState: resetHydrationState,
10217 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
10218 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
10219 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
10220 popHydrationState: popHydrationState
10221 };
10222};
10223
10224// This lets us hook into Fiber to debug what it's doing.
10225// See https://github.com/facebook/react/pull/8033.
10226// This is not part of the public API, not even for React DevTools.
10227// You may only inject a debugTool if you work on React Fiber itself.
10228var ReactFiberInstrumentation = {
10229 debugTool: null
10230};
10231
10232var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10233
10234// This module is forked in different environments.
10235// By default, return `true` to log errors to the console.
10236// Forks can return `false` if this isn't desirable.
10237function showErrorDialog(capturedError) {
10238 return true;
10239}
10240
10241function logCapturedError(capturedError) {
10242 var logError = showErrorDialog(capturedError);
10243
10244 // Allow injected showErrorDialog() to prevent default console.error logging.
10245 // This enables renderers like ReactNative to better manage redbox behavior.
10246 if (logError === false) {
10247 return;
10248 }
10249
10250 var error = capturedError.error;
10251 var suppressLogging = error && error.suppressReactErrorLogging;
10252 if (suppressLogging) {
10253 return;
10254 }
10255
10256 {
10257 var componentName = capturedError.componentName,
10258 componentStack = capturedError.componentStack,
10259 errorBoundaryName = capturedError.errorBoundaryName,
10260 errorBoundaryFound = capturedError.errorBoundaryFound,
10261 willRetry = capturedError.willRetry;
10262
10263
10264 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10265
10266 var errorBoundaryMessage = void 0;
10267 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10268 if (errorBoundaryFound && errorBoundaryName) {
10269 if (willRetry) {
10270 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10271 } else {
10272 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10273 }
10274 } else {
10275 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.';
10276 }
10277 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10278
10279 // In development, we provide our own message with just the component stack.
10280 // We don't include the original error message and JS stack because the browser
10281 // has already printed it. Even if the application swallows the error, it is still
10282 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10283 console.error(combinedMessage);
10284 }
10285}
10286
10287var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
10288var hasCaughtError = ReactErrorUtils.hasCaughtError;
10289var clearCaughtError = ReactErrorUtils.clearCaughtError;
10290
10291
10292var didWarnAboutStateTransition = void 0;
10293var didWarnSetStateChildContext = void 0;
10294var warnAboutUpdateOnUnmounted = void 0;
10295var warnAboutInvalidUpdates = void 0;
10296
10297{
10298 didWarnAboutStateTransition = false;
10299 didWarnSetStateChildContext = false;
10300 var didWarnStateUpdateForUnmountedComponent = {};
10301
10302 warnAboutUpdateOnUnmounted = function (fiber) {
10303 var componentName = getComponentName(fiber) || 'ReactClass';
10304 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10305 return;
10306 }
10307 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);
10308 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10309 };
10310
10311 warnAboutInvalidUpdates = function (instance) {
10312 switch (ReactDebugCurrentFiber.phase) {
10313 case 'getChildContext':
10314 if (didWarnSetStateChildContext) {
10315 return;
10316 }
10317 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10318 didWarnSetStateChildContext = true;
10319 break;
10320 case 'render':
10321 if (didWarnAboutStateTransition) {
10322 return;
10323 }
10324 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`.');
10325 didWarnAboutStateTransition = true;
10326 break;
10327 }
10328 };
10329}
10330
10331var ReactFiberScheduler = function (config) {
10332 var hostContext = ReactFiberHostContext(config);
10333 var hydrationContext = ReactFiberHydrationContext(config);
10334 var popHostContainer = hostContext.popHostContainer,
10335 popHostContext = hostContext.popHostContext,
10336 resetHostContainer = hostContext.resetHostContainer;
10337
10338 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
10339 beginWork = _ReactFiberBeginWork.beginWork,
10340 beginFailedWork = _ReactFiberBeginWork.beginFailedWork;
10341
10342 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
10343 completeWork = _ReactFiberCompleteWo.completeWork;
10344
10345 var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError),
10346 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
10347 commitPlacement = _ReactFiberCommitWork.commitPlacement,
10348 commitDeletion = _ReactFiberCommitWork.commitDeletion,
10349 commitWork = _ReactFiberCommitWork.commitWork,
10350 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
10351 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
10352 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
10353
10354 var now = config.now,
10355 scheduleDeferredCallback = config.scheduleDeferredCallback,
10356 cancelDeferredCallback = config.cancelDeferredCallback,
10357 prepareForCommit = config.prepareForCommit,
10358 resetAfterCommit = config.resetAfterCommit;
10359
10360 // Represents the current time in ms.
10361
10362 var startTime = now();
10363 var mostRecentCurrentTime = msToExpirationTime(0);
10364
10365 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
10366 var lastUniqueAsyncExpiration = 0;
10367
10368 // Represents the expiration time that incoming updates should use. (If this
10369 // is NoWork, use the default strategy: async updates in async mode, sync
10370 // updates in sync mode.)
10371 var expirationContext = NoWork;
10372
10373 var isWorking = false;
10374
10375 // The next work in progress fiber that we're currently working on.
10376 var nextUnitOfWork = null;
10377 var nextRoot = null;
10378 // The time at which we're currently rendering work.
10379 var nextRenderExpirationTime = NoWork;
10380
10381 // The next fiber with an effect that we're currently committing.
10382 var nextEffect = null;
10383
10384 // Keep track of which fibers have captured an error that need to be handled.
10385 // Work is removed from this collection after componentDidCatch is called.
10386 var capturedErrors = null;
10387 // Keep track of which fibers have failed during the current batch of work.
10388 // This is a different set than capturedErrors, because it is not reset until
10389 // the end of the batch. This is needed to propagate errors correctly if a
10390 // subtree fails more than once.
10391 var failedBoundaries = null;
10392 // Error boundaries that captured an error during the current commit.
10393 var commitPhaseBoundaries = null;
10394 var firstUncaughtError = null;
10395 var didFatal = false;
10396
10397 var isCommitting = false;
10398 var isUnmounting = false;
10399
10400 // Used for performance tracking.
10401 var interruptedBy = null;
10402
10403 function resetContextStack() {
10404 // Reset the stack
10405 reset$1();
10406 // Reset the cursors
10407 resetContext();
10408 resetHostContainer();
10409 }
10410
10411 function commitAllHostEffects() {
10412 while (nextEffect !== null) {
10413 {
10414 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
10415 }
10416 recordEffect();
10417
10418 var effectTag = nextEffect.effectTag;
10419 if (effectTag & ContentReset) {
10420 commitResetTextContent(nextEffect);
10421 }
10422
10423 if (effectTag & Ref) {
10424 var current = nextEffect.alternate;
10425 if (current !== null) {
10426 commitDetachRef(current);
10427 }
10428 }
10429
10430 // The following switch statement is only concerned about placement,
10431 // updates, and deletions. To avoid needing to add a case for every
10432 // possible bitmap value, we remove the secondary effects from the
10433 // effect tag and switch on that value.
10434 var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
10435 switch (primaryEffectTag) {
10436 case Placement:
10437 {
10438 commitPlacement(nextEffect);
10439 // Clear the "placement" from effect tag so that we know that this is inserted, before
10440 // any life-cycles like componentDidMount gets called.
10441 // TODO: findDOMNode doesn't rely on this any more but isMounted
10442 // does and isMounted is deprecated anyway so we should be able
10443 // to kill this.
10444 nextEffect.effectTag &= ~Placement;
10445 break;
10446 }
10447 case PlacementAndUpdate:
10448 {
10449 // Placement
10450 commitPlacement(nextEffect);
10451 // Clear the "placement" from effect tag so that we know that this is inserted, before
10452 // any life-cycles like componentDidMount gets called.
10453 nextEffect.effectTag &= ~Placement;
10454
10455 // Update
10456 var _current = nextEffect.alternate;
10457 commitWork(_current, nextEffect);
10458 break;
10459 }
10460 case Update:
10461 {
10462 var _current2 = nextEffect.alternate;
10463 commitWork(_current2, nextEffect);
10464 break;
10465 }
10466 case Deletion:
10467 {
10468 isUnmounting = true;
10469 commitDeletion(nextEffect);
10470 isUnmounting = false;
10471 break;
10472 }
10473 }
10474 nextEffect = nextEffect.nextEffect;
10475 }
10476
10477 {
10478 ReactDebugCurrentFiber.resetCurrentFiber();
10479 }
10480 }
10481
10482 function commitAllLifeCycles() {
10483 while (nextEffect !== null) {
10484 var effectTag = nextEffect.effectTag;
10485
10486 if (effectTag & (Update | Callback)) {
10487 recordEffect();
10488 var current = nextEffect.alternate;
10489 commitLifeCycles(current, nextEffect);
10490 }
10491
10492 if (effectTag & Ref) {
10493 recordEffect();
10494 commitAttachRef(nextEffect);
10495 }
10496
10497 if (effectTag & Err) {
10498 recordEffect();
10499 commitErrorHandling(nextEffect);
10500 }
10501
10502 var next = nextEffect.nextEffect;
10503 // Ensure that we clean these up so that we don't accidentally keep them.
10504 // I'm not actually sure this matters because we can't reset firstEffect
10505 // and lastEffect since they're on every node, not just the effectful
10506 // ones. So we have to clean everything as we reuse nodes anyway.
10507 nextEffect.nextEffect = null;
10508 // Ensure that we reset the effectTag here so that we can rely on effect
10509 // tags to reason about the current life-cycle.
10510 nextEffect = next;
10511 }
10512 }
10513
10514 function commitRoot(finishedWork) {
10515 // We keep track of this so that captureError can collect any boundaries
10516 // that capture an error during the commit phase. The reason these aren't
10517 // local to this function is because errors that occur during cWU are
10518 // captured elsewhere, to prevent the unmount from being interrupted.
10519 isWorking = true;
10520 isCommitting = true;
10521 startCommitTimer();
10522
10523 var root = finishedWork.stateNode;
10524 !(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;
10525 root.isReadyForCommit = false;
10526
10527 // Reset this to null before calling lifecycles
10528 ReactCurrentOwner.current = null;
10529
10530 var firstEffect = void 0;
10531 if (finishedWork.effectTag > PerformedWork) {
10532 // A fiber's effect list consists only of its children, not itself. So if
10533 // the root has an effect, we need to add it to the end of the list. The
10534 // resulting list is the set that would belong to the root's parent, if
10535 // it had one; that is, all the effects in the tree including the root.
10536 if (finishedWork.lastEffect !== null) {
10537 finishedWork.lastEffect.nextEffect = finishedWork;
10538 firstEffect = finishedWork.firstEffect;
10539 } else {
10540 firstEffect = finishedWork;
10541 }
10542 } else {
10543 // There is no effect on the root.
10544 firstEffect = finishedWork.firstEffect;
10545 }
10546
10547 prepareForCommit();
10548
10549 // Commit all the side-effects within a tree. We'll do this in two passes.
10550 // The first pass performs all the host insertions, updates, deletions and
10551 // ref unmounts.
10552 nextEffect = firstEffect;
10553 startCommitHostEffectsTimer();
10554 while (nextEffect !== null) {
10555 var didError = false;
10556 var _error = void 0;
10557 {
10558 invokeGuardedCallback$2(null, commitAllHostEffects, null);
10559 if (hasCaughtError()) {
10560 didError = true;
10561 _error = clearCaughtError();
10562 }
10563 }
10564 if (didError) {
10565 !(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;
10566 captureError(nextEffect, _error);
10567 // Clean-up
10568 if (nextEffect !== null) {
10569 nextEffect = nextEffect.nextEffect;
10570 }
10571 }
10572 }
10573 stopCommitHostEffectsTimer();
10574
10575 resetAfterCommit();
10576
10577 // The work-in-progress tree is now the current tree. This must come after
10578 // the first pass of the commit phase, so that the previous tree is still
10579 // current during componentWillUnmount, but before the second pass, so that
10580 // the finished work is current during componentDidMount/Update.
10581 root.current = finishedWork;
10582
10583 // In the second pass we'll perform all life-cycles and ref callbacks.
10584 // Life-cycles happen as a separate pass so that all placements, updates,
10585 // and deletions in the entire tree have already been invoked.
10586 // This pass also triggers any renderer-specific initial effects.
10587 nextEffect = firstEffect;
10588 startCommitLifeCyclesTimer();
10589 while (nextEffect !== null) {
10590 var _didError = false;
10591 var _error2 = void 0;
10592 {
10593 invokeGuardedCallback$2(null, commitAllLifeCycles, null);
10594 if (hasCaughtError()) {
10595 _didError = true;
10596 _error2 = clearCaughtError();
10597 }
10598 }
10599 if (_didError) {
10600 !(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;
10601 captureError(nextEffect, _error2);
10602 if (nextEffect !== null) {
10603 nextEffect = nextEffect.nextEffect;
10604 }
10605 }
10606 }
10607
10608 isCommitting = false;
10609 isWorking = false;
10610 stopCommitLifeCyclesTimer();
10611 stopCommitTimer();
10612 if (typeof onCommitRoot === 'function') {
10613 onCommitRoot(finishedWork.stateNode);
10614 }
10615 if (true && ReactFiberInstrumentation_1.debugTool) {
10616 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
10617 }
10618
10619 // If we caught any errors during this commit, schedule their boundaries
10620 // to update.
10621 if (commitPhaseBoundaries) {
10622 commitPhaseBoundaries.forEach(scheduleErrorRecovery);
10623 commitPhaseBoundaries = null;
10624 }
10625
10626 if (firstUncaughtError !== null) {
10627 var _error3 = firstUncaughtError;
10628 firstUncaughtError = null;
10629 onUncaughtError(_error3);
10630 }
10631
10632 var remainingTime = root.current.expirationTime;
10633
10634 if (remainingTime === NoWork) {
10635 capturedErrors = null;
10636 failedBoundaries = null;
10637 }
10638
10639 return remainingTime;
10640 }
10641
10642 function resetExpirationTime(workInProgress, renderTime) {
10643 if (renderTime !== Never && workInProgress.expirationTime === Never) {
10644 // The children of this component are hidden. Don't bubble their
10645 // expiration times.
10646 return;
10647 }
10648
10649 // Check for pending updates.
10650 var newExpirationTime = getUpdateExpirationTime(workInProgress);
10651
10652 // TODO: Calls need to visit stateNode
10653
10654 // Bubble up the earliest expiration time.
10655 var child = workInProgress.child;
10656 while (child !== null) {
10657 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
10658 newExpirationTime = child.expirationTime;
10659 }
10660 child = child.sibling;
10661 }
10662 workInProgress.expirationTime = newExpirationTime;
10663 }
10664
10665 function completeUnitOfWork(workInProgress) {
10666 while (true) {
10667 // The current, flushed, state of this fiber is the alternate.
10668 // Ideally nothing should rely on this, but relying on it here
10669 // means that we don't need an additional field on the work in
10670 // progress.
10671 var current = workInProgress.alternate;
10672 {
10673 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10674 }
10675 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
10676 {
10677 ReactDebugCurrentFiber.resetCurrentFiber();
10678 }
10679
10680 var returnFiber = workInProgress['return'];
10681 var siblingFiber = workInProgress.sibling;
10682
10683 resetExpirationTime(workInProgress, nextRenderExpirationTime);
10684
10685 if (next !== null) {
10686 stopWorkTimer(workInProgress);
10687 if (true && ReactFiberInstrumentation_1.debugTool) {
10688 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10689 }
10690 // If completing this work spawned new work, do that next. We'll come
10691 // back here again.
10692 return next;
10693 }
10694
10695 if (returnFiber !== null) {
10696 // Append all the effects of the subtree and this fiber onto the effect
10697 // list of the parent. The completion order of the children affects the
10698 // side-effect order.
10699 if (returnFiber.firstEffect === null) {
10700 returnFiber.firstEffect = workInProgress.firstEffect;
10701 }
10702 if (workInProgress.lastEffect !== null) {
10703 if (returnFiber.lastEffect !== null) {
10704 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
10705 }
10706 returnFiber.lastEffect = workInProgress.lastEffect;
10707 }
10708
10709 // If this fiber had side-effects, we append it AFTER the children's
10710 // side-effects. We can perform certain side-effects earlier if
10711 // needed, by doing multiple passes over the effect list. We don't want
10712 // to schedule our own side-effect on our own list because if end up
10713 // reusing children we'll schedule this effect onto itself since we're
10714 // at the end.
10715 var effectTag = workInProgress.effectTag;
10716 // Skip both NoWork and PerformedWork tags when creating the effect list.
10717 // PerformedWork effect is read by React DevTools but shouldn't be committed.
10718 if (effectTag > PerformedWork) {
10719 if (returnFiber.lastEffect !== null) {
10720 returnFiber.lastEffect.nextEffect = workInProgress;
10721 } else {
10722 returnFiber.firstEffect = workInProgress;
10723 }
10724 returnFiber.lastEffect = workInProgress;
10725 }
10726 }
10727
10728 stopWorkTimer(workInProgress);
10729 if (true && ReactFiberInstrumentation_1.debugTool) {
10730 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10731 }
10732
10733 if (siblingFiber !== null) {
10734 // If there is more work to do in this returnFiber, do that next.
10735 return siblingFiber;
10736 } else if (returnFiber !== null) {
10737 // If there's no more work in this returnFiber. Complete the returnFiber.
10738 workInProgress = returnFiber;
10739 continue;
10740 } else {
10741 // We've reached the root.
10742 var root = workInProgress.stateNode;
10743 root.isReadyForCommit = true;
10744 return null;
10745 }
10746 }
10747
10748 // Without this explicit null return Flow complains of invalid return type
10749 // TODO Remove the above while(true) loop
10750 // eslint-disable-next-line no-unreachable
10751 return null;
10752 }
10753
10754 function performUnitOfWork(workInProgress) {
10755 // The current, flushed, state of this fiber is the alternate.
10756 // Ideally nothing should rely on this, but relying on it here
10757 // means that we don't need an additional field on the work in
10758 // progress.
10759 var current = workInProgress.alternate;
10760
10761 // See if beginning this work spawns more work.
10762 startWorkTimer(workInProgress);
10763 {
10764 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10765 }
10766
10767 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
10768 {
10769 ReactDebugCurrentFiber.resetCurrentFiber();
10770 }
10771 if (true && ReactFiberInstrumentation_1.debugTool) {
10772 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10773 }
10774
10775 if (next === null) {
10776 // If this doesn't spawn new work, complete the current work.
10777 next = completeUnitOfWork(workInProgress);
10778 }
10779
10780 ReactCurrentOwner.current = null;
10781
10782 return next;
10783 }
10784
10785 function performFailedUnitOfWork(workInProgress) {
10786 // The current, flushed, state of this fiber is the alternate.
10787 // Ideally nothing should rely on this, but relying on it here
10788 // means that we don't need an additional field on the work in
10789 // progress.
10790 var current = workInProgress.alternate;
10791
10792 // See if beginning this work spawns more work.
10793 startWorkTimer(workInProgress);
10794 {
10795 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10796 }
10797 var next = beginFailedWork(current, workInProgress, nextRenderExpirationTime);
10798 {
10799 ReactDebugCurrentFiber.resetCurrentFiber();
10800 }
10801 if (true && ReactFiberInstrumentation_1.debugTool) {
10802 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10803 }
10804
10805 if (next === null) {
10806 // If this doesn't spawn new work, complete the current work.
10807 next = completeUnitOfWork(workInProgress);
10808 }
10809
10810 ReactCurrentOwner.current = null;
10811
10812 return next;
10813 }
10814
10815 function workLoop(expirationTime) {
10816 if (capturedErrors !== null) {
10817 // If there are unhandled errors, switch to the slow work loop.
10818 // TODO: How to avoid this check in the fast path? Maybe the renderer
10819 // could keep track of which roots have unhandled errors and call a
10820 // forked version of renderRoot.
10821 slowWorkLoopThatChecksForFailedWork(expirationTime);
10822 return;
10823 }
10824 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10825 return;
10826 }
10827
10828 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10829 // Flush all expired work.
10830 while (nextUnitOfWork !== null) {
10831 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10832 }
10833 } else {
10834 // Flush asynchronous work until the deadline runs out of time.
10835 while (nextUnitOfWork !== null && !shouldYield()) {
10836 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10837 }
10838 }
10839 }
10840
10841 function slowWorkLoopThatChecksForFailedWork(expirationTime) {
10842 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10843 return;
10844 }
10845
10846 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10847 // Flush all expired work.
10848 while (nextUnitOfWork !== null) {
10849 if (hasCapturedError(nextUnitOfWork)) {
10850 // Use a forked version of performUnitOfWork
10851 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
10852 } else {
10853 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10854 }
10855 }
10856 } else {
10857 // Flush asynchronous work until the deadline runs out of time.
10858 while (nextUnitOfWork !== null && !shouldYield()) {
10859 if (hasCapturedError(nextUnitOfWork)) {
10860 // Use a forked version of performUnitOfWork
10861 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
10862 } else {
10863 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10864 }
10865 }
10866 }
10867 }
10868
10869 function renderRootCatchBlock(root, failedWork, boundary, expirationTime) {
10870 // We're going to restart the error boundary that captured the error.
10871 // Conceptually, we're unwinding the stack. We need to unwind the
10872 // context stack, too.
10873 unwindContexts(failedWork, boundary);
10874
10875 // Restart the error boundary using a forked version of
10876 // performUnitOfWork that deletes the boundary's children. The entire
10877 // failed subree will be unmounted. During the commit phase, a special
10878 // lifecycle method is called on the error boundary, which triggers
10879 // a re-render.
10880 nextUnitOfWork = performFailedUnitOfWork(boundary);
10881
10882 // Continue working.
10883 workLoop(expirationTime);
10884 }
10885
10886 function renderRoot(root, expirationTime) {
10887 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10888 isWorking = true;
10889
10890 // We're about to mutate the work-in-progress tree. If the root was pending
10891 // commit, it no longer is: we'll need to complete it again.
10892 root.isReadyForCommit = false;
10893
10894 // Check if we're starting from a fresh stack, or if we're resuming from
10895 // previously yielded work.
10896 if (root !== nextRoot || expirationTime !== nextRenderExpirationTime || nextUnitOfWork === null) {
10897 // Reset the stack and start working from the root.
10898 resetContextStack();
10899 nextRoot = root;
10900 nextRenderExpirationTime = expirationTime;
10901 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, expirationTime);
10902 }
10903
10904 startWorkLoopTimer(nextUnitOfWork);
10905
10906 var didError = false;
10907 var error = null;
10908 {
10909 invokeGuardedCallback$2(null, workLoop, null, expirationTime);
10910 if (hasCaughtError()) {
10911 didError = true;
10912 error = clearCaughtError();
10913 }
10914 }
10915
10916 // An error was thrown during the render phase.
10917 while (didError) {
10918 if (didFatal) {
10919 // This was a fatal error. Don't attempt to recover from it.
10920 firstUncaughtError = error;
10921 break;
10922 }
10923
10924 var failedWork = nextUnitOfWork;
10925 if (failedWork === null) {
10926 // An error was thrown but there's no current unit of work. This can
10927 // happen during the commit phase if there's a bug in the renderer.
10928 didFatal = true;
10929 continue;
10930 }
10931
10932 // "Capture" the error by finding the nearest boundary. If there is no
10933 // error boundary, we use the root.
10934 var boundary = captureError(failedWork, error);
10935 !(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;
10936
10937 if (didFatal) {
10938 // The error we just captured was a fatal error. This happens
10939 // when the error propagates to the root more than once.
10940 continue;
10941 }
10942
10943 didError = false;
10944 error = null;
10945 {
10946 invokeGuardedCallback$2(null, renderRootCatchBlock, null, root, failedWork, boundary, expirationTime);
10947 if (hasCaughtError()) {
10948 didError = true;
10949 error = clearCaughtError();
10950 continue;
10951 }
10952 }
10953 // We're finished working. Exit the error loop.
10954 break;
10955 }
10956
10957 var uncaughtError = firstUncaughtError;
10958
10959 // We're done performing work. Time to clean up.
10960 stopWorkLoopTimer(interruptedBy);
10961 interruptedBy = null;
10962 isWorking = false;
10963 didFatal = false;
10964 firstUncaughtError = null;
10965
10966 if (uncaughtError !== null) {
10967 onUncaughtError(uncaughtError);
10968 }
10969
10970 return root.isReadyForCommit ? root.current.alternate : null;
10971 }
10972
10973 // Returns the boundary that captured the error, or null if the error is ignored
10974 function captureError(failedWork, error) {
10975 // It is no longer valid because we exited the user code.
10976 ReactCurrentOwner.current = null;
10977 {
10978 ReactDebugCurrentFiber.resetCurrentFiber();
10979 }
10980
10981 // Search for the nearest error boundary.
10982 var boundary = null;
10983
10984 // Passed to logCapturedError()
10985 var errorBoundaryFound = false;
10986 var willRetry = false;
10987 var errorBoundaryName = null;
10988
10989 // Host containers are a special case. If the failed work itself is a host
10990 // container, then it acts as its own boundary. In all other cases, we
10991 // ignore the work itself and only search through the parents.
10992 if (failedWork.tag === HostRoot) {
10993 boundary = failedWork;
10994
10995 if (isFailedBoundary(failedWork)) {
10996 // If this root already failed, there must have been an error when
10997 // attempting to unmount it. This is a worst-case scenario and
10998 // should only be possible if there's a bug in the renderer.
10999 didFatal = true;
11000 }
11001 } else {
11002 var node = failedWork['return'];
11003 while (node !== null && boundary === null) {
11004 if (node.tag === ClassComponent) {
11005 var instance = node.stateNode;
11006 if (typeof instance.componentDidCatch === 'function') {
11007 errorBoundaryFound = true;
11008 errorBoundaryName = getComponentName(node);
11009
11010 // Found an error boundary!
11011 boundary = node;
11012 willRetry = true;
11013 }
11014 } else if (node.tag === HostRoot) {
11015 // Treat the root like a no-op error boundary
11016 boundary = node;
11017 }
11018
11019 if (isFailedBoundary(node)) {
11020 // This boundary is already in a failed state.
11021
11022 // If we're currently unmounting, that means this error was
11023 // thrown while unmounting a failed subtree. We should ignore
11024 // the error.
11025 if (isUnmounting) {
11026 return null;
11027 }
11028
11029 // If we're in the commit phase, we should check to see if
11030 // this boundary already captured an error during this commit.
11031 // This case exists because multiple errors can be thrown during
11032 // a single commit without interruption.
11033 if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) {
11034 // If so, we should ignore this error.
11035 return null;
11036 }
11037
11038 // The error should propagate to the next boundary -? we keep looking.
11039 boundary = null;
11040 willRetry = false;
11041 }
11042
11043 node = node['return'];
11044 }
11045 }
11046
11047 if (boundary !== null) {
11048 // Add to the collection of failed boundaries. This lets us know that
11049 // subsequent errors in this subtree should propagate to the next boundary.
11050 if (failedBoundaries === null) {
11051 failedBoundaries = new Set();
11052 }
11053 failedBoundaries.add(boundary);
11054
11055 // This method is unsafe outside of the begin and complete phases.
11056 // We might be in the commit phase when an error is captured.
11057 // The risk is that the return path from this Fiber may not be accurate.
11058 // That risk is acceptable given the benefit of providing users more context.
11059 var _componentStack = getStackAddendumByWorkInProgressFiber(failedWork);
11060 var _componentName = getComponentName(failedWork);
11061
11062 // Add to the collection of captured errors. This is stored as a global
11063 // map of errors and their component stack location keyed by the boundaries
11064 // that capture them. We mostly use this Map as a Set; it's a Map only to
11065 // avoid adding a field to Fiber to store the error.
11066 if (capturedErrors === null) {
11067 capturedErrors = new Map();
11068 }
11069
11070 var capturedError = {
11071 componentName: _componentName,
11072 componentStack: _componentStack,
11073 error: error,
11074 errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
11075 errorBoundaryFound: errorBoundaryFound,
11076 errorBoundaryName: errorBoundaryName,
11077 willRetry: willRetry
11078 };
11079
11080 capturedErrors.set(boundary, capturedError);
11081
11082 try {
11083 logCapturedError(capturedError);
11084 } catch (e) {
11085 // Prevent cycle if logCapturedError() throws.
11086 // A cycle may still occur if logCapturedError renders a component that throws.
11087 var suppressLogging = e && e.suppressReactErrorLogging;
11088 if (!suppressLogging) {
11089 console.error(e);
11090 }
11091 }
11092
11093 // If we're in the commit phase, defer scheduling an update on the
11094 // boundary until after the commit is complete
11095 if (isCommitting) {
11096 if (commitPhaseBoundaries === null) {
11097 commitPhaseBoundaries = new Set();
11098 }
11099 commitPhaseBoundaries.add(boundary);
11100 } else {
11101 // Otherwise, schedule an update now.
11102 // TODO: Is this actually necessary during the render phase? Is it
11103 // possible to unwind and continue rendering at the same priority,
11104 // without corrupting internal state?
11105 scheduleErrorRecovery(boundary);
11106 }
11107 return boundary;
11108 } else if (firstUncaughtError === null) {
11109 // If no boundary is found, we'll need to throw the error
11110 firstUncaughtError = error;
11111 }
11112 return null;
11113 }
11114
11115 function hasCapturedError(fiber) {
11116 // TODO: capturedErrors should store the boundary instance, to avoid needing
11117 // to check the alternate.
11118 return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate));
11119 }
11120
11121 function isFailedBoundary(fiber) {
11122 // TODO: failedBoundaries should store the boundary instance, to avoid
11123 // needing to check the alternate.
11124 return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate));
11125 }
11126
11127 function commitErrorHandling(effectfulFiber) {
11128 var capturedError = void 0;
11129 if (capturedErrors !== null) {
11130 capturedError = capturedErrors.get(effectfulFiber);
11131 capturedErrors['delete'](effectfulFiber);
11132 if (capturedError == null) {
11133 if (effectfulFiber.alternate !== null) {
11134 effectfulFiber = effectfulFiber.alternate;
11135 capturedError = capturedErrors.get(effectfulFiber);
11136 capturedErrors['delete'](effectfulFiber);
11137 }
11138 }
11139 }
11140
11141 !(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;
11142
11143 switch (effectfulFiber.tag) {
11144 case ClassComponent:
11145 var instance = effectfulFiber.stateNode;
11146
11147 var info = {
11148 componentStack: capturedError.componentStack
11149 };
11150
11151 // Allow the boundary to handle the error, usually by scheduling
11152 // an update to itself
11153 instance.componentDidCatch(capturedError.error, info);
11154 return;
11155 case HostRoot:
11156 if (firstUncaughtError === null) {
11157 firstUncaughtError = capturedError.error;
11158 }
11159 return;
11160 default:
11161 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
11162 }
11163 }
11164
11165 function unwindContexts(from, to) {
11166 var node = from;
11167 while (node !== null) {
11168 switch (node.tag) {
11169 case ClassComponent:
11170 popContextProvider(node);
11171 break;
11172 case HostComponent:
11173 popHostContext(node);
11174 break;
11175 case HostRoot:
11176 popHostContainer(node);
11177 break;
11178 case HostPortal:
11179 popHostContainer(node);
11180 break;
11181 }
11182 if (node === to || node.alternate === to) {
11183 stopFailedWorkTimer(node);
11184 break;
11185 } else {
11186 stopWorkTimer(node);
11187 }
11188 node = node['return'];
11189 }
11190 }
11191
11192 function computeAsyncExpiration() {
11193 // Given the current clock time, returns an expiration time. We use rounding
11194 // to batch like updates together.
11195 // Should complete within ~1000ms. 1200ms max.
11196 var currentTime = recalculateCurrentTime();
11197 var expirationMs = 1000;
11198 var bucketSizeMs = 200;
11199 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11200 }
11201
11202 // Creates a unique async expiration time.
11203 function computeUniqueAsyncExpiration() {
11204 var result = computeAsyncExpiration();
11205 if (result <= lastUniqueAsyncExpiration) {
11206 // Since we assume the current time monotonically increases, we only hit
11207 // this branch when computeUniqueAsyncExpiration is fired multiple times
11208 // within a 200ms window (or whatever the async bucket size is).
11209 result = lastUniqueAsyncExpiration + 1;
11210 }
11211 lastUniqueAsyncExpiration = result;
11212 return lastUniqueAsyncExpiration;
11213 }
11214
11215 function computeExpirationForFiber(fiber) {
11216 var expirationTime = void 0;
11217 if (expirationContext !== NoWork) {
11218 // An explicit expiration context was set;
11219 expirationTime = expirationContext;
11220 } else if (isWorking) {
11221 if (isCommitting) {
11222 // Updates that occur during the commit phase should have sync priority
11223 // by default.
11224 expirationTime = Sync;
11225 } else {
11226 // Updates during the render phase should expire at the same time as
11227 // the work that is being rendered.
11228 expirationTime = nextRenderExpirationTime;
11229 }
11230 } else {
11231 // No explicit expiration context was set, and we're not currently
11232 // performing work. Calculate a new expiration time.
11233 if (fiber.internalContextTag & AsyncUpdates) {
11234 // This is an async update
11235 expirationTime = computeAsyncExpiration();
11236 } else {
11237 // This is a sync update
11238 expirationTime = Sync;
11239 }
11240 }
11241 return expirationTime;
11242 }
11243
11244 function scheduleWork(fiber, expirationTime) {
11245 return scheduleWorkImpl(fiber, expirationTime, false);
11246 }
11247
11248 function checkRootNeedsClearing(root, fiber, expirationTime) {
11249 if (!isWorking && root === nextRoot && expirationTime < nextRenderExpirationTime) {
11250 // Restart the root from the top.
11251 if (nextUnitOfWork !== null) {
11252 // This is an interruption. (Used for performance tracking.)
11253 interruptedBy = fiber;
11254 }
11255 nextRoot = null;
11256 nextUnitOfWork = null;
11257 nextRenderExpirationTime = NoWork;
11258 }
11259 }
11260
11261 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
11262 recordScheduleUpdate();
11263
11264 {
11265 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11266 var instance = fiber.stateNode;
11267 warnAboutInvalidUpdates(instance);
11268 }
11269 }
11270
11271 var node = fiber;
11272 while (node !== null) {
11273 // Walk the parent path to the root and update each node's
11274 // expiration time.
11275 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
11276 node.expirationTime = expirationTime;
11277 }
11278 if (node.alternate !== null) {
11279 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
11280 node.alternate.expirationTime = expirationTime;
11281 }
11282 }
11283 if (node['return'] === null) {
11284 if (node.tag === HostRoot) {
11285 var root = node.stateNode;
11286
11287 checkRootNeedsClearing(root, fiber, expirationTime);
11288 requestWork(root, expirationTime);
11289 checkRootNeedsClearing(root, fiber, expirationTime);
11290 } else {
11291 {
11292 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11293 warnAboutUpdateOnUnmounted(fiber);
11294 }
11295 }
11296 return;
11297 }
11298 }
11299 node = node['return'];
11300 }
11301 }
11302
11303 function scheduleErrorRecovery(fiber) {
11304 scheduleWorkImpl(fiber, Sync, true);
11305 }
11306
11307 function recalculateCurrentTime() {
11308 // Subtract initial time so it fits inside 32bits
11309 var ms = now() - startTime;
11310 mostRecentCurrentTime = msToExpirationTime(ms);
11311 return mostRecentCurrentTime;
11312 }
11313
11314 function deferredUpdates(fn) {
11315 var previousExpirationContext = expirationContext;
11316 expirationContext = computeAsyncExpiration();
11317 try {
11318 return fn();
11319 } finally {
11320 expirationContext = previousExpirationContext;
11321 }
11322 }
11323
11324 function syncUpdates(fn) {
11325 var previousExpirationContext = expirationContext;
11326 expirationContext = Sync;
11327 try {
11328 return fn();
11329 } finally {
11330 expirationContext = previousExpirationContext;
11331 }
11332 }
11333
11334 // TODO: Everything below this is written as if it has been lifted to the
11335 // renderers. I'll do this in a follow-up.
11336
11337 // Linked-list of roots
11338 var firstScheduledRoot = null;
11339 var lastScheduledRoot = null;
11340
11341 var callbackExpirationTime = NoWork;
11342 var callbackID = -1;
11343 var isRendering = false;
11344 var nextFlushedRoot = null;
11345 var nextFlushedExpirationTime = NoWork;
11346 var deadlineDidExpire = false;
11347 var hasUnhandledError = false;
11348 var unhandledError = null;
11349 var deadline = null;
11350
11351 var isBatchingUpdates = false;
11352 var isUnbatchingUpdates = false;
11353
11354 var completedBatches = null;
11355
11356 // Use these to prevent an infinite loop of nested updates
11357 var NESTED_UPDATE_LIMIT = 1000;
11358 var nestedUpdateCount = 0;
11359
11360 var timeHeuristicForUnitOfWork = 1;
11361
11362 function scheduleCallbackWithExpiration(expirationTime) {
11363 if (callbackExpirationTime !== NoWork) {
11364 // A callback is already scheduled. Check its expiration time (timeout).
11365 if (expirationTime > callbackExpirationTime) {
11366 // Existing callback has sufficient timeout. Exit.
11367 return;
11368 } else {
11369 // Existing callback has insufficient timeout. Cancel and schedule a
11370 // new one.
11371 cancelDeferredCallback(callbackID);
11372 }
11373 // The request callback timer is already running. Don't start a new one.
11374 } else {
11375 startRequestCallbackTimer();
11376 }
11377
11378 // Compute a timeout for the given expiration time.
11379 var currentMs = now() - startTime;
11380 var expirationMs = expirationTimeToMs(expirationTime);
11381 var timeout = expirationMs - currentMs;
11382
11383 callbackExpirationTime = expirationTime;
11384 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
11385 }
11386
11387 // requestWork is called by the scheduler whenever a root receives an update.
11388 // It's up to the renderer to call renderRoot at some point in the future.
11389 function requestWork(root, expirationTime) {
11390 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
11391 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.');
11392 }
11393
11394 // Add the root to the schedule.
11395 // Check if this root is already part of the schedule.
11396 if (root.nextScheduledRoot === null) {
11397 // This root is not already scheduled. Add it.
11398 root.remainingExpirationTime = expirationTime;
11399 if (lastScheduledRoot === null) {
11400 firstScheduledRoot = lastScheduledRoot = root;
11401 root.nextScheduledRoot = root;
11402 } else {
11403 lastScheduledRoot.nextScheduledRoot = root;
11404 lastScheduledRoot = root;
11405 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11406 }
11407 } else {
11408 // This root is already scheduled, but its priority may have increased.
11409 var remainingExpirationTime = root.remainingExpirationTime;
11410 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
11411 // Update the priority.
11412 root.remainingExpirationTime = expirationTime;
11413 }
11414 }
11415
11416 if (isRendering) {
11417 // Prevent reentrancy. Remaining work will be scheduled at the end of
11418 // the currently rendering batch.
11419 return;
11420 }
11421
11422 if (isBatchingUpdates) {
11423 // Flush work at the end of the batch.
11424 if (isUnbatchingUpdates) {
11425 // ...unless we're inside unbatchedUpdates, in which case we should
11426 // flush it now.
11427 nextFlushedRoot = root;
11428 nextFlushedExpirationTime = Sync;
11429 performWorkOnRoot(root, Sync, recalculateCurrentTime());
11430 }
11431 return;
11432 }
11433
11434 // TODO: Get rid of Sync and use current time?
11435 if (expirationTime === Sync) {
11436 performWork(Sync, null);
11437 } else {
11438 scheduleCallbackWithExpiration(expirationTime);
11439 }
11440 }
11441
11442 function findHighestPriorityRoot() {
11443 var highestPriorityWork = NoWork;
11444 var highestPriorityRoot = null;
11445
11446 if (lastScheduledRoot !== null) {
11447 var previousScheduledRoot = lastScheduledRoot;
11448 var root = firstScheduledRoot;
11449 while (root !== null) {
11450 var remainingExpirationTime = root.remainingExpirationTime;
11451 if (remainingExpirationTime === NoWork) {
11452 // This root no longer has work. Remove it from the scheduler.
11453
11454 // TODO: This check is redudant, but Flow is confused by the branch
11455 // below where we set lastScheduledRoot to null, even though we break
11456 // from the loop right after.
11457 !(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;
11458 if (root === root.nextScheduledRoot) {
11459 // This is the only root in the list.
11460 root.nextScheduledRoot = null;
11461 firstScheduledRoot = lastScheduledRoot = null;
11462 break;
11463 } else if (root === firstScheduledRoot) {
11464 // This is the first root in the list.
11465 var next = root.nextScheduledRoot;
11466 firstScheduledRoot = next;
11467 lastScheduledRoot.nextScheduledRoot = next;
11468 root.nextScheduledRoot = null;
11469 } else if (root === lastScheduledRoot) {
11470 // This is the last root in the list.
11471 lastScheduledRoot = previousScheduledRoot;
11472 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11473 root.nextScheduledRoot = null;
11474 break;
11475 } else {
11476 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
11477 root.nextScheduledRoot = null;
11478 }
11479 root = previousScheduledRoot.nextScheduledRoot;
11480 } else {
11481 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
11482 // Update the priority, if it's higher
11483 highestPriorityWork = remainingExpirationTime;
11484 highestPriorityRoot = root;
11485 }
11486 if (root === lastScheduledRoot) {
11487 break;
11488 }
11489 previousScheduledRoot = root;
11490 root = root.nextScheduledRoot;
11491 }
11492 }
11493 }
11494
11495 // If the next root is the same as the previous root, this is a nested
11496 // update. To prevent an infinite loop, increment the nested update count.
11497 var previousFlushedRoot = nextFlushedRoot;
11498 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot) {
11499 nestedUpdateCount++;
11500 } else {
11501 // Reset whenever we switch roots.
11502 nestedUpdateCount = 0;
11503 }
11504 nextFlushedRoot = highestPriorityRoot;
11505 nextFlushedExpirationTime = highestPriorityWork;
11506 }
11507
11508 function performAsyncWork(dl) {
11509 performWork(NoWork, dl);
11510 }
11511
11512 function performWork(minExpirationTime, dl) {
11513 deadline = dl;
11514
11515 // Keep working on roots until there's no more work, or until the we reach
11516 // the deadline.
11517 findHighestPriorityRoot();
11518
11519 if (enableUserTimingAPI && deadline !== null) {
11520 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
11521 stopRequestCallbackTimer(didExpire);
11522 }
11523
11524 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || nextFlushedExpirationTime <= minExpirationTime) && !deadlineDidExpire) {
11525 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, recalculateCurrentTime());
11526 // Find the next highest priority work.
11527 findHighestPriorityRoot();
11528 }
11529
11530 // We're done flushing work. Either we ran out of time in this callback,
11531 // or there's no more work left with sufficient priority.
11532
11533 // If we're inside a callback, set this to false since we just completed it.
11534 if (deadline !== null) {
11535 callbackExpirationTime = NoWork;
11536 callbackID = -1;
11537 }
11538 // If there's work left over, schedule a new callback.
11539 if (nextFlushedExpirationTime !== NoWork) {
11540 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
11541 }
11542
11543 // Clean-up.
11544 deadline = null;
11545 deadlineDidExpire = false;
11546 nestedUpdateCount = 0;
11547
11548 finishRendering();
11549 }
11550
11551 function flushRoot(root, expirationTime) {
11552 !!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;
11553 // Perform work on root as if the given expiration time is the current time.
11554 // This has the effect of synchronously flushing all work up to and
11555 // including the given time.
11556 performWorkOnRoot(root, expirationTime, expirationTime);
11557 finishRendering();
11558 }
11559
11560 function finishRendering() {
11561 if (completedBatches !== null) {
11562 var batches = completedBatches;
11563 completedBatches = null;
11564 for (var i = 0; i < batches.length; i++) {
11565 var batch = batches[i];
11566 try {
11567 batch._onComplete();
11568 } catch (error) {
11569 if (!hasUnhandledError) {
11570 hasUnhandledError = true;
11571 unhandledError = error;
11572 }
11573 }
11574 }
11575 }
11576
11577 if (hasUnhandledError) {
11578 var _error4 = unhandledError;
11579 unhandledError = null;
11580 hasUnhandledError = false;
11581 throw _error4;
11582 }
11583 }
11584
11585 function performWorkOnRoot(root, expirationTime, currentTime) {
11586 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11587
11588 isRendering = true;
11589
11590 // Check if this is async work or sync/expired work.
11591 if (expirationTime <= currentTime) {
11592 // Flush sync work.
11593 var finishedWork = root.finishedWork;
11594 if (finishedWork !== null) {
11595 // This root is already complete. We can commit it.
11596 completeRoot(root, finishedWork, expirationTime);
11597 } else {
11598 root.finishedWork = null;
11599 finishedWork = renderRoot(root, expirationTime);
11600 if (finishedWork !== null) {
11601 // We've completed the root. Commit it.
11602 completeRoot(root, finishedWork, expirationTime);
11603 }
11604 }
11605 } else {
11606 // Flush async work.
11607 var _finishedWork = root.finishedWork;
11608 if (_finishedWork !== null) {
11609 // This root is already complete. We can commit it.
11610 completeRoot(root, _finishedWork, expirationTime);
11611 } else {
11612 root.finishedWork = null;
11613 _finishedWork = renderRoot(root, expirationTime);
11614 if (_finishedWork !== null) {
11615 // We've completed the root. Check the deadline one more time
11616 // before committing.
11617 if (!shouldYield()) {
11618 // Still time left. Commit the root.
11619 completeRoot(root, _finishedWork, expirationTime);
11620 } else {
11621 // There's no time left. Mark this root as complete. We'll come
11622 // back and commit it later.
11623 root.finishedWork = _finishedWork;
11624 }
11625 }
11626 }
11627 }
11628
11629 isRendering = false;
11630 }
11631
11632 function completeRoot(root, finishedWork, expirationTime) {
11633 // Check if there's a batch that matches this expiration time.
11634 var firstBatch = root.firstBatch;
11635 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
11636 if (completedBatches === null) {
11637 completedBatches = [firstBatch];
11638 } else {
11639 completedBatches.push(firstBatch);
11640 }
11641 if (firstBatch._defer) {
11642 // This root is blocked from committing by a batch. Unschedule it until
11643 // we receive another update.
11644 root.finishedWork = finishedWork;
11645 root.remainingExpirationTime = NoWork;
11646 return;
11647 }
11648 }
11649
11650 // Commit the root.
11651 root.finishedWork = null;
11652 root.remainingExpirationTime = commitRoot(finishedWork);
11653 }
11654
11655 // When working on async work, the reconciler asks the renderer if it should
11656 // yield execution. For DOM, we implement this with requestIdleCallback.
11657 function shouldYield() {
11658 if (deadline === null) {
11659 return false;
11660 }
11661 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
11662 // Disregard deadline.didTimeout. Only expired work should be flushed
11663 // during a timeout. This path is only hit for non-expired work.
11664 return false;
11665 }
11666 deadlineDidExpire = true;
11667 return true;
11668 }
11669
11670 // TODO: Not happy about this hook. Conceptually, renderRoot should return a
11671 // tuple of (isReadyForCommit, didError, error)
11672 function onUncaughtError(error) {
11673 !(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;
11674 // Unschedule this root so we don't work on it again until there's
11675 // another update.
11676 nextFlushedRoot.remainingExpirationTime = NoWork;
11677 if (!hasUnhandledError) {
11678 hasUnhandledError = true;
11679 unhandledError = error;
11680 }
11681 }
11682
11683 // TODO: Batching should be implemented at the renderer level, not inside
11684 // the reconciler.
11685 function batchedUpdates(fn, a) {
11686 var previousIsBatchingUpdates = isBatchingUpdates;
11687 isBatchingUpdates = true;
11688 try {
11689 return fn(a);
11690 } finally {
11691 isBatchingUpdates = previousIsBatchingUpdates;
11692 if (!isBatchingUpdates && !isRendering) {
11693 performWork(Sync, null);
11694 }
11695 }
11696 }
11697
11698 // TODO: Batching should be implemented at the renderer level, not inside
11699 // the reconciler.
11700 function unbatchedUpdates(fn) {
11701 if (isBatchingUpdates && !isUnbatchingUpdates) {
11702 isUnbatchingUpdates = true;
11703 try {
11704 return fn();
11705 } finally {
11706 isUnbatchingUpdates = false;
11707 }
11708 }
11709 return fn();
11710 }
11711
11712 // TODO: Batching should be implemented at the renderer level, not within
11713 // the reconciler.
11714 function flushSync(fn) {
11715 var previousIsBatchingUpdates = isBatchingUpdates;
11716 isBatchingUpdates = true;
11717 try {
11718 return syncUpdates(fn);
11719 } finally {
11720 isBatchingUpdates = previousIsBatchingUpdates;
11721 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
11722 performWork(Sync, null);
11723 }
11724 }
11725
11726 return {
11727 computeExpirationForFiber: computeExpirationForFiber,
11728 scheduleWork: scheduleWork,
11729 requestWork: requestWork,
11730 flushRoot: flushRoot,
11731 batchedUpdates: batchedUpdates,
11732 unbatchedUpdates: unbatchedUpdates,
11733 flushSync: flushSync,
11734 deferredUpdates: deferredUpdates,
11735 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
11736 };
11737};
11738
11739var didWarnAboutNestedUpdates = void 0;
11740
11741{
11742 didWarnAboutNestedUpdates = false;
11743}
11744
11745// 0 is PROD, 1 is DEV.
11746// Might add PROFILE later.
11747
11748
11749function getContextForSubtree(parentComponent) {
11750 if (!parentComponent) {
11751 return emptyObject_1;
11752 }
11753
11754 var fiber = get(parentComponent);
11755 var parentContext = findCurrentUnmaskedContext(fiber);
11756 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
11757}
11758
11759var ReactFiberReconciler$1 = function (config) {
11760 var getPublicInstance = config.getPublicInstance;
11761
11762 var _ReactFiberScheduler = ReactFiberScheduler(config),
11763 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
11764 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
11765 scheduleWork = _ReactFiberScheduler.scheduleWork,
11766 requestWork = _ReactFiberScheduler.requestWork,
11767 flushRoot = _ReactFiberScheduler.flushRoot,
11768 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
11769 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
11770 flushSync = _ReactFiberScheduler.flushSync,
11771 deferredUpdates = _ReactFiberScheduler.deferredUpdates;
11772
11773 function scheduleRootUpdate(current, element, expirationTime, callback) {
11774 {
11775 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
11776 didWarnAboutNestedUpdates = true;
11777 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');
11778 }
11779 }
11780
11781 callback = callback === undefined ? null : callback;
11782 {
11783 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
11784 }
11785
11786 var update = {
11787 expirationTime: expirationTime,
11788 partialState: { element: element },
11789 callback: callback,
11790 isReplace: false,
11791 isForced: false,
11792 next: null
11793 };
11794 insertUpdateIntoFiber(current, update);
11795 scheduleWork(current, expirationTime);
11796
11797 return expirationTime;
11798 }
11799
11800 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
11801 // TODO: If this is a nested container, this won't be the root.
11802 var current = container.current;
11803
11804 {
11805 if (ReactFiberInstrumentation_1.debugTool) {
11806 if (current.alternate === null) {
11807 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
11808 } else if (element === null) {
11809 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
11810 } else {
11811 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
11812 }
11813 }
11814 }
11815
11816 var context = getContextForSubtree(parentComponent);
11817 if (container.context === null) {
11818 container.context = context;
11819 } else {
11820 container.pendingContext = context;
11821 }
11822
11823 return scheduleRootUpdate(current, element, expirationTime, callback);
11824 }
11825
11826 function findHostInstance(fiber) {
11827 var hostFiber = findCurrentHostFiber(fiber);
11828 if (hostFiber === null) {
11829 return null;
11830 }
11831 return hostFiber.stateNode;
11832 }
11833
11834 return {
11835 createContainer: function (containerInfo, isAsync, hydrate) {
11836 return createFiberRoot(containerInfo, isAsync, hydrate);
11837 },
11838 updateContainer: function (element, container, parentComponent, callback) {
11839 var current = container.current;
11840 var expirationTime = computeExpirationForFiber(current);
11841 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
11842 },
11843
11844
11845 updateContainerAtExpirationTime: updateContainerAtExpirationTime,
11846
11847 flushRoot: flushRoot,
11848
11849 requestWork: requestWork,
11850
11851 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
11852
11853 batchedUpdates: batchedUpdates,
11854
11855 unbatchedUpdates: unbatchedUpdates,
11856
11857 deferredUpdates: deferredUpdates,
11858
11859 flushSync: flushSync,
11860
11861 getPublicRootInstance: function (container) {
11862 var containerFiber = container.current;
11863 if (!containerFiber.child) {
11864 return null;
11865 }
11866 switch (containerFiber.child.tag) {
11867 case HostComponent:
11868 return getPublicInstance(containerFiber.child.stateNode);
11869 default:
11870 return containerFiber.child.stateNode;
11871 }
11872 },
11873
11874
11875 findHostInstance: findHostInstance,
11876
11877 findHostInstanceWithNoPortals: function (fiber) {
11878 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
11879 if (hostFiber === null) {
11880 return null;
11881 }
11882 return hostFiber.stateNode;
11883 },
11884 injectIntoDevTools: function (devToolsConfig) {
11885 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
11886
11887 return injectInternals(_assign({}, devToolsConfig, {
11888 findHostInstanceByFiber: function (fiber) {
11889 return findHostInstance(fiber);
11890 },
11891 findFiberByHostInstance: function (instance) {
11892 if (!findFiberByHostInstance) {
11893 // Might not be implemented by the renderer.
11894 return null;
11895 }
11896 return findFiberByHostInstance(instance);
11897 }
11898 }));
11899 }
11900 };
11901};
11902
11903var ReactFiberReconciler$2 = Object.freeze({
11904 default: ReactFiberReconciler$1
11905});
11906
11907var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
11908
11909// TODO: bundle Flow types with the package.
11910
11911
11912
11913// TODO: decide on the top-level export form.
11914// This is hacky but makes it work with both Rollup and Jest.
11915var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
11916
11917function createPortal$1(children, containerInfo,
11918// TODO: figure out the API for cross-renderer implementation.
11919implementation) {
11920 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
11921
11922 return {
11923 // This tag allow us to uniquely identify this as a React Portal
11924 $$typeof: REACT_PORTAL_TYPE,
11925 key: key == null ? null : '' + key,
11926 children: children,
11927 containerInfo: containerInfo,
11928 implementation: implementation
11929 };
11930}
11931
11932// TODO: this is special because it gets imported during build.
11933
11934var ReactVersion = '16.2.0';
11935
11936// a requestAnimationFrame, storing the time for the start of the frame, then
11937// scheduling a postMessage which gets scheduled after paint. Within the
11938// postMessage handler do as much work as possible until time + frame rate.
11939// By separating the idle call into a separate event tick we ensure that
11940// layout, paint and other browser work is counted against the available time.
11941// The frame rate is dynamically adjusted.
11942
11943{
11944 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
11945 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
11946 }
11947}
11948
11949var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
11950
11951var now = void 0;
11952if (hasNativePerformanceNow) {
11953 now = function () {
11954 return performance.now();
11955 };
11956} else {
11957 now = function () {
11958 return Date.now();
11959 };
11960}
11961
11962// TODO: There's no way to cancel, because Fiber doesn't atm.
11963var rIC = void 0;
11964var cIC = void 0;
11965
11966if (!ExecutionEnvironment_1.canUseDOM) {
11967 rIC = function (frameCallback) {
11968 return setTimeout(function () {
11969 frameCallback({
11970 timeRemaining: function () {
11971 return Infinity;
11972 }
11973 });
11974 });
11975 };
11976 cIC = function (timeoutID) {
11977 clearTimeout(timeoutID);
11978 };
11979} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
11980 // Polyfill requestIdleCallback and cancelIdleCallback
11981
11982 var scheduledRICCallback = null;
11983 var isIdleScheduled = false;
11984 var timeoutTime = -1;
11985
11986 var isAnimationFrameScheduled = false;
11987
11988 var frameDeadline = 0;
11989 // We start out assuming that we run at 30fps but then the heuristic tracking
11990 // will adjust this value to a faster fps if we get more frequent animation
11991 // frames.
11992 var previousFrameTime = 33;
11993 var activeFrameTime = 33;
11994
11995 var frameDeadlineObject = void 0;
11996 if (hasNativePerformanceNow) {
11997 frameDeadlineObject = {
11998 didTimeout: false,
11999 timeRemaining: function () {
12000 // We assume that if we have a performance timer that the rAF callback
12001 // gets a performance timer value. Not sure if this is always true.
12002 var remaining = frameDeadline - performance.now();
12003 return remaining > 0 ? remaining : 0;
12004 }
12005 };
12006 } else {
12007 frameDeadlineObject = {
12008 didTimeout: false,
12009 timeRemaining: function () {
12010 // Fallback to Date.now()
12011 var remaining = frameDeadline - Date.now();
12012 return remaining > 0 ? remaining : 0;
12013 }
12014 };
12015 }
12016
12017 // We use the postMessage trick to defer idle work until after the repaint.
12018 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12019 var idleTick = function (event) {
12020 if (event.source !== window || event.data !== messageKey) {
12021 return;
12022 }
12023
12024 isIdleScheduled = false;
12025
12026 var currentTime = now();
12027 if (frameDeadline - currentTime <= 0) {
12028 // There's no time left in this idle period. Check if the callback has
12029 // a timeout and whether it's been exceeded.
12030 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12031 // Exceeded the timeout. Invoke the callback even though there's no
12032 // time left.
12033 frameDeadlineObject.didTimeout = true;
12034 } else {
12035 // No timeout.
12036 if (!isAnimationFrameScheduled) {
12037 // Schedule another animation callback so we retry later.
12038 isAnimationFrameScheduled = true;
12039 requestAnimationFrame(animationTick);
12040 }
12041 // Exit without invoking the callback.
12042 return;
12043 }
12044 } else {
12045 // There's still time left in this idle period.
12046 frameDeadlineObject.didTimeout = false;
12047 }
12048
12049 timeoutTime = -1;
12050 var callback = scheduledRICCallback;
12051 scheduledRICCallback = null;
12052 if (callback !== null) {
12053 callback(frameDeadlineObject);
12054 }
12055 };
12056 // Assumes that we have addEventListener in this environment. Might need
12057 // something better for old IE.
12058 window.addEventListener('message', idleTick, false);
12059
12060 var animationTick = function (rafTime) {
12061 isAnimationFrameScheduled = false;
12062 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12063 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12064 if (nextFrameTime < 8) {
12065 // Defensive coding. We don't support higher frame rates than 120hz.
12066 // If we get lower than that, it is probably a bug.
12067 nextFrameTime = 8;
12068 }
12069 // If one frame goes long, then the next one can be short to catch up.
12070 // If two frames are short in a row, then that's an indication that we
12071 // actually have a higher frame rate than what we're currently optimizing.
12072 // We adjust our heuristic dynamically accordingly. For example, if we're
12073 // running on 120hz display or 90hz VR display.
12074 // Take the max of the two in case one of them was an anomaly due to
12075 // missed frame deadlines.
12076 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12077 } else {
12078 previousFrameTime = nextFrameTime;
12079 }
12080 frameDeadline = rafTime + activeFrameTime;
12081 if (!isIdleScheduled) {
12082 isIdleScheduled = true;
12083 window.postMessage(messageKey, '*');
12084 }
12085 };
12086
12087 rIC = function (callback, options) {
12088 // This assumes that we only schedule one callback at a time because that's
12089 // how Fiber uses it.
12090 scheduledRICCallback = callback;
12091 if (options != null && typeof options.timeout === 'number') {
12092 timeoutTime = now() + options.timeout;
12093 }
12094 if (!isAnimationFrameScheduled) {
12095 // If rAF didn't already schedule one, we need to schedule a frame.
12096 // TODO: If this rAF doesn't materialize because the browser throttles, we
12097 // might want to still have setTimeout trigger rIC as a backup to ensure
12098 // that we keep performing work.
12099 isAnimationFrameScheduled = true;
12100 requestAnimationFrame(animationTick);
12101 }
12102 return 0;
12103 };
12104
12105 cIC = function () {
12106 scheduledRICCallback = null;
12107 isIdleScheduled = false;
12108 timeoutTime = -1;
12109 };
12110} else {
12111 rIC = window.requestIdleCallback;
12112 cIC = window.cancelIdleCallback;
12113}
12114
12115var didWarnSelectedSetOnOption = false;
12116
12117function flattenChildren(children) {
12118 var content = '';
12119
12120 // Flatten children and warn if they aren't strings or numbers;
12121 // invalid types are ignored.
12122 // We can silently skip them because invalid DOM nesting warning
12123 // catches these cases in Fiber.
12124 React.Children.forEach(children, function (child) {
12125 if (child == null) {
12126 return;
12127 }
12128 if (typeof child === 'string' || typeof child === 'number') {
12129 content += child;
12130 }
12131 });
12132
12133 return content;
12134}
12135
12136/**
12137 * Implements an <option> host component that warns when `selected` is set.
12138 */
12139
12140function validateProps(element, props) {
12141 // TODO (yungsters): Remove support for `selected` in <option>.
12142 {
12143 if (props.selected != null && !didWarnSelectedSetOnOption) {
12144 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
12145 didWarnSelectedSetOnOption = true;
12146 }
12147 }
12148}
12149
12150function postMountWrapper$1(element, props) {
12151 // value="" should make a value attribute (#6219)
12152 if (props.value != null) {
12153 element.setAttribute('value', props.value);
12154 }
12155}
12156
12157function getHostProps$1(element, props) {
12158 var hostProps = _assign({ children: undefined }, props);
12159 var content = flattenChildren(props.children);
12160
12161 if (content) {
12162 hostProps.children = content;
12163 }
12164
12165 return hostProps;
12166}
12167
12168// TODO: direct imports like some-package/src/* are bad. Fix me.
12169var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
12170var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12171
12172
12173var didWarnValueDefaultValue$1 = void 0;
12174
12175{
12176 didWarnValueDefaultValue$1 = false;
12177}
12178
12179function getDeclarationErrorAddendum() {
12180 var ownerName = getCurrentFiberOwnerName$3();
12181 if (ownerName) {
12182 return '\n\nCheck the render method of `' + ownerName + '`.';
12183 }
12184 return '';
12185}
12186
12187var valuePropNames = ['value', 'defaultValue'];
12188
12189/**
12190 * Validation function for `value` and `defaultValue`.
12191 */
12192function checkSelectPropTypes(props) {
12193 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
12194
12195 for (var i = 0; i < valuePropNames.length; i++) {
12196 var propName = valuePropNames[i];
12197 if (props[propName] == null) {
12198 continue;
12199 }
12200 var isArray = Array.isArray(props[propName]);
12201 if (props.multiple && !isArray) {
12202 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
12203 } else if (!props.multiple && isArray) {
12204 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
12205 }
12206 }
12207}
12208
12209function updateOptions(node, multiple, propValue, setDefaultSelected) {
12210 var options = node.options;
12211
12212 if (multiple) {
12213 var selectedValues = propValue;
12214 var selectedValue = {};
12215 for (var i = 0; i < selectedValues.length; i++) {
12216 // Prefix to avoid chaos with special keys.
12217 selectedValue['$' + selectedValues[i]] = true;
12218 }
12219 for (var _i = 0; _i < options.length; _i++) {
12220 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
12221 if (options[_i].selected !== selected) {
12222 options[_i].selected = selected;
12223 }
12224 if (selected && setDefaultSelected) {
12225 options[_i].defaultSelected = true;
12226 }
12227 }
12228 } else {
12229 // Do not set `select.value` as exact behavior isn't consistent across all
12230 // browsers for all cases.
12231 var _selectedValue = '' + propValue;
12232 var defaultSelected = null;
12233 for (var _i2 = 0; _i2 < options.length; _i2++) {
12234 if (options[_i2].value === _selectedValue) {
12235 options[_i2].selected = true;
12236 if (setDefaultSelected) {
12237 options[_i2].defaultSelected = true;
12238 }
12239 return;
12240 }
12241 if (defaultSelected === null && !options[_i2].disabled) {
12242 defaultSelected = options[_i2];
12243 }
12244 }
12245 if (defaultSelected !== null) {
12246 defaultSelected.selected = true;
12247 }
12248 }
12249}
12250
12251/**
12252 * Implements a <select> host component that allows optionally setting the
12253 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
12254 * stringable. If `multiple` is true, the prop must be an array of stringables.
12255 *
12256 * If `value` is not supplied (or null/undefined), user actions that change the
12257 * selected option will trigger updates to the rendered options.
12258 *
12259 * If it is supplied (and not null/undefined), the rendered options will not
12260 * update in response to user actions. Instead, the `value` prop must change in
12261 * order for the rendered options to update.
12262 *
12263 * If `defaultValue` is provided, any options with the supplied values will be
12264 * selected.
12265 */
12266
12267function getHostProps$2(element, props) {
12268 return _assign({}, props, {
12269 value: undefined
12270 });
12271}
12272
12273function initWrapperState$1(element, props) {
12274 var node = element;
12275 {
12276 checkSelectPropTypes(props);
12277 }
12278
12279 var value = props.value;
12280 node._wrapperState = {
12281 initialValue: value != null ? value : props.defaultValue,
12282 wasMultiple: !!props.multiple
12283 };
12284
12285 {
12286 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
12287 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');
12288 didWarnValueDefaultValue$1 = true;
12289 }
12290 }
12291}
12292
12293function postMountWrapper$2(element, props) {
12294 var node = element;
12295 node.multiple = !!props.multiple;
12296 var value = props.value;
12297 if (value != null) {
12298 updateOptions(node, !!props.multiple, value, false);
12299 } else if (props.defaultValue != null) {
12300 updateOptions(node, !!props.multiple, props.defaultValue, true);
12301 }
12302}
12303
12304function postUpdateWrapper(element, props) {
12305 var node = element;
12306 // After the initial mount, we control selected-ness manually so don't pass
12307 // this value down
12308 node._wrapperState.initialValue = undefined;
12309
12310 var wasMultiple = node._wrapperState.wasMultiple;
12311 node._wrapperState.wasMultiple = !!props.multiple;
12312
12313 var value = props.value;
12314 if (value != null) {
12315 updateOptions(node, !!props.multiple, value, false);
12316 } else if (wasMultiple !== !!props.multiple) {
12317 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
12318 if (props.defaultValue != null) {
12319 updateOptions(node, !!props.multiple, props.defaultValue, true);
12320 } else {
12321 // Revert the select back to its default unselected state.
12322 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
12323 }
12324 }
12325}
12326
12327function restoreControlledState$2(element, props) {
12328 var node = element;
12329 var value = props.value;
12330
12331 if (value != null) {
12332 updateOptions(node, !!props.multiple, value, false);
12333 }
12334}
12335
12336// TODO: direct imports like some-package/src/* are bad. Fix me.
12337var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12338
12339var didWarnValDefaultVal = false;
12340
12341/**
12342 * Implements a <textarea> host component that allows setting `value`, and
12343 * `defaultValue`. This differs from the traditional DOM API because value is
12344 * usually set as PCDATA children.
12345 *
12346 * If `value` is not supplied (or null/undefined), user actions that affect the
12347 * value will trigger updates to the element.
12348 *
12349 * If `value` is supplied (and not null/undefined), the rendered element will
12350 * not trigger updates to the element. Instead, the `value` prop must change in
12351 * order for the rendered element to be updated.
12352 *
12353 * The rendered element will be initialized with an empty value, the prop
12354 * `defaultValue` if specified, or the children content (deprecated).
12355 */
12356
12357function getHostProps$3(element, props) {
12358 var node = element;
12359 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
12360
12361 // Always set children to the same thing. In IE9, the selection range will
12362 // get reset if `textContent` is mutated. We could add a check in setTextContent
12363 // to only set the value if/when the value differs from the node value (which would
12364 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
12365 // solution. The value can be a boolean or object so that's why it's forced
12366 // to be a string.
12367 var hostProps = _assign({}, props, {
12368 value: undefined,
12369 defaultValue: undefined,
12370 children: '' + node._wrapperState.initialValue
12371 });
12372
12373 return hostProps;
12374}
12375
12376function initWrapperState$2(element, props) {
12377 var node = element;
12378 {
12379 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
12380 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
12381 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');
12382 didWarnValDefaultVal = true;
12383 }
12384 }
12385
12386 var initialValue = props.value;
12387
12388 // Only bother fetching default value if we're going to use it
12389 if (initialValue == null) {
12390 var defaultValue = props.defaultValue;
12391 // TODO (yungsters): Remove support for children content in <textarea>.
12392 var children = props.children;
12393 if (children != null) {
12394 {
12395 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
12396 }
12397 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
12398 if (Array.isArray(children)) {
12399 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
12400 children = children[0];
12401 }
12402
12403 defaultValue = '' + children;
12404 }
12405 if (defaultValue == null) {
12406 defaultValue = '';
12407 }
12408 initialValue = defaultValue;
12409 }
12410
12411 node._wrapperState = {
12412 initialValue: '' + initialValue
12413 };
12414}
12415
12416function updateWrapper$1(element, props) {
12417 var node = element;
12418 var value = props.value;
12419 if (value != null) {
12420 // Cast `value` to a string to ensure the value is set correctly. While
12421 // browsers typically do this as necessary, jsdom doesn't.
12422 var newValue = '' + value;
12423
12424 // To avoid side effects (such as losing text selection), only set value if changed
12425 if (newValue !== node.value) {
12426 node.value = newValue;
12427 }
12428 if (props.defaultValue == null) {
12429 node.defaultValue = newValue;
12430 }
12431 }
12432 if (props.defaultValue != null) {
12433 node.defaultValue = props.defaultValue;
12434 }
12435}
12436
12437function postMountWrapper$3(element, props) {
12438 var node = element;
12439 // This is in postMount because we need access to the DOM node, which is not
12440 // available until after the component has mounted.
12441 var textContent = node.textContent;
12442
12443 // Only set node.value if textContent is equal to the expected
12444 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
12445 // will populate textContent as well.
12446 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
12447 if (textContent === node._wrapperState.initialValue) {
12448 node.value = textContent;
12449 }
12450}
12451
12452function restoreControlledState$3(element, props) {
12453 // DOM component is still mounted; update
12454 updateWrapper$1(element, props);
12455}
12456
12457var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
12458var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
12459var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
12460
12461var Namespaces = {
12462 html: HTML_NAMESPACE$1,
12463 mathml: MATH_NAMESPACE,
12464 svg: SVG_NAMESPACE
12465};
12466
12467// Assumes there is no parent namespace.
12468function getIntrinsicNamespace(type) {
12469 switch (type) {
12470 case 'svg':
12471 return SVG_NAMESPACE;
12472 case 'math':
12473 return MATH_NAMESPACE;
12474 default:
12475 return HTML_NAMESPACE$1;
12476 }
12477}
12478
12479function getChildNamespace(parentNamespace, type) {
12480 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
12481 // No (or default) parent namespace: potential entry point.
12482 return getIntrinsicNamespace(type);
12483 }
12484 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
12485 // We're leaving SVG.
12486 return HTML_NAMESPACE$1;
12487 }
12488 // By default, pass namespace below.
12489 return parentNamespace;
12490}
12491
12492/* globals MSApp */
12493
12494/**
12495 * Create a function which has 'unsafe' privileges (required by windows8 apps)
12496 */
12497var createMicrosoftUnsafeLocalFunction = function (func) {
12498 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
12499 return function (arg0, arg1, arg2, arg3) {
12500 MSApp.execUnsafeLocalFunction(function () {
12501 return func(arg0, arg1, arg2, arg3);
12502 });
12503 };
12504 } else {
12505 return func;
12506 }
12507};
12508
12509// SVG temp container for IE lacking innerHTML
12510var reusableSVGContainer = void 0;
12511
12512/**
12513 * Set the innerHTML property of a node
12514 *
12515 * @param {DOMElement} node
12516 * @param {string} html
12517 * @internal
12518 */
12519var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
12520 // IE does not have innerHTML for SVG nodes, so instead we inject the
12521 // new markup in a temp node and then move the child nodes across into
12522 // the target node
12523
12524 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
12525 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
12526 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
12527 var svgNode = reusableSVGContainer.firstChild;
12528 while (node.firstChild) {
12529 node.removeChild(node.firstChild);
12530 }
12531 while (svgNode.firstChild) {
12532 node.appendChild(svgNode.firstChild);
12533 }
12534 } else {
12535 node.innerHTML = html;
12536 }
12537});
12538
12539/**
12540 * Set the textContent property of a node. For text updates, it's faster
12541 * to set the `nodeValue` of the Text node directly instead of using
12542 * `.textContent` which will remove the existing node and create a new one.
12543 *
12544 * @param {DOMElement} node
12545 * @param {string} text
12546 * @internal
12547 */
12548var setTextContent = function (node, text) {
12549 if (text) {
12550 var firstChild = node.firstChild;
12551
12552 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
12553 firstChild.nodeValue = text;
12554 return;
12555 }
12556 }
12557 node.textContent = text;
12558};
12559
12560/**
12561 * CSS properties which accept numbers but are not in units of "px".
12562 */
12563var isUnitlessNumber = {
12564 animationIterationCount: true,
12565 borderImageOutset: true,
12566 borderImageSlice: true,
12567 borderImageWidth: true,
12568 boxFlex: true,
12569 boxFlexGroup: true,
12570 boxOrdinalGroup: true,
12571 columnCount: true,
12572 columns: true,
12573 flex: true,
12574 flexGrow: true,
12575 flexPositive: true,
12576 flexShrink: true,
12577 flexNegative: true,
12578 flexOrder: true,
12579 gridRow: true,
12580 gridRowEnd: true,
12581 gridRowSpan: true,
12582 gridRowStart: true,
12583 gridColumn: true,
12584 gridColumnEnd: true,
12585 gridColumnSpan: true,
12586 gridColumnStart: true,
12587 fontWeight: true,
12588 lineClamp: true,
12589 lineHeight: true,
12590 opacity: true,
12591 order: true,
12592 orphans: true,
12593 tabSize: true,
12594 widows: true,
12595 zIndex: true,
12596 zoom: true,
12597
12598 // SVG-related properties
12599 fillOpacity: true,
12600 floodOpacity: true,
12601 stopOpacity: true,
12602 strokeDasharray: true,
12603 strokeDashoffset: true,
12604 strokeMiterlimit: true,
12605 strokeOpacity: true,
12606 strokeWidth: true
12607};
12608
12609/**
12610 * @param {string} prefix vendor-specific prefix, eg: Webkit
12611 * @param {string} key style name, eg: transitionDuration
12612 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
12613 * WebkitTransitionDuration
12614 */
12615function prefixKey(prefix, key) {
12616 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
12617}
12618
12619/**
12620 * Support style names that may come passed in prefixed by adding permutations
12621 * of vendor prefixes.
12622 */
12623var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
12624
12625// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
12626// infinite loop, because it iterates over the newly added props too.
12627Object.keys(isUnitlessNumber).forEach(function (prop) {
12628 prefixes.forEach(function (prefix) {
12629 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
12630 });
12631});
12632
12633/**
12634 * Convert a value into the proper css writable value. The style name `name`
12635 * should be logical (no hyphens), as specified
12636 * in `CSSProperty.isUnitlessNumber`.
12637 *
12638 * @param {string} name CSS property name such as `topMargin`.
12639 * @param {*} value CSS property value such as `10px`.
12640 * @return {string} Normalized style value with dimensions applied.
12641 */
12642function dangerousStyleValue(name, value, isCustomProperty) {
12643 // Note that we've removed escapeTextForBrowser() calls here since the
12644 // whole string will be escaped when the attribute is injected into
12645 // the markup. If you provide unsafe user data here they can inject
12646 // arbitrary CSS which may be problematic (I couldn't repro this):
12647 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
12648 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
12649 // This is not an XSS hole but instead a potential CSS injection issue
12650 // which has lead to a greater discussion about how we're going to
12651 // trust URLs moving forward. See #2115901
12652
12653 var isEmpty = value == null || typeof value === 'boolean' || value === '';
12654 if (isEmpty) {
12655 return '';
12656 }
12657
12658 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
12659 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
12660 }
12661
12662 return ('' + value).trim();
12663}
12664
12665/**
12666 * Copyright (c) 2013-present, Facebook, Inc.
12667 *
12668 * This source code is licensed under the MIT license found in the
12669 * LICENSE file in the root directory of this source tree.
12670 *
12671 * @typechecks
12672 */
12673
12674var _uppercasePattern = /([A-Z])/g;
12675
12676/**
12677 * Hyphenates a camelcased string, for example:
12678 *
12679 * > hyphenate('backgroundColor')
12680 * < "background-color"
12681 *
12682 * For CSS style names, use `hyphenateStyleName` instead which works properly
12683 * with all vendor prefixes, including `ms`.
12684 *
12685 * @param {string} string
12686 * @return {string}
12687 */
12688function hyphenate(string) {
12689 return string.replace(_uppercasePattern, '-$1').toLowerCase();
12690}
12691
12692var hyphenate_1 = hyphenate;
12693
12694/**
12695 * Copyright (c) 2013-present, Facebook, Inc.
12696 *
12697 * This source code is licensed under the MIT license found in the
12698 * LICENSE file in the root directory of this source tree.
12699 *
12700 * @typechecks
12701 */
12702
12703
12704
12705
12706
12707var msPattern = /^ms-/;
12708
12709/**
12710 * Hyphenates a camelcased CSS property name, for example:
12711 *
12712 * > hyphenateStyleName('backgroundColor')
12713 * < "background-color"
12714 * > hyphenateStyleName('MozTransition')
12715 * < "-moz-transition"
12716 * > hyphenateStyleName('msTransition')
12717 * < "-ms-transition"
12718 *
12719 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
12720 * is converted to `-ms-`.
12721 *
12722 * @param {string} string
12723 * @return {string}
12724 */
12725function hyphenateStyleName(string) {
12726 return hyphenate_1(string).replace(msPattern, '-ms-');
12727}
12728
12729var hyphenateStyleName_1 = hyphenateStyleName;
12730
12731/**
12732 * Copyright (c) 2013-present, Facebook, Inc.
12733 *
12734 * This source code is licensed under the MIT license found in the
12735 * LICENSE file in the root directory of this source tree.
12736 *
12737 * @typechecks
12738 */
12739
12740var _hyphenPattern = /-(.)/g;
12741
12742/**
12743 * Camelcases a hyphenated string, for example:
12744 *
12745 * > camelize('background-color')
12746 * < "backgroundColor"
12747 *
12748 * @param {string} string
12749 * @return {string}
12750 */
12751function camelize(string) {
12752 return string.replace(_hyphenPattern, function (_, character) {
12753 return character.toUpperCase();
12754 });
12755}
12756
12757var camelize_1 = camelize;
12758
12759/**
12760 * Copyright (c) 2013-present, Facebook, Inc.
12761 *
12762 * This source code is licensed under the MIT license found in the
12763 * LICENSE file in the root directory of this source tree.
12764 *
12765 * @typechecks
12766 */
12767
12768
12769
12770
12771
12772var msPattern$1 = /^-ms-/;
12773
12774/**
12775 * Camelcases a hyphenated CSS property name, for example:
12776 *
12777 * > camelizeStyleName('background-color')
12778 * < "backgroundColor"
12779 * > camelizeStyleName('-moz-transition')
12780 * < "MozTransition"
12781 * > camelizeStyleName('-ms-transition')
12782 * < "msTransition"
12783 *
12784 * As Andi Smith suggests
12785 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
12786 * is converted to lowercase `ms`.
12787 *
12788 * @param {string} string
12789 * @return {string}
12790 */
12791function camelizeStyleName(string) {
12792 return camelize_1(string.replace(msPattern$1, 'ms-'));
12793}
12794
12795var camelizeStyleName_1 = camelizeStyleName;
12796
12797var warnValidStyle = emptyFunction_1;
12798
12799{
12800 // 'msTransform' is correct, but the other prefixes should be capitalized
12801 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
12802
12803 // style values shouldn't contain a semicolon
12804 var badStyleValueWithSemicolonPattern = /;\s*$/;
12805
12806 var warnedStyleNames = {};
12807 var warnedStyleValues = {};
12808 var warnedForNaNValue = false;
12809 var warnedForInfinityValue = false;
12810
12811 var warnHyphenatedStyleName = function (name, getStack) {
12812 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12813 return;
12814 }
12815
12816 warnedStyleNames[name] = true;
12817 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
12818 };
12819
12820 var warnBadVendoredStyleName = function (name, getStack) {
12821 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12822 return;
12823 }
12824
12825 warnedStyleNames[name] = true;
12826 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
12827 };
12828
12829 var warnStyleValueWithSemicolon = function (name, value, getStack) {
12830 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
12831 return;
12832 }
12833
12834 warnedStyleValues[value] = true;
12835 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
12836 };
12837
12838 var warnStyleValueIsNaN = function (name, value, getStack) {
12839 if (warnedForNaNValue) {
12840 return;
12841 }
12842
12843 warnedForNaNValue = true;
12844 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
12845 };
12846
12847 var warnStyleValueIsInfinity = function (name, value, getStack) {
12848 if (warnedForInfinityValue) {
12849 return;
12850 }
12851
12852 warnedForInfinityValue = true;
12853 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
12854 };
12855
12856 warnValidStyle = function (name, value, getStack) {
12857 if (name.indexOf('-') > -1) {
12858 warnHyphenatedStyleName(name, getStack);
12859 } else if (badVendoredStyleNamePattern.test(name)) {
12860 warnBadVendoredStyleName(name, getStack);
12861 } else if (badStyleValueWithSemicolonPattern.test(value)) {
12862 warnStyleValueWithSemicolon(name, value, getStack);
12863 }
12864
12865 if (typeof value === 'number') {
12866 if (isNaN(value)) {
12867 warnStyleValueIsNaN(name, value, getStack);
12868 } else if (!isFinite(value)) {
12869 warnStyleValueIsInfinity(name, value, getStack);
12870 }
12871 }
12872 };
12873}
12874
12875var warnValidStyle$1 = warnValidStyle;
12876
12877/**
12878 * Operations for dealing with CSS properties.
12879 */
12880
12881/**
12882 * This creates a string that is expected to be equivalent to the style
12883 * attribute generated by server-side rendering. It by-passes warnings and
12884 * security checks so it's not safe to use this value for anything other than
12885 * comparison. It is only used in DEV for SSR validation.
12886 */
12887function createDangerousStringForStyles(styles) {
12888 {
12889 var serialized = '';
12890 var delimiter = '';
12891 for (var styleName in styles) {
12892 if (!styles.hasOwnProperty(styleName)) {
12893 continue;
12894 }
12895 var styleValue = styles[styleName];
12896 if (styleValue != null) {
12897 var isCustomProperty = styleName.indexOf('--') === 0;
12898 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
12899 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
12900
12901 delimiter = ';';
12902 }
12903 }
12904 return serialized || null;
12905 }
12906}
12907
12908/**
12909 * Sets the value for multiple styles on a node. If a value is specified as
12910 * '' (empty string), the corresponding style property will be unset.
12911 *
12912 * @param {DOMElement} node
12913 * @param {object} styles
12914 */
12915function setValueForStyles(node, styles, getStack) {
12916 var style = node.style;
12917 for (var styleName in styles) {
12918 if (!styles.hasOwnProperty(styleName)) {
12919 continue;
12920 }
12921 var isCustomProperty = styleName.indexOf('--') === 0;
12922 {
12923 if (!isCustomProperty) {
12924 warnValidStyle$1(styleName, styles[styleName], getStack);
12925 }
12926 }
12927 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
12928 if (styleName === 'float') {
12929 styleName = 'cssFloat';
12930 }
12931 if (isCustomProperty) {
12932 style.setProperty(styleName, styleValue);
12933 } else {
12934 style[styleName] = styleValue;
12935 }
12936 }
12937}
12938
12939// For HTML, certain tags should omit their close tag. We keep a whitelist for
12940// those special-case tags.
12941
12942var omittedCloseTags = {
12943 area: true,
12944 base: true,
12945 br: true,
12946 col: true,
12947 embed: true,
12948 hr: true,
12949 img: true,
12950 input: true,
12951 keygen: true,
12952 link: true,
12953 meta: true,
12954 param: true,
12955 source: true,
12956 track: true,
12957 wbr: true
12958};
12959
12960// For HTML, certain tags cannot have children. This has the same purpose as
12961// `omittedCloseTags` except that `menuitem` should still have its closing tag.
12962
12963var voidElementTags = _assign({
12964 menuitem: true
12965}, omittedCloseTags);
12966
12967var HTML$1 = '__html';
12968
12969function assertValidProps(tag, props, getStack) {
12970 if (!props) {
12971 return;
12972 }
12973 // Note the use of `==` which checks for null or undefined.
12974 if (voidElementTags[tag]) {
12975 !(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;
12976 }
12977 if (props.dangerouslySetInnerHTML != null) {
12978 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
12979 !(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;
12980 }
12981 {
12982 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());
12983 }
12984 !(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;
12985}
12986
12987function isCustomComponent(tagName, props) {
12988 if (tagName.indexOf('-') === -1) {
12989 return typeof props.is === 'string';
12990 }
12991 switch (tagName) {
12992 // These are reserved SVG and MathML elements.
12993 // We don't mind this whitelist too much because we expect it to never grow.
12994 // The alternative is to track the namespace in a few places which is convoluted.
12995 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
12996 case 'annotation-xml':
12997 case 'color-profile':
12998 case 'font-face':
12999 case 'font-face-src':
13000 case 'font-face-uri':
13001 case 'font-face-format':
13002 case 'font-face-name':
13003 case 'missing-glyph':
13004 return false;
13005 default:
13006 return true;
13007 }
13008}
13009
13010// When adding attributes to the HTML or SVG whitelist, be sure to
13011// also add them to this module to ensure casing and incorrect name
13012// warnings.
13013var possibleStandardNames = {
13014 // HTML
13015 accept: 'accept',
13016 acceptcharset: 'acceptCharset',
13017 'accept-charset': 'acceptCharset',
13018 accesskey: 'accessKey',
13019 action: 'action',
13020 allowfullscreen: 'allowFullScreen',
13021 alt: 'alt',
13022 as: 'as',
13023 async: 'async',
13024 autocapitalize: 'autoCapitalize',
13025 autocomplete: 'autoComplete',
13026 autocorrect: 'autoCorrect',
13027 autofocus: 'autoFocus',
13028 autoplay: 'autoPlay',
13029 autosave: 'autoSave',
13030 capture: 'capture',
13031 cellpadding: 'cellPadding',
13032 cellspacing: 'cellSpacing',
13033 challenge: 'challenge',
13034 charset: 'charSet',
13035 checked: 'checked',
13036 children: 'children',
13037 cite: 'cite',
13038 'class': 'className',
13039 classid: 'classID',
13040 classname: 'className',
13041 cols: 'cols',
13042 colspan: 'colSpan',
13043 content: 'content',
13044 contenteditable: 'contentEditable',
13045 contextmenu: 'contextMenu',
13046 controls: 'controls',
13047 controlslist: 'controlsList',
13048 coords: 'coords',
13049 crossorigin: 'crossOrigin',
13050 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13051 data: 'data',
13052 datetime: 'dateTime',
13053 'default': 'default',
13054 defaultchecked: 'defaultChecked',
13055 defaultvalue: 'defaultValue',
13056 defer: 'defer',
13057 dir: 'dir',
13058 disabled: 'disabled',
13059 download: 'download',
13060 draggable: 'draggable',
13061 enctype: 'encType',
13062 'for': 'htmlFor',
13063 form: 'form',
13064 formmethod: 'formMethod',
13065 formaction: 'formAction',
13066 formenctype: 'formEncType',
13067 formnovalidate: 'formNoValidate',
13068 formtarget: 'formTarget',
13069 frameborder: 'frameBorder',
13070 headers: 'headers',
13071 height: 'height',
13072 hidden: 'hidden',
13073 high: 'high',
13074 href: 'href',
13075 hreflang: 'hrefLang',
13076 htmlfor: 'htmlFor',
13077 httpequiv: 'httpEquiv',
13078 'http-equiv': 'httpEquiv',
13079 icon: 'icon',
13080 id: 'id',
13081 innerhtml: 'innerHTML',
13082 inputmode: 'inputMode',
13083 integrity: 'integrity',
13084 is: 'is',
13085 itemid: 'itemID',
13086 itemprop: 'itemProp',
13087 itemref: 'itemRef',
13088 itemscope: 'itemScope',
13089 itemtype: 'itemType',
13090 keyparams: 'keyParams',
13091 keytype: 'keyType',
13092 kind: 'kind',
13093 label: 'label',
13094 lang: 'lang',
13095 list: 'list',
13096 loop: 'loop',
13097 low: 'low',
13098 manifest: 'manifest',
13099 marginwidth: 'marginWidth',
13100 marginheight: 'marginHeight',
13101 max: 'max',
13102 maxlength: 'maxLength',
13103 media: 'media',
13104 mediagroup: 'mediaGroup',
13105 method: 'method',
13106 min: 'min',
13107 minlength: 'minLength',
13108 multiple: 'multiple',
13109 muted: 'muted',
13110 name: 'name',
13111 nomodule: 'noModule',
13112 nonce: 'nonce',
13113 novalidate: 'noValidate',
13114 open: 'open',
13115 optimum: 'optimum',
13116 pattern: 'pattern',
13117 placeholder: 'placeholder',
13118 playsinline: 'playsInline',
13119 poster: 'poster',
13120 preload: 'preload',
13121 profile: 'profile',
13122 radiogroup: 'radioGroup',
13123 readonly: 'readOnly',
13124 referrerpolicy: 'referrerPolicy',
13125 rel: 'rel',
13126 required: 'required',
13127 reversed: 'reversed',
13128 role: 'role',
13129 rows: 'rows',
13130 rowspan: 'rowSpan',
13131 sandbox: 'sandbox',
13132 scope: 'scope',
13133 scoped: 'scoped',
13134 scrolling: 'scrolling',
13135 seamless: 'seamless',
13136 selected: 'selected',
13137 shape: 'shape',
13138 size: 'size',
13139 sizes: 'sizes',
13140 span: 'span',
13141 spellcheck: 'spellCheck',
13142 src: 'src',
13143 srcdoc: 'srcDoc',
13144 srclang: 'srcLang',
13145 srcset: 'srcSet',
13146 start: 'start',
13147 step: 'step',
13148 style: 'style',
13149 summary: 'summary',
13150 tabindex: 'tabIndex',
13151 target: 'target',
13152 title: 'title',
13153 type: 'type',
13154 usemap: 'useMap',
13155 value: 'value',
13156 width: 'width',
13157 wmode: 'wmode',
13158 wrap: 'wrap',
13159
13160 // SVG
13161 about: 'about',
13162 accentheight: 'accentHeight',
13163 'accent-height': 'accentHeight',
13164 accumulate: 'accumulate',
13165 additive: 'additive',
13166 alignmentbaseline: 'alignmentBaseline',
13167 'alignment-baseline': 'alignmentBaseline',
13168 allowreorder: 'allowReorder',
13169 alphabetic: 'alphabetic',
13170 amplitude: 'amplitude',
13171 arabicform: 'arabicForm',
13172 'arabic-form': 'arabicForm',
13173 ascent: 'ascent',
13174 attributename: 'attributeName',
13175 attributetype: 'attributeType',
13176 autoreverse: 'autoReverse',
13177 azimuth: 'azimuth',
13178 basefrequency: 'baseFrequency',
13179 baselineshift: 'baselineShift',
13180 'baseline-shift': 'baselineShift',
13181 baseprofile: 'baseProfile',
13182 bbox: 'bbox',
13183 begin: 'begin',
13184 bias: 'bias',
13185 by: 'by',
13186 calcmode: 'calcMode',
13187 capheight: 'capHeight',
13188 'cap-height': 'capHeight',
13189 clip: 'clip',
13190 clippath: 'clipPath',
13191 'clip-path': 'clipPath',
13192 clippathunits: 'clipPathUnits',
13193 cliprule: 'clipRule',
13194 'clip-rule': 'clipRule',
13195 color: 'color',
13196 colorinterpolation: 'colorInterpolation',
13197 'color-interpolation': 'colorInterpolation',
13198 colorinterpolationfilters: 'colorInterpolationFilters',
13199 'color-interpolation-filters': 'colorInterpolationFilters',
13200 colorprofile: 'colorProfile',
13201 'color-profile': 'colorProfile',
13202 colorrendering: 'colorRendering',
13203 'color-rendering': 'colorRendering',
13204 contentscripttype: 'contentScriptType',
13205 contentstyletype: 'contentStyleType',
13206 cursor: 'cursor',
13207 cx: 'cx',
13208 cy: 'cy',
13209 d: 'd',
13210 datatype: 'datatype',
13211 decelerate: 'decelerate',
13212 descent: 'descent',
13213 diffuseconstant: 'diffuseConstant',
13214 direction: 'direction',
13215 display: 'display',
13216 divisor: 'divisor',
13217 dominantbaseline: 'dominantBaseline',
13218 'dominant-baseline': 'dominantBaseline',
13219 dur: 'dur',
13220 dx: 'dx',
13221 dy: 'dy',
13222 edgemode: 'edgeMode',
13223 elevation: 'elevation',
13224 enablebackground: 'enableBackground',
13225 'enable-background': 'enableBackground',
13226 end: 'end',
13227 exponent: 'exponent',
13228 externalresourcesrequired: 'externalResourcesRequired',
13229 fill: 'fill',
13230 fillopacity: 'fillOpacity',
13231 'fill-opacity': 'fillOpacity',
13232 fillrule: 'fillRule',
13233 'fill-rule': 'fillRule',
13234 filter: 'filter',
13235 filterres: 'filterRes',
13236 filterunits: 'filterUnits',
13237 floodopacity: 'floodOpacity',
13238 'flood-opacity': 'floodOpacity',
13239 floodcolor: 'floodColor',
13240 'flood-color': 'floodColor',
13241 focusable: 'focusable',
13242 fontfamily: 'fontFamily',
13243 'font-family': 'fontFamily',
13244 fontsize: 'fontSize',
13245 'font-size': 'fontSize',
13246 fontsizeadjust: 'fontSizeAdjust',
13247 'font-size-adjust': 'fontSizeAdjust',
13248 fontstretch: 'fontStretch',
13249 'font-stretch': 'fontStretch',
13250 fontstyle: 'fontStyle',
13251 'font-style': 'fontStyle',
13252 fontvariant: 'fontVariant',
13253 'font-variant': 'fontVariant',
13254 fontweight: 'fontWeight',
13255 'font-weight': 'fontWeight',
13256 format: 'format',
13257 from: 'from',
13258 fx: 'fx',
13259 fy: 'fy',
13260 g1: 'g1',
13261 g2: 'g2',
13262 glyphname: 'glyphName',
13263 'glyph-name': 'glyphName',
13264 glyphorientationhorizontal: 'glyphOrientationHorizontal',
13265 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
13266 glyphorientationvertical: 'glyphOrientationVertical',
13267 'glyph-orientation-vertical': 'glyphOrientationVertical',
13268 glyphref: 'glyphRef',
13269 gradienttransform: 'gradientTransform',
13270 gradientunits: 'gradientUnits',
13271 hanging: 'hanging',
13272 horizadvx: 'horizAdvX',
13273 'horiz-adv-x': 'horizAdvX',
13274 horizoriginx: 'horizOriginX',
13275 'horiz-origin-x': 'horizOriginX',
13276 ideographic: 'ideographic',
13277 imagerendering: 'imageRendering',
13278 'image-rendering': 'imageRendering',
13279 in2: 'in2',
13280 'in': 'in',
13281 inlist: 'inlist',
13282 intercept: 'intercept',
13283 k1: 'k1',
13284 k2: 'k2',
13285 k3: 'k3',
13286 k4: 'k4',
13287 k: 'k',
13288 kernelmatrix: 'kernelMatrix',
13289 kernelunitlength: 'kernelUnitLength',
13290 kerning: 'kerning',
13291 keypoints: 'keyPoints',
13292 keysplines: 'keySplines',
13293 keytimes: 'keyTimes',
13294 lengthadjust: 'lengthAdjust',
13295 letterspacing: 'letterSpacing',
13296 'letter-spacing': 'letterSpacing',
13297 lightingcolor: 'lightingColor',
13298 'lighting-color': 'lightingColor',
13299 limitingconeangle: 'limitingConeAngle',
13300 local: 'local',
13301 markerend: 'markerEnd',
13302 'marker-end': 'markerEnd',
13303 markerheight: 'markerHeight',
13304 markermid: 'markerMid',
13305 'marker-mid': 'markerMid',
13306 markerstart: 'markerStart',
13307 'marker-start': 'markerStart',
13308 markerunits: 'markerUnits',
13309 markerwidth: 'markerWidth',
13310 mask: 'mask',
13311 maskcontentunits: 'maskContentUnits',
13312 maskunits: 'maskUnits',
13313 mathematical: 'mathematical',
13314 mode: 'mode',
13315 numoctaves: 'numOctaves',
13316 offset: 'offset',
13317 opacity: 'opacity',
13318 operator: 'operator',
13319 order: 'order',
13320 orient: 'orient',
13321 orientation: 'orientation',
13322 origin: 'origin',
13323 overflow: 'overflow',
13324 overlineposition: 'overlinePosition',
13325 'overline-position': 'overlinePosition',
13326 overlinethickness: 'overlineThickness',
13327 'overline-thickness': 'overlineThickness',
13328 paintorder: 'paintOrder',
13329 'paint-order': 'paintOrder',
13330 panose1: 'panose1',
13331 'panose-1': 'panose1',
13332 pathlength: 'pathLength',
13333 patterncontentunits: 'patternContentUnits',
13334 patterntransform: 'patternTransform',
13335 patternunits: 'patternUnits',
13336 pointerevents: 'pointerEvents',
13337 'pointer-events': 'pointerEvents',
13338 points: 'points',
13339 pointsatx: 'pointsAtX',
13340 pointsaty: 'pointsAtY',
13341 pointsatz: 'pointsAtZ',
13342 prefix: 'prefix',
13343 preservealpha: 'preserveAlpha',
13344 preserveaspectratio: 'preserveAspectRatio',
13345 primitiveunits: 'primitiveUnits',
13346 property: 'property',
13347 r: 'r',
13348 radius: 'radius',
13349 refx: 'refX',
13350 refy: 'refY',
13351 renderingintent: 'renderingIntent',
13352 'rendering-intent': 'renderingIntent',
13353 repeatcount: 'repeatCount',
13354 repeatdur: 'repeatDur',
13355 requiredextensions: 'requiredExtensions',
13356 requiredfeatures: 'requiredFeatures',
13357 resource: 'resource',
13358 restart: 'restart',
13359 result: 'result',
13360 results: 'results',
13361 rotate: 'rotate',
13362 rx: 'rx',
13363 ry: 'ry',
13364 scale: 'scale',
13365 security: 'security',
13366 seed: 'seed',
13367 shaperendering: 'shapeRendering',
13368 'shape-rendering': 'shapeRendering',
13369 slope: 'slope',
13370 spacing: 'spacing',
13371 specularconstant: 'specularConstant',
13372 specularexponent: 'specularExponent',
13373 speed: 'speed',
13374 spreadmethod: 'spreadMethod',
13375 startoffset: 'startOffset',
13376 stddeviation: 'stdDeviation',
13377 stemh: 'stemh',
13378 stemv: 'stemv',
13379 stitchtiles: 'stitchTiles',
13380 stopcolor: 'stopColor',
13381 'stop-color': 'stopColor',
13382 stopopacity: 'stopOpacity',
13383 'stop-opacity': 'stopOpacity',
13384 strikethroughposition: 'strikethroughPosition',
13385 'strikethrough-position': 'strikethroughPosition',
13386 strikethroughthickness: 'strikethroughThickness',
13387 'strikethrough-thickness': 'strikethroughThickness',
13388 string: 'string',
13389 stroke: 'stroke',
13390 strokedasharray: 'strokeDasharray',
13391 'stroke-dasharray': 'strokeDasharray',
13392 strokedashoffset: 'strokeDashoffset',
13393 'stroke-dashoffset': 'strokeDashoffset',
13394 strokelinecap: 'strokeLinecap',
13395 'stroke-linecap': 'strokeLinecap',
13396 strokelinejoin: 'strokeLinejoin',
13397 'stroke-linejoin': 'strokeLinejoin',
13398 strokemiterlimit: 'strokeMiterlimit',
13399 'stroke-miterlimit': 'strokeMiterlimit',
13400 strokewidth: 'strokeWidth',
13401 'stroke-width': 'strokeWidth',
13402 strokeopacity: 'strokeOpacity',
13403 'stroke-opacity': 'strokeOpacity',
13404 suppresscontenteditablewarning: 'suppressContentEditableWarning',
13405 suppresshydrationwarning: 'suppressHydrationWarning',
13406 surfacescale: 'surfaceScale',
13407 systemlanguage: 'systemLanguage',
13408 tablevalues: 'tableValues',
13409 targetx: 'targetX',
13410 targety: 'targetY',
13411 textanchor: 'textAnchor',
13412 'text-anchor': 'textAnchor',
13413 textdecoration: 'textDecoration',
13414 'text-decoration': 'textDecoration',
13415 textlength: 'textLength',
13416 textrendering: 'textRendering',
13417 'text-rendering': 'textRendering',
13418 to: 'to',
13419 transform: 'transform',
13420 'typeof': 'typeof',
13421 u1: 'u1',
13422 u2: 'u2',
13423 underlineposition: 'underlinePosition',
13424 'underline-position': 'underlinePosition',
13425 underlinethickness: 'underlineThickness',
13426 'underline-thickness': 'underlineThickness',
13427 unicode: 'unicode',
13428 unicodebidi: 'unicodeBidi',
13429 'unicode-bidi': 'unicodeBidi',
13430 unicoderange: 'unicodeRange',
13431 'unicode-range': 'unicodeRange',
13432 unitsperem: 'unitsPerEm',
13433 'units-per-em': 'unitsPerEm',
13434 unselectable: 'unselectable',
13435 valphabetic: 'vAlphabetic',
13436 'v-alphabetic': 'vAlphabetic',
13437 values: 'values',
13438 vectoreffect: 'vectorEffect',
13439 'vector-effect': 'vectorEffect',
13440 version: 'version',
13441 vertadvy: 'vertAdvY',
13442 'vert-adv-y': 'vertAdvY',
13443 vertoriginx: 'vertOriginX',
13444 'vert-origin-x': 'vertOriginX',
13445 vertoriginy: 'vertOriginY',
13446 'vert-origin-y': 'vertOriginY',
13447 vhanging: 'vHanging',
13448 'v-hanging': 'vHanging',
13449 videographic: 'vIdeographic',
13450 'v-ideographic': 'vIdeographic',
13451 viewbox: 'viewBox',
13452 viewtarget: 'viewTarget',
13453 visibility: 'visibility',
13454 vmathematical: 'vMathematical',
13455 'v-mathematical': 'vMathematical',
13456 vocab: 'vocab',
13457 widths: 'widths',
13458 wordspacing: 'wordSpacing',
13459 'word-spacing': 'wordSpacing',
13460 writingmode: 'writingMode',
13461 'writing-mode': 'writingMode',
13462 x1: 'x1',
13463 x2: 'x2',
13464 x: 'x',
13465 xchannelselector: 'xChannelSelector',
13466 xheight: 'xHeight',
13467 'x-height': 'xHeight',
13468 xlinkactuate: 'xlinkActuate',
13469 'xlink:actuate': 'xlinkActuate',
13470 xlinkarcrole: 'xlinkArcrole',
13471 'xlink:arcrole': 'xlinkArcrole',
13472 xlinkhref: 'xlinkHref',
13473 'xlink:href': 'xlinkHref',
13474 xlinkrole: 'xlinkRole',
13475 'xlink:role': 'xlinkRole',
13476 xlinkshow: 'xlinkShow',
13477 'xlink:show': 'xlinkShow',
13478 xlinktitle: 'xlinkTitle',
13479 'xlink:title': 'xlinkTitle',
13480 xlinktype: 'xlinkType',
13481 'xlink:type': 'xlinkType',
13482 xmlbase: 'xmlBase',
13483 'xml:base': 'xmlBase',
13484 xmllang: 'xmlLang',
13485 'xml:lang': 'xmlLang',
13486 xmlns: 'xmlns',
13487 'xml:space': 'xmlSpace',
13488 xmlnsxlink: 'xmlnsXlink',
13489 'xmlns:xlink': 'xmlnsXlink',
13490 xmlspace: 'xmlSpace',
13491 y1: 'y1',
13492 y2: 'y2',
13493 y: 'y',
13494 ychannelselector: 'yChannelSelector',
13495 z: 'z',
13496 zoomandpan: 'zoomAndPan'
13497};
13498
13499var ariaProperties = {
13500 'aria-current': 0, // state
13501 'aria-details': 0,
13502 'aria-disabled': 0, // state
13503 'aria-hidden': 0, // state
13504 'aria-invalid': 0, // state
13505 'aria-keyshortcuts': 0,
13506 'aria-label': 0,
13507 'aria-roledescription': 0,
13508 // Widget Attributes
13509 'aria-autocomplete': 0,
13510 'aria-checked': 0,
13511 'aria-expanded': 0,
13512 'aria-haspopup': 0,
13513 'aria-level': 0,
13514 'aria-modal': 0,
13515 'aria-multiline': 0,
13516 'aria-multiselectable': 0,
13517 'aria-orientation': 0,
13518 'aria-placeholder': 0,
13519 'aria-pressed': 0,
13520 'aria-readonly': 0,
13521 'aria-required': 0,
13522 'aria-selected': 0,
13523 'aria-sort': 0,
13524 'aria-valuemax': 0,
13525 'aria-valuemin': 0,
13526 'aria-valuenow': 0,
13527 'aria-valuetext': 0,
13528 // Live Region Attributes
13529 'aria-atomic': 0,
13530 'aria-busy': 0,
13531 'aria-live': 0,
13532 'aria-relevant': 0,
13533 // Drag-and-Drop Attributes
13534 'aria-dropeffect': 0,
13535 'aria-grabbed': 0,
13536 // Relationship Attributes
13537 'aria-activedescendant': 0,
13538 'aria-colcount': 0,
13539 'aria-colindex': 0,
13540 'aria-colspan': 0,
13541 'aria-controls': 0,
13542 'aria-describedby': 0,
13543 'aria-errormessage': 0,
13544 'aria-flowto': 0,
13545 'aria-labelledby': 0,
13546 'aria-owns': 0,
13547 'aria-posinset': 0,
13548 'aria-rowcount': 0,
13549 'aria-rowindex': 0,
13550 'aria-rowspan': 0,
13551 'aria-setsize': 0
13552};
13553
13554var warnedProperties = {};
13555var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13556var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13557
13558var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
13559
13560function getStackAddendum() {
13561 var stack = ReactDebugCurrentFrame.getStackAddendum();
13562 return stack != null ? stack : '';
13563}
13564
13565function validateProperty(tagName, name) {
13566 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
13567 return true;
13568 }
13569
13570 if (rARIACamel.test(name)) {
13571 var ariaName = 'aria-' + name.slice(4).toLowerCase();
13572 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
13573
13574 // If this is an aria-* attribute, but is not listed in the known DOM
13575 // DOM properties, then it is an invalid aria-* attribute.
13576 if (correctName == null) {
13577 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
13578 warnedProperties[name] = true;
13579 return true;
13580 }
13581 // aria-* attributes should be lowercase; suggest the lowercase version.
13582 if (name !== correctName) {
13583 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
13584 warnedProperties[name] = true;
13585 return true;
13586 }
13587 }
13588
13589 if (rARIA.test(name)) {
13590 var lowerCasedName = name.toLowerCase();
13591 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
13592
13593 // If this is an aria-* attribute, but is not listed in the known DOM
13594 // DOM properties, then it is an invalid aria-* attribute.
13595 if (standardName == null) {
13596 warnedProperties[name] = true;
13597 return false;
13598 }
13599 // aria-* attributes should be lowercase; suggest the lowercase version.
13600 if (name !== standardName) {
13601 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
13602 warnedProperties[name] = true;
13603 return true;
13604 }
13605 }
13606
13607 return true;
13608}
13609
13610function warnInvalidARIAProps(type, props) {
13611 var invalidProps = [];
13612
13613 for (var key in props) {
13614 var isValid = validateProperty(type, key);
13615 if (!isValid) {
13616 invalidProps.push(key);
13617 }
13618 }
13619
13620 var unknownPropString = invalidProps.map(function (prop) {
13621 return '`' + prop + '`';
13622 }).join(', ');
13623
13624 if (invalidProps.length === 1) {
13625 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13626 } else if (invalidProps.length > 1) {
13627 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13628 }
13629}
13630
13631function validateProperties(type, props) {
13632 if (isCustomComponent(type, props)) {
13633 return;
13634 }
13635 warnInvalidARIAProps(type, props);
13636}
13637
13638var didWarnValueNull = false;
13639
13640function getStackAddendum$1() {
13641 var stack = ReactDebugCurrentFrame.getStackAddendum();
13642 return stack != null ? stack : '';
13643}
13644
13645function validateProperties$1(type, props) {
13646 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
13647 return;
13648 }
13649
13650 if (props != null && props.value === null && !didWarnValueNull) {
13651 didWarnValueNull = true;
13652 if (type === 'select' && props.multiple) {
13653 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());
13654 } else {
13655 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());
13656 }
13657 }
13658}
13659
13660function getStackAddendum$2() {
13661 var stack = ReactDebugCurrentFrame.getStackAddendum();
13662 return stack != null ? stack : '';
13663}
13664
13665var validateProperty$1 = function () {};
13666
13667{
13668 var warnedProperties$1 = {};
13669 var _hasOwnProperty = Object.prototype.hasOwnProperty;
13670 var EVENT_NAME_REGEX = /^on./;
13671 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
13672 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13673 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13674
13675 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
13676 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
13677 return true;
13678 }
13679
13680 var lowerCasedName = name.toLowerCase();
13681 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
13682 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.');
13683 warnedProperties$1[name] = true;
13684 return true;
13685 }
13686
13687 // We can't rely on the event system being injected on the server.
13688 if (canUseEventSystem) {
13689 if (registrationNameModules.hasOwnProperty(name)) {
13690 return true;
13691 }
13692 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
13693 if (registrationName != null) {
13694 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
13695 warnedProperties$1[name] = true;
13696 return true;
13697 }
13698 if (EVENT_NAME_REGEX.test(name)) {
13699 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
13700 warnedProperties$1[name] = true;
13701 return true;
13702 }
13703 } else if (EVENT_NAME_REGEX.test(name)) {
13704 // If no event plugins have been injected, we are in a server environment.
13705 // So we can't tell if the event name is correct for sure, but we can filter
13706 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
13707 if (INVALID_EVENT_NAME_REGEX.test(name)) {
13708 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
13709 }
13710 warnedProperties$1[name] = true;
13711 return true;
13712 }
13713
13714 // Let the ARIA attribute hook validate ARIA attributes
13715 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
13716 return true;
13717 }
13718
13719 if (lowerCasedName === 'innerhtml') {
13720 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
13721 warnedProperties$1[name] = true;
13722 return true;
13723 }
13724
13725 if (lowerCasedName === 'aria') {
13726 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
13727 warnedProperties$1[name] = true;
13728 return true;
13729 }
13730
13731 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
13732 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());
13733 warnedProperties$1[name] = true;
13734 return true;
13735 }
13736
13737 if (typeof value === 'number' && isNaN(value)) {
13738 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
13739 warnedProperties$1[name] = true;
13740 return true;
13741 }
13742
13743 var propertyInfo = getPropertyInfo(name);
13744 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
13745
13746 // Known attributes should match the casing specified in the property config.
13747 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
13748 var standardName = possibleStandardNames[lowerCasedName];
13749 if (standardName !== name) {
13750 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
13751 warnedProperties$1[name] = true;
13752 return true;
13753 }
13754 } else if (!isReserved && name !== lowerCasedName) {
13755 // Unknown attributes should have lowercase casing since that's how they
13756 // will be cased anyway with server rendering.
13757 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());
13758 warnedProperties$1[name] = true;
13759 return true;
13760 }
13761
13762 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13763 if (value) {
13764 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());
13765 } else {
13766 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());
13767 }
13768 warnedProperties$1[name] = true;
13769 return true;
13770 }
13771
13772 // Now that we've validated casing, do not validate
13773 // data types for reserved props
13774 if (isReserved) {
13775 return true;
13776 }
13777
13778 // Warn when a known attribute is a bad type
13779 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13780 warnedProperties$1[name] = true;
13781 return false;
13782 }
13783
13784 return true;
13785 };
13786}
13787
13788var warnUnknownProperties = function (type, props, canUseEventSystem) {
13789 var unknownProps = [];
13790 for (var key in props) {
13791 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
13792 if (!isValid) {
13793 unknownProps.push(key);
13794 }
13795 }
13796
13797 var unknownPropString = unknownProps.map(function (prop) {
13798 return '`' + prop + '`';
13799 }).join(', ');
13800 if (unknownProps.length === 1) {
13801 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());
13802 } else if (unknownProps.length > 1) {
13803 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());
13804 }
13805};
13806
13807function validateProperties$2(type, props, canUseEventSystem) {
13808 if (isCustomComponent(type, props)) {
13809 return;
13810 }
13811 warnUnknownProperties(type, props, canUseEventSystem);
13812}
13813
13814// TODO: direct imports like some-package/src/* are bad. Fix me.
13815var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
13816var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13817
13818var didWarnInvalidHydration = false;
13819var didWarnShadyDOM = false;
13820
13821var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
13822var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
13823var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
13824var AUTOFOCUS = 'autoFocus';
13825var CHILDREN = 'children';
13826var STYLE = 'style';
13827var HTML = '__html';
13828
13829var HTML_NAMESPACE = Namespaces.html;
13830
13831
13832var getStack = emptyFunction_1.thatReturns('');
13833
13834var warnedUnknownTags = void 0;
13835var suppressHydrationWarning = void 0;
13836
13837var validatePropertiesInDevelopment = void 0;
13838var warnForTextDifference = void 0;
13839var warnForPropDifference = void 0;
13840var warnForExtraAttributes = void 0;
13841var warnForInvalidEventListener = void 0;
13842
13843var normalizeMarkupForTextOrAttribute = void 0;
13844var normalizeHTML = void 0;
13845
13846{
13847 getStack = getCurrentFiberStackAddendum$3;
13848
13849 warnedUnknownTags = {
13850 // Chrome is the only major browser not shipping <time>. But as of July
13851 // 2017 it intends to ship it due to widespread usage. We intentionally
13852 // *don't* warn for <time> even if it's unrecognized by Chrome because
13853 // it soon will be, and many apps have been using it anyway.
13854 time: true,
13855 // There are working polyfills for <dialog>. Let people use it.
13856 dialog: true
13857 };
13858
13859 validatePropertiesInDevelopment = function (type, props) {
13860 validateProperties(type, props);
13861 validateProperties$1(type, props);
13862 validateProperties$2(type, props, /* canUseEventSystem */true);
13863 };
13864
13865 // HTML parsing normalizes CR and CRLF to LF.
13866 // It also can turn \u0000 into \uFFFD inside attributes.
13867 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
13868 // If we have a mismatch, it might be caused by that.
13869 // We will still patch up in this case but not fire the warning.
13870 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
13871 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
13872
13873 normalizeMarkupForTextOrAttribute = function (markup) {
13874 var markupString = typeof markup === 'string' ? markup : '' + markup;
13875 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
13876 };
13877
13878 warnForTextDifference = function (serverText, clientText) {
13879 if (didWarnInvalidHydration) {
13880 return;
13881 }
13882 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
13883 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
13884 if (normalizedServerText === normalizedClientText) {
13885 return;
13886 }
13887 didWarnInvalidHydration = true;
13888 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
13889 };
13890
13891 warnForPropDifference = function (propName, serverValue, clientValue) {
13892 if (didWarnInvalidHydration) {
13893 return;
13894 }
13895 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
13896 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
13897 if (normalizedServerValue === normalizedClientValue) {
13898 return;
13899 }
13900 didWarnInvalidHydration = true;
13901 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
13902 };
13903
13904 warnForExtraAttributes = function (attributeNames) {
13905 if (didWarnInvalidHydration) {
13906 return;
13907 }
13908 didWarnInvalidHydration = true;
13909 var names = [];
13910 attributeNames.forEach(function (name) {
13911 names.push(name);
13912 });
13913 warning_1(false, 'Extra attributes from the server: %s', names);
13914 };
13915
13916 warnForInvalidEventListener = function (registrationName, listener) {
13917 if (listener === false) {
13918 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());
13919 } else {
13920 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
13921 }
13922 };
13923
13924 // Parse the HTML and read it back to normalize the HTML string so that it
13925 // can be used for comparison.
13926 normalizeHTML = function (parent, html) {
13927 // We could have created a separate document here to avoid
13928 // re-initializing custom elements if they exist. But this breaks
13929 // how <noscript> is being handled. So we use the same document.
13930 // See the discussion in https://github.com/facebook/react/pull/11157.
13931 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
13932 testElement.innerHTML = html;
13933 return testElement.innerHTML;
13934 };
13935}
13936
13937function ensureListeningTo(rootContainerElement, registrationName) {
13938 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
13939 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
13940 listenTo(registrationName, doc);
13941}
13942
13943function getOwnerDocumentFromRootContainer(rootContainerElement) {
13944 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
13945}
13946
13947function trapClickOnNonInteractiveElement(node) {
13948 // Mobile Safari does not fire properly bubble click events on
13949 // non-interactive elements, which means delegated click listeners do not
13950 // fire. The workaround for this bug involves attaching an empty click
13951 // listener on the target node.
13952 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
13953 // Just set it using the onclick property so that we don't have to manage any
13954 // bookkeeping for it. Not sure if we need to clear it when the listener is
13955 // removed.
13956 // TODO: Only do this for the relevant Safaris maybe?
13957 node.onclick = emptyFunction_1;
13958}
13959
13960function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
13961 for (var propKey in nextProps) {
13962 if (!nextProps.hasOwnProperty(propKey)) {
13963 continue;
13964 }
13965 var nextProp = nextProps[propKey];
13966 if (propKey === STYLE) {
13967 {
13968 if (nextProp) {
13969 // Freeze the next style object so that we can assume it won't be
13970 // mutated. We have already warned for this in the past.
13971 Object.freeze(nextProp);
13972 }
13973 }
13974 // Relies on `updateStylesByID` not mutating `styleUpdates`.
13975 setValueForStyles(domElement, nextProp, getStack);
13976 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
13977 var nextHtml = nextProp ? nextProp[HTML] : undefined;
13978 if (nextHtml != null) {
13979 setInnerHTML(domElement, nextHtml);
13980 }
13981 } else if (propKey === CHILDREN) {
13982 if (typeof nextProp === 'string') {
13983 // Avoid setting initial textContent when the text is empty. In IE11 setting
13984 // textContent on a <textarea> will cause the placeholder to not
13985 // show within the <textarea> until it has been focused and blurred again.
13986 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
13987 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
13988 if (canSetTextContent) {
13989 setTextContent(domElement, nextProp);
13990 }
13991 } else if (typeof nextProp === 'number') {
13992 setTextContent(domElement, '' + nextProp);
13993 }
13994 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
13995 // Noop
13996 } else if (propKey === AUTOFOCUS) {
13997 // We polyfill it separately on the client during commit.
13998 // We blacklist it here rather than in the property list because we emit it in SSR.
13999 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14000 if (nextProp != null) {
14001 if (true && typeof nextProp !== 'function') {
14002 warnForInvalidEventListener(propKey, nextProp);
14003 }
14004 ensureListeningTo(rootContainerElement, propKey);
14005 }
14006 } else if (nextProp != null) {
14007 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14008 }
14009 }
14010}
14011
14012function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14013 // TODO: Handle wasCustomComponentTag
14014 for (var i = 0; i < updatePayload.length; i += 2) {
14015 var propKey = updatePayload[i];
14016 var propValue = updatePayload[i + 1];
14017 if (propKey === STYLE) {
14018 setValueForStyles(domElement, propValue, getStack);
14019 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14020 setInnerHTML(domElement, propValue);
14021 } else if (propKey === CHILDREN) {
14022 setTextContent(domElement, propValue);
14023 } else {
14024 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14025 }
14026 }
14027}
14028
14029function createElement$1(type, props, rootContainerElement, parentNamespace) {
14030 var isCustomComponentTag = void 0;
14031
14032 // We create tags in the namespace of their parent container, except HTML
14033 // tags get no namespace.
14034 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14035 var domElement = void 0;
14036 var namespaceURI = parentNamespace;
14037 if (namespaceURI === HTML_NAMESPACE) {
14038 namespaceURI = getIntrinsicNamespace(type);
14039 }
14040 if (namespaceURI === HTML_NAMESPACE) {
14041 {
14042 isCustomComponentTag = isCustomComponent(type, props);
14043 // Should this check be gated by parent namespace? Not sure we want to
14044 // allow <SVG> or <mATH>.
14045 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14046 }
14047
14048 if (type === 'script') {
14049 // Create the script via .innerHTML so its "parser-inserted" flag is
14050 // set to true and it does not execute
14051 var div = ownerDocument.createElement('div');
14052 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14053 // This is guaranteed to yield a script element.
14054 var firstChild = div.firstChild;
14055 domElement = div.removeChild(firstChild);
14056 } else if (typeof props.is === 'string') {
14057 // $FlowIssue `createElement` should be updated for Web Components
14058 domElement = ownerDocument.createElement(type, { is: props.is });
14059 } else {
14060 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14061 // See discussion in https://github.com/facebook/react/pull/6896
14062 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14063 domElement = ownerDocument.createElement(type);
14064 }
14065 } else {
14066 domElement = ownerDocument.createElementNS(namespaceURI, type);
14067 }
14068
14069 {
14070 if (namespaceURI === HTML_NAMESPACE) {
14071 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14072 warnedUnknownTags[type] = true;
14073 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);
14074 }
14075 }
14076 }
14077
14078 return domElement;
14079}
14080
14081function createTextNode$1(text, rootContainerElement) {
14082 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14083}
14084
14085function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14086 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14087 {
14088 validatePropertiesInDevelopment(tag, rawProps);
14089 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14090 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14091 didWarnShadyDOM = true;
14092 }
14093 }
14094
14095 // TODO: Make sure that we check isMounted before firing any of these events.
14096 var props = void 0;
14097 switch (tag) {
14098 case 'iframe':
14099 case 'object':
14100 trapBubbledEvent('topLoad', 'load', domElement);
14101 props = rawProps;
14102 break;
14103 case 'video':
14104 case 'audio':
14105 // Create listener for each media event
14106 for (var event in mediaEventTypes) {
14107 if (mediaEventTypes.hasOwnProperty(event)) {
14108 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14109 }
14110 }
14111 props = rawProps;
14112 break;
14113 case 'source':
14114 trapBubbledEvent('topError', 'error', domElement);
14115 props = rawProps;
14116 break;
14117 case 'img':
14118 case 'image':
14119 case 'link':
14120 trapBubbledEvent('topError', 'error', domElement);
14121 trapBubbledEvent('topLoad', 'load', domElement);
14122 props = rawProps;
14123 break;
14124 case 'form':
14125 trapBubbledEvent('topReset', 'reset', domElement);
14126 trapBubbledEvent('topSubmit', 'submit', domElement);
14127 props = rawProps;
14128 break;
14129 case 'details':
14130 trapBubbledEvent('topToggle', 'toggle', domElement);
14131 props = rawProps;
14132 break;
14133 case 'input':
14134 initWrapperState(domElement, rawProps);
14135 props = getHostProps(domElement, rawProps);
14136 trapBubbledEvent('topInvalid', 'invalid', domElement);
14137 // For controlled components we always need to ensure we're listening
14138 // to onChange. Even if there is no listener.
14139 ensureListeningTo(rootContainerElement, 'onChange');
14140 break;
14141 case 'option':
14142 validateProps(domElement, rawProps);
14143 props = getHostProps$1(domElement, rawProps);
14144 break;
14145 case 'select':
14146 initWrapperState$1(domElement, rawProps);
14147 props = getHostProps$2(domElement, rawProps);
14148 trapBubbledEvent('topInvalid', 'invalid', domElement);
14149 // For controlled components we always need to ensure we're listening
14150 // to onChange. Even if there is no listener.
14151 ensureListeningTo(rootContainerElement, 'onChange');
14152 break;
14153 case 'textarea':
14154 initWrapperState$2(domElement, rawProps);
14155 props = getHostProps$3(domElement, rawProps);
14156 trapBubbledEvent('topInvalid', 'invalid', domElement);
14157 // For controlled components we always need to ensure we're listening
14158 // to onChange. Even if there is no listener.
14159 ensureListeningTo(rootContainerElement, 'onChange');
14160 break;
14161 default:
14162 props = rawProps;
14163 }
14164
14165 assertValidProps(tag, props, getStack);
14166
14167 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
14168
14169 switch (tag) {
14170 case 'input':
14171 // TODO: Make sure we check if this is still unmounted or do any clean
14172 // up necessary since we never stop tracking anymore.
14173 track(domElement);
14174 postMountWrapper(domElement, rawProps);
14175 break;
14176 case 'textarea':
14177 // TODO: Make sure we check if this is still unmounted or do any clean
14178 // up necessary since we never stop tracking anymore.
14179 track(domElement);
14180 postMountWrapper$3(domElement, rawProps);
14181 break;
14182 case 'option':
14183 postMountWrapper$1(domElement, rawProps);
14184 break;
14185 case 'select':
14186 postMountWrapper$2(domElement, rawProps);
14187 break;
14188 default:
14189 if (typeof props.onClick === 'function') {
14190 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14191 trapClickOnNonInteractiveElement(domElement);
14192 }
14193 break;
14194 }
14195}
14196
14197// Calculate the diff between the two objects.
14198function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
14199 {
14200 validatePropertiesInDevelopment(tag, nextRawProps);
14201 }
14202
14203 var updatePayload = null;
14204
14205 var lastProps = void 0;
14206 var nextProps = void 0;
14207 switch (tag) {
14208 case 'input':
14209 lastProps = getHostProps(domElement, lastRawProps);
14210 nextProps = getHostProps(domElement, nextRawProps);
14211 updatePayload = [];
14212 break;
14213 case 'option':
14214 lastProps = getHostProps$1(domElement, lastRawProps);
14215 nextProps = getHostProps$1(domElement, nextRawProps);
14216 updatePayload = [];
14217 break;
14218 case 'select':
14219 lastProps = getHostProps$2(domElement, lastRawProps);
14220 nextProps = getHostProps$2(domElement, nextRawProps);
14221 updatePayload = [];
14222 break;
14223 case 'textarea':
14224 lastProps = getHostProps$3(domElement, lastRawProps);
14225 nextProps = getHostProps$3(domElement, nextRawProps);
14226 updatePayload = [];
14227 break;
14228 default:
14229 lastProps = lastRawProps;
14230 nextProps = nextRawProps;
14231 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
14232 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14233 trapClickOnNonInteractiveElement(domElement);
14234 }
14235 break;
14236 }
14237
14238 assertValidProps(tag, nextProps, getStack);
14239
14240 var propKey = void 0;
14241 var styleName = void 0;
14242 var styleUpdates = null;
14243 for (propKey in lastProps) {
14244 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
14245 continue;
14246 }
14247 if (propKey === STYLE) {
14248 var lastStyle = lastProps[propKey];
14249 for (styleName in lastStyle) {
14250 if (lastStyle.hasOwnProperty(styleName)) {
14251 if (!styleUpdates) {
14252 styleUpdates = {};
14253 }
14254 styleUpdates[styleName] = '';
14255 }
14256 }
14257 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
14258 // Noop. This is handled by the clear text mechanism.
14259 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14260 // Noop
14261 } else if (propKey === AUTOFOCUS) {
14262 // Noop. It doesn't work on updates anyway.
14263 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14264 // This is a special case. If any listener updates we need to ensure
14265 // that the "current" fiber pointer gets updated so we need a commit
14266 // to update this element.
14267 if (!updatePayload) {
14268 updatePayload = [];
14269 }
14270 } else {
14271 // For all other deleted properties we add it to the queue. We use
14272 // the whitelist in the commit phase instead.
14273 (updatePayload = updatePayload || []).push(propKey, null);
14274 }
14275 }
14276 for (propKey in nextProps) {
14277 var nextProp = nextProps[propKey];
14278 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
14279 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
14280 continue;
14281 }
14282 if (propKey === STYLE) {
14283 {
14284 if (nextProp) {
14285 // Freeze the next style object so that we can assume it won't be
14286 // mutated. We have already warned for this in the past.
14287 Object.freeze(nextProp);
14288 }
14289 }
14290 if (lastProp) {
14291 // Unset styles on `lastProp` but not on `nextProp`.
14292 for (styleName in lastProp) {
14293 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
14294 if (!styleUpdates) {
14295 styleUpdates = {};
14296 }
14297 styleUpdates[styleName] = '';
14298 }
14299 }
14300 // Update styles that changed since `lastProp`.
14301 for (styleName in nextProp) {
14302 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
14303 if (!styleUpdates) {
14304 styleUpdates = {};
14305 }
14306 styleUpdates[styleName] = nextProp[styleName];
14307 }
14308 }
14309 } else {
14310 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14311 if (!styleUpdates) {
14312 if (!updatePayload) {
14313 updatePayload = [];
14314 }
14315 updatePayload.push(propKey, styleUpdates);
14316 }
14317 styleUpdates = nextProp;
14318 }
14319 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14320 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14321 var lastHtml = lastProp ? lastProp[HTML] : undefined;
14322 if (nextHtml != null) {
14323 if (lastHtml !== nextHtml) {
14324 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
14325 }
14326 } else {
14327 // TODO: It might be too late to clear this if we have children
14328 // inserted already.
14329 }
14330 } else if (propKey === CHILDREN) {
14331 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
14332 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
14333 }
14334 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14335 // Noop
14336 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14337 if (nextProp != null) {
14338 // We eagerly listen to this even though we haven't committed yet.
14339 if (true && typeof nextProp !== 'function') {
14340 warnForInvalidEventListener(propKey, nextProp);
14341 }
14342 ensureListeningTo(rootContainerElement, propKey);
14343 }
14344 if (!updatePayload && lastProp !== nextProp) {
14345 // This is a special case. If any listener updates we need to ensure
14346 // that the "current" props pointer gets updated so we need a commit
14347 // to update this element.
14348 updatePayload = [];
14349 }
14350 } else {
14351 // For any other property we always add it to the queue and then we
14352 // filter it out using the whitelist during the commit.
14353 (updatePayload = updatePayload || []).push(propKey, nextProp);
14354 }
14355 }
14356 if (styleUpdates) {
14357 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
14358 }
14359 return updatePayload;
14360}
14361
14362// Apply the diff.
14363function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
14364 // Update checked *before* name.
14365 // In the middle of an update, it is possible to have multiple checked.
14366 // When a checked radio tries to change name, browser makes another radio's checked false.
14367 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
14368 updateChecked(domElement, nextRawProps);
14369 }
14370
14371 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
14372 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
14373 // Apply the diff.
14374 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
14375
14376 // TODO: Ensure that an update gets scheduled if any of the special props
14377 // changed.
14378 switch (tag) {
14379 case 'input':
14380 // Update the wrapper around inputs *after* updating props. This has to
14381 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
14382 // raise warnings and prevent the new value from being assigned.
14383 updateWrapper(domElement, nextRawProps);
14384 break;
14385 case 'textarea':
14386 updateWrapper$1(domElement, nextRawProps);
14387 break;
14388 case 'select':
14389 // <select> value update needs to occur after <option> children
14390 // reconciliation
14391 postUpdateWrapper(domElement, nextRawProps);
14392 break;
14393 }
14394}
14395
14396function getPossibleStandardName(propName) {
14397 {
14398 var lowerCasedName = propName.toLowerCase();
14399 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14400 return null;
14401 }
14402 return possibleStandardNames[lowerCasedName] || null;
14403 }
14404 return null;
14405}
14406
14407function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
14408 var isCustomComponentTag = void 0;
14409 var extraAttributeNames = void 0;
14410
14411 {
14412 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
14413 isCustomComponentTag = isCustomComponent(tag, rawProps);
14414 validatePropertiesInDevelopment(tag, rawProps);
14415 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14416 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14417 didWarnShadyDOM = true;
14418 }
14419 }
14420
14421 // TODO: Make sure that we check isMounted before firing any of these events.
14422 switch (tag) {
14423 case 'iframe':
14424 case 'object':
14425 trapBubbledEvent('topLoad', 'load', domElement);
14426 break;
14427 case 'video':
14428 case 'audio':
14429 // Create listener for each media event
14430 for (var event in mediaEventTypes) {
14431 if (mediaEventTypes.hasOwnProperty(event)) {
14432 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14433 }
14434 }
14435 break;
14436 case 'source':
14437 trapBubbledEvent('topError', 'error', domElement);
14438 break;
14439 case 'img':
14440 case 'image':
14441 case 'link':
14442 trapBubbledEvent('topError', 'error', domElement);
14443 trapBubbledEvent('topLoad', 'load', domElement);
14444 break;
14445 case 'form':
14446 trapBubbledEvent('topReset', 'reset', domElement);
14447 trapBubbledEvent('topSubmit', 'submit', domElement);
14448 break;
14449 case 'details':
14450 trapBubbledEvent('topToggle', 'toggle', domElement);
14451 break;
14452 case 'input':
14453 initWrapperState(domElement, rawProps);
14454 trapBubbledEvent('topInvalid', 'invalid', domElement);
14455 // For controlled components we always need to ensure we're listening
14456 // to onChange. Even if there is no listener.
14457 ensureListeningTo(rootContainerElement, 'onChange');
14458 break;
14459 case 'option':
14460 validateProps(domElement, rawProps);
14461 break;
14462 case 'select':
14463 initWrapperState$1(domElement, rawProps);
14464 trapBubbledEvent('topInvalid', 'invalid', domElement);
14465 // For controlled components we always need to ensure we're listening
14466 // to onChange. Even if there is no listener.
14467 ensureListeningTo(rootContainerElement, 'onChange');
14468 break;
14469 case 'textarea':
14470 initWrapperState$2(domElement, rawProps);
14471 trapBubbledEvent('topInvalid', 'invalid', domElement);
14472 // For controlled components we always need to ensure we're listening
14473 // to onChange. Even if there is no listener.
14474 ensureListeningTo(rootContainerElement, 'onChange');
14475 break;
14476 }
14477
14478 assertValidProps(tag, rawProps, getStack);
14479
14480 {
14481 extraAttributeNames = new Set();
14482 var attributes = domElement.attributes;
14483 for (var i = 0; i < attributes.length; i++) {
14484 var name = attributes[i].name.toLowerCase();
14485 switch (name) {
14486 // Built-in SSR attribute is whitelisted
14487 case 'data-reactroot':
14488 break;
14489 // Controlled attributes are not validated
14490 // TODO: Only ignore them on controlled tags.
14491 case 'value':
14492 break;
14493 case 'checked':
14494 break;
14495 case 'selected':
14496 break;
14497 default:
14498 // Intentionally use the original name.
14499 // See discussion in https://github.com/facebook/react/pull/10676.
14500 extraAttributeNames.add(attributes[i].name);
14501 }
14502 }
14503 }
14504
14505 var updatePayload = null;
14506 for (var propKey in rawProps) {
14507 if (!rawProps.hasOwnProperty(propKey)) {
14508 continue;
14509 }
14510 var nextProp = rawProps[propKey];
14511 if (propKey === CHILDREN) {
14512 // For text content children we compare against textContent. This
14513 // might match additional HTML that is hidden when we read it using
14514 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
14515 // satisfies our requirement. Our requirement is not to produce perfect
14516 // HTML and attributes. Ideally we should preserve structure but it's
14517 // ok not to if the visible content is still enough to indicate what
14518 // even listeners these nodes might be wired up to.
14519 // TODO: Warn if there is more than a single textNode as a child.
14520 // TODO: Should we use domElement.firstChild.nodeValue to compare?
14521 if (typeof nextProp === 'string') {
14522 if (domElement.textContent !== nextProp) {
14523 if (true && !suppressHydrationWarning) {
14524 warnForTextDifference(domElement.textContent, nextProp);
14525 }
14526 updatePayload = [CHILDREN, nextProp];
14527 }
14528 } else if (typeof nextProp === 'number') {
14529 if (domElement.textContent !== '' + nextProp) {
14530 if (true && !suppressHydrationWarning) {
14531 warnForTextDifference(domElement.textContent, nextProp);
14532 }
14533 updatePayload = [CHILDREN, '' + nextProp];
14534 }
14535 }
14536 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14537 if (nextProp != null) {
14538 if (true && typeof nextProp !== 'function') {
14539 warnForInvalidEventListener(propKey, nextProp);
14540 }
14541 ensureListeningTo(rootContainerElement, propKey);
14542 }
14543 } else if (true &&
14544 // Convince Flow we've calculated it (it's DEV-only in this method.)
14545 typeof isCustomComponentTag === 'boolean') {
14546 // Validate that the properties correspond to their expected values.
14547 var serverValue = void 0;
14548 var propertyInfo = getPropertyInfo(propKey);
14549 if (suppressHydrationWarning) {
14550 // Don't bother comparing. We're ignoring all these warnings.
14551 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
14552 // Controlled attributes are not validated
14553 // TODO: Only ignore them on controlled tags.
14554 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
14555 // Noop
14556 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14557 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
14558 var serverHTML = domElement.innerHTML;
14559 var expectedHTML = normalizeHTML(domElement, rawHtml);
14560 if (expectedHTML !== serverHTML) {
14561 warnForPropDifference(propKey, serverHTML, expectedHTML);
14562 }
14563 } else if (propKey === STYLE) {
14564 // $FlowFixMe - Should be inferred as not undefined.
14565 extraAttributeNames['delete'](propKey);
14566 var expectedStyle = createDangerousStringForStyles(nextProp);
14567 serverValue = domElement.getAttribute('style');
14568 if (expectedStyle !== serverValue) {
14569 warnForPropDifference(propKey, serverValue, expectedStyle);
14570 }
14571 } else if (isCustomComponentTag) {
14572 // $FlowFixMe - Should be inferred as not undefined.
14573 extraAttributeNames['delete'](propKey.toLowerCase());
14574 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14575
14576 if (nextProp !== serverValue) {
14577 warnForPropDifference(propKey, serverValue, nextProp);
14578 }
14579 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
14580 var isMismatchDueToBadCasing = false;
14581 if (propertyInfo !== null) {
14582 // $FlowFixMe - Should be inferred as not undefined.
14583 extraAttributeNames['delete'](propertyInfo.attributeName);
14584 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
14585 } else {
14586 var ownNamespace = parentNamespace;
14587 if (ownNamespace === HTML_NAMESPACE) {
14588 ownNamespace = getIntrinsicNamespace(tag);
14589 }
14590 if (ownNamespace === HTML_NAMESPACE) {
14591 // $FlowFixMe - Should be inferred as not undefined.
14592 extraAttributeNames['delete'](propKey.toLowerCase());
14593 } else {
14594 var standardName = getPossibleStandardName(propKey);
14595 if (standardName !== null && standardName !== propKey) {
14596 // If an SVG prop is supplied with bad casing, it will
14597 // be successfully parsed from HTML, but will produce a mismatch
14598 // (and would be incorrectly rendered on the client).
14599 // However, we already warn about bad casing elsewhere.
14600 // So we'll skip the misleading extra mismatch warning in this case.
14601 isMismatchDueToBadCasing = true;
14602 // $FlowFixMe - Should be inferred as not undefined.
14603 extraAttributeNames['delete'](standardName);
14604 }
14605 // $FlowFixMe - Should be inferred as not undefined.
14606 extraAttributeNames['delete'](propKey);
14607 }
14608 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14609 }
14610
14611 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
14612 warnForPropDifference(propKey, serverValue, nextProp);
14613 }
14614 }
14615 }
14616 }
14617
14618 {
14619 // $FlowFixMe - Should be inferred as not undefined.
14620 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
14621 // $FlowFixMe - Should be inferred as not undefined.
14622 warnForExtraAttributes(extraAttributeNames);
14623 }
14624 }
14625
14626 switch (tag) {
14627 case 'input':
14628 // TODO: Make sure we check if this is still unmounted or do any clean
14629 // up necessary since we never stop tracking anymore.
14630 track(domElement);
14631 postMountWrapper(domElement, rawProps);
14632 break;
14633 case 'textarea':
14634 // TODO: Make sure we check if this is still unmounted or do any clean
14635 // up necessary since we never stop tracking anymore.
14636 track(domElement);
14637 postMountWrapper$3(domElement, rawProps);
14638 break;
14639 case 'select':
14640 case 'option':
14641 // For input and textarea we current always set the value property at
14642 // post mount to force it to diverge from attributes. However, for
14643 // option and select we don't quite do the same thing and select
14644 // is not resilient to the DOM state changing so we don't do that here.
14645 // TODO: Consider not doing this for input and textarea.
14646 break;
14647 default:
14648 if (typeof rawProps.onClick === 'function') {
14649 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14650 trapClickOnNonInteractiveElement(domElement);
14651 }
14652 break;
14653 }
14654
14655 return updatePayload;
14656}
14657
14658function diffHydratedText$1(textNode, text) {
14659 var isDifferent = textNode.nodeValue !== text;
14660 return isDifferent;
14661}
14662
14663function warnForUnmatchedText$1(textNode, text) {
14664 {
14665 warnForTextDifference(textNode.nodeValue, text);
14666 }
14667}
14668
14669function warnForDeletedHydratableElement$1(parentNode, child) {
14670 {
14671 if (didWarnInvalidHydration) {
14672 return;
14673 }
14674 didWarnInvalidHydration = true;
14675 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
14676 }
14677}
14678
14679function warnForDeletedHydratableText$1(parentNode, child) {
14680 {
14681 if (didWarnInvalidHydration) {
14682 return;
14683 }
14684 didWarnInvalidHydration = true;
14685 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
14686 }
14687}
14688
14689function warnForInsertedHydratedElement$1(parentNode, tag, props) {
14690 {
14691 if (didWarnInvalidHydration) {
14692 return;
14693 }
14694 didWarnInvalidHydration = true;
14695 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
14696 }
14697}
14698
14699function warnForInsertedHydratedText$1(parentNode, text) {
14700 {
14701 if (text === '') {
14702 // We expect to insert empty text nodes since they're not represented in
14703 // the HTML.
14704 // TODO: Remove this special case if we can just avoid inserting empty
14705 // text nodes.
14706 return;
14707 }
14708 if (didWarnInvalidHydration) {
14709 return;
14710 }
14711 didWarnInvalidHydration = true;
14712 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
14713 }
14714}
14715
14716function restoreControlledState$1(domElement, tag, props) {
14717 switch (tag) {
14718 case 'input':
14719 restoreControlledState(domElement, props);
14720 return;
14721 case 'textarea':
14722 restoreControlledState$3(domElement, props);
14723 return;
14724 case 'select':
14725 restoreControlledState$2(domElement, props);
14726 return;
14727 }
14728}
14729
14730var ReactDOMFiberComponent = Object.freeze({
14731 createElement: createElement$1,
14732 createTextNode: createTextNode$1,
14733 setInitialProperties: setInitialProperties$1,
14734 diffProperties: diffProperties$1,
14735 updateProperties: updateProperties$1,
14736 diffHydratedProperties: diffHydratedProperties$1,
14737 diffHydratedText: diffHydratedText$1,
14738 warnForUnmatchedText: warnForUnmatchedText$1,
14739 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
14740 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
14741 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
14742 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
14743 restoreControlledState: restoreControlledState$1
14744});
14745
14746// TODO: direct imports like some-package/src/* are bad. Fix me.
14747var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14748
14749var validateDOMNesting = emptyFunction_1;
14750
14751{
14752 // This validation code was written based on the HTML5 parsing spec:
14753 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14754 //
14755 // Note: this does not catch all invalid nesting, nor does it try to (as it's
14756 // not clear what practical benefit doing so provides); instead, we warn only
14757 // for cases where the parser will give a parse tree differing from what React
14758 // intended. For example, <b><div></div></b> is invalid but we don't warn
14759 // because it still parses correctly; we do warn for other cases like nested
14760 // <p> tags where the beginning of the second element implicitly closes the
14761 // first, causing a confusing mess.
14762
14763 // https://html.spec.whatwg.org/multipage/syntax.html#special
14764 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'];
14765
14766 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14767 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
14768
14769 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
14770 // TODO: Distinguish by namespace here -- for <title>, including it here
14771 // errs on the side of fewer warnings
14772 'foreignObject', 'desc', 'title'];
14773
14774 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
14775 var buttonScopeTags = inScopeTags.concat(['button']);
14776
14777 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
14778 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
14779
14780 var emptyAncestorInfo = {
14781 current: null,
14782
14783 formTag: null,
14784 aTagInScope: null,
14785 buttonTagInScope: null,
14786 nobrTagInScope: null,
14787 pTagInButtonScope: null,
14788
14789 listItemTagAutoclosing: null,
14790 dlItemTagAutoclosing: null
14791 };
14792
14793 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
14794 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
14795 var info = { tag: tag, instance: instance };
14796
14797 if (inScopeTags.indexOf(tag) !== -1) {
14798 ancestorInfo.aTagInScope = null;
14799 ancestorInfo.buttonTagInScope = null;
14800 ancestorInfo.nobrTagInScope = null;
14801 }
14802 if (buttonScopeTags.indexOf(tag) !== -1) {
14803 ancestorInfo.pTagInButtonScope = null;
14804 }
14805
14806 // See rules for 'li', 'dd', 'dt' start tags in
14807 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14808 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
14809 ancestorInfo.listItemTagAutoclosing = null;
14810 ancestorInfo.dlItemTagAutoclosing = null;
14811 }
14812
14813 ancestorInfo.current = info;
14814
14815 if (tag === 'form') {
14816 ancestorInfo.formTag = info;
14817 }
14818 if (tag === 'a') {
14819 ancestorInfo.aTagInScope = info;
14820 }
14821 if (tag === 'button') {
14822 ancestorInfo.buttonTagInScope = info;
14823 }
14824 if (tag === 'nobr') {
14825 ancestorInfo.nobrTagInScope = info;
14826 }
14827 if (tag === 'p') {
14828 ancestorInfo.pTagInButtonScope = info;
14829 }
14830 if (tag === 'li') {
14831 ancestorInfo.listItemTagAutoclosing = info;
14832 }
14833 if (tag === 'dd' || tag === 'dt') {
14834 ancestorInfo.dlItemTagAutoclosing = info;
14835 }
14836
14837 return ancestorInfo;
14838 };
14839
14840 /**
14841 * Returns whether
14842 */
14843 var isTagValidWithParent = function (tag, parentTag) {
14844 // First, let's check if we're in an unusual parsing mode...
14845 switch (parentTag) {
14846 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
14847 case 'select':
14848 return tag === 'option' || tag === 'optgroup' || tag === '#text';
14849 case 'optgroup':
14850 return tag === 'option' || tag === '#text';
14851 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
14852 // but
14853 case 'option':
14854 return tag === '#text';
14855 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
14856 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
14857 // No special behavior since these rules fall back to "in body" mode for
14858 // all except special table nodes which cause bad parsing behavior anyway.
14859
14860 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
14861 case 'tr':
14862 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
14863 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
14864 case 'tbody':
14865 case 'thead':
14866 case 'tfoot':
14867 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
14868 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
14869 case 'colgroup':
14870 return tag === 'col' || tag === 'template';
14871 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
14872 case 'table':
14873 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
14874 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
14875 case 'head':
14876 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
14877 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
14878 case 'html':
14879 return tag === 'head' || tag === 'body';
14880 case '#document':
14881 return tag === 'html';
14882 }
14883
14884 // Probably in the "in body" parsing mode, so we outlaw only tag combos
14885 // where the parsing rules cause implicit opens or closes to be added.
14886 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14887 switch (tag) {
14888 case 'h1':
14889 case 'h2':
14890 case 'h3':
14891 case 'h4':
14892 case 'h5':
14893 case 'h6':
14894 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
14895
14896 case 'rp':
14897 case 'rt':
14898 return impliedEndTags.indexOf(parentTag) === -1;
14899
14900 case 'body':
14901 case 'caption':
14902 case 'col':
14903 case 'colgroup':
14904 case 'frame':
14905 case 'head':
14906 case 'html':
14907 case 'tbody':
14908 case 'td':
14909 case 'tfoot':
14910 case 'th':
14911 case 'thead':
14912 case 'tr':
14913 // These tags are only valid with a few parents that have special child
14914 // parsing rules -- if we're down here, then none of those matched and
14915 // so we allow it only if we don't know what the parent is, as all other
14916 // cases are invalid.
14917 return parentTag == null;
14918 }
14919
14920 return true;
14921 };
14922
14923 /**
14924 * Returns whether
14925 */
14926 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
14927 switch (tag) {
14928 case 'address':
14929 case 'article':
14930 case 'aside':
14931 case 'blockquote':
14932 case 'center':
14933 case 'details':
14934 case 'dialog':
14935 case 'dir':
14936 case 'div':
14937 case 'dl':
14938 case 'fieldset':
14939 case 'figcaption':
14940 case 'figure':
14941 case 'footer':
14942 case 'header':
14943 case 'hgroup':
14944 case 'main':
14945 case 'menu':
14946 case 'nav':
14947 case 'ol':
14948 case 'p':
14949 case 'section':
14950 case 'summary':
14951 case 'ul':
14952 case 'pre':
14953 case 'listing':
14954 case 'table':
14955 case 'hr':
14956 case 'xmp':
14957 case 'h1':
14958 case 'h2':
14959 case 'h3':
14960 case 'h4':
14961 case 'h5':
14962 case 'h6':
14963 return ancestorInfo.pTagInButtonScope;
14964
14965 case 'form':
14966 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
14967
14968 case 'li':
14969 return ancestorInfo.listItemTagAutoclosing;
14970
14971 case 'dd':
14972 case 'dt':
14973 return ancestorInfo.dlItemTagAutoclosing;
14974
14975 case 'button':
14976 return ancestorInfo.buttonTagInScope;
14977
14978 case 'a':
14979 // Spec says something about storing a list of markers, but it sounds
14980 // equivalent to this check.
14981 return ancestorInfo.aTagInScope;
14982
14983 case 'nobr':
14984 return ancestorInfo.nobrTagInScope;
14985 }
14986
14987 return null;
14988 };
14989
14990 var didWarn = {};
14991
14992 validateDOMNesting = function (childTag, childText, ancestorInfo) {
14993 ancestorInfo = ancestorInfo || emptyAncestorInfo;
14994 var parentInfo = ancestorInfo.current;
14995 var parentTag = parentInfo && parentInfo.tag;
14996
14997 if (childText != null) {
14998 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
14999 childTag = '#text';
15000 }
15001
15002 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15003 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15004 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15005 if (!invalidParentOrAncestor) {
15006 return;
15007 }
15008
15009 var ancestorTag = invalidParentOrAncestor.tag;
15010 var addendum = getCurrentFiberStackAddendum$6();
15011
15012 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15013 if (didWarn[warnKey]) {
15014 return;
15015 }
15016 didWarn[warnKey] = true;
15017
15018 var tagDisplayName = childTag;
15019 var whitespaceInfo = '';
15020 if (childTag === '#text') {
15021 if (/\S/.test(childText)) {
15022 tagDisplayName = 'Text nodes';
15023 } else {
15024 tagDisplayName = 'Whitespace text nodes';
15025 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15026 }
15027 } else {
15028 tagDisplayName = '<' + childTag + '>';
15029 }
15030
15031 if (invalidParent) {
15032 var info = '';
15033 if (ancestorTag === 'table' && childTag === 'tr') {
15034 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15035 }
15036 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15037 } else {
15038 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15039 }
15040 };
15041
15042 // TODO: turn this into a named export
15043 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15044}
15045
15046var validateDOMNesting$1 = validateDOMNesting;
15047
15048// TODO: This type is shared between the reconciler and ReactDOM, but will
15049// eventually be lifted out to the renderer.
15050
15051// TODO: direct imports like some-package/src/* are bad. Fix me.
15052var createElement = createElement$1;
15053var createTextNode = createTextNode$1;
15054var setInitialProperties = setInitialProperties$1;
15055var diffProperties = diffProperties$1;
15056var updateProperties = updateProperties$1;
15057var diffHydratedProperties = diffHydratedProperties$1;
15058var diffHydratedText = diffHydratedText$1;
15059var warnForUnmatchedText = warnForUnmatchedText$1;
15060var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15061var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15062var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15063var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15064var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15065var precacheFiberNode = precacheFiberNode$1;
15066var updateFiberProps = updateFiberProps$1;
15067
15068
15069var SUPPRESS_HYDRATION_WARNING = void 0;
15070var topLevelUpdateWarnings = void 0;
15071var warnOnInvalidCallback = void 0;
15072var didWarnAboutUnstableCreatePortal = false;
15073
15074{
15075 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15076 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') {
15077 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');
15078 }
15079
15080 topLevelUpdateWarnings = function (container) {
15081 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15082 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15083 if (hostInstance) {
15084 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.');
15085 }
15086 }
15087
15088 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15089 var rootEl = getReactRootElementInContainer(container);
15090 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15091
15092 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.');
15093
15094 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.');
15095 };
15096
15097 warnOnInvalidCallback = function (callback, callerName) {
15098 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
15099 };
15100}
15101
15102injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
15103
15104var eventsEnabled = null;
15105var selectionInformation = null;
15106
15107function ReactBatch(root) {
15108 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
15109 this._expirationTime = expirationTime;
15110 this._root = root;
15111 this._next = null;
15112 this._callbacks = null;
15113 this._didComplete = false;
15114 this._hasChildren = false;
15115 this._children = null;
15116 this._defer = true;
15117}
15118ReactBatch.prototype.render = function (children) {
15119 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
15120 this._hasChildren = true;
15121 this._children = children;
15122 var internalRoot = this._root._internalRoot;
15123 var expirationTime = this._expirationTime;
15124 var work = new ReactWork();
15125 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
15126 return work;
15127};
15128ReactBatch.prototype.then = function (onComplete) {
15129 if (this._didComplete) {
15130 onComplete();
15131 return;
15132 }
15133 var callbacks = this._callbacks;
15134 if (callbacks === null) {
15135 callbacks = this._callbacks = [];
15136 }
15137 callbacks.push(onComplete);
15138};
15139ReactBatch.prototype.commit = function () {
15140 var internalRoot = this._root._internalRoot;
15141 var firstBatch = internalRoot.firstBatch;
15142 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15143
15144 if (!this._hasChildren) {
15145 // This batch is empty. Return.
15146 this._next = null;
15147 this._defer = false;
15148 return;
15149 }
15150
15151 var expirationTime = this._expirationTime;
15152
15153 // Ensure this is the first batch in the list.
15154 if (firstBatch !== this) {
15155 // This batch is not the earliest batch. We need to move it to the front.
15156 // Update its expiration time to be the expiration time of the earliest
15157 // batch, so that we can flush it without flushing the other batches.
15158 if (this._hasChildren) {
15159 expirationTime = this._expirationTime = firstBatch._expirationTime;
15160 // Rendering this batch again ensures its children will be the final state
15161 // when we flush (updates are processed in insertion order: last
15162 // update wins).
15163 // TODO: This forces a restart. Should we print a warning?
15164 this.render(this._children);
15165 }
15166
15167 // Remove the batch from the list.
15168 var previous = null;
15169 var batch = firstBatch;
15170 while (batch !== this) {
15171 previous = batch;
15172 batch = batch._next;
15173 }
15174 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15175 previous._next = batch._next;
15176
15177 // Add it to the front.
15178 this._next = firstBatch;
15179 firstBatch = internalRoot.firstBatch = this;
15180 }
15181
15182 // Synchronously flush all the work up to this batch's expiration time.
15183 this._defer = false;
15184 DOMRenderer.flushRoot(internalRoot, expirationTime);
15185
15186 // Pop the batch from the list.
15187 var next = this._next;
15188 this._next = null;
15189 firstBatch = internalRoot.firstBatch = next;
15190
15191 // Append the next earliest batch's children to the update queue.
15192 if (firstBatch !== null && firstBatch._hasChildren) {
15193 firstBatch.render(firstBatch._children);
15194 }
15195};
15196ReactBatch.prototype._onComplete = function () {
15197 if (this._didComplete) {
15198 return;
15199 }
15200 this._didComplete = true;
15201 var callbacks = this._callbacks;
15202 if (callbacks === null) {
15203 return;
15204 }
15205 // TODO: Error handling.
15206 for (var i = 0; i < callbacks.length; i++) {
15207 var _callback = callbacks[i];
15208 _callback();
15209 }
15210};
15211
15212function ReactWork() {
15213 this._callbacks = null;
15214 this._didCommit = false;
15215 // TODO: Avoid need to bind by replacing callbacks in the update queue with
15216 // list of Work objects.
15217 this._onCommit = this._onCommit.bind(this);
15218}
15219ReactWork.prototype.then = function (onCommit) {
15220 if (this._didCommit) {
15221 onCommit();
15222 return;
15223 }
15224 var callbacks = this._callbacks;
15225 if (callbacks === null) {
15226 callbacks = this._callbacks = [];
15227 }
15228 callbacks.push(onCommit);
15229};
15230ReactWork.prototype._onCommit = function () {
15231 if (this._didCommit) {
15232 return;
15233 }
15234 this._didCommit = true;
15235 var callbacks = this._callbacks;
15236 if (callbacks === null) {
15237 return;
15238 }
15239 // TODO: Error handling.
15240 for (var i = 0; i < callbacks.length; i++) {
15241 var _callback2 = callbacks[i];
15242 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
15243 _callback2();
15244 }
15245};
15246
15247function ReactRoot(container, isAsync, hydrate) {
15248 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
15249 this._internalRoot = root;
15250}
15251ReactRoot.prototype.render = function (children, callback) {
15252 var root = this._internalRoot;
15253 var work = new ReactWork();
15254 callback = callback === undefined ? null : callback;
15255 {
15256 warnOnInvalidCallback(callback, 'render');
15257 }
15258 if (callback !== null) {
15259 work.then(callback);
15260 }
15261 DOMRenderer.updateContainer(children, root, null, work._onCommit);
15262 return work;
15263};
15264ReactRoot.prototype.unmount = function (callback) {
15265 var root = this._internalRoot;
15266 var work = new ReactWork();
15267 callback = callback === undefined ? null : callback;
15268 {
15269 warnOnInvalidCallback(callback, 'render');
15270 }
15271 if (callback !== null) {
15272 work.then(callback);
15273 }
15274 DOMRenderer.updateContainer(null, root, null, work._onCommit);
15275 return work;
15276};
15277ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
15278 var root = this._internalRoot;
15279 var work = new ReactWork();
15280 callback = callback === undefined ? null : callback;
15281 {
15282 warnOnInvalidCallback(callback, 'render');
15283 }
15284 if (callback !== null) {
15285 work.then(callback);
15286 }
15287 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
15288 return work;
15289};
15290ReactRoot.prototype.createBatch = function () {
15291 var batch = new ReactBatch(this);
15292 var expirationTime = batch._expirationTime;
15293
15294 var internalRoot = this._internalRoot;
15295 var firstBatch = internalRoot.firstBatch;
15296 if (firstBatch === null) {
15297 internalRoot.firstBatch = batch;
15298 batch._next = null;
15299 } else {
15300 // Insert sorted by expiration time then insertion order
15301 var insertAfter = null;
15302 var insertBefore = firstBatch;
15303 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
15304 insertAfter = insertBefore;
15305 insertBefore = insertBefore._next;
15306 }
15307 batch._next = insertBefore;
15308 if (insertAfter !== null) {
15309 insertAfter._next = batch;
15310 }
15311 }
15312
15313 return batch;
15314};
15315
15316/**
15317 * True if the supplied DOM node is a valid node element.
15318 *
15319 * @param {?DOMElement} node The candidate DOM node.
15320 * @return {boolean} True if the DOM is a valid DOM node.
15321 * @internal
15322 */
15323function isValidContainer(node) {
15324 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 '));
15325}
15326
15327function getReactRootElementInContainer(container) {
15328 if (!container) {
15329 return null;
15330 }
15331
15332 if (container.nodeType === DOCUMENT_NODE) {
15333 return container.documentElement;
15334 } else {
15335 return container.firstChild;
15336 }
15337}
15338
15339function shouldHydrateDueToLegacyHeuristic(container) {
15340 var rootElement = getReactRootElementInContainer(container);
15341 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
15342}
15343
15344function shouldAutoFocusHostComponent(type, props) {
15345 switch (type) {
15346 case 'button':
15347 case 'input':
15348 case 'select':
15349 case 'textarea':
15350 return !!props.autoFocus;
15351 }
15352 return false;
15353}
15354
15355var DOMRenderer = reactReconciler({
15356 getRootHostContext: function (rootContainerInstance) {
15357 var type = void 0;
15358 var namespace = void 0;
15359 var nodeType = rootContainerInstance.nodeType;
15360 switch (nodeType) {
15361 case DOCUMENT_NODE:
15362 case DOCUMENT_FRAGMENT_NODE:
15363 {
15364 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
15365 var root = rootContainerInstance.documentElement;
15366 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
15367 break;
15368 }
15369 default:
15370 {
15371 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
15372 var ownNamespace = container.namespaceURI || null;
15373 type = container.tagName;
15374 namespace = getChildNamespace(ownNamespace, type);
15375 break;
15376 }
15377 }
15378 {
15379 var validatedTag = type.toLowerCase();
15380 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
15381 return { namespace: namespace, ancestorInfo: _ancestorInfo };
15382 }
15383 return namespace;
15384 },
15385 getChildHostContext: function (parentHostContext, type) {
15386 {
15387 var parentHostContextDev = parentHostContext;
15388 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
15389 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
15390 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
15391 }
15392 var parentNamespace = parentHostContext;
15393 return getChildNamespace(parentNamespace, type);
15394 },
15395 getPublicInstance: function (instance) {
15396 return instance;
15397 },
15398 prepareForCommit: function () {
15399 eventsEnabled = isEnabled();
15400 selectionInformation = getSelectionInformation();
15401 setEnabled(false);
15402 },
15403 resetAfterCommit: function () {
15404 restoreSelection(selectionInformation);
15405 selectionInformation = null;
15406 setEnabled(eventsEnabled);
15407 eventsEnabled = null;
15408 },
15409 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15410 var parentNamespace = void 0;
15411 {
15412 // TODO: take namespace into account when validating.
15413 var hostContextDev = hostContext;
15414 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
15415 if (typeof props.children === 'string' || typeof props.children === 'number') {
15416 var string = '' + props.children;
15417 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15418 validateDOMNesting$1(null, string, ownAncestorInfo);
15419 }
15420 parentNamespace = hostContextDev.namespace;
15421 }
15422 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
15423 precacheFiberNode(internalInstanceHandle, domElement);
15424 updateFiberProps(domElement, props);
15425 return domElement;
15426 },
15427 appendInitialChild: function (parentInstance, child) {
15428 parentInstance.appendChild(child);
15429 },
15430 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
15431 setInitialProperties(domElement, type, props, rootContainerInstance);
15432 return shouldAutoFocusHostComponent(type, props);
15433 },
15434 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
15435 {
15436 var hostContextDev = hostContext;
15437 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
15438 var string = '' + newProps.children;
15439 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15440 validateDOMNesting$1(null, string, ownAncestorInfo);
15441 }
15442 }
15443 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
15444 },
15445 shouldSetTextContent: function (type, props) {
15446 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
15447 },
15448 shouldDeprioritizeSubtree: function (type, props) {
15449 return !!props.hidden;
15450 },
15451 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
15452 {
15453 var hostContextDev = hostContext;
15454 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
15455 }
15456 var textNode = createTextNode(text, rootContainerInstance);
15457 precacheFiberNode(internalInstanceHandle, textNode);
15458 return textNode;
15459 },
15460
15461
15462 now: now,
15463
15464 mutation: {
15465 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
15466 // Despite the naming that might imply otherwise, this method only
15467 // fires if there is an `Update` effect scheduled during mounting.
15468 // This happens if `finalizeInitialChildren` returns `true` (which it
15469 // does to implement the `autoFocus` attribute on the client). But
15470 // there are also other cases when this might happen (such as patching
15471 // up text content during hydration mismatch). So we'll check this again.
15472 if (shouldAutoFocusHostComponent(type, newProps)) {
15473 domElement.focus();
15474 }
15475 },
15476 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
15477 // Update the props handle so that we know which props are the ones with
15478 // with current event handlers.
15479 updateFiberProps(domElement, newProps);
15480 // Apply the diff to the DOM node.
15481 updateProperties(domElement, updatePayload, type, oldProps, newProps);
15482 },
15483 resetTextContent: function (domElement) {
15484 setTextContent(domElement, '');
15485 },
15486 commitTextUpdate: function (textInstance, oldText, newText) {
15487 textInstance.nodeValue = newText;
15488 },
15489 appendChild: function (parentInstance, child) {
15490 parentInstance.appendChild(child);
15491 },
15492 appendChildToContainer: function (container, child) {
15493 if (container.nodeType === COMMENT_NODE) {
15494 container.parentNode.insertBefore(child, container);
15495 } else {
15496 container.appendChild(child);
15497 }
15498 },
15499 insertBefore: function (parentInstance, child, beforeChild) {
15500 parentInstance.insertBefore(child, beforeChild);
15501 },
15502 insertInContainerBefore: function (container, child, beforeChild) {
15503 if (container.nodeType === COMMENT_NODE) {
15504 container.parentNode.insertBefore(child, beforeChild);
15505 } else {
15506 container.insertBefore(child, beforeChild);
15507 }
15508 },
15509 removeChild: function (parentInstance, child) {
15510 parentInstance.removeChild(child);
15511 },
15512 removeChildFromContainer: function (container, child) {
15513 if (container.nodeType === COMMENT_NODE) {
15514 container.parentNode.removeChild(child);
15515 } else {
15516 container.removeChild(child);
15517 }
15518 }
15519 },
15520
15521 hydration: {
15522 canHydrateInstance: function (instance, type, props) {
15523 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
15524 return null;
15525 }
15526 // This has now been refined to an element node.
15527 return instance;
15528 },
15529 canHydrateTextInstance: function (instance, text) {
15530 if (text === '' || instance.nodeType !== TEXT_NODE) {
15531 // Empty strings are not parsed by HTML so there won't be a correct match here.
15532 return null;
15533 }
15534 // This has now been refined to a text node.
15535 return instance;
15536 },
15537 getNextHydratableSibling: function (instance) {
15538 var node = instance.nextSibling;
15539 // Skip non-hydratable nodes.
15540 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
15541 node = node.nextSibling;
15542 }
15543 return node;
15544 },
15545 getFirstHydratableChild: function (parentInstance) {
15546 var next = parentInstance.firstChild;
15547 // Skip non-hydratable nodes.
15548 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
15549 next = next.nextSibling;
15550 }
15551 return next;
15552 },
15553 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15554 precacheFiberNode(internalInstanceHandle, instance);
15555 // TODO: Possibly defer this until the commit phase where all the events
15556 // get attached.
15557 updateFiberProps(instance, props);
15558 var parentNamespace = void 0;
15559 {
15560 var hostContextDev = hostContext;
15561 parentNamespace = hostContextDev.namespace;
15562 }
15563 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
15564 },
15565 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
15566 precacheFiberNode(internalInstanceHandle, textInstance);
15567 return diffHydratedText(textInstance, text);
15568 },
15569 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
15570 {
15571 warnForUnmatchedText(textInstance, text);
15572 }
15573 },
15574 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
15575 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15576 warnForUnmatchedText(textInstance, text);
15577 }
15578 },
15579 didNotHydrateContainerInstance: function (parentContainer, instance) {
15580 {
15581 if (instance.nodeType === 1) {
15582 warnForDeletedHydratableElement(parentContainer, instance);
15583 } else {
15584 warnForDeletedHydratableText(parentContainer, instance);
15585 }
15586 }
15587 },
15588 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
15589 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15590 if (instance.nodeType === 1) {
15591 warnForDeletedHydratableElement(parentInstance, instance);
15592 } else {
15593 warnForDeletedHydratableText(parentInstance, instance);
15594 }
15595 }
15596 },
15597 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
15598 {
15599 warnForInsertedHydratedElement(parentContainer, type, props);
15600 }
15601 },
15602 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
15603 {
15604 warnForInsertedHydratedText(parentContainer, text);
15605 }
15606 },
15607 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
15608 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15609 warnForInsertedHydratedElement(parentInstance, type, props);
15610 }
15611 },
15612 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
15613 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15614 warnForInsertedHydratedText(parentInstance, text);
15615 }
15616 }
15617 },
15618
15619 scheduleDeferredCallback: rIC,
15620 cancelDeferredCallback: cIC
15621});
15622
15623injection$3.injectFiberBatchedUpdates(DOMRenderer.batchedUpdates);
15624
15625var warnedAboutHydrateAPI = false;
15626
15627function legacyCreateRootFromDOMContainer(container, forceHydrate) {
15628 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
15629 // First clear any existing content.
15630 if (!shouldHydrate) {
15631 var warned = false;
15632 var rootSibling = void 0;
15633 while (rootSibling = container.lastChild) {
15634 {
15635 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
15636 warned = true;
15637 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.');
15638 }
15639 }
15640 container.removeChild(rootSibling);
15641 }
15642 }
15643 {
15644 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
15645 warnedAboutHydrateAPI = true;
15646 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.');
15647 }
15648 }
15649 // Legacy roots are not async by default.
15650 var isAsync = false;
15651 return new ReactRoot(container, isAsync, shouldHydrate);
15652}
15653
15654function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
15655 // TODO: Ensure all entry points contain this check
15656 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15657
15658 {
15659 topLevelUpdateWarnings(container);
15660 }
15661
15662 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
15663 // member of intersection type." Whyyyyyy.
15664 var root = container._reactRootContainer;
15665 if (!root) {
15666 // Initial mount
15667 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
15668 if (typeof callback === 'function') {
15669 var originalCallback = callback;
15670 callback = function () {
15671 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15672 originalCallback.call(instance);
15673 };
15674 }
15675 // Initial mount should not be batched.
15676 DOMRenderer.unbatchedUpdates(function () {
15677 if (parentComponent != null) {
15678 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15679 } else {
15680 root.render(children, callback);
15681 }
15682 });
15683 } else {
15684 if (typeof callback === 'function') {
15685 var _originalCallback = callback;
15686 callback = function () {
15687 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15688 _originalCallback.call(instance);
15689 };
15690 }
15691 // Update
15692 if (parentComponent != null) {
15693 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15694 } else {
15695 root.render(children, callback);
15696 }
15697 }
15698 return DOMRenderer.getPublicRootInstance(root._internalRoot);
15699}
15700
15701function createPortal(children, container) {
15702 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15703
15704 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15705 // TODO: pass ReactDOM portal implementation as third argument
15706 return createPortal$1(children, container, null, key);
15707}
15708
15709var ReactDOM = {
15710 createPortal: createPortal,
15711
15712 findDOMNode: function (componentOrElement) {
15713 {
15714 var owner = ReactCurrentOwner.current;
15715 if (owner !== null) {
15716 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
15717 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');
15718 owner.stateNode._warnedAboutRefsInRender = true;
15719 }
15720 }
15721 if (componentOrElement == null) {
15722 return null;
15723 }
15724 if (componentOrElement.nodeType === ELEMENT_NODE) {
15725 return componentOrElement;
15726 }
15727
15728 var inst = get(componentOrElement);
15729 if (inst) {
15730 return DOMRenderer.findHostInstance(inst);
15731 }
15732
15733 if (typeof componentOrElement.render === 'function') {
15734 invariant_1(false, 'Unable to find node on an unmounted component.');
15735 } else {
15736 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
15737 }
15738 },
15739 hydrate: function (element, container, callback) {
15740 // TODO: throw or warn if we couldn't hydrate?
15741 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
15742 },
15743 render: function (element, container, callback) {
15744 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
15745 },
15746 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
15747 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
15748 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
15749 },
15750 unmountComponentAtNode: function (container) {
15751 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
15752
15753 if (container._reactRootContainer) {
15754 {
15755 var rootEl = getReactRootElementInContainer(container);
15756 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
15757 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
15758 }
15759
15760 // Unmount should not be batched.
15761 DOMRenderer.unbatchedUpdates(function () {
15762 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
15763 container._reactRootContainer = null;
15764 });
15765 });
15766 // If you call unmountComponentAtNode twice in quick succession, you'll
15767 // get `true` twice. That's probably fine?
15768 return true;
15769 } else {
15770 {
15771 var _rootEl = getReactRootElementInContainer(container);
15772 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
15773
15774 // Check if the container itself is a React root node.
15775 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
15776
15777 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.');
15778 }
15779
15780 return false;
15781 }
15782 },
15783
15784
15785 // Temporary alias since we already shipped React 16 RC with it.
15786 // TODO: remove in React 17.
15787 unstable_createPortal: function () {
15788 if (!didWarnAboutUnstableCreatePortal) {
15789 didWarnAboutUnstableCreatePortal = true;
15790 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.');
15791 }
15792 return createPortal.apply(undefined, arguments);
15793 },
15794
15795
15796 unstable_batchedUpdates: batchedUpdates,
15797
15798 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
15799
15800 flushSync: DOMRenderer.flushSync,
15801
15802 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
15803 // For TapEventPlugin which is popular in open source
15804 EventPluginHub: EventPluginHub,
15805 // Used by test-utils
15806 EventPluginRegistry: EventPluginRegistry,
15807 EventPropagators: EventPropagators,
15808 ReactControlledComponent: ReactControlledComponent,
15809 ReactDOMComponentTree: ReactDOMComponentTree,
15810 ReactDOMEventListener: ReactDOMEventListener
15811 }
15812};
15813
15814{
15815 // Show deprecation warnings as we don't want to support injection forever.
15816 // We do it now to let the internal injection happen without warnings.
15817 // https://github.com/facebook/react/issues/11689
15818 enableWarningOnInjection();
15819}
15820
15821if (enableCreateRoot) {
15822 ReactDOM.createRoot = function createRoot(container, options) {
15823 var hydrate = options != null && options.hydrate === true;
15824 return new ReactRoot(container, true, hydrate);
15825 };
15826}
15827
15828var foundDevTools = DOMRenderer.injectIntoDevTools({
15829 findFiberByHostInstance: getClosestInstanceFromNode,
15830 bundleType: 1,
15831 version: ReactVersion,
15832 rendererPackageName: 'react-dom'
15833});
15834
15835{
15836 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
15837 // If we're in Chrome or Firefox, provide a download link if not installed.
15838 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
15839 var protocol = window.location.protocol;
15840 // Don't warn in exotic cases like chrome-extension://.
15841 if (/^(https?|file):$/.test(protocol)) {
15842 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');
15843 }
15844 }
15845 }
15846}
15847
15848
15849
15850var ReactDOM$2 = Object.freeze({
15851 default: ReactDOM
15852});
15853
15854var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
15855
15856// TODO: decide on the top-level export form.
15857// This is hacky but makes it work with both Rollup and Jest.
15858var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
15859
15860return reactDom;
15861
15862})));