· 8 years ago · Jan 23, 2018, 11:26 AM
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 (Fabric):
5622var enablePersistentReconciler = false;
5623
5624// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
5625var debugRenderPhaseSideEffects = false;
5626
5627// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
5628var warnAboutDeprecatedLifecycles = false;
5629
5630// Only used in www builds.
5631
5632// Prefix measurements so that it's possible to filter them.
5633// Longer prefixes are hard to read in DevTools.
5634var reactEmoji = '\u269B';
5635var warningEmoji = '\u26D4';
5636var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
5637
5638// Keep track of current fiber so that we know the path to unwind on pause.
5639// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5640var currentFiber = null;
5641// If we're in the middle of user code, which fiber and method is it?
5642// Reusing `currentFiber` would be confusing for this because user code fiber
5643// can change during commit phase too, but we don't need to unwind it (since
5644// lifecycles in the commit phase don't resemble a tree).
5645var currentPhase = null;
5646var currentPhaseFiber = null;
5647// Did lifecycle hook schedule an update? This is often a performance problem,
5648// so we will keep track of it, and include it in the report.
5649// Track commits caused by cascading updates.
5650var isCommitting = false;
5651var hasScheduledUpdateInCurrentCommit = false;
5652var hasScheduledUpdateInCurrentPhase = false;
5653var commitCountInCurrentWorkLoop = 0;
5654var effectCountInCurrentCommit = 0;
5655var isWaitingForCallback = false;
5656// During commits, we only show a measurement once per method name
5657// to avoid stretch the commit phase with measurement overhead.
5658var labelsInCurrentCommit = new Set();
5659
5660var formatMarkName = function (markName) {
5661 return reactEmoji + ' ' + markName;
5662};
5663
5664var formatLabel = function (label, warning) {
5665 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
5666 var suffix = warning ? ' Warning: ' + warning : '';
5667 return '' + prefix + label + suffix;
5668};
5669
5670var beginMark = function (markName) {
5671 performance.mark(formatMarkName(markName));
5672};
5673
5674var clearMark = function (markName) {
5675 performance.clearMarks(formatMarkName(markName));
5676};
5677
5678var endMark = function (label, markName, warning) {
5679 var formattedMarkName = formatMarkName(markName);
5680 var formattedLabel = formatLabel(label, warning);
5681 try {
5682 performance.measure(formattedLabel, formattedMarkName);
5683 } catch (err) {}
5684 // If previous mark was missing for some reason, this will throw.
5685 // This could only happen if React crashed in an unexpected place earlier.
5686 // Don't pile on with more errors.
5687
5688 // Clear marks immediately to avoid growing buffer.
5689 performance.clearMarks(formattedMarkName);
5690 performance.clearMeasures(formattedLabel);
5691};
5692
5693var getFiberMarkName = function (label, debugID) {
5694 return label + ' (#' + debugID + ')';
5695};
5696
5697var getFiberLabel = function (componentName, isMounted, phase) {
5698 if (phase === null) {
5699 // These are composite component total time measurements.
5700 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
5701 } else {
5702 // Composite component methods.
5703 return componentName + '.' + phase;
5704 }
5705};
5706
5707var beginFiberMark = function (fiber, phase) {
5708 var componentName = getComponentName(fiber) || 'Unknown';
5709 var debugID = fiber._debugID;
5710 var isMounted = fiber.alternate !== null;
5711 var label = getFiberLabel(componentName, isMounted, phase);
5712
5713 if (isCommitting && labelsInCurrentCommit.has(label)) {
5714 // During the commit phase, we don't show duplicate labels because
5715 // there is a fixed overhead for every measurement, and we don't
5716 // want to stretch the commit phase beyond necessary.
5717 return false;
5718 }
5719 labelsInCurrentCommit.add(label);
5720
5721 var markName = getFiberMarkName(label, debugID);
5722 beginMark(markName);
5723 return true;
5724};
5725
5726var clearFiberMark = function (fiber, phase) {
5727 var componentName = getComponentName(fiber) || 'Unknown';
5728 var debugID = fiber._debugID;
5729 var isMounted = fiber.alternate !== null;
5730 var label = getFiberLabel(componentName, isMounted, phase);
5731 var markName = getFiberMarkName(label, debugID);
5732 clearMark(markName);
5733};
5734
5735var endFiberMark = function (fiber, phase, warning) {
5736 var componentName = getComponentName(fiber) || 'Unknown';
5737 var debugID = fiber._debugID;
5738 var isMounted = fiber.alternate !== null;
5739 var label = getFiberLabel(componentName, isMounted, phase);
5740 var markName = getFiberMarkName(label, debugID);
5741 endMark(label, markName, warning);
5742};
5743
5744var shouldIgnoreFiber = function (fiber) {
5745 // Host components should be skipped in the timeline.
5746 // We could check typeof fiber.type, but does this work with RN?
5747 switch (fiber.tag) {
5748 case HostRoot:
5749 case HostComponent:
5750 case HostText:
5751 case HostPortal:
5752 case CallComponent:
5753 case ReturnComponent:
5754 case Fragment:
5755 return true;
5756 default:
5757 return false;
5758 }
5759};
5760
5761var clearPendingPhaseMeasurement = function () {
5762 if (currentPhase !== null && currentPhaseFiber !== null) {
5763 clearFiberMark(currentPhaseFiber, currentPhase);
5764 }
5765 currentPhaseFiber = null;
5766 currentPhase = null;
5767 hasScheduledUpdateInCurrentPhase = false;
5768};
5769
5770var pauseTimers = function () {
5771 // Stops all currently active measurements so that they can be resumed
5772 // if we continue in a later deferred loop from the same unit of work.
5773 var fiber = currentFiber;
5774 while (fiber) {
5775 if (fiber._debugIsCurrentlyTiming) {
5776 endFiberMark(fiber, null, null);
5777 }
5778 fiber = fiber['return'];
5779 }
5780};
5781
5782var resumeTimersRecursively = function (fiber) {
5783 if (fiber['return'] !== null) {
5784 resumeTimersRecursively(fiber['return']);
5785 }
5786 if (fiber._debugIsCurrentlyTiming) {
5787 beginFiberMark(fiber, null);
5788 }
5789};
5790
5791var resumeTimers = function () {
5792 // Resumes all measurements that were active during the last deferred loop.
5793 if (currentFiber !== null) {
5794 resumeTimersRecursively(currentFiber);
5795 }
5796};
5797
5798function recordEffect() {
5799 if (enableUserTimingAPI) {
5800 effectCountInCurrentCommit++;
5801 }
5802}
5803
5804function recordScheduleUpdate() {
5805 if (enableUserTimingAPI) {
5806 if (isCommitting) {
5807 hasScheduledUpdateInCurrentCommit = true;
5808 }
5809 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
5810 hasScheduledUpdateInCurrentPhase = true;
5811 }
5812 }
5813}
5814
5815function startRequestCallbackTimer() {
5816 if (enableUserTimingAPI) {
5817 if (supportsUserTiming && !isWaitingForCallback) {
5818 isWaitingForCallback = true;
5819 beginMark('(Waiting for async callback...)');
5820 }
5821 }
5822}
5823
5824function stopRequestCallbackTimer(didExpire) {
5825 if (enableUserTimingAPI) {
5826 if (supportsUserTiming) {
5827 isWaitingForCallback = false;
5828 var warning = didExpire ? 'React was blocked by main thread' : null;
5829 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
5830 }
5831 }
5832}
5833
5834function startWorkTimer(fiber) {
5835 if (enableUserTimingAPI) {
5836 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5837 return;
5838 }
5839 // If we pause, this is the fiber to unwind from.
5840 currentFiber = fiber;
5841 if (!beginFiberMark(fiber, null)) {
5842 return;
5843 }
5844 fiber._debugIsCurrentlyTiming = true;
5845 }
5846}
5847
5848function cancelWorkTimer(fiber) {
5849 if (enableUserTimingAPI) {
5850 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5851 return;
5852 }
5853 // Remember we shouldn't complete measurement for this fiber.
5854 // Otherwise flamechart will be deep even for small updates.
5855 fiber._debugIsCurrentlyTiming = false;
5856 clearFiberMark(fiber, null);
5857 }
5858}
5859
5860function stopWorkTimer(fiber) {
5861 if (enableUserTimingAPI) {
5862 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5863 return;
5864 }
5865 // If we pause, its parent is the fiber to unwind from.
5866 currentFiber = fiber['return'];
5867 if (!fiber._debugIsCurrentlyTiming) {
5868 return;
5869 }
5870 fiber._debugIsCurrentlyTiming = false;
5871 endFiberMark(fiber, null, null);
5872 }
5873}
5874
5875function stopFailedWorkTimer(fiber) {
5876 if (enableUserTimingAPI) {
5877 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5878 return;
5879 }
5880 // If we pause, its parent is the fiber to unwind from.
5881 currentFiber = fiber['return'];
5882 if (!fiber._debugIsCurrentlyTiming) {
5883 return;
5884 }
5885 fiber._debugIsCurrentlyTiming = false;
5886 var warning = 'An error was thrown inside this error boundary';
5887 endFiberMark(fiber, null, warning);
5888 }
5889}
5890
5891function startPhaseTimer(fiber, phase) {
5892 if (enableUserTimingAPI) {
5893 if (!supportsUserTiming) {
5894 return;
5895 }
5896 clearPendingPhaseMeasurement();
5897 if (!beginFiberMark(fiber, phase)) {
5898 return;
5899 }
5900 currentPhaseFiber = fiber;
5901 currentPhase = phase;
5902 }
5903}
5904
5905function stopPhaseTimer() {
5906 if (enableUserTimingAPI) {
5907 if (!supportsUserTiming) {
5908 return;
5909 }
5910 if (currentPhase !== null && currentPhaseFiber !== null) {
5911 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
5912 endFiberMark(currentPhaseFiber, currentPhase, warning);
5913 }
5914 currentPhase = null;
5915 currentPhaseFiber = null;
5916 }
5917}
5918
5919function startWorkLoopTimer(nextUnitOfWork) {
5920 if (enableUserTimingAPI) {
5921 currentFiber = nextUnitOfWork;
5922 if (!supportsUserTiming) {
5923 return;
5924 }
5925 commitCountInCurrentWorkLoop = 0;
5926 // This is top level call.
5927 // Any other measurements are performed within.
5928 beginMark('(React Tree Reconciliation)');
5929 // Resume any measurements that were in progress during the last loop.
5930 resumeTimers();
5931 }
5932}
5933
5934function stopWorkLoopTimer(interruptedBy) {
5935 if (enableUserTimingAPI) {
5936 if (!supportsUserTiming) {
5937 return;
5938 }
5939 var warning = null;
5940 if (interruptedBy !== null) {
5941 if (interruptedBy.tag === HostRoot) {
5942 warning = 'A top-level update interrupted the previous render';
5943 } else {
5944 var componentName = getComponentName(interruptedBy) || 'Unknown';
5945 warning = 'An update to ' + componentName + ' interrupted the previous render';
5946 }
5947 } else if (commitCountInCurrentWorkLoop > 1) {
5948 warning = 'There were cascading updates';
5949 }
5950 commitCountInCurrentWorkLoop = 0;
5951 // Pause any measurements until the next loop.
5952 pauseTimers();
5953 endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning);
5954 }
5955}
5956
5957function startCommitTimer() {
5958 if (enableUserTimingAPI) {
5959 if (!supportsUserTiming) {
5960 return;
5961 }
5962 isCommitting = true;
5963 hasScheduledUpdateInCurrentCommit = false;
5964 labelsInCurrentCommit.clear();
5965 beginMark('(Committing Changes)');
5966 }
5967}
5968
5969function stopCommitTimer() {
5970 if (enableUserTimingAPI) {
5971 if (!supportsUserTiming) {
5972 return;
5973 }
5974
5975 var warning = null;
5976 if (hasScheduledUpdateInCurrentCommit) {
5977 warning = 'Lifecycle hook scheduled a cascading update';
5978 } else if (commitCountInCurrentWorkLoop > 0) {
5979 warning = 'Caused by a cascading update in earlier commit';
5980 }
5981 hasScheduledUpdateInCurrentCommit = false;
5982 commitCountInCurrentWorkLoop++;
5983 isCommitting = false;
5984 labelsInCurrentCommit.clear();
5985
5986 endMark('(Committing Changes)', '(Committing Changes)', warning);
5987 }
5988}
5989
5990function startCommitHostEffectsTimer() {
5991 if (enableUserTimingAPI) {
5992 if (!supportsUserTiming) {
5993 return;
5994 }
5995 effectCountInCurrentCommit = 0;
5996 beginMark('(Committing Host Effects)');
5997 }
5998}
5999
6000function stopCommitHostEffectsTimer() {
6001 if (enableUserTimingAPI) {
6002 if (!supportsUserTiming) {
6003 return;
6004 }
6005 var count = effectCountInCurrentCommit;
6006 effectCountInCurrentCommit = 0;
6007 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
6008 }
6009}
6010
6011function startCommitLifeCyclesTimer() {
6012 if (enableUserTimingAPI) {
6013 if (!supportsUserTiming) {
6014 return;
6015 }
6016 effectCountInCurrentCommit = 0;
6017 beginMark('(Calling Lifecycle Methods)');
6018 }
6019}
6020
6021function stopCommitLifeCyclesTimer() {
6022 if (enableUserTimingAPI) {
6023 if (!supportsUserTiming) {
6024 return;
6025 }
6026 var count = effectCountInCurrentCommit;
6027 effectCountInCurrentCommit = 0;
6028 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
6029 }
6030}
6031
6032var warnedAboutMissingGetChildContext = void 0;
6033
6034{
6035 warnedAboutMissingGetChildContext = {};
6036}
6037
6038// A cursor to the current merged context object on the stack.
6039var contextStackCursor = createCursor(emptyObject_1);
6040// A cursor to a boolean indicating whether the context has changed.
6041var didPerformWorkStackCursor = createCursor(false);
6042// Keep track of the previous context object that was on the stack.
6043// We use this to get access to the parent context after we have already
6044// pushed the next context provider, and now need to merge their contexts.
6045var previousContext = emptyObject_1;
6046
6047function getUnmaskedContext(workInProgress) {
6048 var hasOwnContext = isContextProvider(workInProgress);
6049 if (hasOwnContext) {
6050 // If the fiber is a context provider itself, when we read its context
6051 // we have already pushed its own child context on the stack. A context
6052 // provider should not "see" its own child context. Therefore we read the
6053 // previous (parent) context instead for a context provider.
6054 return previousContext;
6055 }
6056 return contextStackCursor.current;
6057}
6058
6059function cacheContext(workInProgress, unmaskedContext, maskedContext) {
6060 var instance = workInProgress.stateNode;
6061 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
6062 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
6063}
6064
6065function getMaskedContext(workInProgress, unmaskedContext) {
6066 var type = workInProgress.type;
6067 var contextTypes = type.contextTypes;
6068 if (!contextTypes) {
6069 return emptyObject_1;
6070 }
6071
6072 // Avoid recreating masked context unless unmasked context has changed.
6073 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
6074 // This may trigger infinite loops if componentWillReceiveProps calls setState.
6075 var instance = workInProgress.stateNode;
6076 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
6077 return instance.__reactInternalMemoizedMaskedChildContext;
6078 }
6079
6080 var context = {};
6081 for (var key in contextTypes) {
6082 context[key] = unmaskedContext[key];
6083 }
6084
6085 {
6086 var name = getComponentName(workInProgress) || 'Unknown';
6087 checkPropTypes_1(contextTypes, context, 'context', name, ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6088 }
6089
6090 // Cache unmasked context so we can avoid recreating masked context unless necessary.
6091 // Context is created before the class component is instantiated so check for instance.
6092 if (instance) {
6093 cacheContext(workInProgress, unmaskedContext, context);
6094 }
6095
6096 return context;
6097}
6098
6099function hasContextChanged() {
6100 return didPerformWorkStackCursor.current;
6101}
6102
6103function isContextConsumer(fiber) {
6104 return fiber.tag === ClassComponent && fiber.type.contextTypes != null;
6105}
6106
6107function isContextProvider(fiber) {
6108 return fiber.tag === ClassComponent && fiber.type.childContextTypes != null;
6109}
6110
6111function popContextProvider(fiber) {
6112 if (!isContextProvider(fiber)) {
6113 return;
6114 }
6115
6116 pop(didPerformWorkStackCursor, fiber);
6117 pop(contextStackCursor, fiber);
6118}
6119
6120function popTopLevelContextObject(fiber) {
6121 pop(didPerformWorkStackCursor, fiber);
6122 pop(contextStackCursor, fiber);
6123}
6124
6125function pushTopLevelContextObject(fiber, context, didChange) {
6126 !(contextStackCursor.cursor == null) ? invariant_1(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6127
6128 push(contextStackCursor, context, fiber);
6129 push(didPerformWorkStackCursor, didChange, fiber);
6130}
6131
6132function processChildContext(fiber, parentContext) {
6133 var instance = fiber.stateNode;
6134 var childContextTypes = fiber.type.childContextTypes;
6135
6136 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
6137 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
6138 if (typeof instance.getChildContext !== 'function') {
6139 {
6140 var componentName = getComponentName(fiber) || 'Unknown';
6141
6142 if (!warnedAboutMissingGetChildContext[componentName]) {
6143 warnedAboutMissingGetChildContext[componentName] = true;
6144 warning_1(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
6145 }
6146 }
6147 return parentContext;
6148 }
6149
6150 var childContext = void 0;
6151 {
6152 ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
6153 }
6154 startPhaseTimer(fiber, 'getChildContext');
6155 childContext = instance.getChildContext();
6156 stopPhaseTimer();
6157 {
6158 ReactDebugCurrentFiber.setCurrentPhase(null);
6159 }
6160 for (var contextKey in childContext) {
6161 !(contextKey in childContextTypes) ? invariant_1(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(fiber) || 'Unknown', contextKey) : void 0;
6162 }
6163 {
6164 var name = getComponentName(fiber) || 'Unknown';
6165 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
6166 // In practice, there is one case in which we won't get a stack. It's when
6167 // somebody calls unstable_renderSubtreeIntoContainer() and we process
6168 // context from the parent component instance. The stack will be missing
6169 // because it's outside of the reconciliation, and so the pointer has not
6170 // been set. This is rare and doesn't matter. We'll also remove that API.
6171 ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6172 }
6173
6174 return _assign({}, parentContext, childContext);
6175}
6176
6177function pushContextProvider(workInProgress) {
6178 if (!isContextProvider(workInProgress)) {
6179 return false;
6180 }
6181
6182 var instance = workInProgress.stateNode;
6183 // We push the context as early as possible to ensure stack integrity.
6184 // If the instance does not exist yet, we will push null at first,
6185 // and replace it on the stack later when invalidating the context.
6186 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject_1;
6187
6188 // Remember the parent context so we can merge with it later.
6189 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
6190 previousContext = contextStackCursor.current;
6191 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
6192 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
6193
6194 return true;
6195}
6196
6197function invalidateContextProvider(workInProgress, didChange) {
6198 var instance = workInProgress.stateNode;
6199 !instance ? invariant_1(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6200
6201 if (didChange) {
6202 // Merge parent and own context.
6203 // Skip this if we're not updating due to sCU.
6204 // This avoids unnecessarily recomputing memoized values.
6205 var mergedContext = processChildContext(workInProgress, previousContext);
6206 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
6207
6208 // Replace the old (or empty) context with the new one.
6209 // It is important to unwind the context in the reverse order.
6210 pop(didPerformWorkStackCursor, workInProgress);
6211 pop(contextStackCursor, workInProgress);
6212 // Now push the new context and mark that it has changed.
6213 push(contextStackCursor, mergedContext, workInProgress);
6214 push(didPerformWorkStackCursor, didChange, workInProgress);
6215 } else {
6216 pop(didPerformWorkStackCursor, workInProgress);
6217 push(didPerformWorkStackCursor, didChange, workInProgress);
6218 }
6219}
6220
6221function resetContext() {
6222 previousContext = emptyObject_1;
6223 contextStackCursor.current = emptyObject_1;
6224 didPerformWorkStackCursor.current = false;
6225}
6226
6227function findCurrentUnmaskedContext(fiber) {
6228 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
6229 // makes sense elsewhere
6230 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? invariant_1(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6231
6232 var node = fiber;
6233 while (node.tag !== HostRoot) {
6234 if (isContextProvider(node)) {
6235 return node.stateNode.__reactInternalMemoizedMergedChildContext;
6236 }
6237 var parent = node['return'];
6238 !parent ? invariant_1(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6239 node = parent;
6240 }
6241 return node.stateNode.context;
6242}
6243
6244var NoWork = 0; // TODO: Use an opaque type once ESLint et al support the syntax
6245
6246var Sync = 1;
6247var Never = 2147483647; // Max int32: Math.pow(2, 31) - 1
6248
6249var UNIT_SIZE = 10;
6250var MAGIC_NUMBER_OFFSET = 2;
6251
6252// 1 unit of expiration time represents 10ms.
6253function msToExpirationTime(ms) {
6254 // Always add an offset so that we don't clash with the magic number for NoWork.
6255 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET;
6256}
6257
6258function expirationTimeToMs(expirationTime) {
6259 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE;
6260}
6261
6262function ceiling(num, precision) {
6263 return ((num / precision | 0) + 1) * precision;
6264}
6265
6266function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6267 return ceiling(currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
6268}
6269
6270var NoContext = 0;
6271var AsyncUpdates = 1;
6272
6273var hasBadMapPolyfill = void 0;
6274
6275{
6276 hasBadMapPolyfill = false;
6277 try {
6278 var nonExtensibleObject = Object.preventExtensions({});
6279 var testMap = new Map([[nonExtensibleObject, null]]);
6280 var testSet = new Set([nonExtensibleObject]);
6281 // This is necessary for Rollup to not consider these unused.
6282 // https://github.com/rollup/rollup/issues/1771
6283 // TODO: we can remove these if Rollup fixes the bug.
6284 testMap.set(0, 0);
6285 testSet.add(0);
6286 } catch (e) {
6287 // TODO: Consider warning about bad polyfills
6288 hasBadMapPolyfill = true;
6289 }
6290}
6291
6292// A Fiber is work on a Component that needs to be done or was done. There can
6293// be more than one per component.
6294
6295
6296var debugCounter = void 0;
6297
6298{
6299 debugCounter = 1;
6300}
6301
6302function FiberNode(tag, pendingProps, key, internalContextTag) {
6303 // Instance
6304 this.tag = tag;
6305 this.key = key;
6306 this.type = null;
6307 this.stateNode = null;
6308
6309 // Fiber
6310 this['return'] = null;
6311 this.child = null;
6312 this.sibling = null;
6313 this.index = 0;
6314
6315 this.ref = null;
6316
6317 this.pendingProps = pendingProps;
6318 this.memoizedProps = null;
6319 this.updateQueue = null;
6320 this.memoizedState = null;
6321
6322 this.internalContextTag = internalContextTag;
6323
6324 // Effects
6325 this.effectTag = NoEffect;
6326 this.nextEffect = null;
6327
6328 this.firstEffect = null;
6329 this.lastEffect = null;
6330
6331 this.expirationTime = NoWork;
6332
6333 this.alternate = null;
6334
6335 {
6336 this._debugID = debugCounter++;
6337 this._debugSource = null;
6338 this._debugOwner = null;
6339 this._debugIsCurrentlyTiming = false;
6340 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
6341 Object.preventExtensions(this);
6342 }
6343 }
6344}
6345
6346// This is a constructor function, rather than a POJO constructor, still
6347// please ensure we do the following:
6348// 1) Nobody should add any instance methods on this. Instance methods can be
6349// more difficult to predict when they get optimized and they are almost
6350// never inlined properly in static compilers.
6351// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
6352// always know when it is a fiber.
6353// 3) We might want to experiment with using numeric keys since they are easier
6354// to optimize in a non-JIT environment.
6355// 4) We can easily go from a constructor to a createFiber object literal if that
6356// is faster.
6357// 5) It should be easy to port this to a C struct and keep a C implementation
6358// compatible.
6359var createFiber = function (tag, pendingProps, key, internalContextTag) {
6360 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
6361 return new FiberNode(tag, pendingProps, key, internalContextTag);
6362};
6363
6364function shouldConstruct(Component) {
6365 return !!(Component.prototype && Component.prototype.isReactComponent);
6366}
6367
6368// This is used to create an alternate fiber to do work on.
6369function createWorkInProgress(current, pendingProps, expirationTime) {
6370 var workInProgress = current.alternate;
6371 if (workInProgress === null) {
6372 // We use a double buffering pooling technique because we know that we'll
6373 // only ever need at most two versions of a tree. We pool the "other" unused
6374 // node that we're free to reuse. This is lazily created to avoid allocating
6375 // extra objects for things that are never updated. It also allow us to
6376 // reclaim the extra memory if needed.
6377 workInProgress = createFiber(current.tag, pendingProps, current.key, current.internalContextTag);
6378 workInProgress.type = current.type;
6379 workInProgress.stateNode = current.stateNode;
6380
6381 {
6382 // DEV-only fields
6383 workInProgress._debugID = current._debugID;
6384 workInProgress._debugSource = current._debugSource;
6385 workInProgress._debugOwner = current._debugOwner;
6386 }
6387
6388 workInProgress.alternate = current;
6389 current.alternate = workInProgress;
6390 } else {
6391 workInProgress.pendingProps = pendingProps;
6392
6393 // We already have an alternate.
6394 // Reset the effect tag.
6395 workInProgress.effectTag = NoEffect;
6396
6397 // The effect list is no longer valid.
6398 workInProgress.nextEffect = null;
6399 workInProgress.firstEffect = null;
6400 workInProgress.lastEffect = null;
6401 }
6402
6403 workInProgress.expirationTime = expirationTime;
6404
6405 workInProgress.child = current.child;
6406 workInProgress.memoizedProps = current.memoizedProps;
6407 workInProgress.memoizedState = current.memoizedState;
6408 workInProgress.updateQueue = current.updateQueue;
6409
6410 // These will be overridden during the parent's reconciliation
6411 workInProgress.sibling = current.sibling;
6412 workInProgress.index = current.index;
6413 workInProgress.ref = current.ref;
6414
6415 return workInProgress;
6416}
6417
6418function createHostRootFiber(isAsync) {
6419 var internalContextTag = isAsync ? AsyncUpdates : NoContext;
6420 return createFiber(HostRoot, null, null, internalContextTag);
6421}
6422
6423function createFiberFromElement(element, internalContextTag, expirationTime) {
6424 var owner = null;
6425 {
6426 owner = element._owner;
6427 }
6428
6429 var fiber = void 0;
6430 var type = element.type;
6431 var key = element.key;
6432 var pendingProps = element.props;
6433 if (typeof type === 'function') {
6434 fiber = shouldConstruct(type) ? createFiber(ClassComponent, pendingProps, key, internalContextTag) : createFiber(IndeterminateComponent, pendingProps, key, internalContextTag);
6435 fiber.type = type;
6436 } else if (typeof type === 'string') {
6437 fiber = createFiber(HostComponent, pendingProps, key, internalContextTag);
6438 fiber.type = type;
6439 } else {
6440 switch (type) {
6441 case REACT_FRAGMENT_TYPE:
6442 return createFiberFromFragment(pendingProps.children, internalContextTag, expirationTime, key);
6443 case REACT_CALL_TYPE:
6444 fiber = createFiber(CallComponent, pendingProps, key, internalContextTag);
6445 fiber.type = REACT_CALL_TYPE;
6446 break;
6447 case REACT_RETURN_TYPE:
6448 fiber = createFiber(ReturnComponent, pendingProps, key, internalContextTag);
6449 fiber.type = REACT_RETURN_TYPE;
6450 break;
6451 default:
6452 {
6453 if (typeof type === 'object' && type !== null && typeof type.tag === 'number') {
6454 // Currently assumed to be a continuation and therefore is a
6455 // fiber already.
6456 // TODO: The yield system is currently broken for updates in some
6457 // cases. The reified yield stores a fiber, but we don't know which
6458 // fiber that is; the current or a workInProgress? When the
6459 // continuation gets rendered here we don't know if we can reuse that
6460 // fiber or if we need to clone it. There is probably a clever way to
6461 // restructure this.
6462 fiber = type;
6463 fiber.pendingProps = pendingProps;
6464 } else {
6465 var info = '';
6466 {
6467 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
6468 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.';
6469 }
6470 var ownerName = owner ? getComponentName(owner) : null;
6471 if (ownerName) {
6472 info += '\n\nCheck the render method of `' + ownerName + '`.';
6473 }
6474 }
6475 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);
6476 }
6477 }
6478 }
6479 }
6480
6481 {
6482 fiber._debugSource = element._source;
6483 fiber._debugOwner = element._owner;
6484 }
6485
6486 fiber.expirationTime = expirationTime;
6487
6488 return fiber;
6489}
6490
6491function createFiberFromFragment(elements, internalContextTag, expirationTime, key) {
6492 var fiber = createFiber(Fragment, elements, key, internalContextTag);
6493 fiber.expirationTime = expirationTime;
6494 return fiber;
6495}
6496
6497function createFiberFromText(content, internalContextTag, expirationTime) {
6498 var fiber = createFiber(HostText, content, null, internalContextTag);
6499 fiber.expirationTime = expirationTime;
6500 return fiber;
6501}
6502
6503function createFiberFromHostInstanceForDeletion() {
6504 var fiber = createFiber(HostComponent, null, null, NoContext);
6505 fiber.type = 'DELETED';
6506 return fiber;
6507}
6508
6509function createFiberFromPortal(portal, internalContextTag, expirationTime) {
6510 var pendingProps = portal.children !== null ? portal.children : [];
6511 var fiber = createFiber(HostPortal, pendingProps, portal.key, internalContextTag);
6512 fiber.expirationTime = expirationTime;
6513 fiber.stateNode = {
6514 containerInfo: portal.containerInfo,
6515 pendingChildren: null, // Used by persistent updates
6516 implementation: portal.implementation
6517 };
6518 return fiber;
6519}
6520
6521// TODO: This should be lifted into the renderer.
6522
6523
6524function createFiberRoot(containerInfo, isAsync, hydrate) {
6525 // Cyclic construction. This cheats the type system right now because
6526 // stateNode is any.
6527 var uninitializedFiber = createHostRootFiber(isAsync);
6528 var root = {
6529 current: uninitializedFiber,
6530 containerInfo: containerInfo,
6531 pendingChildren: null,
6532 remainingExpirationTime: NoWork,
6533 isReadyForCommit: false,
6534 finishedWork: null,
6535 context: null,
6536 pendingContext: null,
6537 hydrate: hydrate,
6538 firstBatch: null,
6539 nextScheduledRoot: null
6540 };
6541 uninitializedFiber.stateNode = root;
6542 return root;
6543}
6544
6545var onCommitFiberRoot = null;
6546var onCommitFiberUnmount = null;
6547var hasLoggedError = false;
6548
6549function catchErrors(fn) {
6550 return function (arg) {
6551 try {
6552 return fn(arg);
6553 } catch (err) {
6554 if (true && !hasLoggedError) {
6555 hasLoggedError = true;
6556 warning_1(false, 'React DevTools encountered an error: %s', err);
6557 }
6558 }
6559 };
6560}
6561
6562function injectInternals(internals) {
6563 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
6564 // No DevTools
6565 return false;
6566 }
6567 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
6568 if (hook.isDisabled) {
6569 // This isn't a real property on the hook, but it can be set to opt out
6570 // of DevTools integration and associated warnings and logs.
6571 // https://github.com/facebook/react/issues/3877
6572 return true;
6573 }
6574 if (!hook.supportsFiber) {
6575 {
6576 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');
6577 }
6578 // DevTools exists, even though it doesn't support Fiber.
6579 return true;
6580 }
6581 try {
6582 var rendererID = hook.inject(internals);
6583 // We have successfully injected, so now it is safe to set up hooks.
6584 onCommitFiberRoot = catchErrors(function (root) {
6585 return hook.onCommitFiberRoot(rendererID, root);
6586 });
6587 onCommitFiberUnmount = catchErrors(function (fiber) {
6588 return hook.onCommitFiberUnmount(rendererID, fiber);
6589 });
6590 } catch (err) {
6591 // Catch all errors because it is unsafe to throw during initialization.
6592 {
6593 warning_1(false, 'React DevTools encountered an error: %s.', err);
6594 }
6595 }
6596 // DevTools exists
6597 return true;
6598}
6599
6600function onCommitRoot(root) {
6601 if (typeof onCommitFiberRoot === 'function') {
6602 onCommitFiberRoot(root);
6603 }
6604}
6605
6606function onCommitUnmount(fiber) {
6607 if (typeof onCommitFiberUnmount === 'function') {
6608 onCommitFiberUnmount(fiber);
6609 }
6610}
6611
6612var didWarnUpdateInsideUpdate = void 0;
6613
6614{
6615 didWarnUpdateInsideUpdate = false;
6616}
6617
6618// Callbacks are not validated until invocation
6619
6620
6621// Singly linked-list of updates. When an update is scheduled, it is added to
6622// the queue of the current fiber and the work-in-progress fiber. The two queues
6623// are separate but they share a persistent structure.
6624//
6625// During reconciliation, updates are removed from the work-in-progress fiber,
6626// but they remain on the current fiber. That ensures that if a work-in-progress
6627// is aborted, the aborted updates are recovered by cloning from current.
6628//
6629// The work-in-progress queue is always a subset of the current queue.
6630//
6631// When the tree is committed, the work-in-progress becomes the current.
6632
6633
6634function createUpdateQueue(baseState) {
6635 var queue = {
6636 baseState: baseState,
6637 expirationTime: NoWork,
6638 first: null,
6639 last: null,
6640 callbackList: null,
6641 hasForceUpdate: false,
6642 isInitialized: false
6643 };
6644 {
6645 queue.isProcessing = false;
6646 }
6647 return queue;
6648}
6649
6650function insertUpdateIntoQueue(queue, update) {
6651 // Append the update to the end of the list.
6652 if (queue.last === null) {
6653 // Queue is empty
6654 queue.first = queue.last = update;
6655 } else {
6656 queue.last.next = update;
6657 queue.last = update;
6658 }
6659 if (queue.expirationTime === NoWork || queue.expirationTime > update.expirationTime) {
6660 queue.expirationTime = update.expirationTime;
6661 }
6662}
6663
6664function insertUpdateIntoFiber(fiber, update) {
6665 // We'll have at least one and at most two distinct update queues.
6666 var alternateFiber = fiber.alternate;
6667 var queue1 = fiber.updateQueue;
6668 if (queue1 === null) {
6669 // TODO: We don't know what the base state will be until we begin work.
6670 // It depends on which fiber is the next current. Initialize with an empty
6671 // base state, then set to the memoizedState when rendering. Not super
6672 // happy with this approach.
6673 queue1 = fiber.updateQueue = createUpdateQueue(null);
6674 }
6675
6676 var queue2 = void 0;
6677 if (alternateFiber !== null) {
6678 queue2 = alternateFiber.updateQueue;
6679 if (queue2 === null) {
6680 queue2 = alternateFiber.updateQueue = createUpdateQueue(null);
6681 }
6682 } else {
6683 queue2 = null;
6684 }
6685 queue2 = queue2 !== queue1 ? queue2 : null;
6686
6687 // Warn if an update is scheduled from inside an updater function.
6688 {
6689 if ((queue1.isProcessing || queue2 !== null && queue2.isProcessing) && !didWarnUpdateInsideUpdate) {
6690 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.');
6691 didWarnUpdateInsideUpdate = true;
6692 }
6693 }
6694
6695 // If there's only one queue, add the update to that queue and exit.
6696 if (queue2 === null) {
6697 insertUpdateIntoQueue(queue1, update);
6698 return;
6699 }
6700
6701 // If either queue is empty, we need to add to both queues.
6702 if (queue1.last === null || queue2.last === null) {
6703 insertUpdateIntoQueue(queue1, update);
6704 insertUpdateIntoQueue(queue2, update);
6705 return;
6706 }
6707
6708 // If both lists are not empty, the last update is the same for both lists
6709 // because of structural sharing. So, we should only append to one of
6710 // the lists.
6711 insertUpdateIntoQueue(queue1, update);
6712 // But we still need to update the `last` pointer of queue2.
6713 queue2.last = update;
6714}
6715
6716function getUpdateExpirationTime(fiber) {
6717 if (fiber.tag !== ClassComponent && fiber.tag !== HostRoot) {
6718 return NoWork;
6719 }
6720 var updateQueue = fiber.updateQueue;
6721 if (updateQueue === null) {
6722 return NoWork;
6723 }
6724 return updateQueue.expirationTime;
6725}
6726
6727function getStateFromUpdate(update, instance, prevState, props) {
6728 var partialState = update.partialState;
6729 if (typeof partialState === 'function') {
6730 var updateFn = partialState;
6731
6732 // Invoke setState callback an extra time to help detect side-effects.
6733 if (debugRenderPhaseSideEffects) {
6734 updateFn.call(instance, prevState, props);
6735 }
6736
6737 return updateFn.call(instance, prevState, props);
6738 } else {
6739 return partialState;
6740 }
6741}
6742
6743function processUpdateQueue(current, workInProgress, queue, instance, props, renderExpirationTime) {
6744 if (current !== null && current.updateQueue === queue) {
6745 // We need to create a work-in-progress queue, by cloning the current queue.
6746 var currentQueue = queue;
6747 queue = workInProgress.updateQueue = {
6748 baseState: currentQueue.baseState,
6749 expirationTime: currentQueue.expirationTime,
6750 first: currentQueue.first,
6751 last: currentQueue.last,
6752 isInitialized: currentQueue.isInitialized,
6753 // These fields are no longer valid because they were already committed.
6754 // Reset them.
6755 callbackList: null,
6756 hasForceUpdate: false
6757 };
6758 }
6759
6760 {
6761 // Set this flag so we can warn if setState is called inside the update
6762 // function of another setState.
6763 queue.isProcessing = true;
6764 }
6765
6766 // Reset the remaining expiration time. If we skip over any updates, we'll
6767 // increase this accordingly.
6768 queue.expirationTime = NoWork;
6769
6770 // TODO: We don't know what the base state will be until we begin work.
6771 // It depends on which fiber is the next current. Initialize with an empty
6772 // base state, then set to the memoizedState when rendering. Not super
6773 // happy with this approach.
6774 var state = void 0;
6775 if (queue.isInitialized) {
6776 state = queue.baseState;
6777 } else {
6778 state = queue.baseState = workInProgress.memoizedState;
6779 queue.isInitialized = true;
6780 }
6781 var dontMutatePrevState = true;
6782 var update = queue.first;
6783 var didSkip = false;
6784 while (update !== null) {
6785 var updateExpirationTime = update.expirationTime;
6786 if (updateExpirationTime > renderExpirationTime) {
6787 // This update does not have sufficient priority. Skip it.
6788 var remainingExpirationTime = queue.expirationTime;
6789 if (remainingExpirationTime === NoWork || remainingExpirationTime > updateExpirationTime) {
6790 // Update the remaining expiration time.
6791 queue.expirationTime = updateExpirationTime;
6792 }
6793 if (!didSkip) {
6794 didSkip = true;
6795 queue.baseState = state;
6796 }
6797 // Continue to the next update.
6798 update = update.next;
6799 continue;
6800 }
6801
6802 // This update does have sufficient priority.
6803
6804 // If no previous updates were skipped, drop this update from the queue by
6805 // advancing the head of the list.
6806 if (!didSkip) {
6807 queue.first = update.next;
6808 if (queue.first === null) {
6809 queue.last = null;
6810 }
6811 }
6812
6813 // Process the update
6814 var _partialState = void 0;
6815 if (update.isReplace) {
6816 state = getStateFromUpdate(update, instance, state, props);
6817 dontMutatePrevState = true;
6818 } else {
6819 _partialState = getStateFromUpdate(update, instance, state, props);
6820 if (_partialState) {
6821 if (dontMutatePrevState) {
6822 // $FlowFixMe: Idk how to type this properly.
6823 state = _assign({}, state, _partialState);
6824 } else {
6825 state = _assign(state, _partialState);
6826 }
6827 dontMutatePrevState = false;
6828 }
6829 }
6830 if (update.isForced) {
6831 queue.hasForceUpdate = true;
6832 }
6833 if (update.callback !== null) {
6834 // Append to list of callbacks.
6835 var _callbackList = queue.callbackList;
6836 if (_callbackList === null) {
6837 _callbackList = queue.callbackList = [];
6838 }
6839 _callbackList.push(update);
6840 }
6841 update = update.next;
6842 }
6843
6844 if (queue.callbackList !== null) {
6845 workInProgress.effectTag |= Callback;
6846 } else if (queue.first === null && !queue.hasForceUpdate) {
6847 // The queue is empty. We can reset it.
6848 workInProgress.updateQueue = null;
6849 }
6850
6851 if (!didSkip) {
6852 didSkip = true;
6853 queue.baseState = state;
6854 }
6855
6856 {
6857 // No longer processing.
6858 queue.isProcessing = false;
6859 }
6860
6861 return state;
6862}
6863
6864function commitCallbacks(queue, context) {
6865 var callbackList = queue.callbackList;
6866 if (callbackList === null) {
6867 return;
6868 }
6869 // Set the list to null to make sure they don't get called more than once.
6870 queue.callbackList = null;
6871 for (var i = 0; i < callbackList.length; i++) {
6872 var update = callbackList[i];
6873 var _callback = update.callback;
6874 // This update might be processed again. Clear the callback so it's only
6875 // called once.
6876 update.callback = null;
6877 !(typeof _callback === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0;
6878 _callback.call(context);
6879 }
6880}
6881
6882var fakeInternalInstance = {};
6883var isArray = Array.isArray;
6884
6885var didWarnAboutLegacyWillMount = void 0;
6886var didWarnAboutLegacyWillReceiveProps = void 0;
6887var didWarnAboutLegacyWillUpdate = void 0;
6888var didWarnAboutStateAssignmentForComponent = void 0;
6889var didWarnAboutUndefinedDerivedState = void 0;
6890var didWarnAboutUninitializedState = void 0;
6891var didWarnAboutWillReceivePropsAndDerivedState = void 0;
6892var warnOnInvalidCallback$1 = void 0;
6893
6894{
6895 if (warnAboutDeprecatedLifecycles) {
6896 didWarnAboutLegacyWillMount = {};
6897 didWarnAboutLegacyWillReceiveProps = {};
6898 didWarnAboutLegacyWillUpdate = {};
6899 }
6900 didWarnAboutStateAssignmentForComponent = {};
6901 didWarnAboutUndefinedDerivedState = {};
6902 didWarnAboutUninitializedState = {};
6903 didWarnAboutWillReceivePropsAndDerivedState = {};
6904
6905 var didWarnOnInvalidCallback = {};
6906
6907 warnOnInvalidCallback$1 = function (callback, callerName) {
6908 if (callback === null || typeof callback === 'function') {
6909 return;
6910 }
6911 var key = callerName + '_' + callback;
6912 if (!didWarnOnInvalidCallback[key]) {
6913 warning_1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
6914 didWarnOnInvalidCallback[key] = true;
6915 }
6916 };
6917
6918 // This is so gross but it's at least non-critical and can be removed if
6919 // it causes problems. This is meant to give a nicer error message for
6920 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
6921 // ...)) which otherwise throws a "_processChildContext is not a function"
6922 // exception.
6923 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
6924 enumerable: false,
6925 value: function () {
6926 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).');
6927 }
6928 });
6929 Object.freeze(fakeInternalInstance);
6930}
6931
6932var ReactFiberClassComponent = function (scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState) {
6933 // Class component state updater
6934 var updater = {
6935 isMounted: isMounted,
6936 enqueueSetState: function (instance, partialState, callback) {
6937 var fiber = get(instance);
6938 callback = callback === undefined ? null : callback;
6939 {
6940 warnOnInvalidCallback$1(callback, 'setState');
6941 }
6942 var expirationTime = computeExpirationForFiber(fiber);
6943 var update = {
6944 expirationTime: expirationTime,
6945 partialState: partialState,
6946 callback: callback,
6947 isReplace: false,
6948 isForced: false,
6949 nextCallback: null,
6950 next: null
6951 };
6952 insertUpdateIntoFiber(fiber, update);
6953 scheduleWork(fiber, expirationTime);
6954 },
6955 enqueueReplaceState: function (instance, state, callback) {
6956 var fiber = get(instance);
6957 callback = callback === undefined ? null : callback;
6958 {
6959 warnOnInvalidCallback$1(callback, 'replaceState');
6960 }
6961 var expirationTime = computeExpirationForFiber(fiber);
6962 var update = {
6963 expirationTime: expirationTime,
6964 partialState: state,
6965 callback: callback,
6966 isReplace: true,
6967 isForced: false,
6968 nextCallback: null,
6969 next: null
6970 };
6971 insertUpdateIntoFiber(fiber, update);
6972 scheduleWork(fiber, expirationTime);
6973 },
6974 enqueueForceUpdate: function (instance, callback) {
6975 var fiber = get(instance);
6976 callback = callback === undefined ? null : callback;
6977 {
6978 warnOnInvalidCallback$1(callback, 'forceUpdate');
6979 }
6980 var expirationTime = computeExpirationForFiber(fiber);
6981 var update = {
6982 expirationTime: expirationTime,
6983 partialState: null,
6984 callback: callback,
6985 isReplace: false,
6986 isForced: true,
6987 nextCallback: null,
6988 next: null
6989 };
6990 insertUpdateIntoFiber(fiber, update);
6991 scheduleWork(fiber, expirationTime);
6992 }
6993 };
6994
6995 function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
6996 if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) {
6997 // If the workInProgress already has an Update effect, return true
6998 return true;
6999 }
7000
7001 var instance = workInProgress.stateNode;
7002 var type = workInProgress.type;
7003 if (typeof instance.shouldComponentUpdate === 'function') {
7004 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
7005 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext);
7006 stopPhaseTimer();
7007
7008 // Simulate an async bailout/interruption by invoking lifecycle twice.
7009 if (debugRenderPhaseSideEffects) {
7010 instance.shouldComponentUpdate(newProps, newState, newContext);
7011 }
7012
7013 {
7014 warning_1(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(workInProgress) || 'Unknown');
7015 }
7016
7017 return shouldUpdate;
7018 }
7019
7020 if (type.prototype && type.prototype.isPureReactComponent) {
7021 return !shallowEqual_1(oldProps, newProps) || !shallowEqual_1(oldState, newState);
7022 }
7023
7024 return true;
7025 }
7026
7027 function checkClassInstance(workInProgress) {
7028 var instance = workInProgress.stateNode;
7029 var type = workInProgress.type;
7030 {
7031 var name = getComponentName(workInProgress);
7032 var renderPresent = instance.render;
7033
7034 if (!renderPresent) {
7035 if (type.prototype && typeof type.prototype.render === 'function') {
7036 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
7037 } else {
7038 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
7039 }
7040 }
7041
7042 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
7043 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);
7044 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
7045 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);
7046 var noInstancePropTypes = !instance.propTypes;
7047 warning_1(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
7048 var noInstanceContextTypes = !instance.contextTypes;
7049 warning_1(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
7050 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
7051 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);
7052 if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
7053 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');
7054 }
7055 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
7056 warning_1(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
7057 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
7058 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);
7059 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
7060 warning_1(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
7061 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
7062 warning_1(noUnsafeComponentWillRecieveProps, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
7063 var hasMutatedProps = instance.props !== workInProgress.pendingProps;
7064 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);
7065 var noInstanceDefaultProps = !instance.defaultProps;
7066 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);
7067 }
7068
7069 var state = instance.state;
7070 if (state && (typeof state !== 'object' || isArray(state))) {
7071 warning_1(false, '%s.state: must be set to an object or null', getComponentName(workInProgress));
7072 }
7073 if (typeof instance.getChildContext === 'function') {
7074 warning_1(typeof workInProgress.type.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', getComponentName(workInProgress));
7075 }
7076 }
7077
7078 function resetInputPointers(workInProgress, instance) {
7079 instance.props = workInProgress.memoizedProps;
7080 instance.state = workInProgress.memoizedState;
7081 }
7082
7083 function adoptClassInstance(workInProgress, instance) {
7084 instance.updater = updater;
7085 workInProgress.stateNode = instance;
7086 // The instance needs access to the fiber so that it can schedule updates
7087 set(instance, workInProgress);
7088 {
7089 instance._reactInternalInstance = fakeInternalInstance;
7090 }
7091 }
7092
7093 function constructClassInstance(workInProgress, props) {
7094 var ctor = workInProgress.type;
7095 var unmaskedContext = getUnmaskedContext(workInProgress);
7096 var needsContext = isContextConsumer(workInProgress);
7097 var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject_1;
7098 var instance = new ctor(props, context);
7099 var state = instance.state !== null && instance.state !== undefined ? instance.state : null;
7100 adoptClassInstance(workInProgress, instance);
7101
7102 {
7103 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
7104 var componentName = getComponentName(workInProgress) || 'Unknown';
7105 if (!didWarnAboutUninitializedState[componentName]) {
7106 warning_1(false, '%s: Did not properly initialize state during construction. ' + 'Expected state to be an object, but it was %s.', componentName, instance.state === null ? 'null' : 'undefined');
7107 didWarnAboutUninitializedState[componentName] = true;
7108 }
7109 }
7110 }
7111
7112 workInProgress.memoizedState = state;
7113
7114 var partialState = callGetDerivedStateFromProps(workInProgress, instance, props);
7115
7116 if (partialState !== null && partialState !== undefined) {
7117 // Render-phase updates (like this) should not be added to the update queue,
7118 // So that multiple render passes do not enqueue multiple updates.
7119 // Instead, just synchronously merge the returned state into the instance.
7120 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
7121 }
7122
7123 // Cache unmasked context so we can avoid recreating masked context unless necessary.
7124 // ReactFiberContext usually updates this cache but can't for newly-created instances.
7125 if (needsContext) {
7126 cacheContext(workInProgress, unmaskedContext, context);
7127 }
7128
7129 return instance;
7130 }
7131
7132 function callComponentWillMount(workInProgress, instance) {
7133 startPhaseTimer(workInProgress, 'componentWillMount');
7134 var oldState = instance.state;
7135
7136 if (typeof instance.componentWillMount === 'function') {
7137 {
7138 if (warnAboutDeprecatedLifecycles) {
7139 var componentName = getComponentName(workInProgress) || 'Component';
7140 if (!didWarnAboutLegacyWillMount[componentName]) {
7141 warning_1(false, '%s: componentWillMount() is deprecated and will be ' + 'removed in the next major version. Read about the motivations ' + 'behind this change: ' + 'https://fb.me/react-async-component-lifecycle-hooks' + '\n\n' + 'As a temporary workaround, you can rename to ' + 'UNSAFE_componentWillMount instead.', componentName);
7142 didWarnAboutLegacyWillMount[componentName] = true;
7143 }
7144 }
7145 }
7146 instance.componentWillMount();
7147 } else {
7148 instance.UNSAFE_componentWillMount();
7149 }
7150
7151 stopPhaseTimer();
7152
7153 if (oldState !== instance.state) {
7154 {
7155 warning_1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress));
7156 }
7157 updater.enqueueReplaceState(instance, instance.state, null);
7158 }
7159 }
7160
7161 function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) {
7162 var oldState = instance.state;
7163 if (typeof instance.componentWillReceiveProps === 'function') {
7164 {
7165 if (warnAboutDeprecatedLifecycles) {
7166 var componentName = getComponentName(workInProgress) || 'Component';
7167 if (!didWarnAboutLegacyWillReceiveProps[componentName]) {
7168 warning_1(false, '%s: componentWillReceiveProps() is deprecated and ' + 'will be removed in the next major version. Use ' + 'static getDerivedStateFromProps() instead. Read about the ' + 'motivations behind this change: ' + 'https://fb.me/react-async-component-lifecycle-hooks' + '\n\n' + 'As a temporary workaround, you can rename to ' + 'UNSAFE_componentWillReceiveProps instead.', componentName);
7169 didWarnAboutLegacyWillReceiveProps[componentName] = true;
7170 }
7171 }
7172 }
7173
7174 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7175 instance.componentWillReceiveProps(newProps, newContext);
7176 stopPhaseTimer();
7177 } else {
7178 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7179 instance.UNSAFE_componentWillReceiveProps(newProps, newContext);
7180 stopPhaseTimer();
7181
7182 // Simulate an async bailout/interruption by invoking lifecycle twice.
7183 if (debugRenderPhaseSideEffects) {
7184 instance.UNSAFE_componentWillReceiveProps(newProps, newContext);
7185 }
7186 }
7187
7188 if (instance.state !== oldState) {
7189 {
7190 var _componentName = getComponentName(workInProgress) || 'Component';
7191 if (!didWarnAboutStateAssignmentForComponent[_componentName]) {
7192 warning_1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', _componentName);
7193 didWarnAboutStateAssignmentForComponent[_componentName] = true;
7194 }
7195 }
7196 updater.enqueueReplaceState(instance, instance.state, null);
7197 }
7198 }
7199
7200 function callGetDerivedStateFromProps(workInProgress, instance, props) {
7201 var type = workInProgress.type;
7202
7203
7204 if (typeof type.getDerivedStateFromProps === 'function') {
7205 {
7206 if (typeof instance.componentWillReceiveProps === 'function' || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
7207 var componentName = getComponentName(workInProgress) || 'Unknown';
7208 if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) {
7209 warning_1(false, '%s: Defines both componentWillReceiveProps() and static ' + 'getDerivedStateFromProps() methods. We recommend using ' + 'only getDerivedStateFromProps().', componentName);
7210 didWarnAboutWillReceivePropsAndDerivedState[componentName] = true;
7211 }
7212 }
7213 }
7214
7215 var partialState = type.getDerivedStateFromProps.call(null, props, workInProgress.memoizedState);
7216
7217 {
7218 if (partialState === undefined) {
7219 var _componentName2 = getComponentName(workInProgress) || 'Unknown';
7220 if (!didWarnAboutUndefinedDerivedState[_componentName2]) {
7221 warning_1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', _componentName2);
7222 didWarnAboutUndefinedDerivedState[_componentName2] = _componentName2;
7223 }
7224 }
7225 }
7226
7227 return partialState;
7228 }
7229 }
7230
7231 // Invokes the mount life-cycles on a previously never rendered instance.
7232 function mountClassInstance(workInProgress, renderExpirationTime) {
7233 var current = workInProgress.alternate;
7234
7235 {
7236 checkClassInstance(workInProgress);
7237 }
7238
7239 var instance = workInProgress.stateNode;
7240 var props = workInProgress.pendingProps;
7241 var unmaskedContext = getUnmaskedContext(workInProgress);
7242
7243 instance.props = props;
7244 instance.state = workInProgress.memoizedState;
7245 instance.refs = emptyObject_1;
7246 instance.context = getMaskedContext(workInProgress, unmaskedContext);
7247
7248 if (enableAsyncSubtreeAPI && workInProgress.type != null && workInProgress.type.prototype != null && workInProgress.type.prototype.unstable_isAsyncReactComponent === true) {
7249 workInProgress.internalContextTag |= AsyncUpdates;
7250 }
7251
7252 if (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function') {
7253 callComponentWillMount(workInProgress, instance);
7254 // If we had additional state updates during this life-cycle, let's
7255 // process them now.
7256 var updateQueue = workInProgress.updateQueue;
7257 if (updateQueue !== null) {
7258 instance.state = processUpdateQueue(current, workInProgress, updateQueue, instance, props, renderExpirationTime);
7259 }
7260 }
7261 if (typeof instance.componentDidMount === 'function') {
7262 workInProgress.effectTag |= Update;
7263 }
7264 }
7265
7266 // Called on a preexisting class instance. Returns false if a resumed render
7267 // could be reused.
7268 // function resumeMountClassInstance(
7269 // workInProgress: Fiber,
7270 // priorityLevel: PriorityLevel,
7271 // ): boolean {
7272 // const instance = workInProgress.stateNode;
7273 // resetInputPointers(workInProgress, instance);
7274
7275 // let newState = workInProgress.memoizedState;
7276 // let newProps = workInProgress.pendingProps;
7277 // if (!newProps) {
7278 // // If there isn't any new props, then we'll reuse the memoized props.
7279 // // This could be from already completed work.
7280 // newProps = workInProgress.memoizedProps;
7281 // invariant(
7282 // newProps != null,
7283 // 'There should always be pending or memoized props. This error is ' +
7284 // 'likely caused by a bug in React. Please file an issue.',
7285 // );
7286 // }
7287 // const newUnmaskedContext = getUnmaskedContext(workInProgress);
7288 // const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7289
7290 // const oldContext = instance.context;
7291 // const oldProps = workInProgress.memoizedProps;
7292
7293 // if (
7294 // typeof instance.componentWillReceiveProps === 'function' &&
7295 // (oldProps !== newProps || oldContext !== newContext)
7296 // ) {
7297 // callComponentWillReceiveProps(
7298 // workInProgress,
7299 // instance,
7300 // newProps,
7301 // newContext,
7302 // );
7303 // }
7304
7305 // // Process the update queue before calling shouldComponentUpdate
7306 // const updateQueue = workInProgress.updateQueue;
7307 // if (updateQueue !== null) {
7308 // newState = processUpdateQueue(
7309 // workInProgress,
7310 // updateQueue,
7311 // instance,
7312 // newState,
7313 // newProps,
7314 // priorityLevel,
7315 // );
7316 // }
7317
7318 // // TODO: Should we deal with a setState that happened after the last
7319 // // componentWillMount and before this componentWillMount? Probably
7320 // // unsupported anyway.
7321
7322 // if (
7323 // !checkShouldComponentUpdate(
7324 // workInProgress,
7325 // workInProgress.memoizedProps,
7326 // newProps,
7327 // workInProgress.memoizedState,
7328 // newState,
7329 // newContext,
7330 // )
7331 // ) {
7332 // // Update the existing instance's state, props, and context pointers even
7333 // // though we're bailing out.
7334 // instance.props = newProps;
7335 // instance.state = newState;
7336 // instance.context = newContext;
7337 // return false;
7338 // }
7339
7340 // // Update the input pointers now so that they are correct when we call
7341 // // componentWillMount
7342 // instance.props = newProps;
7343 // instance.state = newState;
7344 // instance.context = newContext;
7345
7346 // if (typeof instance.componentWillMount === 'function') {
7347 // callComponentWillMount(workInProgress, instance);
7348 // // componentWillMount may have called setState. Process the update queue.
7349 // const newUpdateQueue = workInProgress.updateQueue;
7350 // if (newUpdateQueue !== null) {
7351 // newState = processUpdateQueue(
7352 // workInProgress,
7353 // newUpdateQueue,
7354 // instance,
7355 // newState,
7356 // newProps,
7357 // priorityLevel,
7358 // );
7359 // }
7360 // }
7361
7362 // if (typeof instance.componentDidMount === 'function') {
7363 // workInProgress.effectTag |= Update;
7364 // }
7365
7366 // instance.state = newState;
7367
7368 // return true;
7369 // }
7370
7371 // Invokes the update life-cycles and returns false if it shouldn't rerender.
7372 function updateClassInstance(current, workInProgress, renderExpirationTime) {
7373 var instance = workInProgress.stateNode;
7374 resetInputPointers(workInProgress, instance);
7375
7376 var oldProps = workInProgress.memoizedProps;
7377 var newProps = workInProgress.pendingProps;
7378 var oldContext = instance.context;
7379 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7380 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7381
7382 // Note: During these life-cycles, instance.props/instance.state are what
7383 // ever the previously attempted to render - not the "current". However,
7384 // during componentDidUpdate we pass the "current" props.
7385
7386 if ((typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function') && (oldProps !== newProps || oldContext !== newContext)) {
7387 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7388 }
7389
7390 var partialState = void 0;
7391 if (oldProps !== newProps) {
7392 partialState = callGetDerivedStateFromProps(workInProgress, instance, newProps);
7393 }
7394
7395 // Compute the next state using the memoized state and the update queue.
7396 var oldState = workInProgress.memoizedState;
7397 // TODO: Previous state can be null.
7398 var newState = void 0;
7399 if (workInProgress.updateQueue !== null) {
7400 newState = processUpdateQueue(current, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7401 } else {
7402 newState = oldState;
7403 }
7404
7405 if (partialState !== null && partialState !== undefined) {
7406 // Render-phase updates (like this) should not be added to the update queue,
7407 // So that multiple render passes do not enqueue multiple updates.
7408 // Instead, just synchronously merge the returned state into the instance.
7409 newState = newState === null || newState === undefined ? partialState : _assign({}, newState, partialState);
7410 }
7411
7412 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7413 // If an update was already in progress, we should schedule an Update
7414 // effect even though we're bailing out, so that cWU/cDU are called.
7415 if (typeof instance.componentDidUpdate === 'function') {
7416 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7417 workInProgress.effectTag |= Update;
7418 }
7419 }
7420 return false;
7421 }
7422
7423 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7424
7425 if (shouldUpdate) {
7426 if (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function') {
7427 if (typeof instance.componentWillUpdate === 'function') {
7428 {
7429 if (warnAboutDeprecatedLifecycles) {
7430 var componentName = getComponentName(workInProgress) || 'Component';
7431 if (!didWarnAboutLegacyWillUpdate[componentName]) {
7432 warning_1(false, '%s: componentWillUpdate() is deprecated and will be ' + 'removed in the next major version. Read about the motivations ' + 'behind this change: ' + 'https://fb.me/react-async-component-lifecycle-hooks' + '\n\n' + 'As a temporary workaround, you can rename to ' + 'UNSAFE_componentWillUpdate instead.', componentName);
7433 didWarnAboutLegacyWillUpdate[componentName] = true;
7434 }
7435 }
7436 }
7437
7438 startPhaseTimer(workInProgress, 'componentWillUpdate');
7439 instance.componentWillUpdate(newProps, newState, newContext);
7440 stopPhaseTimer();
7441 } else {
7442 startPhaseTimer(workInProgress, 'componentWillUpdate');
7443 instance.UNSAFE_componentWillUpdate(newProps, newState, newContext);
7444 stopPhaseTimer();
7445
7446 // Simulate an async bailout/interruption by invoking lifecycle twice.
7447 if (debugRenderPhaseSideEffects) {
7448 instance.UNSAFE_componentWillUpdate(newProps, newState, newContext);
7449 }
7450 }
7451 }
7452 if (typeof instance.componentDidUpdate === 'function') {
7453 workInProgress.effectTag |= Update;
7454 }
7455 } else {
7456 // If an update was already in progress, we should schedule an Update
7457 // effect even though we're bailing out, so that cWU/cDU are called.
7458 if (typeof instance.componentDidUpdate === 'function') {
7459 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7460 workInProgress.effectTag |= Update;
7461 }
7462 }
7463
7464 // If shouldComponentUpdate returned false, we should still update the
7465 // memoized props/state to indicate that this work can be reused.
7466 memoizeProps(workInProgress, newProps);
7467 memoizeState(workInProgress, newState);
7468 }
7469
7470 // Update the existing instance's state, props, and context pointers even
7471 // if shouldComponentUpdate returns false.
7472 instance.props = newProps;
7473 instance.state = newState;
7474 instance.context = newContext;
7475
7476 return shouldUpdate;
7477 }
7478
7479 return {
7480 adoptClassInstance: adoptClassInstance,
7481 callGetDerivedStateFromProps: callGetDerivedStateFromProps,
7482 constructClassInstance: constructClassInstance,
7483 mountClassInstance: mountClassInstance,
7484 // resumeMountClassInstance,
7485 updateClassInstance: updateClassInstance
7486 };
7487};
7488
7489var getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
7490
7491
7492var didWarnAboutMaps = void 0;
7493var ownerHasKeyUseWarning = void 0;
7494var ownerHasFunctionTypeWarning = void 0;
7495var warnForMissingKey = function (child) {};
7496
7497{
7498 didWarnAboutMaps = false;
7499 /**
7500 * Warn if there's no key explicitly set on dynamic arrays of children or
7501 * object keys are not valid. This allows us to keep track of children between
7502 * updates.
7503 */
7504 ownerHasKeyUseWarning = {};
7505 ownerHasFunctionTypeWarning = {};
7506
7507 warnForMissingKey = function (child) {
7508 if (child === null || typeof child !== 'object') {
7509 return;
7510 }
7511 if (!child._store || child._store.validated || child.key != null) {
7512 return;
7513 }
7514 !(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;
7515 child._store.validated = true;
7516
7517 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() || '');
7518 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
7519 return;
7520 }
7521 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
7522
7523 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());
7524 };
7525}
7526
7527var isArray$1 = Array.isArray;
7528
7529function coerceRef(current, element) {
7530 var mixedRef = element.ref;
7531 if (mixedRef !== null && typeof mixedRef !== 'function') {
7532 if (element._owner) {
7533 var owner = element._owner;
7534 var inst = void 0;
7535 if (owner) {
7536 var ownerFiber = owner;
7537 !(ownerFiber.tag === ClassComponent) ? invariant_1(false, 'Stateless function components cannot have refs.') : void 0;
7538 inst = ownerFiber.stateNode;
7539 }
7540 !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;
7541 var stringRef = '' + mixedRef;
7542 // Check if previous string ref matches new string ref
7543 if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
7544 return current.ref;
7545 }
7546 var ref = function (value) {
7547 var refs = inst.refs === emptyObject_1 ? inst.refs = {} : inst.refs;
7548 if (value === null) {
7549 delete refs[stringRef];
7550 } else {
7551 refs[stringRef] = value;
7552 }
7553 };
7554 ref._stringRef = stringRef;
7555 return ref;
7556 } else {
7557 !(typeof mixedRef === 'string') ? invariant_1(false, 'Expected ref to be a function or a string.') : void 0;
7558 !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;
7559 }
7560 }
7561 return mixedRef;
7562}
7563
7564function throwOnInvalidObjectType(returnFiber, newChild) {
7565 if (returnFiber.type !== 'textarea') {
7566 var addendum = '';
7567 {
7568 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$2() || '');
7569 }
7570 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);
7571 }
7572}
7573
7574function warnOnFunctionType() {
7575 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() || '');
7576
7577 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
7578 return;
7579 }
7580 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
7581
7582 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() || '');
7583}
7584
7585// This wrapper function exists because I expect to clone the code in each path
7586// to be able to optimize each path individually by branching early. This needs
7587// a compiler or we can do it manually. Helpers that don't need this branching
7588// live outside of this function.
7589function ChildReconciler(shouldTrackSideEffects) {
7590 function deleteChild(returnFiber, childToDelete) {
7591 if (!shouldTrackSideEffects) {
7592 // Noop.
7593 return;
7594 }
7595 // Deletions are added in reversed order so we add it to the front.
7596 // At this point, the return fiber's effect list is empty except for
7597 // deletions, so we can just append the deletion to the list. The remaining
7598 // effects aren't added until the complete phase. Once we implement
7599 // resuming, this may not be true.
7600 var last = returnFiber.lastEffect;
7601 if (last !== null) {
7602 last.nextEffect = childToDelete;
7603 returnFiber.lastEffect = childToDelete;
7604 } else {
7605 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7606 }
7607 childToDelete.nextEffect = null;
7608 childToDelete.effectTag = Deletion;
7609 }
7610
7611 function deleteRemainingChildren(returnFiber, currentFirstChild) {
7612 if (!shouldTrackSideEffects) {
7613 // Noop.
7614 return null;
7615 }
7616
7617 // TODO: For the shouldClone case, this could be micro-optimized a bit by
7618 // assuming that after the first child we've already added everything.
7619 var childToDelete = currentFirstChild;
7620 while (childToDelete !== null) {
7621 deleteChild(returnFiber, childToDelete);
7622 childToDelete = childToDelete.sibling;
7623 }
7624 return null;
7625 }
7626
7627 function mapRemainingChildren(returnFiber, currentFirstChild) {
7628 // Add the remaining children to a temporary map so that we can find them by
7629 // keys quickly. Implicit (null) keys get added to this set with their index
7630 var existingChildren = new Map();
7631
7632 var existingChild = currentFirstChild;
7633 while (existingChild !== null) {
7634 if (existingChild.key !== null) {
7635 existingChildren.set(existingChild.key, existingChild);
7636 } else {
7637 existingChildren.set(existingChild.index, existingChild);
7638 }
7639 existingChild = existingChild.sibling;
7640 }
7641 return existingChildren;
7642 }
7643
7644 function useFiber(fiber, pendingProps, expirationTime) {
7645 // We currently set sibling to null and index to 0 here because it is easy
7646 // to forget to do before returning it. E.g. for the single child case.
7647 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
7648 clone.index = 0;
7649 clone.sibling = null;
7650 return clone;
7651 }
7652
7653 function placeChild(newFiber, lastPlacedIndex, newIndex) {
7654 newFiber.index = newIndex;
7655 if (!shouldTrackSideEffects) {
7656 // Noop.
7657 return lastPlacedIndex;
7658 }
7659 var current = newFiber.alternate;
7660 if (current !== null) {
7661 var oldIndex = current.index;
7662 if (oldIndex < lastPlacedIndex) {
7663 // This is a move.
7664 newFiber.effectTag = Placement;
7665 return lastPlacedIndex;
7666 } else {
7667 // This item can stay in place.
7668 return oldIndex;
7669 }
7670 } else {
7671 // This is an insertion.
7672 newFiber.effectTag = Placement;
7673 return lastPlacedIndex;
7674 }
7675 }
7676
7677 function placeSingleChild(newFiber) {
7678 // This is simpler for the single child case. We only need to do a
7679 // placement for inserting new children.
7680 if (shouldTrackSideEffects && newFiber.alternate === null) {
7681 newFiber.effectTag = Placement;
7682 }
7683 return newFiber;
7684 }
7685
7686 function updateTextNode(returnFiber, current, textContent, expirationTime) {
7687 if (current === null || current.tag !== HostText) {
7688 // Insert
7689 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
7690 created['return'] = returnFiber;
7691 return created;
7692 } else {
7693 // Update
7694 var existing = useFiber(current, textContent, expirationTime);
7695 existing['return'] = returnFiber;
7696 return existing;
7697 }
7698 }
7699
7700 function updateElement(returnFiber, current, element, expirationTime) {
7701 if (current !== null && current.type === element.type) {
7702 // Move based on index
7703 var existing = useFiber(current, element.props, expirationTime);
7704 existing.ref = coerceRef(current, element);
7705 existing['return'] = returnFiber;
7706 {
7707 existing._debugSource = element._source;
7708 existing._debugOwner = element._owner;
7709 }
7710 return existing;
7711 } else {
7712 // Insert
7713 var created = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
7714 created.ref = coerceRef(current, element);
7715 created['return'] = returnFiber;
7716 return created;
7717 }
7718 }
7719
7720 function updatePortal(returnFiber, current, portal, expirationTime) {
7721 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
7722 // Insert
7723 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
7724 created['return'] = returnFiber;
7725 return created;
7726 } else {
7727 // Update
7728 var existing = useFiber(current, portal.children || [], expirationTime);
7729 existing['return'] = returnFiber;
7730 return existing;
7731 }
7732 }
7733
7734 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
7735 if (current === null || current.tag !== Fragment) {
7736 // Insert
7737 var created = createFiberFromFragment(fragment, returnFiber.internalContextTag, expirationTime, key);
7738 created['return'] = returnFiber;
7739 return created;
7740 } else {
7741 // Update
7742 var existing = useFiber(current, fragment, expirationTime);
7743 existing['return'] = returnFiber;
7744 return existing;
7745 }
7746 }
7747
7748 function createChild(returnFiber, newChild, expirationTime) {
7749 if (typeof newChild === 'string' || typeof newChild === 'number') {
7750 // Text nodes don't have keys. If the previous node is implicitly keyed
7751 // we can continue to replace it without aborting even if it is not a text
7752 // node.
7753 var created = createFiberFromText('' + newChild, returnFiber.internalContextTag, expirationTime);
7754 created['return'] = returnFiber;
7755 return created;
7756 }
7757
7758 if (typeof newChild === 'object' && newChild !== null) {
7759 switch (newChild.$$typeof) {
7760 case REACT_ELEMENT_TYPE:
7761 {
7762 var _created = createFiberFromElement(newChild, returnFiber.internalContextTag, expirationTime);
7763 _created.ref = coerceRef(null, newChild);
7764 _created['return'] = returnFiber;
7765 return _created;
7766 }
7767 case REACT_PORTAL_TYPE:
7768 {
7769 var _created2 = createFiberFromPortal(newChild, returnFiber.internalContextTag, expirationTime);
7770 _created2['return'] = returnFiber;
7771 return _created2;
7772 }
7773 }
7774
7775 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7776 var _created3 = createFiberFromFragment(newChild, returnFiber.internalContextTag, expirationTime, null);
7777 _created3['return'] = returnFiber;
7778 return _created3;
7779 }
7780
7781 throwOnInvalidObjectType(returnFiber, newChild);
7782 }
7783
7784 {
7785 if (typeof newChild === 'function') {
7786 warnOnFunctionType();
7787 }
7788 }
7789
7790 return null;
7791 }
7792
7793 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
7794 // Update the fiber if the keys match, otherwise return null.
7795
7796 var key = oldFiber !== null ? oldFiber.key : null;
7797
7798 if (typeof newChild === 'string' || typeof newChild === 'number') {
7799 // Text nodes don't have keys. If the previous node is implicitly keyed
7800 // we can continue to replace it without aborting even if it is not a text
7801 // node.
7802 if (key !== null) {
7803 return null;
7804 }
7805 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
7806 }
7807
7808 if (typeof newChild === 'object' && newChild !== null) {
7809 switch (newChild.$$typeof) {
7810 case REACT_ELEMENT_TYPE:
7811 {
7812 if (newChild.key === key) {
7813 if (newChild.type === REACT_FRAGMENT_TYPE) {
7814 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
7815 }
7816 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
7817 } else {
7818 return null;
7819 }
7820 }
7821 case REACT_PORTAL_TYPE:
7822 {
7823 if (newChild.key === key) {
7824 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
7825 } else {
7826 return null;
7827 }
7828 }
7829 }
7830
7831 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7832 if (key !== null) {
7833 return null;
7834 }
7835
7836 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
7837 }
7838
7839 throwOnInvalidObjectType(returnFiber, newChild);
7840 }
7841
7842 {
7843 if (typeof newChild === 'function') {
7844 warnOnFunctionType();
7845 }
7846 }
7847
7848 return null;
7849 }
7850
7851 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
7852 if (typeof newChild === 'string' || typeof newChild === 'number') {
7853 // Text nodes don't have keys, so we neither have to check the old nor
7854 // new node for the key. If both are text nodes, they match.
7855 var matchedFiber = existingChildren.get(newIdx) || null;
7856 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
7857 }
7858
7859 if (typeof newChild === 'object' && newChild !== null) {
7860 switch (newChild.$$typeof) {
7861 case REACT_ELEMENT_TYPE:
7862 {
7863 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7864 if (newChild.type === REACT_FRAGMENT_TYPE) {
7865 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
7866 }
7867 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
7868 }
7869 case REACT_PORTAL_TYPE:
7870 {
7871 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7872 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
7873 }
7874 }
7875
7876 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7877 var _matchedFiber3 = existingChildren.get(newIdx) || null;
7878 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
7879 }
7880
7881 throwOnInvalidObjectType(returnFiber, newChild);
7882 }
7883
7884 {
7885 if (typeof newChild === 'function') {
7886 warnOnFunctionType();
7887 }
7888 }
7889
7890 return null;
7891 }
7892
7893 /**
7894 * Warns if there is a duplicate or missing key
7895 */
7896 function warnOnInvalidKey(child, knownKeys) {
7897 {
7898 if (typeof child !== 'object' || child === null) {
7899 return knownKeys;
7900 }
7901 switch (child.$$typeof) {
7902 case REACT_ELEMENT_TYPE:
7903 case REACT_PORTAL_TYPE:
7904 warnForMissingKey(child);
7905 var key = child.key;
7906 if (typeof key !== 'string') {
7907 break;
7908 }
7909 if (knownKeys === null) {
7910 knownKeys = new Set();
7911 knownKeys.add(key);
7912 break;
7913 }
7914 if (!knownKeys.has(key)) {
7915 knownKeys.add(key);
7916 break;
7917 }
7918 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());
7919 break;
7920 default:
7921 break;
7922 }
7923 }
7924 return knownKeys;
7925 }
7926
7927 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
7928 // This algorithm can't optimize by searching from boths ends since we
7929 // don't have backpointers on fibers. I'm trying to see how far we can get
7930 // with that model. If it ends up not being worth the tradeoffs, we can
7931 // add it later.
7932
7933 // Even with a two ended optimization, we'd want to optimize for the case
7934 // where there are few changes and brute force the comparison instead of
7935 // going for the Map. It'd like to explore hitting that path first in
7936 // forward-only mode and only go for the Map once we notice that we need
7937 // lots of look ahead. This doesn't handle reversal as well as two ended
7938 // search but that's unusual. Besides, for the two ended optimization to
7939 // work on Iterables, we'd need to copy the whole set.
7940
7941 // In this first iteration, we'll just live with hitting the bad case
7942 // (adding everything to a Map) in for every insert/move.
7943
7944 // If you change this code, also update reconcileChildrenIterator() which
7945 // uses the same algorithm.
7946
7947 {
7948 // First, validate keys.
7949 var knownKeys = null;
7950 for (var i = 0; i < newChildren.length; i++) {
7951 var child = newChildren[i];
7952 knownKeys = warnOnInvalidKey(child, knownKeys);
7953 }
7954 }
7955
7956 var resultingFirstChild = null;
7957 var previousNewFiber = null;
7958
7959 var oldFiber = currentFirstChild;
7960 var lastPlacedIndex = 0;
7961 var newIdx = 0;
7962 var nextOldFiber = null;
7963 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
7964 if (oldFiber.index > newIdx) {
7965 nextOldFiber = oldFiber;
7966 oldFiber = null;
7967 } else {
7968 nextOldFiber = oldFiber.sibling;
7969 }
7970 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
7971 if (newFiber === null) {
7972 // TODO: This breaks on empty slots like null children. That's
7973 // unfortunate because it triggers the slow path all the time. We need
7974 // a better way to communicate whether this was a miss or null,
7975 // boolean, undefined, etc.
7976 if (oldFiber === null) {
7977 oldFiber = nextOldFiber;
7978 }
7979 break;
7980 }
7981 if (shouldTrackSideEffects) {
7982 if (oldFiber && newFiber.alternate === null) {
7983 // We matched the slot, but we didn't reuse the existing fiber, so we
7984 // need to delete the existing child.
7985 deleteChild(returnFiber, oldFiber);
7986 }
7987 }
7988 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
7989 if (previousNewFiber === null) {
7990 // TODO: Move out of the loop. This only happens for the first run.
7991 resultingFirstChild = newFiber;
7992 } else {
7993 // TODO: Defer siblings if we're not at the right index for this slot.
7994 // I.e. if we had null values before, then we want to defer this
7995 // for each null value. However, we also don't want to call updateSlot
7996 // with the previous one.
7997 previousNewFiber.sibling = newFiber;
7998 }
7999 previousNewFiber = newFiber;
8000 oldFiber = nextOldFiber;
8001 }
8002
8003 if (newIdx === newChildren.length) {
8004 // We've reached the end of the new children. We can delete the rest.
8005 deleteRemainingChildren(returnFiber, oldFiber);
8006 return resultingFirstChild;
8007 }
8008
8009 if (oldFiber === null) {
8010 // If we don't have any more existing children we can choose a fast path
8011 // since the rest will all be insertions.
8012 for (; newIdx < newChildren.length; newIdx++) {
8013 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
8014 if (!_newFiber) {
8015 continue;
8016 }
8017 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
8018 if (previousNewFiber === null) {
8019 // TODO: Move out of the loop. This only happens for the first run.
8020 resultingFirstChild = _newFiber;
8021 } else {
8022 previousNewFiber.sibling = _newFiber;
8023 }
8024 previousNewFiber = _newFiber;
8025 }
8026 return resultingFirstChild;
8027 }
8028
8029 // Add all children to a key map for quick lookups.
8030 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8031
8032 // Keep scanning and use the map to restore deleted items as moves.
8033 for (; newIdx < newChildren.length; newIdx++) {
8034 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
8035 if (_newFiber2) {
8036 if (shouldTrackSideEffects) {
8037 if (_newFiber2.alternate !== null) {
8038 // The new fiber is a work in progress, but if there exists a
8039 // current, that means that we reused the fiber. We need to delete
8040 // it from the child list so that we don't add it to the deletion
8041 // list.
8042 existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key);
8043 }
8044 }
8045 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
8046 if (previousNewFiber === null) {
8047 resultingFirstChild = _newFiber2;
8048 } else {
8049 previousNewFiber.sibling = _newFiber2;
8050 }
8051 previousNewFiber = _newFiber2;
8052 }
8053 }
8054
8055 if (shouldTrackSideEffects) {
8056 // Any existing children that weren't consumed above were deleted. We need
8057 // to add them to the deletion list.
8058 existingChildren.forEach(function (child) {
8059 return deleteChild(returnFiber, child);
8060 });
8061 }
8062
8063 return resultingFirstChild;
8064 }
8065
8066 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
8067 // This is the same implementation as reconcileChildrenArray(),
8068 // but using the iterator instead.
8069
8070 var iteratorFn = getIteratorFn(newChildrenIterable);
8071 !(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;
8072
8073 {
8074 // Warn about using Maps as children
8075 if (typeof newChildrenIterable.entries === 'function') {
8076 var possibleMap = newChildrenIterable;
8077 if (possibleMap.entries === iteratorFn) {
8078 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());
8079 didWarnAboutMaps = true;
8080 }
8081 }
8082
8083 // First, validate keys.
8084 // We'll get a different iterator later for the main pass.
8085 var _newChildren = iteratorFn.call(newChildrenIterable);
8086 if (_newChildren) {
8087 var knownKeys = null;
8088 var _step = _newChildren.next();
8089 for (; !_step.done; _step = _newChildren.next()) {
8090 var child = _step.value;
8091 knownKeys = warnOnInvalidKey(child, knownKeys);
8092 }
8093 }
8094 }
8095
8096 var newChildren = iteratorFn.call(newChildrenIterable);
8097 !(newChildren != null) ? invariant_1(false, 'An iterable object provided no iterator.') : void 0;
8098
8099 var resultingFirstChild = null;
8100 var previousNewFiber = null;
8101
8102 var oldFiber = currentFirstChild;
8103 var lastPlacedIndex = 0;
8104 var newIdx = 0;
8105 var nextOldFiber = null;
8106
8107 var step = newChildren.next();
8108 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
8109 if (oldFiber.index > newIdx) {
8110 nextOldFiber = oldFiber;
8111 oldFiber = null;
8112 } else {
8113 nextOldFiber = oldFiber.sibling;
8114 }
8115 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
8116 if (newFiber === null) {
8117 // TODO: This breaks on empty slots like null children. That's
8118 // unfortunate because it triggers the slow path all the time. We need
8119 // a better way to communicate whether this was a miss or null,
8120 // boolean, undefined, etc.
8121 if (!oldFiber) {
8122 oldFiber = nextOldFiber;
8123 }
8124 break;
8125 }
8126 if (shouldTrackSideEffects) {
8127 if (oldFiber && newFiber.alternate === null) {
8128 // We matched the slot, but we didn't reuse the existing fiber, so we
8129 // need to delete the existing child.
8130 deleteChild(returnFiber, oldFiber);
8131 }
8132 }
8133 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
8134 if (previousNewFiber === null) {
8135 // TODO: Move out of the loop. This only happens for the first run.
8136 resultingFirstChild = newFiber;
8137 } else {
8138 // TODO: Defer siblings if we're not at the right index for this slot.
8139 // I.e. if we had null values before, then we want to defer this
8140 // for each null value. However, we also don't want to call updateSlot
8141 // with the previous one.
8142 previousNewFiber.sibling = newFiber;
8143 }
8144 previousNewFiber = newFiber;
8145 oldFiber = nextOldFiber;
8146 }
8147
8148 if (step.done) {
8149 // We've reached the end of the new children. We can delete the rest.
8150 deleteRemainingChildren(returnFiber, oldFiber);
8151 return resultingFirstChild;
8152 }
8153
8154 if (oldFiber === null) {
8155 // If we don't have any more existing children we can choose a fast path
8156 // since the rest will all be insertions.
8157 for (; !step.done; newIdx++, step = newChildren.next()) {
8158 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
8159 if (_newFiber3 === null) {
8160 continue;
8161 }
8162 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
8163 if (previousNewFiber === null) {
8164 // TODO: Move out of the loop. This only happens for the first run.
8165 resultingFirstChild = _newFiber3;
8166 } else {
8167 previousNewFiber.sibling = _newFiber3;
8168 }
8169 previousNewFiber = _newFiber3;
8170 }
8171 return resultingFirstChild;
8172 }
8173
8174 // Add all children to a key map for quick lookups.
8175 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8176
8177 // Keep scanning and use the map to restore deleted items as moves.
8178 for (; !step.done; newIdx++, step = newChildren.next()) {
8179 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
8180 if (_newFiber4 !== null) {
8181 if (shouldTrackSideEffects) {
8182 if (_newFiber4.alternate !== null) {
8183 // The new fiber is a work in progress, but if there exists a
8184 // current, that means that we reused the fiber. We need to delete
8185 // it from the child list so that we don't add it to the deletion
8186 // list.
8187 existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key);
8188 }
8189 }
8190 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
8191 if (previousNewFiber === null) {
8192 resultingFirstChild = _newFiber4;
8193 } else {
8194 previousNewFiber.sibling = _newFiber4;
8195 }
8196 previousNewFiber = _newFiber4;
8197 }
8198 }
8199
8200 if (shouldTrackSideEffects) {
8201 // Any existing children that weren't consumed above were deleted. We need
8202 // to add them to the deletion list.
8203 existingChildren.forEach(function (child) {
8204 return deleteChild(returnFiber, child);
8205 });
8206 }
8207
8208 return resultingFirstChild;
8209 }
8210
8211 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
8212 // There's no need to check for keys on text nodes since we don't have a
8213 // way to define them.
8214 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
8215 // We already have an existing node so let's just update it and delete
8216 // the rest.
8217 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
8218 var existing = useFiber(currentFirstChild, textContent, expirationTime);
8219 existing['return'] = returnFiber;
8220 return existing;
8221 }
8222 // The existing first child is not a text node so we need to create one
8223 // and delete the existing ones.
8224 deleteRemainingChildren(returnFiber, currentFirstChild);
8225 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
8226 created['return'] = returnFiber;
8227 return created;
8228 }
8229
8230 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
8231 var key = element.key;
8232 var child = currentFirstChild;
8233 while (child !== null) {
8234 // TODO: If key === null and child.key === null, then this only applies to
8235 // the first item in the list.
8236 if (child.key === key) {
8237 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) {
8238 deleteRemainingChildren(returnFiber, child.sibling);
8239 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
8240 existing.ref = coerceRef(child, element);
8241 existing['return'] = returnFiber;
8242 {
8243 existing._debugSource = element._source;
8244 existing._debugOwner = element._owner;
8245 }
8246 return existing;
8247 } else {
8248 deleteRemainingChildren(returnFiber, child);
8249 break;
8250 }
8251 } else {
8252 deleteChild(returnFiber, child);
8253 }
8254 child = child.sibling;
8255 }
8256
8257 if (element.type === REACT_FRAGMENT_TYPE) {
8258 var created = createFiberFromFragment(element.props.children, returnFiber.internalContextTag, expirationTime, element.key);
8259 created['return'] = returnFiber;
8260 return created;
8261 } else {
8262 var _created4 = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
8263 _created4.ref = coerceRef(currentFirstChild, element);
8264 _created4['return'] = returnFiber;
8265 return _created4;
8266 }
8267 }
8268
8269 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
8270 var key = portal.key;
8271 var child = currentFirstChild;
8272 while (child !== null) {
8273 // TODO: If key === null and child.key === null, then this only applies to
8274 // the first item in the list.
8275 if (child.key === key) {
8276 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
8277 deleteRemainingChildren(returnFiber, child.sibling);
8278 var existing = useFiber(child, portal.children || [], expirationTime);
8279 existing['return'] = returnFiber;
8280 return existing;
8281 } else {
8282 deleteRemainingChildren(returnFiber, child);
8283 break;
8284 }
8285 } else {
8286 deleteChild(returnFiber, child);
8287 }
8288 child = child.sibling;
8289 }
8290
8291 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
8292 created['return'] = returnFiber;
8293 return created;
8294 }
8295
8296 // This API will tag the children with the side-effect of the reconciliation
8297 // itself. They will be added to the side-effect list as we pass through the
8298 // children and the parent.
8299 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
8300 // This function is not recursive.
8301 // If the top level item is an array, we treat it as a set of children,
8302 // not as a fragment. Nested arrays on the other hand will be treated as
8303 // fragment nodes. Recursion happens at the normal flow.
8304
8305 // Handle top level unkeyed fragments as if they were arrays.
8306 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
8307 // We treat the ambiguous cases above the same.
8308 if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
8309 newChild = newChild.props.children;
8310 }
8311
8312 // Handle object types
8313 var isObject = typeof newChild === 'object' && newChild !== null;
8314
8315 if (isObject) {
8316 switch (newChild.$$typeof) {
8317 case REACT_ELEMENT_TYPE:
8318 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
8319 case REACT_PORTAL_TYPE:
8320 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
8321 }
8322 }
8323
8324 if (typeof newChild === 'string' || typeof newChild === 'number') {
8325 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
8326 }
8327
8328 if (isArray$1(newChild)) {
8329 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
8330 }
8331
8332 if (getIteratorFn(newChild)) {
8333 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
8334 }
8335
8336 if (isObject) {
8337 throwOnInvalidObjectType(returnFiber, newChild);
8338 }
8339
8340 {
8341 if (typeof newChild === 'function') {
8342 warnOnFunctionType();
8343 }
8344 }
8345 if (typeof newChild === 'undefined') {
8346 // If the new child is undefined, and the return fiber is a composite
8347 // component, throw an error. If Fiber return types are disabled,
8348 // we already threw above.
8349 switch (returnFiber.tag) {
8350 case ClassComponent:
8351 {
8352 {
8353 var instance = returnFiber.stateNode;
8354 if (instance.render._isMockFunction) {
8355 // We allow auto-mocks to proceed as if they're returning null.
8356 break;
8357 }
8358 }
8359 }
8360 // Intentionally fall through to the next case, which handles both
8361 // functions and classes
8362 // eslint-disable-next-lined no-fallthrough
8363 case FunctionalComponent:
8364 {
8365 var Component = returnFiber.type;
8366 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');
8367 }
8368 }
8369 }
8370
8371 // Remaining cases are all treated as empty.
8372 return deleteRemainingChildren(returnFiber, currentFirstChild);
8373 }
8374
8375 return reconcileChildFibers;
8376}
8377
8378var reconcileChildFibers = ChildReconciler(true);
8379var mountChildFibers = ChildReconciler(false);
8380
8381function cloneChildFibers(current, workInProgress) {
8382 !(current === null || workInProgress.child === current.child) ? invariant_1(false, 'Resuming work not yet implemented.') : void 0;
8383
8384 if (workInProgress.child === null) {
8385 return;
8386 }
8387
8388 var currentChild = workInProgress.child;
8389 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8390 workInProgress.child = newChild;
8391
8392 newChild['return'] = workInProgress;
8393 while (currentChild.sibling !== null) {
8394 currentChild = currentChild.sibling;
8395 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8396 newChild['return'] = workInProgress;
8397 }
8398 newChild.sibling = null;
8399}
8400
8401var didWarnAboutBadClass = void 0;
8402var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0;
8403var didWarnAboutStatelessRefs = void 0;
8404
8405{
8406 didWarnAboutBadClass = {};
8407 didWarnAboutGetDerivedStateOnFunctionalComponent = {};
8408 didWarnAboutStatelessRefs = {};
8409}
8410
8411var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber) {
8412 var shouldSetTextContent = config.shouldSetTextContent,
8413 shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree;
8414 var pushHostContext = hostContext.pushHostContext,
8415 pushHostContainer = hostContext.pushHostContainer;
8416 var enterHydrationState = hydrationContext.enterHydrationState,
8417 resetHydrationState = hydrationContext.resetHydrationState,
8418 tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance;
8419
8420 var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState),
8421 adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance,
8422 callGetDerivedStateFromProps = _ReactFiberClassCompo.callGetDerivedStateFromProps,
8423 constructClassInstance = _ReactFiberClassCompo.constructClassInstance,
8424 mountClassInstance = _ReactFiberClassCompo.mountClassInstance,
8425 updateClassInstance = _ReactFiberClassCompo.updateClassInstance;
8426
8427 // TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
8428
8429
8430 function reconcileChildren(current, workInProgress, nextChildren) {
8431 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, workInProgress.expirationTime);
8432 }
8433
8434 function reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime) {
8435 if (current === null) {
8436 // If this is a fresh new component that hasn't been rendered yet, we
8437 // won't update its child set by applying minimal side-effects. Instead,
8438 // we will add them all to the child before it gets rendered. That means
8439 // we can optimize this reconciliation pass by not tracking side-effects.
8440 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8441 } else {
8442 // If the current child is the same as the work in progress, it means that
8443 // we haven't yet started any work on these children. Therefore, we use
8444 // the clone algorithm to create a copy of all the current children.
8445
8446 // If we had any progressed work already, that is invalid at this point so
8447 // let's throw it out.
8448 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8449 }
8450 }
8451
8452 function updateFragment(current, workInProgress) {
8453 var nextChildren = workInProgress.pendingProps;
8454 if (hasContextChanged()) {
8455 // Normally we can bail out on props equality but if context has changed
8456 // we don't do the bailout and we have to reuse existing props instead.
8457 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
8458 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8459 }
8460 reconcileChildren(current, workInProgress, nextChildren);
8461 memoizeProps(workInProgress, nextChildren);
8462 return workInProgress.child;
8463 }
8464
8465 function markRef(current, workInProgress) {
8466 var ref = workInProgress.ref;
8467 if (ref !== null && (!current || current.ref !== ref)) {
8468 // Schedule a Ref effect
8469 workInProgress.effectTag |= Ref;
8470 }
8471 }
8472
8473 function updateFunctionalComponent(current, workInProgress) {
8474 var fn = workInProgress.type;
8475 var nextProps = workInProgress.pendingProps;
8476
8477 if (hasContextChanged()) {
8478 // Normally we can bail out on props equality but if context has changed
8479 // we don't do the bailout and we have to reuse existing props instead.
8480 } else {
8481 if (workInProgress.memoizedProps === nextProps) {
8482 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8483 }
8484 // TODO: consider bringing fn.shouldComponentUpdate() back.
8485 // It used to be here.
8486 }
8487
8488 var unmaskedContext = getUnmaskedContext(workInProgress);
8489 var context = getMaskedContext(workInProgress, unmaskedContext);
8490
8491 var nextChildren = void 0;
8492
8493 {
8494 ReactCurrentOwner.current = workInProgress;
8495 ReactDebugCurrentFiber.setCurrentPhase('render');
8496 nextChildren = fn(nextProps, context);
8497 ReactDebugCurrentFiber.setCurrentPhase(null);
8498 }
8499 // React DevTools reads this flag.
8500 workInProgress.effectTag |= PerformedWork;
8501 reconcileChildren(current, workInProgress, nextChildren);
8502 memoizeProps(workInProgress, nextProps);
8503 return workInProgress.child;
8504 }
8505
8506 function updateClassComponent(current, workInProgress, renderExpirationTime) {
8507 // Push context providers early to prevent context stack mismatches.
8508 // During mounting we don't know the child context yet as the instance doesn't exist.
8509 // We will invalidate the child context in finishClassComponent() right after rendering.
8510 var hasContext = pushContextProvider(workInProgress);
8511
8512 var shouldUpdate = void 0;
8513 if (current === null) {
8514 if (!workInProgress.stateNode) {
8515 // In the initial pass we might need to construct the instance.
8516 constructClassInstance(workInProgress, workInProgress.pendingProps);
8517 mountClassInstance(workInProgress, renderExpirationTime);
8518
8519 // Simulate an async bailout/interruption by invoking lifecycle twice.
8520 // We do this here rather than inside of ReactFiberClassComponent,
8521 // To more realistically simulate the interruption behavior of async,
8522 // Which would never call componentWillMount() twice on the same instance.
8523 if (debugRenderPhaseSideEffects) {
8524 constructClassInstance(workInProgress, workInProgress.pendingProps);
8525 mountClassInstance(workInProgress, renderExpirationTime);
8526 }
8527
8528 shouldUpdate = true;
8529 } else {
8530 invariant_1(false, 'Resuming work not yet implemented.');
8531 // In a resume, we'll already have an instance we can reuse.
8532 // shouldUpdate = resumeMountClassInstance(workInProgress, renderExpirationTime);
8533 }
8534 } else {
8535 shouldUpdate = updateClassInstance(current, workInProgress, renderExpirationTime);
8536 }
8537 return finishClassComponent(current, workInProgress, shouldUpdate, hasContext);
8538 }
8539
8540 function finishClassComponent(current, workInProgress, shouldUpdate, hasContext) {
8541 // Refs should update even if shouldComponentUpdate returns false
8542 markRef(current, workInProgress);
8543
8544 if (!shouldUpdate) {
8545 // Context providers should defer to sCU for rendering
8546 if (hasContext) {
8547 invalidateContextProvider(workInProgress, false);
8548 }
8549
8550 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8551 }
8552
8553 var instance = workInProgress.stateNode;
8554
8555 // Rerender
8556 ReactCurrentOwner.current = workInProgress;
8557 var nextChildren = void 0;
8558 {
8559 ReactDebugCurrentFiber.setCurrentPhase('render');
8560 nextChildren = instance.render();
8561 if (debugRenderPhaseSideEffects) {
8562 instance.render();
8563 }
8564 ReactDebugCurrentFiber.setCurrentPhase(null);
8565 }
8566 // React DevTools reads this flag.
8567 workInProgress.effectTag |= PerformedWork;
8568 reconcileChildren(current, workInProgress, nextChildren);
8569 // Memoize props and state using the values we just used to render.
8570 // TODO: Restructure so we never read values from the instance.
8571 memoizeState(workInProgress, instance.state);
8572 memoizeProps(workInProgress, instance.props);
8573
8574 // The context might have changed so we need to recalculate it.
8575 if (hasContext) {
8576 invalidateContextProvider(workInProgress, true);
8577 }
8578
8579 return workInProgress.child;
8580 }
8581
8582 function pushHostRootContext(workInProgress) {
8583 var root = workInProgress.stateNode;
8584 if (root.pendingContext) {
8585 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8586 } else if (root.context) {
8587 // Should always be set
8588 pushTopLevelContextObject(workInProgress, root.context, false);
8589 }
8590 pushHostContainer(workInProgress, root.containerInfo);
8591 }
8592
8593 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8594 pushHostRootContext(workInProgress);
8595 var updateQueue = workInProgress.updateQueue;
8596 if (updateQueue !== null) {
8597 var prevState = workInProgress.memoizedState;
8598 var state = processUpdateQueue(current, workInProgress, updateQueue, null, null, renderExpirationTime);
8599 if (prevState === state) {
8600 // If the state is the same as before, that's a bailout because we had
8601 // no work that expires at this time.
8602 resetHydrationState();
8603 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8604 }
8605 var element = state.element;
8606 var root = workInProgress.stateNode;
8607 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
8608 // If we don't have any current children this might be the first pass.
8609 // We always try to hydrate. If this isn't a hydration pass there won't
8610 // be any children to hydrate which is effectively the same thing as
8611 // not hydrating.
8612
8613 // This is a bit of a hack. We track the host root as a placement to
8614 // know that we're currently in a mounting state. That way isMounted
8615 // works as expected. We must reset this before committing.
8616 // TODO: Delete this when we delete isMounted and findDOMNode.
8617 workInProgress.effectTag |= Placement;
8618
8619 // Ensure that children mount into this root without tracking
8620 // side-effects. This ensures that we don't store Placement effects on
8621 // nodes that will be hydrated.
8622 workInProgress.child = mountChildFibers(workInProgress, null, element, renderExpirationTime);
8623 } else {
8624 // Otherwise reset hydration state in case we aborted and resumed another
8625 // root.
8626 resetHydrationState();
8627 reconcileChildren(current, workInProgress, element);
8628 }
8629 memoizeState(workInProgress, state);
8630 return workInProgress.child;
8631 }
8632 resetHydrationState();
8633 // If there is no update queue, that's a bailout because the root has no props.
8634 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8635 }
8636
8637 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8638 pushHostContext(workInProgress);
8639
8640 if (current === null) {
8641 tryToClaimNextHydratableInstance(workInProgress);
8642 }
8643
8644 var type = workInProgress.type;
8645 var memoizedProps = workInProgress.memoizedProps;
8646 var nextProps = workInProgress.pendingProps;
8647 var prevProps = current !== null ? current.memoizedProps : null;
8648
8649 if (hasContextChanged()) {
8650 // Normally we can bail out on props equality but if context has changed
8651 // we don't do the bailout and we have to reuse existing props instead.
8652 } else if (memoizedProps === nextProps) {
8653 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8654 }
8655
8656 var nextChildren = nextProps.children;
8657 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8658
8659 if (isDirectTextChild) {
8660 // We special case a direct text child of a host node. This is a common
8661 // case. We won't handle it as a reified child. We will instead handle
8662 // this in the host environment that also have access to this prop. That
8663 // avoids allocating another HostText fiber and traversing it.
8664 nextChildren = null;
8665 } else if (prevProps && shouldSetTextContent(type, prevProps)) {
8666 // If we're switching from a direct text child to a normal child, or to
8667 // empty, we need to schedule the text content to be reset.
8668 workInProgress.effectTag |= ContentReset;
8669 }
8670
8671 markRef(current, workInProgress);
8672
8673 // Check the host config to see if the children are offscreen/hidden.
8674 if (renderExpirationTime !== Never && workInProgress.internalContextTag & AsyncUpdates && shouldDeprioritizeSubtree(type, nextProps)) {
8675 // Down-prioritize the children.
8676 workInProgress.expirationTime = Never;
8677 // Bailout and come back to this fiber later.
8678 return null;
8679 }
8680
8681 reconcileChildren(current, workInProgress, nextChildren);
8682 memoizeProps(workInProgress, nextProps);
8683 return workInProgress.child;
8684 }
8685
8686 function updateHostText(current, workInProgress) {
8687 if (current === null) {
8688 tryToClaimNextHydratableInstance(workInProgress);
8689 }
8690 var nextProps = workInProgress.pendingProps;
8691 memoizeProps(workInProgress, nextProps);
8692 // Nothing to do here. This is terminal. We'll do the completion step
8693 // immediately after.
8694 return null;
8695 }
8696
8697 function mountIndeterminateComponent(current, workInProgress, renderExpirationTime) {
8698 !(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;
8699 var fn = workInProgress.type;
8700 var props = workInProgress.pendingProps;
8701 var unmaskedContext = getUnmaskedContext(workInProgress);
8702 var context = getMaskedContext(workInProgress, unmaskedContext);
8703
8704 var value = void 0;
8705
8706 {
8707 if (fn.prototype && typeof fn.prototype.render === 'function') {
8708 var componentName = getComponentName(workInProgress) || 'Unknown';
8709
8710 if (!didWarnAboutBadClass[componentName]) {
8711 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);
8712 didWarnAboutBadClass[componentName] = true;
8713 }
8714 }
8715 ReactCurrentOwner.current = workInProgress;
8716 value = fn(props, context);
8717 }
8718 // React DevTools reads this flag.
8719 workInProgress.effectTag |= PerformedWork;
8720
8721 if (typeof value === 'object' && value !== null && typeof value.render === 'function') {
8722 var Component = workInProgress.type;
8723
8724 // Proceed under the assumption that this is a class instance
8725 workInProgress.tag = ClassComponent;
8726
8727 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8728
8729 if (typeof Component.getDerivedStateFromProps === 'function') {
8730 var partialState = callGetDerivedStateFromProps(workInProgress, value, props);
8731
8732 if (partialState !== null && partialState !== undefined) {
8733 workInProgress.memoizedState = _assign({}, workInProgress.memoizedState, partialState);
8734 }
8735 }
8736
8737 // Push context providers early to prevent context stack mismatches.
8738 // During mounting we don't know the child context yet as the instance doesn't exist.
8739 // We will invalidate the child context in finishClassComponent() right after rendering.
8740 var hasContext = pushContextProvider(workInProgress);
8741 adoptClassInstance(workInProgress, value);
8742 mountClassInstance(workInProgress, renderExpirationTime);
8743 return finishClassComponent(current, workInProgress, true, hasContext);
8744 } else {
8745 // Proceed under the assumption that this is a functional component
8746 workInProgress.tag = FunctionalComponent;
8747 {
8748 var _Component = workInProgress.type;
8749
8750 if (_Component) {
8751 warning_1(!_Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', _Component.displayName || _Component.name || 'Component');
8752 }
8753 if (workInProgress.ref !== null) {
8754 var info = '';
8755 var ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
8756 if (ownerName) {
8757 info += '\n\nCheck the render method of `' + ownerName + '`.';
8758 }
8759
8760 var warningKey = ownerName || workInProgress._debugID || '';
8761 var debugSource = workInProgress._debugSource;
8762 if (debugSource) {
8763 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8764 }
8765 if (!didWarnAboutStatelessRefs[warningKey]) {
8766 didWarnAboutStatelessRefs[warningKey] = true;
8767 warning_1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber.getCurrentFiberStackAddendum());
8768 }
8769 }
8770
8771 if (typeof fn.getDerivedStateFromProps === 'function') {
8772 var _componentName = getComponentName(workInProgress) || 'Unknown';
8773
8774 if (!didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName]) {
8775 warning_1(false, '%s: Stateless functional components do not support getDerivedStateFromProps.', _componentName);
8776 didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName] = true;
8777 }
8778 }
8779 }
8780 reconcileChildren(current, workInProgress, value);
8781 memoizeProps(workInProgress, props);
8782 return workInProgress.child;
8783 }
8784 }
8785
8786 function updateCallComponent(current, workInProgress, renderExpirationTime) {
8787 var nextProps = workInProgress.pendingProps;
8788 if (hasContextChanged()) {
8789 // Normally we can bail out on props equality but if context has changed
8790 // we don't do the bailout and we have to reuse existing props instead.
8791 } else if (workInProgress.memoizedProps === nextProps) {
8792 nextProps = workInProgress.memoizedProps;
8793 // TODO: When bailing out, we might need to return the stateNode instead
8794 // of the child. To check it for work.
8795 // return bailoutOnAlreadyFinishedWork(current, workInProgress);
8796 }
8797
8798 var nextChildren = nextProps.children;
8799
8800 // The following is a fork of reconcileChildrenAtExpirationTime but using
8801 // stateNode to store the child.
8802 if (current === null) {
8803 workInProgress.stateNode = mountChildFibers(workInProgress, workInProgress.stateNode, nextChildren, renderExpirationTime);
8804 } else {
8805 workInProgress.stateNode = reconcileChildFibers(workInProgress, current.stateNode, nextChildren, renderExpirationTime);
8806 }
8807
8808 memoizeProps(workInProgress, nextProps);
8809 // This doesn't take arbitrary time so we could synchronously just begin
8810 // eagerly do the work of workInProgress.child as an optimization.
8811 return workInProgress.stateNode;
8812 }
8813
8814 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8815 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8816 var nextChildren = workInProgress.pendingProps;
8817 if (hasContextChanged()) {
8818 // Normally we can bail out on props equality but if context has changed
8819 // we don't do the bailout and we have to reuse existing props instead.
8820 } else if (workInProgress.memoizedProps === nextChildren) {
8821 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8822 }
8823
8824 if (current === null) {
8825 // Portals are special because we don't append the children during mount
8826 // but at commit. Therefore we need to track insertions which the normal
8827 // flow doesn't do during mount. This doesn't happen at the root because
8828 // the root always starts with a "current" with a null child.
8829 // TODO: Consider unifying this with how the root works.
8830 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8831 memoizeProps(workInProgress, nextChildren);
8832 } else {
8833 reconcileChildren(current, workInProgress, nextChildren);
8834 memoizeProps(workInProgress, nextChildren);
8835 }
8836 return workInProgress.child;
8837 }
8838
8839 /*
8840 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
8841 let child = firstChild;
8842 do {
8843 // Ensure that the first and last effect of the parent corresponds
8844 // to the children's first and last effect.
8845 if (!returnFiber.firstEffect) {
8846 returnFiber.firstEffect = child.firstEffect;
8847 }
8848 if (child.lastEffect) {
8849 if (returnFiber.lastEffect) {
8850 returnFiber.lastEffect.nextEffect = child.firstEffect;
8851 }
8852 returnFiber.lastEffect = child.lastEffect;
8853 }
8854 } while (child = child.sibling);
8855 }
8856 */
8857
8858 function bailoutOnAlreadyFinishedWork(current, workInProgress) {
8859 cancelWorkTimer(workInProgress);
8860
8861 // TODO: We should ideally be able to bail out early if the children have no
8862 // more work to do. However, since we don't have a separation of this
8863 // Fiber's priority and its children yet - we don't know without doing lots
8864 // of the same work we do anyway. Once we have that separation we can just
8865 // bail out here if the children has no more work at this priority level.
8866 // if (workInProgress.priorityOfChildren <= priorityLevel) {
8867 // // If there are side-effects in these children that have not yet been
8868 // // committed we need to ensure that they get properly transferred up.
8869 // if (current && current.child !== workInProgress.child) {
8870 // reuseChildrenEffects(workInProgress, child);
8871 // }
8872 // return null;
8873 // }
8874
8875 cloneChildFibers(current, workInProgress);
8876 return workInProgress.child;
8877 }
8878
8879 function bailoutOnLowPriority(current, workInProgress) {
8880 cancelWorkTimer(workInProgress);
8881
8882 // TODO: Handle HostComponent tags here as well and call pushHostContext()?
8883 // See PR 8590 discussion for context
8884 switch (workInProgress.tag) {
8885 case HostRoot:
8886 pushHostRootContext(workInProgress);
8887 break;
8888 case ClassComponent:
8889 pushContextProvider(workInProgress);
8890 break;
8891 case HostPortal:
8892 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8893 break;
8894 }
8895 // TODO: What if this is currently in progress?
8896 // How can that happen? How is this not being cloned?
8897 return null;
8898 }
8899
8900 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead
8901 function memoizeProps(workInProgress, nextProps) {
8902 workInProgress.memoizedProps = nextProps;
8903 }
8904
8905 function memoizeState(workInProgress, nextState) {
8906 workInProgress.memoizedState = nextState;
8907 // Don't reset the updateQueue, in case there are pending updates. Resetting
8908 // is handled by processUpdateQueue.
8909 }
8910
8911 function beginWork(current, workInProgress, renderExpirationTime) {
8912 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8913 return bailoutOnLowPriority(current, workInProgress);
8914 }
8915
8916 switch (workInProgress.tag) {
8917 case IndeterminateComponent:
8918 return mountIndeterminateComponent(current, workInProgress, renderExpirationTime);
8919 case FunctionalComponent:
8920 return updateFunctionalComponent(current, workInProgress);
8921 case ClassComponent:
8922 return updateClassComponent(current, workInProgress, renderExpirationTime);
8923 case HostRoot:
8924 return updateHostRoot(current, workInProgress, renderExpirationTime);
8925 case HostComponent:
8926 return updateHostComponent(current, workInProgress, renderExpirationTime);
8927 case HostText:
8928 return updateHostText(current, workInProgress);
8929 case CallHandlerPhase:
8930 // This is a restart. Reset the tag to the initial phase.
8931 workInProgress.tag = CallComponent;
8932 // Intentionally fall through since this is now the same.
8933 case CallComponent:
8934 return updateCallComponent(current, workInProgress, renderExpirationTime);
8935 case ReturnComponent:
8936 // A return component is just a placeholder, we can just run through the
8937 // next one immediately.
8938 return null;
8939 case HostPortal:
8940 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8941 case Fragment:
8942 return updateFragment(current, workInProgress);
8943 default:
8944 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8945 }
8946 }
8947
8948 function beginFailedWork(current, workInProgress, renderExpirationTime) {
8949 // Push context providers here to avoid a push/pop context mismatch.
8950 switch (workInProgress.tag) {
8951 case ClassComponent:
8952 pushContextProvider(workInProgress);
8953 break;
8954 case HostRoot:
8955 pushHostRootContext(workInProgress);
8956 break;
8957 default:
8958 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
8959 }
8960
8961 // Add an error effect so we can handle the error during the commit phase
8962 workInProgress.effectTag |= Err;
8963
8964 // This is a weird case where we do "resume" work ? work that failed on
8965 // our first attempt. Because we no longer have a notion of "progressed
8966 // deletions," reset the child to the current child to make sure we delete
8967 // it again. TODO: Find a better way to handle this, perhaps during a more
8968 // general overhaul of error handling.
8969 if (current === null) {
8970 workInProgress.child = null;
8971 } else if (workInProgress.child !== current.child) {
8972 workInProgress.child = current.child;
8973 }
8974
8975 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8976 return bailoutOnLowPriority(current, workInProgress);
8977 }
8978
8979 // If we don't bail out, we're going be recomputing our children so we need
8980 // to drop our effect list.
8981 workInProgress.firstEffect = null;
8982 workInProgress.lastEffect = null;
8983
8984 // Unmount the current children as if the component rendered null
8985 var nextChildren = null;
8986 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime);
8987
8988 if (workInProgress.tag === ClassComponent) {
8989 var instance = workInProgress.stateNode;
8990 workInProgress.memoizedProps = instance.props;
8991 workInProgress.memoizedState = instance.state;
8992 }
8993
8994 return workInProgress.child;
8995 }
8996
8997 return {
8998 beginWork: beginWork,
8999 beginFailedWork: beginFailedWork
9000 };
9001};
9002
9003var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) {
9004 var createInstance = config.createInstance,
9005 createTextInstance = config.createTextInstance,
9006 appendInitialChild = config.appendInitialChild,
9007 finalizeInitialChildren = config.finalizeInitialChildren,
9008 prepareUpdate = config.prepareUpdate,
9009 mutation = config.mutation,
9010 persistence = config.persistence;
9011 var getRootHostContainer = hostContext.getRootHostContainer,
9012 popHostContext = hostContext.popHostContext,
9013 getHostContext = hostContext.getHostContext,
9014 popHostContainer = hostContext.popHostContainer;
9015 var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance,
9016 prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance,
9017 popHydrationState = hydrationContext.popHydrationState;
9018
9019
9020 function markUpdate(workInProgress) {
9021 // Tag the fiber with an update effect. This turns a Placement into
9022 // an UpdateAndPlacement.
9023 workInProgress.effectTag |= Update;
9024 }
9025
9026 function markRef(workInProgress) {
9027 workInProgress.effectTag |= Ref;
9028 }
9029
9030 function appendAllReturns(returns, workInProgress) {
9031 var node = workInProgress.stateNode;
9032 if (node) {
9033 node['return'] = workInProgress;
9034 }
9035 while (node !== null) {
9036 if (node.tag === HostComponent || node.tag === HostText || node.tag === HostPortal) {
9037 invariant_1(false, 'A call cannot have host component children.');
9038 } else if (node.tag === ReturnComponent) {
9039 returns.push(node.pendingProps.value);
9040 } else if (node.child !== null) {
9041 node.child['return'] = node;
9042 node = node.child;
9043 continue;
9044 }
9045 while (node.sibling === null) {
9046 if (node['return'] === null || node['return'] === workInProgress) {
9047 return;
9048 }
9049 node = node['return'];
9050 }
9051 node.sibling['return'] = node['return'];
9052 node = node.sibling;
9053 }
9054 }
9055
9056 function moveCallToHandlerPhase(current, workInProgress, renderExpirationTime) {
9057 var props = workInProgress.memoizedProps;
9058 !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;
9059
9060 // First step of the call has completed. Now we need to do the second.
9061 // TODO: It would be nice to have a multi stage call represented by a
9062 // single component, or at least tail call optimize nested ones. Currently
9063 // that requires additional fields that we don't want to add to the fiber.
9064 // So this requires nested handlers.
9065 // Note: This doesn't mutate the alternate node. I don't think it needs to
9066 // since this stage is reset for every pass.
9067 workInProgress.tag = CallHandlerPhase;
9068
9069 // Build up the returns.
9070 // TODO: Compare this to a generator or opaque helpers like Children.
9071 var returns = [];
9072 appendAllReturns(returns, workInProgress);
9073 var fn = props.handler;
9074 var childProps = props.props;
9075 var nextChildren = fn(childProps, returns);
9076
9077 var currentFirstChild = current !== null ? current.child : null;
9078 workInProgress.child = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, renderExpirationTime);
9079 return workInProgress.child;
9080 }
9081
9082 function appendAllChildren(parent, workInProgress) {
9083 // We only have the top Fiber that was created but we need recurse down its
9084 // children to find all the terminal nodes.
9085 var node = workInProgress.child;
9086 while (node !== null) {
9087 if (node.tag === HostComponent || node.tag === HostText) {
9088 appendInitialChild(parent, node.stateNode);
9089 } else if (node.tag === HostPortal) {
9090 // If we have a portal child, then we don't want to traverse
9091 // down its children. Instead, we'll get insertions from each child in
9092 // the portal directly.
9093 } else if (node.child !== null) {
9094 node.child['return'] = node;
9095 node = node.child;
9096 continue;
9097 }
9098 if (node === workInProgress) {
9099 return;
9100 }
9101 while (node.sibling === null) {
9102 if (node['return'] === null || node['return'] === workInProgress) {
9103 return;
9104 }
9105 node = node['return'];
9106 }
9107 node.sibling['return'] = node['return'];
9108 node = node.sibling;
9109 }
9110 }
9111
9112 var updateHostContainer = void 0;
9113 var updateHostComponent = void 0;
9114 var updateHostText = void 0;
9115 if (mutation) {
9116 if (enableMutatingReconciler) {
9117 // Mutation mode
9118 updateHostContainer = function (workInProgress) {
9119 // Noop
9120 };
9121 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9122 // TODO: Type this specific to this type of component.
9123 workInProgress.updateQueue = updatePayload;
9124 // If the update payload indicates that there is a change or if there
9125 // is a new ref we mark this as an update. All the work is done in commitWork.
9126 if (updatePayload) {
9127 markUpdate(workInProgress);
9128 }
9129 };
9130 updateHostText = function (current, workInProgress, oldText, newText) {
9131 // If the text differs, mark it as an update. All the work in done in commitWork.
9132 if (oldText !== newText) {
9133 markUpdate(workInProgress);
9134 }
9135 };
9136 } else {
9137 invariant_1(false, 'Mutating reconciler is disabled.');
9138 }
9139 } else if (persistence) {
9140 if (enablePersistentReconciler) {
9141 // Persistent host tree mode
9142 var cloneInstance = persistence.cloneInstance,
9143 createContainerChildSet = persistence.createContainerChildSet,
9144 appendChildToContainerChildSet = persistence.appendChildToContainerChildSet,
9145 finalizeContainerChildren = persistence.finalizeContainerChildren;
9146
9147 // An unfortunate fork of appendAllChildren because we have two different parent types.
9148
9149 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) {
9150 // We only have the top Fiber that was created but we need recurse down its
9151 // children to find all the terminal nodes.
9152 var node = workInProgress.child;
9153 while (node !== null) {
9154 if (node.tag === HostComponent || node.tag === HostText) {
9155 appendChildToContainerChildSet(containerChildSet, node.stateNode);
9156 } else if (node.tag === HostPortal) {
9157 // If we have a portal child, then we don't want to traverse
9158 // down its children. Instead, we'll get insertions from each child in
9159 // the portal directly.
9160 } else if (node.child !== null) {
9161 node.child['return'] = node;
9162 node = node.child;
9163 continue;
9164 }
9165 if (node === workInProgress) {
9166 return;
9167 }
9168 while (node.sibling === null) {
9169 if (node['return'] === null || node['return'] === workInProgress) {
9170 return;
9171 }
9172 node = node['return'];
9173 }
9174 node.sibling['return'] = node['return'];
9175 node = node.sibling;
9176 }
9177 };
9178 updateHostContainer = function (workInProgress) {
9179 var portalOrRoot = workInProgress.stateNode;
9180 var childrenUnchanged = workInProgress.firstEffect === null;
9181 if (childrenUnchanged) {
9182 // No changes, just reuse the existing instance.
9183 } else {
9184 var container = portalOrRoot.containerInfo;
9185 var newChildSet = createContainerChildSet(container);
9186 if (finalizeContainerChildren(container, newChildSet)) {
9187 markUpdate(workInProgress);
9188 }
9189 portalOrRoot.pendingChildren = newChildSet;
9190 // If children might have changed, we have to add them all to the set.
9191 appendAllChildrenToContainer(newChildSet, workInProgress);
9192 // Schedule an update on the container to swap out the container.
9193 markUpdate(workInProgress);
9194 }
9195 };
9196 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9197 // If there are no effects associated with this node, then none of our children had any updates.
9198 // This guarantees that we can reuse all of them.
9199 var childrenUnchanged = workInProgress.firstEffect === null;
9200 var currentInstance = current.stateNode;
9201 if (childrenUnchanged && updatePayload === null) {
9202 // No changes, just reuse the existing instance.
9203 // Note that this might release a previous clone.
9204 workInProgress.stateNode = currentInstance;
9205 } else {
9206 var recyclableInstance = workInProgress.stateNode;
9207 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9208 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9209 markUpdate(workInProgress);
9210 }
9211 workInProgress.stateNode = newInstance;
9212 if (childrenUnchanged) {
9213 // If there are no other effects in this tree, we need to flag this node as having one.
9214 // Even though we're not going to use it for anything.
9215 // Otherwise parents won't know that there are new children to propagate upwards.
9216 markUpdate(workInProgress);
9217 } else {
9218 // If children might have changed, we have to add them all to the set.
9219 appendAllChildren(newInstance, workInProgress);
9220 }
9221 }
9222 };
9223 updateHostText = function (current, workInProgress, oldText, newText) {
9224 if (oldText !== newText) {
9225 // If the text content differs, we'll create a new text instance for it.
9226 var rootContainerInstance = getRootHostContainer();
9227 var currentHostContext = getHostContext();
9228 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9229 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9230 // This lets the parents know that at least one of their children has changed.
9231 markUpdate(workInProgress);
9232 }
9233 };
9234 } else {
9235 invariant_1(false, 'Persistent reconciler is disabled.');
9236 }
9237 } else {
9238 if (enableNoopReconciler) {
9239 // No host operations
9240 updateHostContainer = function (workInProgress) {
9241 // Noop
9242 };
9243 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9244 // Noop
9245 };
9246 updateHostText = function (current, workInProgress, oldText, newText) {
9247 // Noop
9248 };
9249 } else {
9250 invariant_1(false, 'Noop reconciler is disabled.');
9251 }
9252 }
9253
9254 function completeWork(current, workInProgress, renderExpirationTime) {
9255 var newProps = workInProgress.pendingProps;
9256 switch (workInProgress.tag) {
9257 case FunctionalComponent:
9258 return null;
9259 case ClassComponent:
9260 {
9261 // We are leaving this subtree, so pop context if any.
9262 popContextProvider(workInProgress);
9263 return null;
9264 }
9265 case HostRoot:
9266 {
9267 popHostContainer(workInProgress);
9268 popTopLevelContextObject(workInProgress);
9269 var fiberRoot = workInProgress.stateNode;
9270 if (fiberRoot.pendingContext) {
9271 fiberRoot.context = fiberRoot.pendingContext;
9272 fiberRoot.pendingContext = null;
9273 }
9274
9275 if (current === null || current.child === null) {
9276 // If we hydrated, pop so that we can delete any remaining children
9277 // that weren't hydrated.
9278 popHydrationState(workInProgress);
9279 // This resets the hacky state to fix isMounted before committing.
9280 // TODO: Delete this when we delete isMounted and findDOMNode.
9281 workInProgress.effectTag &= ~Placement;
9282 }
9283 updateHostContainer(workInProgress);
9284 return null;
9285 }
9286 case HostComponent:
9287 {
9288 popHostContext(workInProgress);
9289 var rootContainerInstance = getRootHostContainer();
9290 var type = workInProgress.type;
9291 if (current !== null && workInProgress.stateNode != null) {
9292 // If we have an alternate, that means this is an update and we need to
9293 // schedule a side-effect to do the updates.
9294 var oldProps = current.memoizedProps;
9295 // If we get updated because one of our children updated, we don't
9296 // have newProps so we'll have to reuse them.
9297 // TODO: Split the update API as separate for the props vs. children.
9298 // Even better would be if children weren't special cased at all tho.
9299 var instance = workInProgress.stateNode;
9300 var currentHostContext = getHostContext();
9301 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9302
9303 updateHostComponent(current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9304
9305 if (current.ref !== workInProgress.ref) {
9306 markRef(workInProgress);
9307 }
9308 } else {
9309 if (!newProps) {
9310 !(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;
9311 // This can happen when we abort work.
9312 return null;
9313 }
9314
9315 var _currentHostContext = getHostContext();
9316 // TODO: Move createInstance to beginWork and keep it on a context
9317 // "stack" as the parent. Then append children as we go in beginWork
9318 // or completeWork depending on we want to add then top->down or
9319 // bottom->up. Top->down is faster in IE11.
9320 var wasHydrated = popHydrationState(workInProgress);
9321 if (wasHydrated) {
9322 // TODO: Move this and createInstance step into the beginPhase
9323 // to consolidate.
9324 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) {
9325 // If changes to the hydrated node needs to be applied at the
9326 // commit-phase we mark this as such.
9327 markUpdate(workInProgress);
9328 }
9329 } else {
9330 var _instance = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress);
9331
9332 appendAllChildren(_instance, workInProgress);
9333
9334 // Certain renderers require commit-time effects for initial mount.
9335 // (eg DOM renderer supports auto-focus for certain elements).
9336 // Make sure such renderers get scheduled for later work.
9337 if (finalizeInitialChildren(_instance, type, newProps, rootContainerInstance, _currentHostContext)) {
9338 markUpdate(workInProgress);
9339 }
9340 workInProgress.stateNode = _instance;
9341 }
9342
9343 if (workInProgress.ref !== null) {
9344 // If there is a ref on a host node we need to schedule a callback
9345 markRef(workInProgress);
9346 }
9347 }
9348 return null;
9349 }
9350 case HostText:
9351 {
9352 var newText = newProps;
9353 if (current && workInProgress.stateNode != null) {
9354 var oldText = current.memoizedProps;
9355 // If we have an alternate, that means this is an update and we need
9356 // to schedule a side-effect to do the updates.
9357 updateHostText(current, workInProgress, oldText, newText);
9358 } else {
9359 if (typeof newText !== 'string') {
9360 !(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;
9361 // This can happen when we abort work.
9362 return null;
9363 }
9364 var _rootContainerInstance = getRootHostContainer();
9365 var _currentHostContext2 = getHostContext();
9366 var _wasHydrated = popHydrationState(workInProgress);
9367 if (_wasHydrated) {
9368 if (prepareToHydrateHostTextInstance(workInProgress)) {
9369 markUpdate(workInProgress);
9370 }
9371 } else {
9372 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress);
9373 }
9374 }
9375 return null;
9376 }
9377 case CallComponent:
9378 return moveCallToHandlerPhase(current, workInProgress, renderExpirationTime);
9379 case CallHandlerPhase:
9380 // Reset the tag to now be a first phase call.
9381 workInProgress.tag = CallComponent;
9382 return null;
9383 case ReturnComponent:
9384 // Does nothing.
9385 return null;
9386 case Fragment:
9387 return null;
9388 case HostPortal:
9389 popHostContainer(workInProgress);
9390 updateHostContainer(workInProgress);
9391 return null;
9392 // Error cases
9393 case IndeterminateComponent:
9394 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.');
9395 // eslint-disable-next-line no-fallthrough
9396 default:
9397 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9398 }
9399 }
9400
9401 return {
9402 completeWork: completeWork
9403 };
9404};
9405
9406var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback;
9407var hasCaughtError$1 = ReactErrorUtils.hasCaughtError;
9408var clearCaughtError$1 = ReactErrorUtils.clearCaughtError;
9409
9410
9411var ReactFiberCommitWork = function (config, captureError) {
9412 var getPublicInstance = config.getPublicInstance,
9413 mutation = config.mutation,
9414 persistence = config.persistence;
9415
9416
9417 var callComponentWillUnmountWithTimer = function (current, instance) {
9418 startPhaseTimer(current, 'componentWillUnmount');
9419 instance.props = current.memoizedProps;
9420 instance.state = current.memoizedState;
9421 instance.componentWillUnmount();
9422 stopPhaseTimer();
9423 };
9424
9425 // Capture errors so they don't interrupt unmounting.
9426 function safelyCallComponentWillUnmount(current, instance) {
9427 {
9428 invokeGuardedCallback$3(null, callComponentWillUnmountWithTimer, null, current, instance);
9429 if (hasCaughtError$1()) {
9430 var unmountError = clearCaughtError$1();
9431 captureError(current, unmountError);
9432 }
9433 }
9434 }
9435
9436 function safelyDetachRef(current) {
9437 var ref = current.ref;
9438 if (ref !== null) {
9439 {
9440 invokeGuardedCallback$3(null, ref, null, null);
9441 if (hasCaughtError$1()) {
9442 var refError = clearCaughtError$1();
9443 captureError(current, refError);
9444 }
9445 }
9446 }
9447 }
9448
9449 function commitLifeCycles(current, finishedWork) {
9450 switch (finishedWork.tag) {
9451 case ClassComponent:
9452 {
9453 var instance = finishedWork.stateNode;
9454 if (finishedWork.effectTag & Update) {
9455 if (current === null) {
9456 startPhaseTimer(finishedWork, 'componentDidMount');
9457 instance.props = finishedWork.memoizedProps;
9458 instance.state = finishedWork.memoizedState;
9459 instance.componentDidMount();
9460 stopPhaseTimer();
9461 } else {
9462 var prevProps = current.memoizedProps;
9463 var prevState = current.memoizedState;
9464 startPhaseTimer(finishedWork, 'componentDidUpdate');
9465 instance.props = finishedWork.memoizedProps;
9466 instance.state = finishedWork.memoizedState;
9467 instance.componentDidUpdate(prevProps, prevState);
9468 stopPhaseTimer();
9469 }
9470 }
9471 var updateQueue = finishedWork.updateQueue;
9472 if (updateQueue !== null) {
9473 commitCallbacks(updateQueue, instance);
9474 }
9475 return;
9476 }
9477 case HostRoot:
9478 {
9479 var _updateQueue = finishedWork.updateQueue;
9480 if (_updateQueue !== null) {
9481 var _instance = null;
9482 if (finishedWork.child !== null) {
9483 switch (finishedWork.child.tag) {
9484 case HostComponent:
9485 _instance = getPublicInstance(finishedWork.child.stateNode);
9486 break;
9487 case ClassComponent:
9488 _instance = finishedWork.child.stateNode;
9489 break;
9490 }
9491 }
9492 commitCallbacks(_updateQueue, _instance);
9493 }
9494 return;
9495 }
9496 case HostComponent:
9497 {
9498 var _instance2 = finishedWork.stateNode;
9499
9500 // Renderers may schedule work to be done after host components are mounted
9501 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9502 // These effects should only be committed when components are first mounted,
9503 // aka when there is no current/alternate.
9504 if (current === null && finishedWork.effectTag & Update) {
9505 var type = finishedWork.type;
9506 var props = finishedWork.memoizedProps;
9507 commitMount(_instance2, type, props, finishedWork);
9508 }
9509
9510 return;
9511 }
9512 case HostText:
9513 {
9514 // We have no life-cycles associated with text.
9515 return;
9516 }
9517 case HostPortal:
9518 {
9519 // We have no life-cycles associated with portals.
9520 return;
9521 }
9522 default:
9523 {
9524 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.');
9525 }
9526 }
9527 }
9528
9529 function commitAttachRef(finishedWork) {
9530 var ref = finishedWork.ref;
9531 if (ref !== null) {
9532 var instance = finishedWork.stateNode;
9533 switch (finishedWork.tag) {
9534 case HostComponent:
9535 ref(getPublicInstance(instance));
9536 break;
9537 default:
9538 ref(instance);
9539 }
9540 }
9541 }
9542
9543 function commitDetachRef(current) {
9544 var currentRef = current.ref;
9545 if (currentRef !== null) {
9546 currentRef(null);
9547 }
9548 }
9549
9550 // User-originating errors (lifecycles and refs) should not interrupt
9551 // deletion, so don't let them throw. Host-originating errors should
9552 // interrupt deletion, so it's okay
9553 function commitUnmount(current) {
9554 if (typeof onCommitUnmount === 'function') {
9555 onCommitUnmount(current);
9556 }
9557
9558 switch (current.tag) {
9559 case ClassComponent:
9560 {
9561 safelyDetachRef(current);
9562 var instance = current.stateNode;
9563 if (typeof instance.componentWillUnmount === 'function') {
9564 safelyCallComponentWillUnmount(current, instance);
9565 }
9566 return;
9567 }
9568 case HostComponent:
9569 {
9570 safelyDetachRef(current);
9571 return;
9572 }
9573 case CallComponent:
9574 {
9575 commitNestedUnmounts(current.stateNode);
9576 return;
9577 }
9578 case HostPortal:
9579 {
9580 // TODO: this is recursive.
9581 // We are also not using this parent because
9582 // the portal will get pushed immediately.
9583 if (enableMutatingReconciler && mutation) {
9584 unmountHostComponents(current);
9585 } else if (enablePersistentReconciler && persistence) {
9586 emptyPortalContainer(current);
9587 }
9588 return;
9589 }
9590 }
9591 }
9592
9593 function commitNestedUnmounts(root) {
9594 // While we're inside a removed host node we don't want to call
9595 // removeChild on the inner nodes because they're removed by the top
9596 // call anyway. We also want to call componentWillUnmount on all
9597 // composites before this host node is removed from the tree. Therefore
9598 var node = root;
9599 while (true) {
9600 commitUnmount(node);
9601 // Visit children because they may contain more composite or host nodes.
9602 // Skip portals because commitUnmount() currently visits them recursively.
9603 if (node.child !== null && (
9604 // If we use mutation we drill down into portals using commitUnmount above.
9605 // If we don't use mutation we drill down into portals here instead.
9606 !mutation || node.tag !== HostPortal)) {
9607 node.child['return'] = node;
9608 node = node.child;
9609 continue;
9610 }
9611 if (node === root) {
9612 return;
9613 }
9614 while (node.sibling === null) {
9615 if (node['return'] === null || node['return'] === root) {
9616 return;
9617 }
9618 node = node['return'];
9619 }
9620 node.sibling['return'] = node['return'];
9621 node = node.sibling;
9622 }
9623 }
9624
9625 function detachFiber(current) {
9626 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9627 // should clear the child pointer of the parent alternate to let this
9628 // get GC:ed but we don't know which for sure which parent is the current
9629 // one so we'll settle for GC:ing the subtree of this child. This child
9630 // itself will be GC:ed when the parent updates the next time.
9631 current['return'] = null;
9632 current.child = null;
9633 if (current.alternate) {
9634 current.alternate.child = null;
9635 current.alternate['return'] = null;
9636 }
9637 }
9638
9639 var emptyPortalContainer = void 0;
9640
9641 if (!mutation) {
9642 var commitContainer = void 0;
9643 if (persistence) {
9644 var replaceContainerChildren = persistence.replaceContainerChildren,
9645 createContainerChildSet = persistence.createContainerChildSet;
9646
9647 emptyPortalContainer = function (current) {
9648 var portal = current.stateNode;
9649 var containerInfo = portal.containerInfo;
9650
9651 var emptyChildSet = createContainerChildSet(containerInfo);
9652 replaceContainerChildren(containerInfo, emptyChildSet);
9653 };
9654 commitContainer = function (finishedWork) {
9655 switch (finishedWork.tag) {
9656 case ClassComponent:
9657 {
9658 return;
9659 }
9660 case HostComponent:
9661 {
9662 return;
9663 }
9664 case HostText:
9665 {
9666 return;
9667 }
9668 case HostRoot:
9669 case HostPortal:
9670 {
9671 var portalOrRoot = finishedWork.stateNode;
9672 var containerInfo = portalOrRoot.containerInfo,
9673 _pendingChildren = portalOrRoot.pendingChildren;
9674
9675 replaceContainerChildren(containerInfo, _pendingChildren);
9676 return;
9677 }
9678 default:
9679 {
9680 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.');
9681 }
9682 }
9683 };
9684 } else {
9685 commitContainer = function (finishedWork) {
9686 // Noop
9687 };
9688 }
9689 if (enablePersistentReconciler || enableNoopReconciler) {
9690 return {
9691 commitResetTextContent: function (finishedWork) {},
9692 commitPlacement: function (finishedWork) {},
9693 commitDeletion: function (current) {
9694 // Detach refs and call componentWillUnmount() on the whole subtree.
9695 commitNestedUnmounts(current);
9696 detachFiber(current);
9697 },
9698 commitWork: function (current, finishedWork) {
9699 commitContainer(finishedWork);
9700 },
9701
9702 commitLifeCycles: commitLifeCycles,
9703 commitAttachRef: commitAttachRef,
9704 commitDetachRef: commitDetachRef
9705 };
9706 } else if (persistence) {
9707 invariant_1(false, 'Persistent reconciler is disabled.');
9708 } else {
9709 invariant_1(false, 'Noop reconciler is disabled.');
9710 }
9711 }
9712 var commitMount = mutation.commitMount,
9713 commitUpdate = mutation.commitUpdate,
9714 resetTextContent = mutation.resetTextContent,
9715 commitTextUpdate = mutation.commitTextUpdate,
9716 appendChild = mutation.appendChild,
9717 appendChildToContainer = mutation.appendChildToContainer,
9718 insertBefore = mutation.insertBefore,
9719 insertInContainerBefore = mutation.insertInContainerBefore,
9720 removeChild = mutation.removeChild,
9721 removeChildFromContainer = mutation.removeChildFromContainer;
9722
9723
9724 function getHostParentFiber(fiber) {
9725 var parent = fiber['return'];
9726 while (parent !== null) {
9727 if (isHostParent(parent)) {
9728 return parent;
9729 }
9730 parent = parent['return'];
9731 }
9732 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9733 }
9734
9735 function isHostParent(fiber) {
9736 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9737 }
9738
9739 function getHostSibling(fiber) {
9740 // We're going to search forward into the tree until we find a sibling host
9741 // node. Unfortunately, if multiple insertions are done in a row we have to
9742 // search past them. This leads to exponential search for the next sibling.
9743 var node = fiber;
9744 siblings: while (true) {
9745 // If we didn't find anything, let's try the next sibling.
9746 while (node.sibling === null) {
9747 if (node['return'] === null || isHostParent(node['return'])) {
9748 // If we pop out of the root or hit the parent the fiber we are the
9749 // last sibling.
9750 return null;
9751 }
9752 node = node['return'];
9753 }
9754 node.sibling['return'] = node['return'];
9755 node = node.sibling;
9756 while (node.tag !== HostComponent && node.tag !== HostText) {
9757 // If it is not host node and, we might have a host node inside it.
9758 // Try to search down until we find one.
9759 if (node.effectTag & Placement) {
9760 // If we don't have a child, try the siblings instead.
9761 continue siblings;
9762 }
9763 // If we don't have a child, try the siblings instead.
9764 // We also skip portals because they are not part of this host tree.
9765 if (node.child === null || node.tag === HostPortal) {
9766 continue siblings;
9767 } else {
9768 node.child['return'] = node;
9769 node = node.child;
9770 }
9771 }
9772 // Check if this host node is stable or about to be placed.
9773 if (!(node.effectTag & Placement)) {
9774 // Found it!
9775 return node.stateNode;
9776 }
9777 }
9778 }
9779
9780 function commitPlacement(finishedWork) {
9781 // Recursively insert all host nodes into the parent.
9782 var parentFiber = getHostParentFiber(finishedWork);
9783 var parent = void 0;
9784 var isContainer = void 0;
9785 switch (parentFiber.tag) {
9786 case HostComponent:
9787 parent = parentFiber.stateNode;
9788 isContainer = false;
9789 break;
9790 case HostRoot:
9791 parent = parentFiber.stateNode.containerInfo;
9792 isContainer = true;
9793 break;
9794 case HostPortal:
9795 parent = parentFiber.stateNode.containerInfo;
9796 isContainer = true;
9797 break;
9798 default:
9799 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9800 }
9801 if (parentFiber.effectTag & ContentReset) {
9802 // Reset the text content of the parent before doing any insertions
9803 resetTextContent(parent);
9804 // Clear ContentReset from the effect tag
9805 parentFiber.effectTag &= ~ContentReset;
9806 }
9807
9808 var before = getHostSibling(finishedWork);
9809 // We only have the top Fiber that was inserted but we need recurse down its
9810 // children to find all the terminal nodes.
9811 var node = finishedWork;
9812 while (true) {
9813 if (node.tag === HostComponent || node.tag === HostText) {
9814 if (before) {
9815 if (isContainer) {
9816 insertInContainerBefore(parent, node.stateNode, before);
9817 } else {
9818 insertBefore(parent, node.stateNode, before);
9819 }
9820 } else {
9821 if (isContainer) {
9822 appendChildToContainer(parent, node.stateNode);
9823 } else {
9824 appendChild(parent, node.stateNode);
9825 }
9826 }
9827 } else if (node.tag === HostPortal) {
9828 // If the insertion itself is a portal, then we don't want to traverse
9829 // down its children. Instead, we'll get insertions from each child in
9830 // the portal directly.
9831 } else if (node.child !== null) {
9832 node.child['return'] = node;
9833 node = node.child;
9834 continue;
9835 }
9836 if (node === finishedWork) {
9837 return;
9838 }
9839 while (node.sibling === null) {
9840 if (node['return'] === null || node['return'] === finishedWork) {
9841 return;
9842 }
9843 node = node['return'];
9844 }
9845 node.sibling['return'] = node['return'];
9846 node = node.sibling;
9847 }
9848 }
9849
9850 function unmountHostComponents(current) {
9851 // We only have the top Fiber that was inserted but we need recurse down its
9852 var node = current;
9853
9854 // Each iteration, currentParent is populated with node's host parent if not
9855 // currentParentIsValid.
9856 var currentParentIsValid = false;
9857 var currentParent = void 0;
9858 var currentParentIsContainer = void 0;
9859
9860 while (true) {
9861 if (!currentParentIsValid) {
9862 var parent = node['return'];
9863 findParent: while (true) {
9864 !(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;
9865 switch (parent.tag) {
9866 case HostComponent:
9867 currentParent = parent.stateNode;
9868 currentParentIsContainer = false;
9869 break findParent;
9870 case HostRoot:
9871 currentParent = parent.stateNode.containerInfo;
9872 currentParentIsContainer = true;
9873 break findParent;
9874 case HostPortal:
9875 currentParent = parent.stateNode.containerInfo;
9876 currentParentIsContainer = true;
9877 break findParent;
9878 }
9879 parent = parent['return'];
9880 }
9881 currentParentIsValid = true;
9882 }
9883
9884 if (node.tag === HostComponent || node.tag === HostText) {
9885 commitNestedUnmounts(node);
9886 // After all the children have unmounted, it is now safe to remove the
9887 // node from the tree.
9888 if (currentParentIsContainer) {
9889 removeChildFromContainer(currentParent, node.stateNode);
9890 } else {
9891 removeChild(currentParent, node.stateNode);
9892 }
9893 // Don't visit children because we already visited them.
9894 } else if (node.tag === HostPortal) {
9895 // When we go into a portal, it becomes the parent to remove from.
9896 // We will reassign it back when we pop the portal on the way up.
9897 currentParent = node.stateNode.containerInfo;
9898 // Visit children because portals might contain host components.
9899 if (node.child !== null) {
9900 node.child['return'] = node;
9901 node = node.child;
9902 continue;
9903 }
9904 } else {
9905 commitUnmount(node);
9906 // Visit children because we may find more host components below.
9907 if (node.child !== null) {
9908 node.child['return'] = node;
9909 node = node.child;
9910 continue;
9911 }
9912 }
9913 if (node === current) {
9914 return;
9915 }
9916 while (node.sibling === null) {
9917 if (node['return'] === null || node['return'] === current) {
9918 return;
9919 }
9920 node = node['return'];
9921 if (node.tag === HostPortal) {
9922 // When we go out of the portal, we need to restore the parent.
9923 // Since we don't keep a stack of them, we will search for it.
9924 currentParentIsValid = false;
9925 }
9926 }
9927 node.sibling['return'] = node['return'];
9928 node = node.sibling;
9929 }
9930 }
9931
9932 function commitDeletion(current) {
9933 // Recursively delete all host nodes from the parent.
9934 // Detach refs and call componentWillUnmount() on the whole subtree.
9935 unmountHostComponents(current);
9936 detachFiber(current);
9937 }
9938
9939 function commitWork(current, finishedWork) {
9940 switch (finishedWork.tag) {
9941 case ClassComponent:
9942 {
9943 return;
9944 }
9945 case HostComponent:
9946 {
9947 var instance = finishedWork.stateNode;
9948 if (instance != null) {
9949 // Commit the work prepared earlier.
9950 var newProps = finishedWork.memoizedProps;
9951 // For hydration we reuse the update path but we treat the oldProps
9952 // as the newProps. The updatePayload will contain the real change in
9953 // this case.
9954 var oldProps = current !== null ? current.memoizedProps : newProps;
9955 var type = finishedWork.type;
9956 // TODO: Type the updateQueue to be specific to host components.
9957 var updatePayload = finishedWork.updateQueue;
9958 finishedWork.updateQueue = null;
9959 if (updatePayload !== null) {
9960 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
9961 }
9962 }
9963 return;
9964 }
9965 case HostText:
9966 {
9967 !(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;
9968 var textInstance = finishedWork.stateNode;
9969 var newText = finishedWork.memoizedProps;
9970 // For hydration we reuse the update path but we treat the oldProps
9971 // as the newProps. The updatePayload will contain the real change in
9972 // this case.
9973 var oldText = current !== null ? current.memoizedProps : newText;
9974 commitTextUpdate(textInstance, oldText, newText);
9975 return;
9976 }
9977 case HostRoot:
9978 {
9979 return;
9980 }
9981 default:
9982 {
9983 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.');
9984 }
9985 }
9986 }
9987
9988 function commitResetTextContent(current) {
9989 resetTextContent(current.stateNode);
9990 }
9991
9992 if (enableMutatingReconciler) {
9993 return {
9994 commitResetTextContent: commitResetTextContent,
9995 commitPlacement: commitPlacement,
9996 commitDeletion: commitDeletion,
9997 commitWork: commitWork,
9998 commitLifeCycles: commitLifeCycles,
9999 commitAttachRef: commitAttachRef,
10000 commitDetachRef: commitDetachRef
10001 };
10002 } else {
10003 invariant_1(false, 'Mutating reconciler is disabled.');
10004 }
10005};
10006
10007var NO_CONTEXT = {};
10008
10009var ReactFiberHostContext = function (config) {
10010 var getChildHostContext = config.getChildHostContext,
10011 getRootHostContext = config.getRootHostContext;
10012
10013
10014 var contextStackCursor = createCursor(NO_CONTEXT);
10015 var contextFiberStackCursor = createCursor(NO_CONTEXT);
10016 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
10017
10018 function requiredContext(c) {
10019 !(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;
10020 return c;
10021 }
10022
10023 function getRootHostContainer() {
10024 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10025 return rootInstance;
10026 }
10027
10028 function pushHostContainer(fiber, nextRootInstance) {
10029 // Push current root instance onto the stack;
10030 // This allows us to reset root when portals are popped.
10031 push(rootInstanceStackCursor, nextRootInstance, fiber);
10032
10033 var nextRootContext = getRootHostContext(nextRootInstance);
10034
10035 // Track the context and the Fiber that provided it.
10036 // This enables us to pop only Fibers that provide unique contexts.
10037 push(contextFiberStackCursor, fiber, fiber);
10038 push(contextStackCursor, nextRootContext, fiber);
10039 }
10040
10041 function popHostContainer(fiber) {
10042 pop(contextStackCursor, fiber);
10043 pop(contextFiberStackCursor, fiber);
10044 pop(rootInstanceStackCursor, fiber);
10045 }
10046
10047 function getHostContext() {
10048 var context = requiredContext(contextStackCursor.current);
10049 return context;
10050 }
10051
10052 function pushHostContext(fiber) {
10053 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10054 var context = requiredContext(contextStackCursor.current);
10055 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
10056
10057 // Don't push this Fiber's context unless it's unique.
10058 if (context === nextContext) {
10059 return;
10060 }
10061
10062 // Track the context and the Fiber that provided it.
10063 // This enables us to pop only Fibers that provide unique contexts.
10064 push(contextFiberStackCursor, fiber, fiber);
10065 push(contextStackCursor, nextContext, fiber);
10066 }
10067
10068 function popHostContext(fiber) {
10069 // Do not pop unless this Fiber provided the current context.
10070 // pushHostContext() only pushes Fibers that provide unique contexts.
10071 if (contextFiberStackCursor.current !== fiber) {
10072 return;
10073 }
10074
10075 pop(contextStackCursor, fiber);
10076 pop(contextFiberStackCursor, fiber);
10077 }
10078
10079 function resetHostContainer() {
10080 contextStackCursor.current = NO_CONTEXT;
10081 rootInstanceStackCursor.current = NO_CONTEXT;
10082 }
10083
10084 return {
10085 getHostContext: getHostContext,
10086 getRootHostContainer: getRootHostContainer,
10087 popHostContainer: popHostContainer,
10088 popHostContext: popHostContext,
10089 pushHostContainer: pushHostContainer,
10090 pushHostContext: pushHostContext,
10091 resetHostContainer: resetHostContainer
10092 };
10093};
10094
10095var ReactFiberHydrationContext = function (config) {
10096 var shouldSetTextContent = config.shouldSetTextContent,
10097 hydration = config.hydration;
10098
10099 // If this doesn't have hydration mode.
10100
10101 if (!hydration) {
10102 return {
10103 enterHydrationState: function () {
10104 return false;
10105 },
10106 resetHydrationState: function () {},
10107 tryToClaimNextHydratableInstance: function () {},
10108 prepareToHydrateHostInstance: function () {
10109 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10110 },
10111 prepareToHydrateHostTextInstance: function () {
10112 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10113 },
10114 popHydrationState: function (fiber) {
10115 return false;
10116 }
10117 };
10118 }
10119
10120 var canHydrateInstance = hydration.canHydrateInstance,
10121 canHydrateTextInstance = hydration.canHydrateTextInstance,
10122 getNextHydratableSibling = hydration.getNextHydratableSibling,
10123 getFirstHydratableChild = hydration.getFirstHydratableChild,
10124 hydrateInstance = hydration.hydrateInstance,
10125 hydrateTextInstance = hydration.hydrateTextInstance,
10126 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
10127 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
10128 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
10129 didNotHydrateInstance = hydration.didNotHydrateInstance,
10130 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
10131 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
10132 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
10133 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
10134
10135 // The deepest Fiber on the stack involved in a hydration context.
10136 // This may have been an insertion or a hydration.
10137
10138 var hydrationParentFiber = null;
10139 var nextHydratableInstance = null;
10140 var isHydrating = false;
10141
10142 function enterHydrationState(fiber) {
10143 var parentInstance = fiber.stateNode.containerInfo;
10144 nextHydratableInstance = getFirstHydratableChild(parentInstance);
10145 hydrationParentFiber = fiber;
10146 isHydrating = true;
10147 return true;
10148 }
10149
10150 function deleteHydratableInstance(returnFiber, instance) {
10151 {
10152 switch (returnFiber.tag) {
10153 case HostRoot:
10154 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
10155 break;
10156 case HostComponent:
10157 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
10158 break;
10159 }
10160 }
10161
10162 var childToDelete = createFiberFromHostInstanceForDeletion();
10163 childToDelete.stateNode = instance;
10164 childToDelete['return'] = returnFiber;
10165 childToDelete.effectTag = Deletion;
10166
10167 // This might seem like it belongs on progressedFirstDeletion. However,
10168 // these children are not part of the reconciliation list of children.
10169 // Even if we abort and rereconcile the children, that will try to hydrate
10170 // again and the nodes are still in the host tree so these will be
10171 // recreated.
10172 if (returnFiber.lastEffect !== null) {
10173 returnFiber.lastEffect.nextEffect = childToDelete;
10174 returnFiber.lastEffect = childToDelete;
10175 } else {
10176 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
10177 }
10178 }
10179
10180 function insertNonHydratedInstance(returnFiber, fiber) {
10181 fiber.effectTag |= Placement;
10182 {
10183 switch (returnFiber.tag) {
10184 case HostRoot:
10185 {
10186 var parentContainer = returnFiber.stateNode.containerInfo;
10187 switch (fiber.tag) {
10188 case HostComponent:
10189 var type = fiber.type;
10190 var props = fiber.pendingProps;
10191 didNotFindHydratableContainerInstance(parentContainer, type, props);
10192 break;
10193 case HostText:
10194 var text = fiber.pendingProps;
10195 didNotFindHydratableContainerTextInstance(parentContainer, text);
10196 break;
10197 }
10198 break;
10199 }
10200 case HostComponent:
10201 {
10202 var parentType = returnFiber.type;
10203 var parentProps = returnFiber.memoizedProps;
10204 var parentInstance = returnFiber.stateNode;
10205 switch (fiber.tag) {
10206 case HostComponent:
10207 var _type = fiber.type;
10208 var _props = fiber.pendingProps;
10209 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
10210 break;
10211 case HostText:
10212 var _text = fiber.pendingProps;
10213 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
10214 break;
10215 }
10216 break;
10217 }
10218 default:
10219 return;
10220 }
10221 }
10222 }
10223
10224 function tryHydrate(fiber, nextInstance) {
10225 switch (fiber.tag) {
10226 case HostComponent:
10227 {
10228 var type = fiber.type;
10229 var props = fiber.pendingProps;
10230 var instance = canHydrateInstance(nextInstance, type, props);
10231 if (instance !== null) {
10232 fiber.stateNode = instance;
10233 return true;
10234 }
10235 return false;
10236 }
10237 case HostText:
10238 {
10239 var text = fiber.pendingProps;
10240 var textInstance = canHydrateTextInstance(nextInstance, text);
10241 if (textInstance !== null) {
10242 fiber.stateNode = textInstance;
10243 return true;
10244 }
10245 return false;
10246 }
10247 default:
10248 return false;
10249 }
10250 }
10251
10252 function tryToClaimNextHydratableInstance(fiber) {
10253 if (!isHydrating) {
10254 return;
10255 }
10256 var nextInstance = nextHydratableInstance;
10257 if (!nextInstance) {
10258 // Nothing to hydrate. Make it an insertion.
10259 insertNonHydratedInstance(hydrationParentFiber, fiber);
10260 isHydrating = false;
10261 hydrationParentFiber = fiber;
10262 return;
10263 }
10264 if (!tryHydrate(fiber, nextInstance)) {
10265 // If we can't hydrate this instance let's try the next one.
10266 // We use this as a heuristic. It's based on intuition and not data so it
10267 // might be flawed or unnecessary.
10268 nextInstance = getNextHydratableSibling(nextInstance);
10269 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
10270 // Nothing to hydrate. Make it an insertion.
10271 insertNonHydratedInstance(hydrationParentFiber, fiber);
10272 isHydrating = false;
10273 hydrationParentFiber = fiber;
10274 return;
10275 }
10276 // We matched the next one, we'll now assume that the first one was
10277 // superfluous and we'll delete it. Since we can't eagerly delete it
10278 // we'll have to schedule a deletion. To do that, this node needs a dummy
10279 // fiber associated with it.
10280 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
10281 }
10282 hydrationParentFiber = fiber;
10283 nextHydratableInstance = getFirstHydratableChild(nextInstance);
10284 }
10285
10286 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
10287 var instance = fiber.stateNode;
10288 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
10289 // TODO: Type this specific to this type of component.
10290 fiber.updateQueue = updatePayload;
10291 // If the update payload indicates that there is a change or if there
10292 // is a new ref we mark this as an update.
10293 if (updatePayload !== null) {
10294 return true;
10295 }
10296 return false;
10297 }
10298
10299 function prepareToHydrateHostTextInstance(fiber) {
10300 var textInstance = fiber.stateNode;
10301 var textContent = fiber.memoizedProps;
10302 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
10303 {
10304 if (shouldUpdate) {
10305 // We assume that prepareToHydrateHostTextInstance is called in a context where the
10306 // hydration parent is the parent host component of this host text.
10307 var returnFiber = hydrationParentFiber;
10308 if (returnFiber !== null) {
10309 switch (returnFiber.tag) {
10310 case HostRoot:
10311 {
10312 var parentContainer = returnFiber.stateNode.containerInfo;
10313 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
10314 break;
10315 }
10316 case HostComponent:
10317 {
10318 var parentType = returnFiber.type;
10319 var parentProps = returnFiber.memoizedProps;
10320 var parentInstance = returnFiber.stateNode;
10321 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
10322 break;
10323 }
10324 }
10325 }
10326 }
10327 }
10328 return shouldUpdate;
10329 }
10330
10331 function popToNextHostParent(fiber) {
10332 var parent = fiber['return'];
10333 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
10334 parent = parent['return'];
10335 }
10336 hydrationParentFiber = parent;
10337 }
10338
10339 function popHydrationState(fiber) {
10340 if (fiber !== hydrationParentFiber) {
10341 // We're deeper than the current hydration context, inside an inserted
10342 // tree.
10343 return false;
10344 }
10345 if (!isHydrating) {
10346 // If we're not currently hydrating but we're in a hydration context, then
10347 // we were an insertion and now need to pop up reenter hydration of our
10348 // siblings.
10349 popToNextHostParent(fiber);
10350 isHydrating = true;
10351 return false;
10352 }
10353
10354 var type = fiber.type;
10355
10356 // If we have any remaining hydratable nodes, we need to delete them now.
10357 // We only do this deeper than head and body since they tend to have random
10358 // other nodes in them. We also ignore components with pure text content in
10359 // side of them.
10360 // TODO: Better heuristic.
10361 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
10362 var nextInstance = nextHydratableInstance;
10363 while (nextInstance) {
10364 deleteHydratableInstance(fiber, nextInstance);
10365 nextInstance = getNextHydratableSibling(nextInstance);
10366 }
10367 }
10368
10369 popToNextHostParent(fiber);
10370 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
10371 return true;
10372 }
10373
10374 function resetHydrationState() {
10375 hydrationParentFiber = null;
10376 nextHydratableInstance = null;
10377 isHydrating = false;
10378 }
10379
10380 return {
10381 enterHydrationState: enterHydrationState,
10382 resetHydrationState: resetHydrationState,
10383 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
10384 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
10385 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
10386 popHydrationState: popHydrationState
10387 };
10388};
10389
10390// This lets us hook into Fiber to debug what it's doing.
10391// See https://github.com/facebook/react/pull/8033.
10392// This is not part of the public API, not even for React DevTools.
10393// You may only inject a debugTool if you work on React Fiber itself.
10394var ReactFiberInstrumentation = {
10395 debugTool: null
10396};
10397
10398var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10399
10400// This module is forked in different environments.
10401// By default, return `true` to log errors to the console.
10402// Forks can return `false` if this isn't desirable.
10403function showErrorDialog(capturedError) {
10404 return true;
10405}
10406
10407function logCapturedError(capturedError) {
10408 var logError = showErrorDialog(capturedError);
10409
10410 // Allow injected showErrorDialog() to prevent default console.error logging.
10411 // This enables renderers like ReactNative to better manage redbox behavior.
10412 if (logError === false) {
10413 return;
10414 }
10415
10416 var error = capturedError.error;
10417 var suppressLogging = error && error.suppressReactErrorLogging;
10418 if (suppressLogging) {
10419 return;
10420 }
10421
10422 {
10423 var componentName = capturedError.componentName,
10424 componentStack = capturedError.componentStack,
10425 errorBoundaryName = capturedError.errorBoundaryName,
10426 errorBoundaryFound = capturedError.errorBoundaryFound,
10427 willRetry = capturedError.willRetry;
10428
10429
10430 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10431
10432 var errorBoundaryMessage = void 0;
10433 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10434 if (errorBoundaryFound && errorBoundaryName) {
10435 if (willRetry) {
10436 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10437 } else {
10438 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10439 }
10440 } else {
10441 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.';
10442 }
10443 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10444
10445 // In development, we provide our own message with just the component stack.
10446 // We don't include the original error message and JS stack because the browser
10447 // has already printed it. Even if the application swallows the error, it is still
10448 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10449 console.error(combinedMessage);
10450 }
10451}
10452
10453var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
10454var hasCaughtError = ReactErrorUtils.hasCaughtError;
10455var clearCaughtError = ReactErrorUtils.clearCaughtError;
10456
10457
10458var didWarnAboutStateTransition = void 0;
10459var didWarnSetStateChildContext = void 0;
10460var warnAboutUpdateOnUnmounted = void 0;
10461var warnAboutInvalidUpdates = void 0;
10462
10463{
10464 didWarnAboutStateTransition = false;
10465 didWarnSetStateChildContext = false;
10466 var didWarnStateUpdateForUnmountedComponent = {};
10467
10468 warnAboutUpdateOnUnmounted = function (fiber) {
10469 var componentName = getComponentName(fiber) || 'ReactClass';
10470 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10471 return;
10472 }
10473 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);
10474 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10475 };
10476
10477 warnAboutInvalidUpdates = function (instance) {
10478 switch (ReactDebugCurrentFiber.phase) {
10479 case 'getChildContext':
10480 if (didWarnSetStateChildContext) {
10481 return;
10482 }
10483 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10484 didWarnSetStateChildContext = true;
10485 break;
10486 case 'render':
10487 if (didWarnAboutStateTransition) {
10488 return;
10489 }
10490 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`.');
10491 didWarnAboutStateTransition = true;
10492 break;
10493 }
10494 };
10495}
10496
10497var ReactFiberScheduler = function (config) {
10498 var hostContext = ReactFiberHostContext(config);
10499 var hydrationContext = ReactFiberHydrationContext(config);
10500 var popHostContainer = hostContext.popHostContainer,
10501 popHostContext = hostContext.popHostContext,
10502 resetHostContainer = hostContext.resetHostContainer;
10503
10504 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
10505 beginWork = _ReactFiberBeginWork.beginWork,
10506 beginFailedWork = _ReactFiberBeginWork.beginFailedWork;
10507
10508 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
10509 completeWork = _ReactFiberCompleteWo.completeWork;
10510
10511 var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError),
10512 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
10513 commitPlacement = _ReactFiberCommitWork.commitPlacement,
10514 commitDeletion = _ReactFiberCommitWork.commitDeletion,
10515 commitWork = _ReactFiberCommitWork.commitWork,
10516 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
10517 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
10518 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
10519
10520 var now = config.now,
10521 scheduleDeferredCallback = config.scheduleDeferredCallback,
10522 cancelDeferredCallback = config.cancelDeferredCallback,
10523 prepareForCommit = config.prepareForCommit,
10524 resetAfterCommit = config.resetAfterCommit;
10525
10526 // Represents the current time in ms.
10527
10528 var startTime = now();
10529 var mostRecentCurrentTime = msToExpirationTime(0);
10530
10531 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
10532 var lastUniqueAsyncExpiration = 0;
10533
10534 // Represents the expiration time that incoming updates should use. (If this
10535 // is NoWork, use the default strategy: async updates in async mode, sync
10536 // updates in sync mode.)
10537 var expirationContext = NoWork;
10538
10539 var isWorking = false;
10540
10541 // The next work in progress fiber that we're currently working on.
10542 var nextUnitOfWork = null;
10543 var nextRoot = null;
10544 // The time at which we're currently rendering work.
10545 var nextRenderExpirationTime = NoWork;
10546
10547 // The next fiber with an effect that we're currently committing.
10548 var nextEffect = null;
10549
10550 // Keep track of which fibers have captured an error that need to be handled.
10551 // Work is removed from this collection after componentDidCatch is called.
10552 var capturedErrors = null;
10553 // Keep track of which fibers have failed during the current batch of work.
10554 // This is a different set than capturedErrors, because it is not reset until
10555 // the end of the batch. This is needed to propagate errors correctly if a
10556 // subtree fails more than once.
10557 var failedBoundaries = null;
10558 // Error boundaries that captured an error during the current commit.
10559 var commitPhaseBoundaries = null;
10560 var firstUncaughtError = null;
10561 var didFatal = false;
10562
10563 var isCommitting = false;
10564 var isUnmounting = false;
10565
10566 // Used for performance tracking.
10567 var interruptedBy = null;
10568
10569 function resetContextStack() {
10570 // Reset the stack
10571 reset$1();
10572 // Reset the cursors
10573 resetContext();
10574 resetHostContainer();
10575 }
10576
10577 function commitAllHostEffects() {
10578 while (nextEffect !== null) {
10579 {
10580 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
10581 }
10582 recordEffect();
10583
10584 var effectTag = nextEffect.effectTag;
10585 if (effectTag & ContentReset) {
10586 commitResetTextContent(nextEffect);
10587 }
10588
10589 if (effectTag & Ref) {
10590 var current = nextEffect.alternate;
10591 if (current !== null) {
10592 commitDetachRef(current);
10593 }
10594 }
10595
10596 // The following switch statement is only concerned about placement,
10597 // updates, and deletions. To avoid needing to add a case for every
10598 // possible bitmap value, we remove the secondary effects from the
10599 // effect tag and switch on that value.
10600 var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
10601 switch (primaryEffectTag) {
10602 case Placement:
10603 {
10604 commitPlacement(nextEffect);
10605 // Clear the "placement" from effect tag so that we know that this is inserted, before
10606 // any life-cycles like componentDidMount gets called.
10607 // TODO: findDOMNode doesn't rely on this any more but isMounted
10608 // does and isMounted is deprecated anyway so we should be able
10609 // to kill this.
10610 nextEffect.effectTag &= ~Placement;
10611 break;
10612 }
10613 case PlacementAndUpdate:
10614 {
10615 // Placement
10616 commitPlacement(nextEffect);
10617 // Clear the "placement" from effect tag so that we know that this is inserted, before
10618 // any life-cycles like componentDidMount gets called.
10619 nextEffect.effectTag &= ~Placement;
10620
10621 // Update
10622 var _current = nextEffect.alternate;
10623 commitWork(_current, nextEffect);
10624 break;
10625 }
10626 case Update:
10627 {
10628 var _current2 = nextEffect.alternate;
10629 commitWork(_current2, nextEffect);
10630 break;
10631 }
10632 case Deletion:
10633 {
10634 isUnmounting = true;
10635 commitDeletion(nextEffect);
10636 isUnmounting = false;
10637 break;
10638 }
10639 }
10640 nextEffect = nextEffect.nextEffect;
10641 }
10642
10643 {
10644 ReactDebugCurrentFiber.resetCurrentFiber();
10645 }
10646 }
10647
10648 function commitAllLifeCycles() {
10649 while (nextEffect !== null) {
10650 var effectTag = nextEffect.effectTag;
10651
10652 if (effectTag & (Update | Callback)) {
10653 recordEffect();
10654 var current = nextEffect.alternate;
10655 commitLifeCycles(current, nextEffect);
10656 }
10657
10658 if (effectTag & Ref) {
10659 recordEffect();
10660 commitAttachRef(nextEffect);
10661 }
10662
10663 if (effectTag & Err) {
10664 recordEffect();
10665 commitErrorHandling(nextEffect);
10666 }
10667
10668 var next = nextEffect.nextEffect;
10669 // Ensure that we clean these up so that we don't accidentally keep them.
10670 // I'm not actually sure this matters because we can't reset firstEffect
10671 // and lastEffect since they're on every node, not just the effectful
10672 // ones. So we have to clean everything as we reuse nodes anyway.
10673 nextEffect.nextEffect = null;
10674 // Ensure that we reset the effectTag here so that we can rely on effect
10675 // tags to reason about the current life-cycle.
10676 nextEffect = next;
10677 }
10678 }
10679
10680 function commitRoot(finishedWork) {
10681 // We keep track of this so that captureError can collect any boundaries
10682 // that capture an error during the commit phase. The reason these aren't
10683 // local to this function is because errors that occur during cWU are
10684 // captured elsewhere, to prevent the unmount from being interrupted.
10685 isWorking = true;
10686 isCommitting = true;
10687 startCommitTimer();
10688
10689 var root = finishedWork.stateNode;
10690 !(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;
10691 root.isReadyForCommit = false;
10692
10693 // Reset this to null before calling lifecycles
10694 ReactCurrentOwner.current = null;
10695
10696 var firstEffect = void 0;
10697 if (finishedWork.effectTag > PerformedWork) {
10698 // A fiber's effect list consists only of its children, not itself. So if
10699 // the root has an effect, we need to add it to the end of the list. The
10700 // resulting list is the set that would belong to the root's parent, if
10701 // it had one; that is, all the effects in the tree including the root.
10702 if (finishedWork.lastEffect !== null) {
10703 finishedWork.lastEffect.nextEffect = finishedWork;
10704 firstEffect = finishedWork.firstEffect;
10705 } else {
10706 firstEffect = finishedWork;
10707 }
10708 } else {
10709 // There is no effect on the root.
10710 firstEffect = finishedWork.firstEffect;
10711 }
10712
10713 prepareForCommit();
10714
10715 // Commit all the side-effects within a tree. We'll do this in two passes.
10716 // The first pass performs all the host insertions, updates, deletions and
10717 // ref unmounts.
10718 nextEffect = firstEffect;
10719 startCommitHostEffectsTimer();
10720 while (nextEffect !== null) {
10721 var didError = false;
10722 var _error = void 0;
10723 {
10724 invokeGuardedCallback$2(null, commitAllHostEffects, null);
10725 if (hasCaughtError()) {
10726 didError = true;
10727 _error = clearCaughtError();
10728 }
10729 }
10730 if (didError) {
10731 !(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;
10732 captureError(nextEffect, _error);
10733 // Clean-up
10734 if (nextEffect !== null) {
10735 nextEffect = nextEffect.nextEffect;
10736 }
10737 }
10738 }
10739 stopCommitHostEffectsTimer();
10740
10741 resetAfterCommit();
10742
10743 // The work-in-progress tree is now the current tree. This must come after
10744 // the first pass of the commit phase, so that the previous tree is still
10745 // current during componentWillUnmount, but before the second pass, so that
10746 // the finished work is current during componentDidMount/Update.
10747 root.current = finishedWork;
10748
10749 // In the second pass we'll perform all life-cycles and ref callbacks.
10750 // Life-cycles happen as a separate pass so that all placements, updates,
10751 // and deletions in the entire tree have already been invoked.
10752 // This pass also triggers any renderer-specific initial effects.
10753 nextEffect = firstEffect;
10754 startCommitLifeCyclesTimer();
10755 while (nextEffect !== null) {
10756 var _didError = false;
10757 var _error2 = void 0;
10758 {
10759 invokeGuardedCallback$2(null, commitAllLifeCycles, null);
10760 if (hasCaughtError()) {
10761 _didError = true;
10762 _error2 = clearCaughtError();
10763 }
10764 }
10765 if (_didError) {
10766 !(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;
10767 captureError(nextEffect, _error2);
10768 if (nextEffect !== null) {
10769 nextEffect = nextEffect.nextEffect;
10770 }
10771 }
10772 }
10773
10774 isCommitting = false;
10775 isWorking = false;
10776 stopCommitLifeCyclesTimer();
10777 stopCommitTimer();
10778 if (typeof onCommitRoot === 'function') {
10779 onCommitRoot(finishedWork.stateNode);
10780 }
10781 if (true && ReactFiberInstrumentation_1.debugTool) {
10782 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
10783 }
10784
10785 // If we caught any errors during this commit, schedule their boundaries
10786 // to update.
10787 if (commitPhaseBoundaries) {
10788 commitPhaseBoundaries.forEach(scheduleErrorRecovery);
10789 commitPhaseBoundaries = null;
10790 }
10791
10792 if (firstUncaughtError !== null) {
10793 var _error3 = firstUncaughtError;
10794 firstUncaughtError = null;
10795 onUncaughtError(_error3);
10796 }
10797
10798 var remainingTime = root.current.expirationTime;
10799
10800 if (remainingTime === NoWork) {
10801 capturedErrors = null;
10802 failedBoundaries = null;
10803 }
10804
10805 return remainingTime;
10806 }
10807
10808 function resetExpirationTime(workInProgress, renderTime) {
10809 if (renderTime !== Never && workInProgress.expirationTime === Never) {
10810 // The children of this component are hidden. Don't bubble their
10811 // expiration times.
10812 return;
10813 }
10814
10815 // Check for pending updates.
10816 var newExpirationTime = getUpdateExpirationTime(workInProgress);
10817
10818 // TODO: Calls need to visit stateNode
10819
10820 // Bubble up the earliest expiration time.
10821 var child = workInProgress.child;
10822 while (child !== null) {
10823 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
10824 newExpirationTime = child.expirationTime;
10825 }
10826 child = child.sibling;
10827 }
10828 workInProgress.expirationTime = newExpirationTime;
10829 }
10830
10831 function completeUnitOfWork(workInProgress) {
10832 while (true) {
10833 // The current, flushed, state of this fiber is the alternate.
10834 // Ideally nothing should rely on this, but relying on it here
10835 // means that we don't need an additional field on the work in
10836 // progress.
10837 var current = workInProgress.alternate;
10838 {
10839 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10840 }
10841 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
10842 {
10843 ReactDebugCurrentFiber.resetCurrentFiber();
10844 }
10845
10846 var returnFiber = workInProgress['return'];
10847 var siblingFiber = workInProgress.sibling;
10848
10849 resetExpirationTime(workInProgress, nextRenderExpirationTime);
10850
10851 if (next !== null) {
10852 stopWorkTimer(workInProgress);
10853 if (true && ReactFiberInstrumentation_1.debugTool) {
10854 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10855 }
10856 // If completing this work spawned new work, do that next. We'll come
10857 // back here again.
10858 return next;
10859 }
10860
10861 if (returnFiber !== null) {
10862 // Append all the effects of the subtree and this fiber onto the effect
10863 // list of the parent. The completion order of the children affects the
10864 // side-effect order.
10865 if (returnFiber.firstEffect === null) {
10866 returnFiber.firstEffect = workInProgress.firstEffect;
10867 }
10868 if (workInProgress.lastEffect !== null) {
10869 if (returnFiber.lastEffect !== null) {
10870 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
10871 }
10872 returnFiber.lastEffect = workInProgress.lastEffect;
10873 }
10874
10875 // If this fiber had side-effects, we append it AFTER the children's
10876 // side-effects. We can perform certain side-effects earlier if
10877 // needed, by doing multiple passes over the effect list. We don't want
10878 // to schedule our own side-effect on our own list because if end up
10879 // reusing children we'll schedule this effect onto itself since we're
10880 // at the end.
10881 var effectTag = workInProgress.effectTag;
10882 // Skip both NoWork and PerformedWork tags when creating the effect list.
10883 // PerformedWork effect is read by React DevTools but shouldn't be committed.
10884 if (effectTag > PerformedWork) {
10885 if (returnFiber.lastEffect !== null) {
10886 returnFiber.lastEffect.nextEffect = workInProgress;
10887 } else {
10888 returnFiber.firstEffect = workInProgress;
10889 }
10890 returnFiber.lastEffect = workInProgress;
10891 }
10892 }
10893
10894 stopWorkTimer(workInProgress);
10895 if (true && ReactFiberInstrumentation_1.debugTool) {
10896 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10897 }
10898
10899 if (siblingFiber !== null) {
10900 // If there is more work to do in this returnFiber, do that next.
10901 return siblingFiber;
10902 } else if (returnFiber !== null) {
10903 // If there's no more work in this returnFiber. Complete the returnFiber.
10904 workInProgress = returnFiber;
10905 continue;
10906 } else {
10907 // We've reached the root.
10908 var root = workInProgress.stateNode;
10909 root.isReadyForCommit = true;
10910 return null;
10911 }
10912 }
10913
10914 // Without this explicit null return Flow complains of invalid return type
10915 // TODO Remove the above while(true) loop
10916 // eslint-disable-next-line no-unreachable
10917 return null;
10918 }
10919
10920 function performUnitOfWork(workInProgress) {
10921 // The current, flushed, state of this fiber is the alternate.
10922 // Ideally nothing should rely on this, but relying on it here
10923 // means that we don't need an additional field on the work in
10924 // progress.
10925 var current = workInProgress.alternate;
10926
10927 // See if beginning this work spawns more work.
10928 startWorkTimer(workInProgress);
10929 {
10930 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10931 }
10932
10933 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
10934 {
10935 ReactDebugCurrentFiber.resetCurrentFiber();
10936 }
10937 if (true && ReactFiberInstrumentation_1.debugTool) {
10938 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10939 }
10940
10941 if (next === null) {
10942 // If this doesn't spawn new work, complete the current work.
10943 next = completeUnitOfWork(workInProgress);
10944 }
10945
10946 ReactCurrentOwner.current = null;
10947
10948 return next;
10949 }
10950
10951 function performFailedUnitOfWork(workInProgress) {
10952 // The current, flushed, state of this fiber is the alternate.
10953 // Ideally nothing should rely on this, but relying on it here
10954 // means that we don't need an additional field on the work in
10955 // progress.
10956 var current = workInProgress.alternate;
10957
10958 // See if beginning this work spawns more work.
10959 startWorkTimer(workInProgress);
10960 {
10961 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10962 }
10963 var next = beginFailedWork(current, workInProgress, nextRenderExpirationTime);
10964 {
10965 ReactDebugCurrentFiber.resetCurrentFiber();
10966 }
10967 if (true && ReactFiberInstrumentation_1.debugTool) {
10968 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10969 }
10970
10971 if (next === null) {
10972 // If this doesn't spawn new work, complete the current work.
10973 next = completeUnitOfWork(workInProgress);
10974 }
10975
10976 ReactCurrentOwner.current = null;
10977
10978 return next;
10979 }
10980
10981 function workLoop(expirationTime) {
10982 if (capturedErrors !== null) {
10983 // If there are unhandled errors, switch to the slow work loop.
10984 // TODO: How to avoid this check in the fast path? Maybe the renderer
10985 // could keep track of which roots have unhandled errors and call a
10986 // forked version of renderRoot.
10987 slowWorkLoopThatChecksForFailedWork(expirationTime);
10988 return;
10989 }
10990 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10991 return;
10992 }
10993
10994 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10995 // Flush all expired work.
10996 while (nextUnitOfWork !== null) {
10997 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10998 }
10999 } else {
11000 // Flush asynchronous work until the deadline runs out of time.
11001 while (nextUnitOfWork !== null && !shouldYield()) {
11002 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11003 }
11004 }
11005 }
11006
11007 function slowWorkLoopThatChecksForFailedWork(expirationTime) {
11008 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
11009 return;
11010 }
11011
11012 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
11013 // Flush all expired work.
11014 while (nextUnitOfWork !== null) {
11015 if (hasCapturedError(nextUnitOfWork)) {
11016 // Use a forked version of performUnitOfWork
11017 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11018 } else {
11019 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11020 }
11021 }
11022 } else {
11023 // Flush asynchronous work until the deadline runs out of time.
11024 while (nextUnitOfWork !== null && !shouldYield()) {
11025 if (hasCapturedError(nextUnitOfWork)) {
11026 // Use a forked version of performUnitOfWork
11027 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11028 } else {
11029 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11030 }
11031 }
11032 }
11033 }
11034
11035 function renderRootCatchBlock(root, failedWork, boundary, expirationTime) {
11036 // We're going to restart the error boundary that captured the error.
11037 // Conceptually, we're unwinding the stack. We need to unwind the
11038 // context stack, too.
11039 unwindContexts(failedWork, boundary);
11040
11041 // Restart the error boundary using a forked version of
11042 // performUnitOfWork that deletes the boundary's children. The entire
11043 // failed subree will be unmounted. During the commit phase, a special
11044 // lifecycle method is called on the error boundary, which triggers
11045 // a re-render.
11046 nextUnitOfWork = performFailedUnitOfWork(boundary);
11047
11048 // Continue working.
11049 workLoop(expirationTime);
11050 }
11051
11052 function renderRoot(root, expirationTime) {
11053 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11054 isWorking = true;
11055
11056 // We're about to mutate the work-in-progress tree. If the root was pending
11057 // commit, it no longer is: we'll need to complete it again.
11058 root.isReadyForCommit = false;
11059
11060 // Check if we're starting from a fresh stack, or if we're resuming from
11061 // previously yielded work.
11062 if (root !== nextRoot || expirationTime !== nextRenderExpirationTime || nextUnitOfWork === null) {
11063 // Reset the stack and start working from the root.
11064 resetContextStack();
11065 nextRoot = root;
11066 nextRenderExpirationTime = expirationTime;
11067 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, expirationTime);
11068 }
11069
11070 startWorkLoopTimer(nextUnitOfWork);
11071
11072 var didError = false;
11073 var error = null;
11074 {
11075 invokeGuardedCallback$2(null, workLoop, null, expirationTime);
11076 if (hasCaughtError()) {
11077 didError = true;
11078 error = clearCaughtError();
11079 }
11080 }
11081
11082 // An error was thrown during the render phase.
11083 while (didError) {
11084 if (didFatal) {
11085 // This was a fatal error. Don't attempt to recover from it.
11086 firstUncaughtError = error;
11087 break;
11088 }
11089
11090 var failedWork = nextUnitOfWork;
11091 if (failedWork === null) {
11092 // An error was thrown but there's no current unit of work. This can
11093 // happen during the commit phase if there's a bug in the renderer.
11094 didFatal = true;
11095 continue;
11096 }
11097
11098 // "Capture" the error by finding the nearest boundary. If there is no
11099 // error boundary, we use the root.
11100 var boundary = captureError(failedWork, error);
11101 !(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;
11102
11103 if (didFatal) {
11104 // The error we just captured was a fatal error. This happens
11105 // when the error propagates to the root more than once.
11106 continue;
11107 }
11108
11109 didError = false;
11110 error = null;
11111 {
11112 invokeGuardedCallback$2(null, renderRootCatchBlock, null, root, failedWork, boundary, expirationTime);
11113 if (hasCaughtError()) {
11114 didError = true;
11115 error = clearCaughtError();
11116 continue;
11117 }
11118 }
11119 // We're finished working. Exit the error loop.
11120 break;
11121 }
11122
11123 var uncaughtError = firstUncaughtError;
11124
11125 // We're done performing work. Time to clean up.
11126 stopWorkLoopTimer(interruptedBy);
11127 interruptedBy = null;
11128 isWorking = false;
11129 didFatal = false;
11130 firstUncaughtError = null;
11131
11132 if (uncaughtError !== null) {
11133 onUncaughtError(uncaughtError);
11134 }
11135
11136 return root.isReadyForCommit ? root.current.alternate : null;
11137 }
11138
11139 // Returns the boundary that captured the error, or null if the error is ignored
11140 function captureError(failedWork, error) {
11141 // It is no longer valid because we exited the user code.
11142 ReactCurrentOwner.current = null;
11143 {
11144 ReactDebugCurrentFiber.resetCurrentFiber();
11145 }
11146
11147 // Search for the nearest error boundary.
11148 var boundary = null;
11149
11150 // Passed to logCapturedError()
11151 var errorBoundaryFound = false;
11152 var willRetry = false;
11153 var errorBoundaryName = null;
11154
11155 // Host containers are a special case. If the failed work itself is a host
11156 // container, then it acts as its own boundary. In all other cases, we
11157 // ignore the work itself and only search through the parents.
11158 if (failedWork.tag === HostRoot) {
11159 boundary = failedWork;
11160
11161 if (isFailedBoundary(failedWork)) {
11162 // If this root already failed, there must have been an error when
11163 // attempting to unmount it. This is a worst-case scenario and
11164 // should only be possible if there's a bug in the renderer.
11165 didFatal = true;
11166 }
11167 } else {
11168 var node = failedWork['return'];
11169 while (node !== null && boundary === null) {
11170 if (node.tag === ClassComponent) {
11171 var instance = node.stateNode;
11172 if (typeof instance.componentDidCatch === 'function') {
11173 errorBoundaryFound = true;
11174 errorBoundaryName = getComponentName(node);
11175
11176 // Found an error boundary!
11177 boundary = node;
11178 willRetry = true;
11179 }
11180 } else if (node.tag === HostRoot) {
11181 // Treat the root like a no-op error boundary
11182 boundary = node;
11183 }
11184
11185 if (isFailedBoundary(node)) {
11186 // This boundary is already in a failed state.
11187
11188 // If we're currently unmounting, that means this error was
11189 // thrown while unmounting a failed subtree. We should ignore
11190 // the error.
11191 if (isUnmounting) {
11192 return null;
11193 }
11194
11195 // If we're in the commit phase, we should check to see if
11196 // this boundary already captured an error during this commit.
11197 // This case exists because multiple errors can be thrown during
11198 // a single commit without interruption.
11199 if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) {
11200 // If so, we should ignore this error.
11201 return null;
11202 }
11203
11204 // The error should propagate to the next boundary -? we keep looking.
11205 boundary = null;
11206 willRetry = false;
11207 }
11208
11209 node = node['return'];
11210 }
11211 }
11212
11213 if (boundary !== null) {
11214 // Add to the collection of failed boundaries. This lets us know that
11215 // subsequent errors in this subtree should propagate to the next boundary.
11216 if (failedBoundaries === null) {
11217 failedBoundaries = new Set();
11218 }
11219 failedBoundaries.add(boundary);
11220
11221 // This method is unsafe outside of the begin and complete phases.
11222 // We might be in the commit phase when an error is captured.
11223 // The risk is that the return path from this Fiber may not be accurate.
11224 // That risk is acceptable given the benefit of providing users more context.
11225 var _componentStack = getStackAddendumByWorkInProgressFiber(failedWork);
11226 var _componentName = getComponentName(failedWork);
11227
11228 // Add to the collection of captured errors. This is stored as a global
11229 // map of errors and their component stack location keyed by the boundaries
11230 // that capture them. We mostly use this Map as a Set; it's a Map only to
11231 // avoid adding a field to Fiber to store the error.
11232 if (capturedErrors === null) {
11233 capturedErrors = new Map();
11234 }
11235
11236 var capturedError = {
11237 componentName: _componentName,
11238 componentStack: _componentStack,
11239 error: error,
11240 errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
11241 errorBoundaryFound: errorBoundaryFound,
11242 errorBoundaryName: errorBoundaryName,
11243 willRetry: willRetry
11244 };
11245
11246 capturedErrors.set(boundary, capturedError);
11247
11248 try {
11249 logCapturedError(capturedError);
11250 } catch (e) {
11251 // Prevent cycle if logCapturedError() throws.
11252 // A cycle may still occur if logCapturedError renders a component that throws.
11253 var suppressLogging = e && e.suppressReactErrorLogging;
11254 if (!suppressLogging) {
11255 console.error(e);
11256 }
11257 }
11258
11259 // If we're in the commit phase, defer scheduling an update on the
11260 // boundary until after the commit is complete
11261 if (isCommitting) {
11262 if (commitPhaseBoundaries === null) {
11263 commitPhaseBoundaries = new Set();
11264 }
11265 commitPhaseBoundaries.add(boundary);
11266 } else {
11267 // Otherwise, schedule an update now.
11268 // TODO: Is this actually necessary during the render phase? Is it
11269 // possible to unwind and continue rendering at the same priority,
11270 // without corrupting internal state?
11271 scheduleErrorRecovery(boundary);
11272 }
11273 return boundary;
11274 } else if (firstUncaughtError === null) {
11275 // If no boundary is found, we'll need to throw the error
11276 firstUncaughtError = error;
11277 }
11278 return null;
11279 }
11280
11281 function hasCapturedError(fiber) {
11282 // TODO: capturedErrors should store the boundary instance, to avoid needing
11283 // to check the alternate.
11284 return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate));
11285 }
11286
11287 function isFailedBoundary(fiber) {
11288 // TODO: failedBoundaries should store the boundary instance, to avoid
11289 // needing to check the alternate.
11290 return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate));
11291 }
11292
11293 function commitErrorHandling(effectfulFiber) {
11294 var capturedError = void 0;
11295 if (capturedErrors !== null) {
11296 capturedError = capturedErrors.get(effectfulFiber);
11297 capturedErrors['delete'](effectfulFiber);
11298 if (capturedError == null) {
11299 if (effectfulFiber.alternate !== null) {
11300 effectfulFiber = effectfulFiber.alternate;
11301 capturedError = capturedErrors.get(effectfulFiber);
11302 capturedErrors['delete'](effectfulFiber);
11303 }
11304 }
11305 }
11306
11307 !(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;
11308
11309 switch (effectfulFiber.tag) {
11310 case ClassComponent:
11311 var instance = effectfulFiber.stateNode;
11312
11313 var info = {
11314 componentStack: capturedError.componentStack
11315 };
11316
11317 // Allow the boundary to handle the error, usually by scheduling
11318 // an update to itself
11319 instance.componentDidCatch(capturedError.error, info);
11320 return;
11321 case HostRoot:
11322 if (firstUncaughtError === null) {
11323 firstUncaughtError = capturedError.error;
11324 }
11325 return;
11326 default:
11327 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
11328 }
11329 }
11330
11331 function unwindContexts(from, to) {
11332 var node = from;
11333 while (node !== null) {
11334 switch (node.tag) {
11335 case ClassComponent:
11336 popContextProvider(node);
11337 break;
11338 case HostComponent:
11339 popHostContext(node);
11340 break;
11341 case HostRoot:
11342 popHostContainer(node);
11343 break;
11344 case HostPortal:
11345 popHostContainer(node);
11346 break;
11347 }
11348 if (node === to || node.alternate === to) {
11349 stopFailedWorkTimer(node);
11350 break;
11351 } else {
11352 stopWorkTimer(node);
11353 }
11354 node = node['return'];
11355 }
11356 }
11357
11358 function computeAsyncExpiration() {
11359 // Given the current clock time, returns an expiration time. We use rounding
11360 // to batch like updates together.
11361 // Should complete within ~1000ms. 1200ms max.
11362 var currentTime = recalculateCurrentTime();
11363 var expirationMs = 1000;
11364 var bucketSizeMs = 200;
11365 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11366 }
11367
11368 // Creates a unique async expiration time.
11369 function computeUniqueAsyncExpiration() {
11370 var result = computeAsyncExpiration();
11371 if (result <= lastUniqueAsyncExpiration) {
11372 // Since we assume the current time monotonically increases, we only hit
11373 // this branch when computeUniqueAsyncExpiration is fired multiple times
11374 // within a 200ms window (or whatever the async bucket size is).
11375 result = lastUniqueAsyncExpiration + 1;
11376 }
11377 lastUniqueAsyncExpiration = result;
11378 return lastUniqueAsyncExpiration;
11379 }
11380
11381 function computeExpirationForFiber(fiber) {
11382 var expirationTime = void 0;
11383 if (expirationContext !== NoWork) {
11384 // An explicit expiration context was set;
11385 expirationTime = expirationContext;
11386 } else if (isWorking) {
11387 if (isCommitting) {
11388 // Updates that occur during the commit phase should have sync priority
11389 // by default.
11390 expirationTime = Sync;
11391 } else {
11392 // Updates during the render phase should expire at the same time as
11393 // the work that is being rendered.
11394 expirationTime = nextRenderExpirationTime;
11395 }
11396 } else {
11397 // No explicit expiration context was set, and we're not currently
11398 // performing work. Calculate a new expiration time.
11399 if (fiber.internalContextTag & AsyncUpdates) {
11400 // This is an async update
11401 expirationTime = computeAsyncExpiration();
11402 } else {
11403 // This is a sync update
11404 expirationTime = Sync;
11405 }
11406 }
11407 return expirationTime;
11408 }
11409
11410 function scheduleWork(fiber, expirationTime) {
11411 return scheduleWorkImpl(fiber, expirationTime, false);
11412 }
11413
11414 function checkRootNeedsClearing(root, fiber, expirationTime) {
11415 if (!isWorking && root === nextRoot && expirationTime < nextRenderExpirationTime) {
11416 // Restart the root from the top.
11417 if (nextUnitOfWork !== null) {
11418 // This is an interruption. (Used for performance tracking.)
11419 interruptedBy = fiber;
11420 }
11421 nextRoot = null;
11422 nextUnitOfWork = null;
11423 nextRenderExpirationTime = NoWork;
11424 }
11425 }
11426
11427 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
11428 recordScheduleUpdate();
11429
11430 {
11431 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11432 var instance = fiber.stateNode;
11433 warnAboutInvalidUpdates(instance);
11434 }
11435 }
11436
11437 var node = fiber;
11438 while (node !== null) {
11439 // Walk the parent path to the root and update each node's
11440 // expiration time.
11441 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
11442 node.expirationTime = expirationTime;
11443 }
11444 if (node.alternate !== null) {
11445 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
11446 node.alternate.expirationTime = expirationTime;
11447 }
11448 }
11449 if (node['return'] === null) {
11450 if (node.tag === HostRoot) {
11451 var root = node.stateNode;
11452
11453 checkRootNeedsClearing(root, fiber, expirationTime);
11454 requestWork(root, expirationTime);
11455 checkRootNeedsClearing(root, fiber, expirationTime);
11456 } else {
11457 {
11458 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11459 warnAboutUpdateOnUnmounted(fiber);
11460 }
11461 }
11462 return;
11463 }
11464 }
11465 node = node['return'];
11466 }
11467 }
11468
11469 function scheduleErrorRecovery(fiber) {
11470 scheduleWorkImpl(fiber, Sync, true);
11471 }
11472
11473 function recalculateCurrentTime() {
11474 // Subtract initial time so it fits inside 32bits
11475 var ms = now() - startTime;
11476 mostRecentCurrentTime = msToExpirationTime(ms);
11477 return mostRecentCurrentTime;
11478 }
11479
11480 function deferredUpdates(fn) {
11481 var previousExpirationContext = expirationContext;
11482 expirationContext = computeAsyncExpiration();
11483 try {
11484 return fn();
11485 } finally {
11486 expirationContext = previousExpirationContext;
11487 }
11488 }
11489
11490 function syncUpdates(fn) {
11491 var previousExpirationContext = expirationContext;
11492 expirationContext = Sync;
11493 try {
11494 return fn();
11495 } finally {
11496 expirationContext = previousExpirationContext;
11497 }
11498 }
11499
11500 // TODO: Everything below this is written as if it has been lifted to the
11501 // renderers. I'll do this in a follow-up.
11502
11503 // Linked-list of roots
11504 var firstScheduledRoot = null;
11505 var lastScheduledRoot = null;
11506
11507 var callbackExpirationTime = NoWork;
11508 var callbackID = -1;
11509 var isRendering = false;
11510 var nextFlushedRoot = null;
11511 var nextFlushedExpirationTime = NoWork;
11512 var deadlineDidExpire = false;
11513 var hasUnhandledError = false;
11514 var unhandledError = null;
11515 var deadline = null;
11516
11517 var isBatchingUpdates = false;
11518 var isUnbatchingUpdates = false;
11519
11520 var completedBatches = null;
11521
11522 // Use these to prevent an infinite loop of nested updates
11523 var NESTED_UPDATE_LIMIT = 1000;
11524 var nestedUpdateCount = 0;
11525
11526 var timeHeuristicForUnitOfWork = 1;
11527
11528 function scheduleCallbackWithExpiration(expirationTime) {
11529 if (callbackExpirationTime !== NoWork) {
11530 // A callback is already scheduled. Check its expiration time (timeout).
11531 if (expirationTime > callbackExpirationTime) {
11532 // Existing callback has sufficient timeout. Exit.
11533 return;
11534 } else {
11535 // Existing callback has insufficient timeout. Cancel and schedule a
11536 // new one.
11537 cancelDeferredCallback(callbackID);
11538 }
11539 // The request callback timer is already running. Don't start a new one.
11540 } else {
11541 startRequestCallbackTimer();
11542 }
11543
11544 // Compute a timeout for the given expiration time.
11545 var currentMs = now() - startTime;
11546 var expirationMs = expirationTimeToMs(expirationTime);
11547 var timeout = expirationMs - currentMs;
11548
11549 callbackExpirationTime = expirationTime;
11550 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
11551 }
11552
11553 // requestWork is called by the scheduler whenever a root receives an update.
11554 // It's up to the renderer to call renderRoot at some point in the future.
11555 function requestWork(root, expirationTime) {
11556 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
11557 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.');
11558 }
11559
11560 // Add the root to the schedule.
11561 // Check if this root is already part of the schedule.
11562 if (root.nextScheduledRoot === null) {
11563 // This root is not already scheduled. Add it.
11564 root.remainingExpirationTime = expirationTime;
11565 if (lastScheduledRoot === null) {
11566 firstScheduledRoot = lastScheduledRoot = root;
11567 root.nextScheduledRoot = root;
11568 } else {
11569 lastScheduledRoot.nextScheduledRoot = root;
11570 lastScheduledRoot = root;
11571 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11572 }
11573 } else {
11574 // This root is already scheduled, but its priority may have increased.
11575 var remainingExpirationTime = root.remainingExpirationTime;
11576 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
11577 // Update the priority.
11578 root.remainingExpirationTime = expirationTime;
11579 }
11580 }
11581
11582 if (isRendering) {
11583 // Prevent reentrancy. Remaining work will be scheduled at the end of
11584 // the currently rendering batch.
11585 return;
11586 }
11587
11588 if (isBatchingUpdates) {
11589 // Flush work at the end of the batch.
11590 if (isUnbatchingUpdates) {
11591 // ...unless we're inside unbatchedUpdates, in which case we should
11592 // flush it now.
11593 nextFlushedRoot = root;
11594 nextFlushedExpirationTime = Sync;
11595 performWorkOnRoot(root, Sync, recalculateCurrentTime());
11596 }
11597 return;
11598 }
11599
11600 // TODO: Get rid of Sync and use current time?
11601 if (expirationTime === Sync) {
11602 performWork(Sync, null);
11603 } else {
11604 scheduleCallbackWithExpiration(expirationTime);
11605 }
11606 }
11607
11608 function findHighestPriorityRoot() {
11609 var highestPriorityWork = NoWork;
11610 var highestPriorityRoot = null;
11611
11612 if (lastScheduledRoot !== null) {
11613 var previousScheduledRoot = lastScheduledRoot;
11614 var root = firstScheduledRoot;
11615 while (root !== null) {
11616 var remainingExpirationTime = root.remainingExpirationTime;
11617 if (remainingExpirationTime === NoWork) {
11618 // This root no longer has work. Remove it from the scheduler.
11619
11620 // TODO: This check is redudant, but Flow is confused by the branch
11621 // below where we set lastScheduledRoot to null, even though we break
11622 // from the loop right after.
11623 !(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;
11624 if (root === root.nextScheduledRoot) {
11625 // This is the only root in the list.
11626 root.nextScheduledRoot = null;
11627 firstScheduledRoot = lastScheduledRoot = null;
11628 break;
11629 } else if (root === firstScheduledRoot) {
11630 // This is the first root in the list.
11631 var next = root.nextScheduledRoot;
11632 firstScheduledRoot = next;
11633 lastScheduledRoot.nextScheduledRoot = next;
11634 root.nextScheduledRoot = null;
11635 } else if (root === lastScheduledRoot) {
11636 // This is the last root in the list.
11637 lastScheduledRoot = previousScheduledRoot;
11638 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11639 root.nextScheduledRoot = null;
11640 break;
11641 } else {
11642 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
11643 root.nextScheduledRoot = null;
11644 }
11645 root = previousScheduledRoot.nextScheduledRoot;
11646 } else {
11647 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
11648 // Update the priority, if it's higher
11649 highestPriorityWork = remainingExpirationTime;
11650 highestPriorityRoot = root;
11651 }
11652 if (root === lastScheduledRoot) {
11653 break;
11654 }
11655 previousScheduledRoot = root;
11656 root = root.nextScheduledRoot;
11657 }
11658 }
11659 }
11660
11661 // If the next root is the same as the previous root, this is a nested
11662 // update. To prevent an infinite loop, increment the nested update count.
11663 var previousFlushedRoot = nextFlushedRoot;
11664 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot) {
11665 nestedUpdateCount++;
11666 } else {
11667 // Reset whenever we switch roots.
11668 nestedUpdateCount = 0;
11669 }
11670 nextFlushedRoot = highestPriorityRoot;
11671 nextFlushedExpirationTime = highestPriorityWork;
11672 }
11673
11674 function performAsyncWork(dl) {
11675 performWork(NoWork, dl);
11676 }
11677
11678 function performWork(minExpirationTime, dl) {
11679 deadline = dl;
11680
11681 // Keep working on roots until there's no more work, or until the we reach
11682 // the deadline.
11683 findHighestPriorityRoot();
11684
11685 if (enableUserTimingAPI && deadline !== null) {
11686 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
11687 stopRequestCallbackTimer(didExpire);
11688 }
11689
11690 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || nextFlushedExpirationTime <= minExpirationTime) && !deadlineDidExpire) {
11691 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, recalculateCurrentTime());
11692 // Find the next highest priority work.
11693 findHighestPriorityRoot();
11694 }
11695
11696 // We're done flushing work. Either we ran out of time in this callback,
11697 // or there's no more work left with sufficient priority.
11698
11699 // If we're inside a callback, set this to false since we just completed it.
11700 if (deadline !== null) {
11701 callbackExpirationTime = NoWork;
11702 callbackID = -1;
11703 }
11704 // If there's work left over, schedule a new callback.
11705 if (nextFlushedExpirationTime !== NoWork) {
11706 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
11707 }
11708
11709 // Clean-up.
11710 deadline = null;
11711 deadlineDidExpire = false;
11712 nestedUpdateCount = 0;
11713
11714 finishRendering();
11715 }
11716
11717 function flushRoot(root, expirationTime) {
11718 !!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;
11719 // Perform work on root as if the given expiration time is the current time.
11720 // This has the effect of synchronously flushing all work up to and
11721 // including the given time.
11722 performWorkOnRoot(root, expirationTime, expirationTime);
11723 finishRendering();
11724 }
11725
11726 function finishRendering() {
11727 if (completedBatches !== null) {
11728 var batches = completedBatches;
11729 completedBatches = null;
11730 for (var i = 0; i < batches.length; i++) {
11731 var batch = batches[i];
11732 try {
11733 batch._onComplete();
11734 } catch (error) {
11735 if (!hasUnhandledError) {
11736 hasUnhandledError = true;
11737 unhandledError = error;
11738 }
11739 }
11740 }
11741 }
11742
11743 if (hasUnhandledError) {
11744 var _error4 = unhandledError;
11745 unhandledError = null;
11746 hasUnhandledError = false;
11747 throw _error4;
11748 }
11749 }
11750
11751 function performWorkOnRoot(root, expirationTime, currentTime) {
11752 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11753
11754 isRendering = true;
11755
11756 // Check if this is async work or sync/expired work.
11757 if (expirationTime <= currentTime) {
11758 // Flush sync work.
11759 var finishedWork = root.finishedWork;
11760 if (finishedWork !== null) {
11761 // This root is already complete. We can commit it.
11762 completeRoot(root, finishedWork, expirationTime);
11763 } else {
11764 root.finishedWork = null;
11765 finishedWork = renderRoot(root, expirationTime);
11766 if (finishedWork !== null) {
11767 // We've completed the root. Commit it.
11768 completeRoot(root, finishedWork, expirationTime);
11769 }
11770 }
11771 } else {
11772 // Flush async work.
11773 var _finishedWork = root.finishedWork;
11774 if (_finishedWork !== null) {
11775 // This root is already complete. We can commit it.
11776 completeRoot(root, _finishedWork, expirationTime);
11777 } else {
11778 root.finishedWork = null;
11779 _finishedWork = renderRoot(root, expirationTime);
11780 if (_finishedWork !== null) {
11781 // We've completed the root. Check the deadline one more time
11782 // before committing.
11783 if (!shouldYield()) {
11784 // Still time left. Commit the root.
11785 completeRoot(root, _finishedWork, expirationTime);
11786 } else {
11787 // There's no time left. Mark this root as complete. We'll come
11788 // back and commit it later.
11789 root.finishedWork = _finishedWork;
11790 }
11791 }
11792 }
11793 }
11794
11795 isRendering = false;
11796 }
11797
11798 function completeRoot(root, finishedWork, expirationTime) {
11799 // Check if there's a batch that matches this expiration time.
11800 var firstBatch = root.firstBatch;
11801 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
11802 if (completedBatches === null) {
11803 completedBatches = [firstBatch];
11804 } else {
11805 completedBatches.push(firstBatch);
11806 }
11807 if (firstBatch._defer) {
11808 // This root is blocked from committing by a batch. Unschedule it until
11809 // we receive another update.
11810 root.finishedWork = finishedWork;
11811 root.remainingExpirationTime = NoWork;
11812 return;
11813 }
11814 }
11815
11816 // Commit the root.
11817 root.finishedWork = null;
11818 root.remainingExpirationTime = commitRoot(finishedWork);
11819 }
11820
11821 // When working on async work, the reconciler asks the renderer if it should
11822 // yield execution. For DOM, we implement this with requestIdleCallback.
11823 function shouldYield() {
11824 if (deadline === null) {
11825 return false;
11826 }
11827 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
11828 // Disregard deadline.didTimeout. Only expired work should be flushed
11829 // during a timeout. This path is only hit for non-expired work.
11830 return false;
11831 }
11832 deadlineDidExpire = true;
11833 return true;
11834 }
11835
11836 // TODO: Not happy about this hook. Conceptually, renderRoot should return a
11837 // tuple of (isReadyForCommit, didError, error)
11838 function onUncaughtError(error) {
11839 !(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;
11840 // Unschedule this root so we don't work on it again until there's
11841 // another update.
11842 nextFlushedRoot.remainingExpirationTime = NoWork;
11843 if (!hasUnhandledError) {
11844 hasUnhandledError = true;
11845 unhandledError = error;
11846 }
11847 }
11848
11849 // TODO: Batching should be implemented at the renderer level, not inside
11850 // the reconciler.
11851 function batchedUpdates(fn, a) {
11852 var previousIsBatchingUpdates = isBatchingUpdates;
11853 isBatchingUpdates = true;
11854 try {
11855 return fn(a);
11856 } finally {
11857 isBatchingUpdates = previousIsBatchingUpdates;
11858 if (!isBatchingUpdates && !isRendering) {
11859 performWork(Sync, null);
11860 }
11861 }
11862 }
11863
11864 // TODO: Batching should be implemented at the renderer level, not inside
11865 // the reconciler.
11866 function unbatchedUpdates(fn) {
11867 if (isBatchingUpdates && !isUnbatchingUpdates) {
11868 isUnbatchingUpdates = true;
11869 try {
11870 return fn();
11871 } finally {
11872 isUnbatchingUpdates = false;
11873 }
11874 }
11875 return fn();
11876 }
11877
11878 // TODO: Batching should be implemented at the renderer level, not within
11879 // the reconciler.
11880 function flushSync(fn) {
11881 var previousIsBatchingUpdates = isBatchingUpdates;
11882 isBatchingUpdates = true;
11883 try {
11884 return syncUpdates(fn);
11885 } finally {
11886 isBatchingUpdates = previousIsBatchingUpdates;
11887 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
11888 performWork(Sync, null);
11889 }
11890 }
11891
11892 return {
11893 computeExpirationForFiber: computeExpirationForFiber,
11894 scheduleWork: scheduleWork,
11895 requestWork: requestWork,
11896 flushRoot: flushRoot,
11897 batchedUpdates: batchedUpdates,
11898 unbatchedUpdates: unbatchedUpdates,
11899 flushSync: flushSync,
11900 deferredUpdates: deferredUpdates,
11901 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
11902 };
11903};
11904
11905var didWarnAboutNestedUpdates = void 0;
11906
11907{
11908 didWarnAboutNestedUpdates = false;
11909}
11910
11911// 0 is PROD, 1 is DEV.
11912// Might add PROFILE later.
11913
11914
11915function getContextForSubtree(parentComponent) {
11916 if (!parentComponent) {
11917 return emptyObject_1;
11918 }
11919
11920 var fiber = get(parentComponent);
11921 var parentContext = findCurrentUnmaskedContext(fiber);
11922 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
11923}
11924
11925var ReactFiberReconciler$1 = function (config) {
11926 var getPublicInstance = config.getPublicInstance;
11927
11928 var _ReactFiberScheduler = ReactFiberScheduler(config),
11929 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
11930 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
11931 scheduleWork = _ReactFiberScheduler.scheduleWork,
11932 requestWork = _ReactFiberScheduler.requestWork,
11933 flushRoot = _ReactFiberScheduler.flushRoot,
11934 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
11935 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
11936 flushSync = _ReactFiberScheduler.flushSync,
11937 deferredUpdates = _ReactFiberScheduler.deferredUpdates;
11938
11939 function scheduleRootUpdate(current, element, expirationTime, callback) {
11940 {
11941 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
11942 didWarnAboutNestedUpdates = true;
11943 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');
11944 }
11945 }
11946
11947 callback = callback === undefined ? null : callback;
11948 {
11949 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
11950 }
11951
11952 var update = {
11953 expirationTime: expirationTime,
11954 partialState: { element: element },
11955 callback: callback,
11956 isReplace: false,
11957 isForced: false,
11958 next: null
11959 };
11960 insertUpdateIntoFiber(current, update);
11961 scheduleWork(current, expirationTime);
11962
11963 return expirationTime;
11964 }
11965
11966 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
11967 // TODO: If this is a nested container, this won't be the root.
11968 var current = container.current;
11969
11970 {
11971 if (ReactFiberInstrumentation_1.debugTool) {
11972 if (current.alternate === null) {
11973 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
11974 } else if (element === null) {
11975 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
11976 } else {
11977 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
11978 }
11979 }
11980 }
11981
11982 var context = getContextForSubtree(parentComponent);
11983 if (container.context === null) {
11984 container.context = context;
11985 } else {
11986 container.pendingContext = context;
11987 }
11988
11989 return scheduleRootUpdate(current, element, expirationTime, callback);
11990 }
11991
11992 function findHostInstance(fiber) {
11993 var hostFiber = findCurrentHostFiber(fiber);
11994 if (hostFiber === null) {
11995 return null;
11996 }
11997 return hostFiber.stateNode;
11998 }
11999
12000 return {
12001 createContainer: function (containerInfo, isAsync, hydrate) {
12002 return createFiberRoot(containerInfo, isAsync, hydrate);
12003 },
12004 updateContainer: function (element, container, parentComponent, callback) {
12005 var current = container.current;
12006 var expirationTime = computeExpirationForFiber(current);
12007 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12008 },
12009
12010
12011 updateContainerAtExpirationTime: updateContainerAtExpirationTime,
12012
12013 flushRoot: flushRoot,
12014
12015 requestWork: requestWork,
12016
12017 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
12018
12019 batchedUpdates: batchedUpdates,
12020
12021 unbatchedUpdates: unbatchedUpdates,
12022
12023 deferredUpdates: deferredUpdates,
12024
12025 flushSync: flushSync,
12026
12027 getPublicRootInstance: function (container) {
12028 var containerFiber = container.current;
12029 if (!containerFiber.child) {
12030 return null;
12031 }
12032 switch (containerFiber.child.tag) {
12033 case HostComponent:
12034 return getPublicInstance(containerFiber.child.stateNode);
12035 default:
12036 return containerFiber.child.stateNode;
12037 }
12038 },
12039
12040
12041 findHostInstance: findHostInstance,
12042
12043 findHostInstanceWithNoPortals: function (fiber) {
12044 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
12045 if (hostFiber === null) {
12046 return null;
12047 }
12048 return hostFiber.stateNode;
12049 },
12050 injectIntoDevTools: function (devToolsConfig) {
12051 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12052
12053 return injectInternals(_assign({}, devToolsConfig, {
12054 findHostInstanceByFiber: function (fiber) {
12055 return findHostInstance(fiber);
12056 },
12057 findFiberByHostInstance: function (instance) {
12058 if (!findFiberByHostInstance) {
12059 // Might not be implemented by the renderer.
12060 return null;
12061 }
12062 return findFiberByHostInstance(instance);
12063 }
12064 }));
12065 }
12066 };
12067};
12068
12069var ReactFiberReconciler$2 = Object.freeze({
12070 default: ReactFiberReconciler$1
12071});
12072
12073var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
12074
12075// TODO: bundle Flow types with the package.
12076
12077
12078
12079// TODO: decide on the top-level export form.
12080// This is hacky but makes it work with both Rollup and Jest.
12081var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
12082
12083function createPortal$1(children, containerInfo,
12084// TODO: figure out the API for cross-renderer implementation.
12085implementation) {
12086 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
12087
12088 return {
12089 // This tag allow us to uniquely identify this as a React Portal
12090 $$typeof: REACT_PORTAL_TYPE,
12091 key: key == null ? null : '' + key,
12092 children: children,
12093 containerInfo: containerInfo,
12094 implementation: implementation
12095 };
12096}
12097
12098// TODO: this is special because it gets imported during build.
12099
12100var ReactVersion = '16.2.0';
12101
12102// a requestAnimationFrame, storing the time for the start of the frame, then
12103// scheduling a postMessage which gets scheduled after paint. Within the
12104// postMessage handler do as much work as possible until time + frame rate.
12105// By separating the idle call into a separate event tick we ensure that
12106// layout, paint and other browser work is counted against the available time.
12107// The frame rate is dynamically adjusted.
12108
12109{
12110 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
12111 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
12112 }
12113}
12114
12115var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
12116
12117var now = void 0;
12118if (hasNativePerformanceNow) {
12119 now = function () {
12120 return performance.now();
12121 };
12122} else {
12123 now = function () {
12124 return Date.now();
12125 };
12126}
12127
12128// TODO: There's no way to cancel, because Fiber doesn't atm.
12129var rIC = void 0;
12130var cIC = void 0;
12131
12132if (!ExecutionEnvironment_1.canUseDOM) {
12133 rIC = function (frameCallback) {
12134 return setTimeout(function () {
12135 frameCallback({
12136 timeRemaining: function () {
12137 return Infinity;
12138 }
12139 });
12140 });
12141 };
12142 cIC = function (timeoutID) {
12143 clearTimeout(timeoutID);
12144 };
12145} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
12146 // Polyfill requestIdleCallback and cancelIdleCallback
12147
12148 var scheduledRICCallback = null;
12149 var isIdleScheduled = false;
12150 var timeoutTime = -1;
12151
12152 var isAnimationFrameScheduled = false;
12153
12154 var frameDeadline = 0;
12155 // We start out assuming that we run at 30fps but then the heuristic tracking
12156 // will adjust this value to a faster fps if we get more frequent animation
12157 // frames.
12158 var previousFrameTime = 33;
12159 var activeFrameTime = 33;
12160
12161 var frameDeadlineObject = void 0;
12162 if (hasNativePerformanceNow) {
12163 frameDeadlineObject = {
12164 didTimeout: false,
12165 timeRemaining: function () {
12166 // We assume that if we have a performance timer that the rAF callback
12167 // gets a performance timer value. Not sure if this is always true.
12168 var remaining = frameDeadline - performance.now();
12169 return remaining > 0 ? remaining : 0;
12170 }
12171 };
12172 } else {
12173 frameDeadlineObject = {
12174 didTimeout: false,
12175 timeRemaining: function () {
12176 // Fallback to Date.now()
12177 var remaining = frameDeadline - Date.now();
12178 return remaining > 0 ? remaining : 0;
12179 }
12180 };
12181 }
12182
12183 // We use the postMessage trick to defer idle work until after the repaint.
12184 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12185 var idleTick = function (event) {
12186 if (event.source !== window || event.data !== messageKey) {
12187 return;
12188 }
12189
12190 isIdleScheduled = false;
12191
12192 var currentTime = now();
12193 if (frameDeadline - currentTime <= 0) {
12194 // There's no time left in this idle period. Check if the callback has
12195 // a timeout and whether it's been exceeded.
12196 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12197 // Exceeded the timeout. Invoke the callback even though there's no
12198 // time left.
12199 frameDeadlineObject.didTimeout = true;
12200 } else {
12201 // No timeout.
12202 if (!isAnimationFrameScheduled) {
12203 // Schedule another animation callback so we retry later.
12204 isAnimationFrameScheduled = true;
12205 requestAnimationFrame(animationTick);
12206 }
12207 // Exit without invoking the callback.
12208 return;
12209 }
12210 } else {
12211 // There's still time left in this idle period.
12212 frameDeadlineObject.didTimeout = false;
12213 }
12214
12215 timeoutTime = -1;
12216 var callback = scheduledRICCallback;
12217 scheduledRICCallback = null;
12218 if (callback !== null) {
12219 callback(frameDeadlineObject);
12220 }
12221 };
12222 // Assumes that we have addEventListener in this environment. Might need
12223 // something better for old IE.
12224 window.addEventListener('message', idleTick, false);
12225
12226 var animationTick = function (rafTime) {
12227 isAnimationFrameScheduled = false;
12228 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12229 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12230 if (nextFrameTime < 8) {
12231 // Defensive coding. We don't support higher frame rates than 120hz.
12232 // If we get lower than that, it is probably a bug.
12233 nextFrameTime = 8;
12234 }
12235 // If one frame goes long, then the next one can be short to catch up.
12236 // If two frames are short in a row, then that's an indication that we
12237 // actually have a higher frame rate than what we're currently optimizing.
12238 // We adjust our heuristic dynamically accordingly. For example, if we're
12239 // running on 120hz display or 90hz VR display.
12240 // Take the max of the two in case one of them was an anomaly due to
12241 // missed frame deadlines.
12242 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12243 } else {
12244 previousFrameTime = nextFrameTime;
12245 }
12246 frameDeadline = rafTime + activeFrameTime;
12247 if (!isIdleScheduled) {
12248 isIdleScheduled = true;
12249 window.postMessage(messageKey, '*');
12250 }
12251 };
12252
12253 rIC = function (callback, options) {
12254 // This assumes that we only schedule one callback at a time because that's
12255 // how Fiber uses it.
12256 scheduledRICCallback = callback;
12257 if (options != null && typeof options.timeout === 'number') {
12258 timeoutTime = now() + options.timeout;
12259 }
12260 if (!isAnimationFrameScheduled) {
12261 // If rAF didn't already schedule one, we need to schedule a frame.
12262 // TODO: If this rAF doesn't materialize because the browser throttles, we
12263 // might want to still have setTimeout trigger rIC as a backup to ensure
12264 // that we keep performing work.
12265 isAnimationFrameScheduled = true;
12266 requestAnimationFrame(animationTick);
12267 }
12268 return 0;
12269 };
12270
12271 cIC = function () {
12272 scheduledRICCallback = null;
12273 isIdleScheduled = false;
12274 timeoutTime = -1;
12275 };
12276} else {
12277 rIC = window.requestIdleCallback;
12278 cIC = window.cancelIdleCallback;
12279}
12280
12281var didWarnSelectedSetOnOption = false;
12282
12283function flattenChildren(children) {
12284 var content = '';
12285
12286 // Flatten children and warn if they aren't strings or numbers;
12287 // invalid types are ignored.
12288 // We can silently skip them because invalid DOM nesting warning
12289 // catches these cases in Fiber.
12290 React.Children.forEach(children, function (child) {
12291 if (child == null) {
12292 return;
12293 }
12294 if (typeof child === 'string' || typeof child === 'number') {
12295 content += child;
12296 }
12297 });
12298
12299 return content;
12300}
12301
12302/**
12303 * Implements an <option> host component that warns when `selected` is set.
12304 */
12305
12306function validateProps(element, props) {
12307 // TODO (yungsters): Remove support for `selected` in <option>.
12308 {
12309 if (props.selected != null && !didWarnSelectedSetOnOption) {
12310 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
12311 didWarnSelectedSetOnOption = true;
12312 }
12313 }
12314}
12315
12316function postMountWrapper$1(element, props) {
12317 // value="" should make a value attribute (#6219)
12318 if (props.value != null) {
12319 element.setAttribute('value', props.value);
12320 }
12321}
12322
12323function getHostProps$1(element, props) {
12324 var hostProps = _assign({ children: undefined }, props);
12325 var content = flattenChildren(props.children);
12326
12327 if (content) {
12328 hostProps.children = content;
12329 }
12330
12331 return hostProps;
12332}
12333
12334// TODO: direct imports like some-package/src/* are bad. Fix me.
12335var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
12336var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12337
12338
12339var didWarnValueDefaultValue$1 = void 0;
12340
12341{
12342 didWarnValueDefaultValue$1 = false;
12343}
12344
12345function getDeclarationErrorAddendum() {
12346 var ownerName = getCurrentFiberOwnerName$3();
12347 if (ownerName) {
12348 return '\n\nCheck the render method of `' + ownerName + '`.';
12349 }
12350 return '';
12351}
12352
12353var valuePropNames = ['value', 'defaultValue'];
12354
12355/**
12356 * Validation function for `value` and `defaultValue`.
12357 */
12358function checkSelectPropTypes(props) {
12359 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
12360
12361 for (var i = 0; i < valuePropNames.length; i++) {
12362 var propName = valuePropNames[i];
12363 if (props[propName] == null) {
12364 continue;
12365 }
12366 var isArray = Array.isArray(props[propName]);
12367 if (props.multiple && !isArray) {
12368 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
12369 } else if (!props.multiple && isArray) {
12370 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
12371 }
12372 }
12373}
12374
12375function updateOptions(node, multiple, propValue, setDefaultSelected) {
12376 var options = node.options;
12377
12378 if (multiple) {
12379 var selectedValues = propValue;
12380 var selectedValue = {};
12381 for (var i = 0; i < selectedValues.length; i++) {
12382 // Prefix to avoid chaos with special keys.
12383 selectedValue['$' + selectedValues[i]] = true;
12384 }
12385 for (var _i = 0; _i < options.length; _i++) {
12386 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
12387 if (options[_i].selected !== selected) {
12388 options[_i].selected = selected;
12389 }
12390 if (selected && setDefaultSelected) {
12391 options[_i].defaultSelected = true;
12392 }
12393 }
12394 } else {
12395 // Do not set `select.value` as exact behavior isn't consistent across all
12396 // browsers for all cases.
12397 var _selectedValue = '' + propValue;
12398 var defaultSelected = null;
12399 for (var _i2 = 0; _i2 < options.length; _i2++) {
12400 if (options[_i2].value === _selectedValue) {
12401 options[_i2].selected = true;
12402 if (setDefaultSelected) {
12403 options[_i2].defaultSelected = true;
12404 }
12405 return;
12406 }
12407 if (defaultSelected === null && !options[_i2].disabled) {
12408 defaultSelected = options[_i2];
12409 }
12410 }
12411 if (defaultSelected !== null) {
12412 defaultSelected.selected = true;
12413 }
12414 }
12415}
12416
12417/**
12418 * Implements a <select> host component that allows optionally setting the
12419 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
12420 * stringable. If `multiple` is true, the prop must be an array of stringables.
12421 *
12422 * If `value` is not supplied (or null/undefined), user actions that change the
12423 * selected option will trigger updates to the rendered options.
12424 *
12425 * If it is supplied (and not null/undefined), the rendered options will not
12426 * update in response to user actions. Instead, the `value` prop must change in
12427 * order for the rendered options to update.
12428 *
12429 * If `defaultValue` is provided, any options with the supplied values will be
12430 * selected.
12431 */
12432
12433function getHostProps$2(element, props) {
12434 return _assign({}, props, {
12435 value: undefined
12436 });
12437}
12438
12439function initWrapperState$1(element, props) {
12440 var node = element;
12441 {
12442 checkSelectPropTypes(props);
12443 }
12444
12445 var value = props.value;
12446 node._wrapperState = {
12447 initialValue: value != null ? value : props.defaultValue,
12448 wasMultiple: !!props.multiple
12449 };
12450
12451 {
12452 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
12453 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');
12454 didWarnValueDefaultValue$1 = true;
12455 }
12456 }
12457}
12458
12459function postMountWrapper$2(element, props) {
12460 var node = element;
12461 node.multiple = !!props.multiple;
12462 var value = props.value;
12463 if (value != null) {
12464 updateOptions(node, !!props.multiple, value, false);
12465 } else if (props.defaultValue != null) {
12466 updateOptions(node, !!props.multiple, props.defaultValue, true);
12467 }
12468}
12469
12470function postUpdateWrapper(element, props) {
12471 var node = element;
12472 // After the initial mount, we control selected-ness manually so don't pass
12473 // this value down
12474 node._wrapperState.initialValue = undefined;
12475
12476 var wasMultiple = node._wrapperState.wasMultiple;
12477 node._wrapperState.wasMultiple = !!props.multiple;
12478
12479 var value = props.value;
12480 if (value != null) {
12481 updateOptions(node, !!props.multiple, value, false);
12482 } else if (wasMultiple !== !!props.multiple) {
12483 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
12484 if (props.defaultValue != null) {
12485 updateOptions(node, !!props.multiple, props.defaultValue, true);
12486 } else {
12487 // Revert the select back to its default unselected state.
12488 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
12489 }
12490 }
12491}
12492
12493function restoreControlledState$2(element, props) {
12494 var node = element;
12495 var value = props.value;
12496
12497 if (value != null) {
12498 updateOptions(node, !!props.multiple, value, false);
12499 }
12500}
12501
12502// TODO: direct imports like some-package/src/* are bad. Fix me.
12503var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12504
12505var didWarnValDefaultVal = false;
12506
12507/**
12508 * Implements a <textarea> host component that allows setting `value`, and
12509 * `defaultValue`. This differs from the traditional DOM API because value is
12510 * usually set as PCDATA children.
12511 *
12512 * If `value` is not supplied (or null/undefined), user actions that affect the
12513 * value will trigger updates to the element.
12514 *
12515 * If `value` is supplied (and not null/undefined), the rendered element will
12516 * not trigger updates to the element. Instead, the `value` prop must change in
12517 * order for the rendered element to be updated.
12518 *
12519 * The rendered element will be initialized with an empty value, the prop
12520 * `defaultValue` if specified, or the children content (deprecated).
12521 */
12522
12523function getHostProps$3(element, props) {
12524 var node = element;
12525 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
12526
12527 // Always set children to the same thing. In IE9, the selection range will
12528 // get reset if `textContent` is mutated. We could add a check in setTextContent
12529 // to only set the value if/when the value differs from the node value (which would
12530 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
12531 // solution. The value can be a boolean or object so that's why it's forced
12532 // to be a string.
12533 var hostProps = _assign({}, props, {
12534 value: undefined,
12535 defaultValue: undefined,
12536 children: '' + node._wrapperState.initialValue
12537 });
12538
12539 return hostProps;
12540}
12541
12542function initWrapperState$2(element, props) {
12543 var node = element;
12544 {
12545 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
12546 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
12547 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');
12548 didWarnValDefaultVal = true;
12549 }
12550 }
12551
12552 var initialValue = props.value;
12553
12554 // Only bother fetching default value if we're going to use it
12555 if (initialValue == null) {
12556 var defaultValue = props.defaultValue;
12557 // TODO (yungsters): Remove support for children content in <textarea>.
12558 var children = props.children;
12559 if (children != null) {
12560 {
12561 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
12562 }
12563 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
12564 if (Array.isArray(children)) {
12565 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
12566 children = children[0];
12567 }
12568
12569 defaultValue = '' + children;
12570 }
12571 if (defaultValue == null) {
12572 defaultValue = '';
12573 }
12574 initialValue = defaultValue;
12575 }
12576
12577 node._wrapperState = {
12578 initialValue: '' + initialValue
12579 };
12580}
12581
12582function updateWrapper$1(element, props) {
12583 var node = element;
12584 var value = props.value;
12585 if (value != null) {
12586 // Cast `value` to a string to ensure the value is set correctly. While
12587 // browsers typically do this as necessary, jsdom doesn't.
12588 var newValue = '' + value;
12589
12590 // To avoid side effects (such as losing text selection), only set value if changed
12591 if (newValue !== node.value) {
12592 node.value = newValue;
12593 }
12594 if (props.defaultValue == null) {
12595 node.defaultValue = newValue;
12596 }
12597 }
12598 if (props.defaultValue != null) {
12599 node.defaultValue = props.defaultValue;
12600 }
12601}
12602
12603function postMountWrapper$3(element, props) {
12604 var node = element;
12605 // This is in postMount because we need access to the DOM node, which is not
12606 // available until after the component has mounted.
12607 var textContent = node.textContent;
12608
12609 // Only set node.value if textContent is equal to the expected
12610 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
12611 // will populate textContent as well.
12612 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
12613 if (textContent === node._wrapperState.initialValue) {
12614 node.value = textContent;
12615 }
12616}
12617
12618function restoreControlledState$3(element, props) {
12619 // DOM component is still mounted; update
12620 updateWrapper$1(element, props);
12621}
12622
12623var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
12624var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
12625var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
12626
12627var Namespaces = {
12628 html: HTML_NAMESPACE$1,
12629 mathml: MATH_NAMESPACE,
12630 svg: SVG_NAMESPACE
12631};
12632
12633// Assumes there is no parent namespace.
12634function getIntrinsicNamespace(type) {
12635 switch (type) {
12636 case 'svg':
12637 return SVG_NAMESPACE;
12638 case 'math':
12639 return MATH_NAMESPACE;
12640 default:
12641 return HTML_NAMESPACE$1;
12642 }
12643}
12644
12645function getChildNamespace(parentNamespace, type) {
12646 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
12647 // No (or default) parent namespace: potential entry point.
12648 return getIntrinsicNamespace(type);
12649 }
12650 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
12651 // We're leaving SVG.
12652 return HTML_NAMESPACE$1;
12653 }
12654 // By default, pass namespace below.
12655 return parentNamespace;
12656}
12657
12658/* globals MSApp */
12659
12660/**
12661 * Create a function which has 'unsafe' privileges (required by windows8 apps)
12662 */
12663var createMicrosoftUnsafeLocalFunction = function (func) {
12664 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
12665 return function (arg0, arg1, arg2, arg3) {
12666 MSApp.execUnsafeLocalFunction(function () {
12667 return func(arg0, arg1, arg2, arg3);
12668 });
12669 };
12670 } else {
12671 return func;
12672 }
12673};
12674
12675// SVG temp container for IE lacking innerHTML
12676var reusableSVGContainer = void 0;
12677
12678/**
12679 * Set the innerHTML property of a node
12680 *
12681 * @param {DOMElement} node
12682 * @param {string} html
12683 * @internal
12684 */
12685var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
12686 // IE does not have innerHTML for SVG nodes, so instead we inject the
12687 // new markup in a temp node and then move the child nodes across into
12688 // the target node
12689
12690 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
12691 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
12692 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
12693 var svgNode = reusableSVGContainer.firstChild;
12694 while (node.firstChild) {
12695 node.removeChild(node.firstChild);
12696 }
12697 while (svgNode.firstChild) {
12698 node.appendChild(svgNode.firstChild);
12699 }
12700 } else {
12701 node.innerHTML = html;
12702 }
12703});
12704
12705/**
12706 * Set the textContent property of a node. For text updates, it's faster
12707 * to set the `nodeValue` of the Text node directly instead of using
12708 * `.textContent` which will remove the existing node and create a new one.
12709 *
12710 * @param {DOMElement} node
12711 * @param {string} text
12712 * @internal
12713 */
12714var setTextContent = function (node, text) {
12715 if (text) {
12716 var firstChild = node.firstChild;
12717
12718 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
12719 firstChild.nodeValue = text;
12720 return;
12721 }
12722 }
12723 node.textContent = text;
12724};
12725
12726/**
12727 * CSS properties which accept numbers but are not in units of "px".
12728 */
12729var isUnitlessNumber = {
12730 animationIterationCount: true,
12731 borderImageOutset: true,
12732 borderImageSlice: true,
12733 borderImageWidth: true,
12734 boxFlex: true,
12735 boxFlexGroup: true,
12736 boxOrdinalGroup: true,
12737 columnCount: true,
12738 columns: true,
12739 flex: true,
12740 flexGrow: true,
12741 flexPositive: true,
12742 flexShrink: true,
12743 flexNegative: true,
12744 flexOrder: true,
12745 gridRow: true,
12746 gridRowEnd: true,
12747 gridRowSpan: true,
12748 gridRowStart: true,
12749 gridColumn: true,
12750 gridColumnEnd: true,
12751 gridColumnSpan: true,
12752 gridColumnStart: true,
12753 fontWeight: true,
12754 lineClamp: true,
12755 lineHeight: true,
12756 opacity: true,
12757 order: true,
12758 orphans: true,
12759 tabSize: true,
12760 widows: true,
12761 zIndex: true,
12762 zoom: true,
12763
12764 // SVG-related properties
12765 fillOpacity: true,
12766 floodOpacity: true,
12767 stopOpacity: true,
12768 strokeDasharray: true,
12769 strokeDashoffset: true,
12770 strokeMiterlimit: true,
12771 strokeOpacity: true,
12772 strokeWidth: true
12773};
12774
12775/**
12776 * @param {string} prefix vendor-specific prefix, eg: Webkit
12777 * @param {string} key style name, eg: transitionDuration
12778 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
12779 * WebkitTransitionDuration
12780 */
12781function prefixKey(prefix, key) {
12782 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
12783}
12784
12785/**
12786 * Support style names that may come passed in prefixed by adding permutations
12787 * of vendor prefixes.
12788 */
12789var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
12790
12791// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
12792// infinite loop, because it iterates over the newly added props too.
12793Object.keys(isUnitlessNumber).forEach(function (prop) {
12794 prefixes.forEach(function (prefix) {
12795 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
12796 });
12797});
12798
12799/**
12800 * Convert a value into the proper css writable value. The style name `name`
12801 * should be logical (no hyphens), as specified
12802 * in `CSSProperty.isUnitlessNumber`.
12803 *
12804 * @param {string} name CSS property name such as `topMargin`.
12805 * @param {*} value CSS property value such as `10px`.
12806 * @return {string} Normalized style value with dimensions applied.
12807 */
12808function dangerousStyleValue(name, value, isCustomProperty) {
12809 // Note that we've removed escapeTextForBrowser() calls here since the
12810 // whole string will be escaped when the attribute is injected into
12811 // the markup. If you provide unsafe user data here they can inject
12812 // arbitrary CSS which may be problematic (I couldn't repro this):
12813 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
12814 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
12815 // This is not an XSS hole but instead a potential CSS injection issue
12816 // which has lead to a greater discussion about how we're going to
12817 // trust URLs moving forward. See #2115901
12818
12819 var isEmpty = value == null || typeof value === 'boolean' || value === '';
12820 if (isEmpty) {
12821 return '';
12822 }
12823
12824 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
12825 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
12826 }
12827
12828 return ('' + value).trim();
12829}
12830
12831/**
12832 * Copyright (c) 2013-present, Facebook, Inc.
12833 *
12834 * This source code is licensed under the MIT license found in the
12835 * LICENSE file in the root directory of this source tree.
12836 *
12837 * @typechecks
12838 */
12839
12840var _uppercasePattern = /([A-Z])/g;
12841
12842/**
12843 * Hyphenates a camelcased string, for example:
12844 *
12845 * > hyphenate('backgroundColor')
12846 * < "background-color"
12847 *
12848 * For CSS style names, use `hyphenateStyleName` instead which works properly
12849 * with all vendor prefixes, including `ms`.
12850 *
12851 * @param {string} string
12852 * @return {string}
12853 */
12854function hyphenate(string) {
12855 return string.replace(_uppercasePattern, '-$1').toLowerCase();
12856}
12857
12858var hyphenate_1 = hyphenate;
12859
12860/**
12861 * Copyright (c) 2013-present, Facebook, Inc.
12862 *
12863 * This source code is licensed under the MIT license found in the
12864 * LICENSE file in the root directory of this source tree.
12865 *
12866 * @typechecks
12867 */
12868
12869
12870
12871
12872
12873var msPattern = /^ms-/;
12874
12875/**
12876 * Hyphenates a camelcased CSS property name, for example:
12877 *
12878 * > hyphenateStyleName('backgroundColor')
12879 * < "background-color"
12880 * > hyphenateStyleName('MozTransition')
12881 * < "-moz-transition"
12882 * > hyphenateStyleName('msTransition')
12883 * < "-ms-transition"
12884 *
12885 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
12886 * is converted to `-ms-`.
12887 *
12888 * @param {string} string
12889 * @return {string}
12890 */
12891function hyphenateStyleName(string) {
12892 return hyphenate_1(string).replace(msPattern, '-ms-');
12893}
12894
12895var hyphenateStyleName_1 = hyphenateStyleName;
12896
12897/**
12898 * Copyright (c) 2013-present, Facebook, Inc.
12899 *
12900 * This source code is licensed under the MIT license found in the
12901 * LICENSE file in the root directory of this source tree.
12902 *
12903 * @typechecks
12904 */
12905
12906var _hyphenPattern = /-(.)/g;
12907
12908/**
12909 * Camelcases a hyphenated string, for example:
12910 *
12911 * > camelize('background-color')
12912 * < "backgroundColor"
12913 *
12914 * @param {string} string
12915 * @return {string}
12916 */
12917function camelize(string) {
12918 return string.replace(_hyphenPattern, function (_, character) {
12919 return character.toUpperCase();
12920 });
12921}
12922
12923var camelize_1 = camelize;
12924
12925/**
12926 * Copyright (c) 2013-present, Facebook, Inc.
12927 *
12928 * This source code is licensed under the MIT license found in the
12929 * LICENSE file in the root directory of this source tree.
12930 *
12931 * @typechecks
12932 */
12933
12934
12935
12936
12937
12938var msPattern$1 = /^-ms-/;
12939
12940/**
12941 * Camelcases a hyphenated CSS property name, for example:
12942 *
12943 * > camelizeStyleName('background-color')
12944 * < "backgroundColor"
12945 * > camelizeStyleName('-moz-transition')
12946 * < "MozTransition"
12947 * > camelizeStyleName('-ms-transition')
12948 * < "msTransition"
12949 *
12950 * As Andi Smith suggests
12951 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
12952 * is converted to lowercase `ms`.
12953 *
12954 * @param {string} string
12955 * @return {string}
12956 */
12957function camelizeStyleName(string) {
12958 return camelize_1(string.replace(msPattern$1, 'ms-'));
12959}
12960
12961var camelizeStyleName_1 = camelizeStyleName;
12962
12963var warnValidStyle = emptyFunction_1;
12964
12965{
12966 // 'msTransform' is correct, but the other prefixes should be capitalized
12967 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
12968
12969 // style values shouldn't contain a semicolon
12970 var badStyleValueWithSemicolonPattern = /;\s*$/;
12971
12972 var warnedStyleNames = {};
12973 var warnedStyleValues = {};
12974 var warnedForNaNValue = false;
12975 var warnedForInfinityValue = false;
12976
12977 var warnHyphenatedStyleName = function (name, getStack) {
12978 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12979 return;
12980 }
12981
12982 warnedStyleNames[name] = true;
12983 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
12984 };
12985
12986 var warnBadVendoredStyleName = function (name, getStack) {
12987 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12988 return;
12989 }
12990
12991 warnedStyleNames[name] = true;
12992 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
12993 };
12994
12995 var warnStyleValueWithSemicolon = function (name, value, getStack) {
12996 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
12997 return;
12998 }
12999
13000 warnedStyleValues[value] = true;
13001 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
13002 };
13003
13004 var warnStyleValueIsNaN = function (name, value, getStack) {
13005 if (warnedForNaNValue) {
13006 return;
13007 }
13008
13009 warnedForNaNValue = true;
13010 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
13011 };
13012
13013 var warnStyleValueIsInfinity = function (name, value, getStack) {
13014 if (warnedForInfinityValue) {
13015 return;
13016 }
13017
13018 warnedForInfinityValue = true;
13019 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
13020 };
13021
13022 warnValidStyle = function (name, value, getStack) {
13023 if (name.indexOf('-') > -1) {
13024 warnHyphenatedStyleName(name, getStack);
13025 } else if (badVendoredStyleNamePattern.test(name)) {
13026 warnBadVendoredStyleName(name, getStack);
13027 } else if (badStyleValueWithSemicolonPattern.test(value)) {
13028 warnStyleValueWithSemicolon(name, value, getStack);
13029 }
13030
13031 if (typeof value === 'number') {
13032 if (isNaN(value)) {
13033 warnStyleValueIsNaN(name, value, getStack);
13034 } else if (!isFinite(value)) {
13035 warnStyleValueIsInfinity(name, value, getStack);
13036 }
13037 }
13038 };
13039}
13040
13041var warnValidStyle$1 = warnValidStyle;
13042
13043/**
13044 * Operations for dealing with CSS properties.
13045 */
13046
13047/**
13048 * This creates a string that is expected to be equivalent to the style
13049 * attribute generated by server-side rendering. It by-passes warnings and
13050 * security checks so it's not safe to use this value for anything other than
13051 * comparison. It is only used in DEV for SSR validation.
13052 */
13053function createDangerousStringForStyles(styles) {
13054 {
13055 var serialized = '';
13056 var delimiter = '';
13057 for (var styleName in styles) {
13058 if (!styles.hasOwnProperty(styleName)) {
13059 continue;
13060 }
13061 var styleValue = styles[styleName];
13062 if (styleValue != null) {
13063 var isCustomProperty = styleName.indexOf('--') === 0;
13064 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
13065 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
13066
13067 delimiter = ';';
13068 }
13069 }
13070 return serialized || null;
13071 }
13072}
13073
13074/**
13075 * Sets the value for multiple styles on a node. If a value is specified as
13076 * '' (empty string), the corresponding style property will be unset.
13077 *
13078 * @param {DOMElement} node
13079 * @param {object} styles
13080 */
13081function setValueForStyles(node, styles, getStack) {
13082 var style = node.style;
13083 for (var styleName in styles) {
13084 if (!styles.hasOwnProperty(styleName)) {
13085 continue;
13086 }
13087 var isCustomProperty = styleName.indexOf('--') === 0;
13088 {
13089 if (!isCustomProperty) {
13090 warnValidStyle$1(styleName, styles[styleName], getStack);
13091 }
13092 }
13093 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
13094 if (styleName === 'float') {
13095 styleName = 'cssFloat';
13096 }
13097 if (isCustomProperty) {
13098 style.setProperty(styleName, styleValue);
13099 } else {
13100 style[styleName] = styleValue;
13101 }
13102 }
13103}
13104
13105// For HTML, certain tags should omit their close tag. We keep a whitelist for
13106// those special-case tags.
13107
13108var omittedCloseTags = {
13109 area: true,
13110 base: true,
13111 br: true,
13112 col: true,
13113 embed: true,
13114 hr: true,
13115 img: true,
13116 input: true,
13117 keygen: true,
13118 link: true,
13119 meta: true,
13120 param: true,
13121 source: true,
13122 track: true,
13123 wbr: true
13124};
13125
13126// For HTML, certain tags cannot have children. This has the same purpose as
13127// `omittedCloseTags` except that `menuitem` should still have its closing tag.
13128
13129var voidElementTags = _assign({
13130 menuitem: true
13131}, omittedCloseTags);
13132
13133var HTML$1 = '__html';
13134
13135function assertValidProps(tag, props, getStack) {
13136 if (!props) {
13137 return;
13138 }
13139 // Note the use of `==` which checks for null or undefined.
13140 if (voidElementTags[tag]) {
13141 !(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;
13142 }
13143 if (props.dangerouslySetInnerHTML != null) {
13144 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
13145 !(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;
13146 }
13147 {
13148 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());
13149 }
13150 !(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;
13151}
13152
13153function isCustomComponent(tagName, props) {
13154 if (tagName.indexOf('-') === -1) {
13155 return typeof props.is === 'string';
13156 }
13157 switch (tagName) {
13158 // These are reserved SVG and MathML elements.
13159 // We don't mind this whitelist too much because we expect it to never grow.
13160 // The alternative is to track the namespace in a few places which is convoluted.
13161 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
13162 case 'annotation-xml':
13163 case 'color-profile':
13164 case 'font-face':
13165 case 'font-face-src':
13166 case 'font-face-uri':
13167 case 'font-face-format':
13168 case 'font-face-name':
13169 case 'missing-glyph':
13170 return false;
13171 default:
13172 return true;
13173 }
13174}
13175
13176// When adding attributes to the HTML or SVG whitelist, be sure to
13177// also add them to this module to ensure casing and incorrect name
13178// warnings.
13179var possibleStandardNames = {
13180 // HTML
13181 accept: 'accept',
13182 acceptcharset: 'acceptCharset',
13183 'accept-charset': 'acceptCharset',
13184 accesskey: 'accessKey',
13185 action: 'action',
13186 allowfullscreen: 'allowFullScreen',
13187 alt: 'alt',
13188 as: 'as',
13189 async: 'async',
13190 autocapitalize: 'autoCapitalize',
13191 autocomplete: 'autoComplete',
13192 autocorrect: 'autoCorrect',
13193 autofocus: 'autoFocus',
13194 autoplay: 'autoPlay',
13195 autosave: 'autoSave',
13196 capture: 'capture',
13197 cellpadding: 'cellPadding',
13198 cellspacing: 'cellSpacing',
13199 challenge: 'challenge',
13200 charset: 'charSet',
13201 checked: 'checked',
13202 children: 'children',
13203 cite: 'cite',
13204 'class': 'className',
13205 classid: 'classID',
13206 classname: 'className',
13207 cols: 'cols',
13208 colspan: 'colSpan',
13209 content: 'content',
13210 contenteditable: 'contentEditable',
13211 contextmenu: 'contextMenu',
13212 controls: 'controls',
13213 controlslist: 'controlsList',
13214 coords: 'coords',
13215 crossorigin: 'crossOrigin',
13216 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13217 data: 'data',
13218 datetime: 'dateTime',
13219 'default': 'default',
13220 defaultchecked: 'defaultChecked',
13221 defaultvalue: 'defaultValue',
13222 defer: 'defer',
13223 dir: 'dir',
13224 disabled: 'disabled',
13225 download: 'download',
13226 draggable: 'draggable',
13227 enctype: 'encType',
13228 'for': 'htmlFor',
13229 form: 'form',
13230 formmethod: 'formMethod',
13231 formaction: 'formAction',
13232 formenctype: 'formEncType',
13233 formnovalidate: 'formNoValidate',
13234 formtarget: 'formTarget',
13235 frameborder: 'frameBorder',
13236 headers: 'headers',
13237 height: 'height',
13238 hidden: 'hidden',
13239 high: 'high',
13240 href: 'href',
13241 hreflang: 'hrefLang',
13242 htmlfor: 'htmlFor',
13243 httpequiv: 'httpEquiv',
13244 'http-equiv': 'httpEquiv',
13245 icon: 'icon',
13246 id: 'id',
13247 innerhtml: 'innerHTML',
13248 inputmode: 'inputMode',
13249 integrity: 'integrity',
13250 is: 'is',
13251 itemid: 'itemID',
13252 itemprop: 'itemProp',
13253 itemref: 'itemRef',
13254 itemscope: 'itemScope',
13255 itemtype: 'itemType',
13256 keyparams: 'keyParams',
13257 keytype: 'keyType',
13258 kind: 'kind',
13259 label: 'label',
13260 lang: 'lang',
13261 list: 'list',
13262 loop: 'loop',
13263 low: 'low',
13264 manifest: 'manifest',
13265 marginwidth: 'marginWidth',
13266 marginheight: 'marginHeight',
13267 max: 'max',
13268 maxlength: 'maxLength',
13269 media: 'media',
13270 mediagroup: 'mediaGroup',
13271 method: 'method',
13272 min: 'min',
13273 minlength: 'minLength',
13274 multiple: 'multiple',
13275 muted: 'muted',
13276 name: 'name',
13277 nomodule: 'noModule',
13278 nonce: 'nonce',
13279 novalidate: 'noValidate',
13280 open: 'open',
13281 optimum: 'optimum',
13282 pattern: 'pattern',
13283 placeholder: 'placeholder',
13284 playsinline: 'playsInline',
13285 poster: 'poster',
13286 preload: 'preload',
13287 profile: 'profile',
13288 radiogroup: 'radioGroup',
13289 readonly: 'readOnly',
13290 referrerpolicy: 'referrerPolicy',
13291 rel: 'rel',
13292 required: 'required',
13293 reversed: 'reversed',
13294 role: 'role',
13295 rows: 'rows',
13296 rowspan: 'rowSpan',
13297 sandbox: 'sandbox',
13298 scope: 'scope',
13299 scoped: 'scoped',
13300 scrolling: 'scrolling',
13301 seamless: 'seamless',
13302 selected: 'selected',
13303 shape: 'shape',
13304 size: 'size',
13305 sizes: 'sizes',
13306 span: 'span',
13307 spellcheck: 'spellCheck',
13308 src: 'src',
13309 srcdoc: 'srcDoc',
13310 srclang: 'srcLang',
13311 srcset: 'srcSet',
13312 start: 'start',
13313 step: 'step',
13314 style: 'style',
13315 summary: 'summary',
13316 tabindex: 'tabIndex',
13317 target: 'target',
13318 title: 'title',
13319 type: 'type',
13320 usemap: 'useMap',
13321 value: 'value',
13322 width: 'width',
13323 wmode: 'wmode',
13324 wrap: 'wrap',
13325
13326 // SVG
13327 about: 'about',
13328 accentheight: 'accentHeight',
13329 'accent-height': 'accentHeight',
13330 accumulate: 'accumulate',
13331 additive: 'additive',
13332 alignmentbaseline: 'alignmentBaseline',
13333 'alignment-baseline': 'alignmentBaseline',
13334 allowreorder: 'allowReorder',
13335 alphabetic: 'alphabetic',
13336 amplitude: 'amplitude',
13337 arabicform: 'arabicForm',
13338 'arabic-form': 'arabicForm',
13339 ascent: 'ascent',
13340 attributename: 'attributeName',
13341 attributetype: 'attributeType',
13342 autoreverse: 'autoReverse',
13343 azimuth: 'azimuth',
13344 basefrequency: 'baseFrequency',
13345 baselineshift: 'baselineShift',
13346 'baseline-shift': 'baselineShift',
13347 baseprofile: 'baseProfile',
13348 bbox: 'bbox',
13349 begin: 'begin',
13350 bias: 'bias',
13351 by: 'by',
13352 calcmode: 'calcMode',
13353 capheight: 'capHeight',
13354 'cap-height': 'capHeight',
13355 clip: 'clip',
13356 clippath: 'clipPath',
13357 'clip-path': 'clipPath',
13358 clippathunits: 'clipPathUnits',
13359 cliprule: 'clipRule',
13360 'clip-rule': 'clipRule',
13361 color: 'color',
13362 colorinterpolation: 'colorInterpolation',
13363 'color-interpolation': 'colorInterpolation',
13364 colorinterpolationfilters: 'colorInterpolationFilters',
13365 'color-interpolation-filters': 'colorInterpolationFilters',
13366 colorprofile: 'colorProfile',
13367 'color-profile': 'colorProfile',
13368 colorrendering: 'colorRendering',
13369 'color-rendering': 'colorRendering',
13370 contentscripttype: 'contentScriptType',
13371 contentstyletype: 'contentStyleType',
13372 cursor: 'cursor',
13373 cx: 'cx',
13374 cy: 'cy',
13375 d: 'd',
13376 datatype: 'datatype',
13377 decelerate: 'decelerate',
13378 descent: 'descent',
13379 diffuseconstant: 'diffuseConstant',
13380 direction: 'direction',
13381 display: 'display',
13382 divisor: 'divisor',
13383 dominantbaseline: 'dominantBaseline',
13384 'dominant-baseline': 'dominantBaseline',
13385 dur: 'dur',
13386 dx: 'dx',
13387 dy: 'dy',
13388 edgemode: 'edgeMode',
13389 elevation: 'elevation',
13390 enablebackground: 'enableBackground',
13391 'enable-background': 'enableBackground',
13392 end: 'end',
13393 exponent: 'exponent',
13394 externalresourcesrequired: 'externalResourcesRequired',
13395 fill: 'fill',
13396 fillopacity: 'fillOpacity',
13397 'fill-opacity': 'fillOpacity',
13398 fillrule: 'fillRule',
13399 'fill-rule': 'fillRule',
13400 filter: 'filter',
13401 filterres: 'filterRes',
13402 filterunits: 'filterUnits',
13403 floodopacity: 'floodOpacity',
13404 'flood-opacity': 'floodOpacity',
13405 floodcolor: 'floodColor',
13406 'flood-color': 'floodColor',
13407 focusable: 'focusable',
13408 fontfamily: 'fontFamily',
13409 'font-family': 'fontFamily',
13410 fontsize: 'fontSize',
13411 'font-size': 'fontSize',
13412 fontsizeadjust: 'fontSizeAdjust',
13413 'font-size-adjust': 'fontSizeAdjust',
13414 fontstretch: 'fontStretch',
13415 'font-stretch': 'fontStretch',
13416 fontstyle: 'fontStyle',
13417 'font-style': 'fontStyle',
13418 fontvariant: 'fontVariant',
13419 'font-variant': 'fontVariant',
13420 fontweight: 'fontWeight',
13421 'font-weight': 'fontWeight',
13422 format: 'format',
13423 from: 'from',
13424 fx: 'fx',
13425 fy: 'fy',
13426 g1: 'g1',
13427 g2: 'g2',
13428 glyphname: 'glyphName',
13429 'glyph-name': 'glyphName',
13430 glyphorientationhorizontal: 'glyphOrientationHorizontal',
13431 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
13432 glyphorientationvertical: 'glyphOrientationVertical',
13433 'glyph-orientation-vertical': 'glyphOrientationVertical',
13434 glyphref: 'glyphRef',
13435 gradienttransform: 'gradientTransform',
13436 gradientunits: 'gradientUnits',
13437 hanging: 'hanging',
13438 horizadvx: 'horizAdvX',
13439 'horiz-adv-x': 'horizAdvX',
13440 horizoriginx: 'horizOriginX',
13441 'horiz-origin-x': 'horizOriginX',
13442 ideographic: 'ideographic',
13443 imagerendering: 'imageRendering',
13444 'image-rendering': 'imageRendering',
13445 in2: 'in2',
13446 'in': 'in',
13447 inlist: 'inlist',
13448 intercept: 'intercept',
13449 k1: 'k1',
13450 k2: 'k2',
13451 k3: 'k3',
13452 k4: 'k4',
13453 k: 'k',
13454 kernelmatrix: 'kernelMatrix',
13455 kernelunitlength: 'kernelUnitLength',
13456 kerning: 'kerning',
13457 keypoints: 'keyPoints',
13458 keysplines: 'keySplines',
13459 keytimes: 'keyTimes',
13460 lengthadjust: 'lengthAdjust',
13461 letterspacing: 'letterSpacing',
13462 'letter-spacing': 'letterSpacing',
13463 lightingcolor: 'lightingColor',
13464 'lighting-color': 'lightingColor',
13465 limitingconeangle: 'limitingConeAngle',
13466 local: 'local',
13467 markerend: 'markerEnd',
13468 'marker-end': 'markerEnd',
13469 markerheight: 'markerHeight',
13470 markermid: 'markerMid',
13471 'marker-mid': 'markerMid',
13472 markerstart: 'markerStart',
13473 'marker-start': 'markerStart',
13474 markerunits: 'markerUnits',
13475 markerwidth: 'markerWidth',
13476 mask: 'mask',
13477 maskcontentunits: 'maskContentUnits',
13478 maskunits: 'maskUnits',
13479 mathematical: 'mathematical',
13480 mode: 'mode',
13481 numoctaves: 'numOctaves',
13482 offset: 'offset',
13483 opacity: 'opacity',
13484 operator: 'operator',
13485 order: 'order',
13486 orient: 'orient',
13487 orientation: 'orientation',
13488 origin: 'origin',
13489 overflow: 'overflow',
13490 overlineposition: 'overlinePosition',
13491 'overline-position': 'overlinePosition',
13492 overlinethickness: 'overlineThickness',
13493 'overline-thickness': 'overlineThickness',
13494 paintorder: 'paintOrder',
13495 'paint-order': 'paintOrder',
13496 panose1: 'panose1',
13497 'panose-1': 'panose1',
13498 pathlength: 'pathLength',
13499 patterncontentunits: 'patternContentUnits',
13500 patterntransform: 'patternTransform',
13501 patternunits: 'patternUnits',
13502 pointerevents: 'pointerEvents',
13503 'pointer-events': 'pointerEvents',
13504 points: 'points',
13505 pointsatx: 'pointsAtX',
13506 pointsaty: 'pointsAtY',
13507 pointsatz: 'pointsAtZ',
13508 prefix: 'prefix',
13509 preservealpha: 'preserveAlpha',
13510 preserveaspectratio: 'preserveAspectRatio',
13511 primitiveunits: 'primitiveUnits',
13512 property: 'property',
13513 r: 'r',
13514 radius: 'radius',
13515 refx: 'refX',
13516 refy: 'refY',
13517 renderingintent: 'renderingIntent',
13518 'rendering-intent': 'renderingIntent',
13519 repeatcount: 'repeatCount',
13520 repeatdur: 'repeatDur',
13521 requiredextensions: 'requiredExtensions',
13522 requiredfeatures: 'requiredFeatures',
13523 resource: 'resource',
13524 restart: 'restart',
13525 result: 'result',
13526 results: 'results',
13527 rotate: 'rotate',
13528 rx: 'rx',
13529 ry: 'ry',
13530 scale: 'scale',
13531 security: 'security',
13532 seed: 'seed',
13533 shaperendering: 'shapeRendering',
13534 'shape-rendering': 'shapeRendering',
13535 slope: 'slope',
13536 spacing: 'spacing',
13537 specularconstant: 'specularConstant',
13538 specularexponent: 'specularExponent',
13539 speed: 'speed',
13540 spreadmethod: 'spreadMethod',
13541 startoffset: 'startOffset',
13542 stddeviation: 'stdDeviation',
13543 stemh: 'stemh',
13544 stemv: 'stemv',
13545 stitchtiles: 'stitchTiles',
13546 stopcolor: 'stopColor',
13547 'stop-color': 'stopColor',
13548 stopopacity: 'stopOpacity',
13549 'stop-opacity': 'stopOpacity',
13550 strikethroughposition: 'strikethroughPosition',
13551 'strikethrough-position': 'strikethroughPosition',
13552 strikethroughthickness: 'strikethroughThickness',
13553 'strikethrough-thickness': 'strikethroughThickness',
13554 string: 'string',
13555 stroke: 'stroke',
13556 strokedasharray: 'strokeDasharray',
13557 'stroke-dasharray': 'strokeDasharray',
13558 strokedashoffset: 'strokeDashoffset',
13559 'stroke-dashoffset': 'strokeDashoffset',
13560 strokelinecap: 'strokeLinecap',
13561 'stroke-linecap': 'strokeLinecap',
13562 strokelinejoin: 'strokeLinejoin',
13563 'stroke-linejoin': 'strokeLinejoin',
13564 strokemiterlimit: 'strokeMiterlimit',
13565 'stroke-miterlimit': 'strokeMiterlimit',
13566 strokewidth: 'strokeWidth',
13567 'stroke-width': 'strokeWidth',
13568 strokeopacity: 'strokeOpacity',
13569 'stroke-opacity': 'strokeOpacity',
13570 suppresscontenteditablewarning: 'suppressContentEditableWarning',
13571 suppresshydrationwarning: 'suppressHydrationWarning',
13572 surfacescale: 'surfaceScale',
13573 systemlanguage: 'systemLanguage',
13574 tablevalues: 'tableValues',
13575 targetx: 'targetX',
13576 targety: 'targetY',
13577 textanchor: 'textAnchor',
13578 'text-anchor': 'textAnchor',
13579 textdecoration: 'textDecoration',
13580 'text-decoration': 'textDecoration',
13581 textlength: 'textLength',
13582 textrendering: 'textRendering',
13583 'text-rendering': 'textRendering',
13584 to: 'to',
13585 transform: 'transform',
13586 'typeof': 'typeof',
13587 u1: 'u1',
13588 u2: 'u2',
13589 underlineposition: 'underlinePosition',
13590 'underline-position': 'underlinePosition',
13591 underlinethickness: 'underlineThickness',
13592 'underline-thickness': 'underlineThickness',
13593 unicode: 'unicode',
13594 unicodebidi: 'unicodeBidi',
13595 'unicode-bidi': 'unicodeBidi',
13596 unicoderange: 'unicodeRange',
13597 'unicode-range': 'unicodeRange',
13598 unitsperem: 'unitsPerEm',
13599 'units-per-em': 'unitsPerEm',
13600 unselectable: 'unselectable',
13601 valphabetic: 'vAlphabetic',
13602 'v-alphabetic': 'vAlphabetic',
13603 values: 'values',
13604 vectoreffect: 'vectorEffect',
13605 'vector-effect': 'vectorEffect',
13606 version: 'version',
13607 vertadvy: 'vertAdvY',
13608 'vert-adv-y': 'vertAdvY',
13609 vertoriginx: 'vertOriginX',
13610 'vert-origin-x': 'vertOriginX',
13611 vertoriginy: 'vertOriginY',
13612 'vert-origin-y': 'vertOriginY',
13613 vhanging: 'vHanging',
13614 'v-hanging': 'vHanging',
13615 videographic: 'vIdeographic',
13616 'v-ideographic': 'vIdeographic',
13617 viewbox: 'viewBox',
13618 viewtarget: 'viewTarget',
13619 visibility: 'visibility',
13620 vmathematical: 'vMathematical',
13621 'v-mathematical': 'vMathematical',
13622 vocab: 'vocab',
13623 widths: 'widths',
13624 wordspacing: 'wordSpacing',
13625 'word-spacing': 'wordSpacing',
13626 writingmode: 'writingMode',
13627 'writing-mode': 'writingMode',
13628 x1: 'x1',
13629 x2: 'x2',
13630 x: 'x',
13631 xchannelselector: 'xChannelSelector',
13632 xheight: 'xHeight',
13633 'x-height': 'xHeight',
13634 xlinkactuate: 'xlinkActuate',
13635 'xlink:actuate': 'xlinkActuate',
13636 xlinkarcrole: 'xlinkArcrole',
13637 'xlink:arcrole': 'xlinkArcrole',
13638 xlinkhref: 'xlinkHref',
13639 'xlink:href': 'xlinkHref',
13640 xlinkrole: 'xlinkRole',
13641 'xlink:role': 'xlinkRole',
13642 xlinkshow: 'xlinkShow',
13643 'xlink:show': 'xlinkShow',
13644 xlinktitle: 'xlinkTitle',
13645 'xlink:title': 'xlinkTitle',
13646 xlinktype: 'xlinkType',
13647 'xlink:type': 'xlinkType',
13648 xmlbase: 'xmlBase',
13649 'xml:base': 'xmlBase',
13650 xmllang: 'xmlLang',
13651 'xml:lang': 'xmlLang',
13652 xmlns: 'xmlns',
13653 'xml:space': 'xmlSpace',
13654 xmlnsxlink: 'xmlnsXlink',
13655 'xmlns:xlink': 'xmlnsXlink',
13656 xmlspace: 'xmlSpace',
13657 y1: 'y1',
13658 y2: 'y2',
13659 y: 'y',
13660 ychannelselector: 'yChannelSelector',
13661 z: 'z',
13662 zoomandpan: 'zoomAndPan'
13663};
13664
13665var ariaProperties = {
13666 'aria-current': 0, // state
13667 'aria-details': 0,
13668 'aria-disabled': 0, // state
13669 'aria-hidden': 0, // state
13670 'aria-invalid': 0, // state
13671 'aria-keyshortcuts': 0,
13672 'aria-label': 0,
13673 'aria-roledescription': 0,
13674 // Widget Attributes
13675 'aria-autocomplete': 0,
13676 'aria-checked': 0,
13677 'aria-expanded': 0,
13678 'aria-haspopup': 0,
13679 'aria-level': 0,
13680 'aria-modal': 0,
13681 'aria-multiline': 0,
13682 'aria-multiselectable': 0,
13683 'aria-orientation': 0,
13684 'aria-placeholder': 0,
13685 'aria-pressed': 0,
13686 'aria-readonly': 0,
13687 'aria-required': 0,
13688 'aria-selected': 0,
13689 'aria-sort': 0,
13690 'aria-valuemax': 0,
13691 'aria-valuemin': 0,
13692 'aria-valuenow': 0,
13693 'aria-valuetext': 0,
13694 // Live Region Attributes
13695 'aria-atomic': 0,
13696 'aria-busy': 0,
13697 'aria-live': 0,
13698 'aria-relevant': 0,
13699 // Drag-and-Drop Attributes
13700 'aria-dropeffect': 0,
13701 'aria-grabbed': 0,
13702 // Relationship Attributes
13703 'aria-activedescendant': 0,
13704 'aria-colcount': 0,
13705 'aria-colindex': 0,
13706 'aria-colspan': 0,
13707 'aria-controls': 0,
13708 'aria-describedby': 0,
13709 'aria-errormessage': 0,
13710 'aria-flowto': 0,
13711 'aria-labelledby': 0,
13712 'aria-owns': 0,
13713 'aria-posinset': 0,
13714 'aria-rowcount': 0,
13715 'aria-rowindex': 0,
13716 'aria-rowspan': 0,
13717 'aria-setsize': 0
13718};
13719
13720var warnedProperties = {};
13721var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13722var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13723
13724var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
13725
13726function getStackAddendum() {
13727 var stack = ReactDebugCurrentFrame.getStackAddendum();
13728 return stack != null ? stack : '';
13729}
13730
13731function validateProperty(tagName, name) {
13732 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
13733 return true;
13734 }
13735
13736 if (rARIACamel.test(name)) {
13737 var ariaName = 'aria-' + name.slice(4).toLowerCase();
13738 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
13739
13740 // If this is an aria-* attribute, but is not listed in the known DOM
13741 // DOM properties, then it is an invalid aria-* attribute.
13742 if (correctName == null) {
13743 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
13744 warnedProperties[name] = true;
13745 return true;
13746 }
13747 // aria-* attributes should be lowercase; suggest the lowercase version.
13748 if (name !== correctName) {
13749 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
13750 warnedProperties[name] = true;
13751 return true;
13752 }
13753 }
13754
13755 if (rARIA.test(name)) {
13756 var lowerCasedName = name.toLowerCase();
13757 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
13758
13759 // If this is an aria-* attribute, but is not listed in the known DOM
13760 // DOM properties, then it is an invalid aria-* attribute.
13761 if (standardName == null) {
13762 warnedProperties[name] = true;
13763 return false;
13764 }
13765 // aria-* attributes should be lowercase; suggest the lowercase version.
13766 if (name !== standardName) {
13767 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
13768 warnedProperties[name] = true;
13769 return true;
13770 }
13771 }
13772
13773 return true;
13774}
13775
13776function warnInvalidARIAProps(type, props) {
13777 var invalidProps = [];
13778
13779 for (var key in props) {
13780 var isValid = validateProperty(type, key);
13781 if (!isValid) {
13782 invalidProps.push(key);
13783 }
13784 }
13785
13786 var unknownPropString = invalidProps.map(function (prop) {
13787 return '`' + prop + '`';
13788 }).join(', ');
13789
13790 if (invalidProps.length === 1) {
13791 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13792 } else if (invalidProps.length > 1) {
13793 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13794 }
13795}
13796
13797function validateProperties(type, props) {
13798 if (isCustomComponent(type, props)) {
13799 return;
13800 }
13801 warnInvalidARIAProps(type, props);
13802}
13803
13804var didWarnValueNull = false;
13805
13806function getStackAddendum$1() {
13807 var stack = ReactDebugCurrentFrame.getStackAddendum();
13808 return stack != null ? stack : '';
13809}
13810
13811function validateProperties$1(type, props) {
13812 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
13813 return;
13814 }
13815
13816 if (props != null && props.value === null && !didWarnValueNull) {
13817 didWarnValueNull = true;
13818 if (type === 'select' && props.multiple) {
13819 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());
13820 } else {
13821 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());
13822 }
13823 }
13824}
13825
13826function getStackAddendum$2() {
13827 var stack = ReactDebugCurrentFrame.getStackAddendum();
13828 return stack != null ? stack : '';
13829}
13830
13831var validateProperty$1 = function () {};
13832
13833{
13834 var warnedProperties$1 = {};
13835 var _hasOwnProperty = Object.prototype.hasOwnProperty;
13836 var EVENT_NAME_REGEX = /^on./;
13837 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
13838 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13839 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13840
13841 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
13842 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
13843 return true;
13844 }
13845
13846 var lowerCasedName = name.toLowerCase();
13847 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
13848 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.');
13849 warnedProperties$1[name] = true;
13850 return true;
13851 }
13852
13853 // We can't rely on the event system being injected on the server.
13854 if (canUseEventSystem) {
13855 if (registrationNameModules.hasOwnProperty(name)) {
13856 return true;
13857 }
13858 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
13859 if (registrationName != null) {
13860 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
13861 warnedProperties$1[name] = true;
13862 return true;
13863 }
13864 if (EVENT_NAME_REGEX.test(name)) {
13865 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
13866 warnedProperties$1[name] = true;
13867 return true;
13868 }
13869 } else if (EVENT_NAME_REGEX.test(name)) {
13870 // If no event plugins have been injected, we are in a server environment.
13871 // So we can't tell if the event name is correct for sure, but we can filter
13872 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
13873 if (INVALID_EVENT_NAME_REGEX.test(name)) {
13874 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
13875 }
13876 warnedProperties$1[name] = true;
13877 return true;
13878 }
13879
13880 // Let the ARIA attribute hook validate ARIA attributes
13881 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
13882 return true;
13883 }
13884
13885 if (lowerCasedName === 'innerhtml') {
13886 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
13887 warnedProperties$1[name] = true;
13888 return true;
13889 }
13890
13891 if (lowerCasedName === 'aria') {
13892 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
13893 warnedProperties$1[name] = true;
13894 return true;
13895 }
13896
13897 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
13898 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());
13899 warnedProperties$1[name] = true;
13900 return true;
13901 }
13902
13903 if (typeof value === 'number' && isNaN(value)) {
13904 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
13905 warnedProperties$1[name] = true;
13906 return true;
13907 }
13908
13909 var propertyInfo = getPropertyInfo(name);
13910 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
13911
13912 // Known attributes should match the casing specified in the property config.
13913 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
13914 var standardName = possibleStandardNames[lowerCasedName];
13915 if (standardName !== name) {
13916 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
13917 warnedProperties$1[name] = true;
13918 return true;
13919 }
13920 } else if (!isReserved && name !== lowerCasedName) {
13921 // Unknown attributes should have lowercase casing since that's how they
13922 // will be cased anyway with server rendering.
13923 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());
13924 warnedProperties$1[name] = true;
13925 return true;
13926 }
13927
13928 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13929 if (value) {
13930 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());
13931 } else {
13932 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());
13933 }
13934 warnedProperties$1[name] = true;
13935 return true;
13936 }
13937
13938 // Now that we've validated casing, do not validate
13939 // data types for reserved props
13940 if (isReserved) {
13941 return true;
13942 }
13943
13944 // Warn when a known attribute is a bad type
13945 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13946 warnedProperties$1[name] = true;
13947 return false;
13948 }
13949
13950 return true;
13951 };
13952}
13953
13954var warnUnknownProperties = function (type, props, canUseEventSystem) {
13955 var unknownProps = [];
13956 for (var key in props) {
13957 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
13958 if (!isValid) {
13959 unknownProps.push(key);
13960 }
13961 }
13962
13963 var unknownPropString = unknownProps.map(function (prop) {
13964 return '`' + prop + '`';
13965 }).join(', ');
13966 if (unknownProps.length === 1) {
13967 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());
13968 } else if (unknownProps.length > 1) {
13969 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());
13970 }
13971};
13972
13973function validateProperties$2(type, props, canUseEventSystem) {
13974 if (isCustomComponent(type, props)) {
13975 return;
13976 }
13977 warnUnknownProperties(type, props, canUseEventSystem);
13978}
13979
13980// TODO: direct imports like some-package/src/* are bad. Fix me.
13981var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
13982var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13983
13984var didWarnInvalidHydration = false;
13985var didWarnShadyDOM = false;
13986
13987var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
13988var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
13989var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
13990var AUTOFOCUS = 'autoFocus';
13991var CHILDREN = 'children';
13992var STYLE = 'style';
13993var HTML = '__html';
13994
13995var HTML_NAMESPACE = Namespaces.html;
13996
13997
13998var getStack = emptyFunction_1.thatReturns('');
13999
14000var warnedUnknownTags = void 0;
14001var suppressHydrationWarning = void 0;
14002
14003var validatePropertiesInDevelopment = void 0;
14004var warnForTextDifference = void 0;
14005var warnForPropDifference = void 0;
14006var warnForExtraAttributes = void 0;
14007var warnForInvalidEventListener = void 0;
14008
14009var normalizeMarkupForTextOrAttribute = void 0;
14010var normalizeHTML = void 0;
14011
14012{
14013 getStack = getCurrentFiberStackAddendum$3;
14014
14015 warnedUnknownTags = {
14016 // Chrome is the only major browser not shipping <time>. But as of July
14017 // 2017 it intends to ship it due to widespread usage. We intentionally
14018 // *don't* warn for <time> even if it's unrecognized by Chrome because
14019 // it soon will be, and many apps have been using it anyway.
14020 time: true,
14021 // There are working polyfills for <dialog>. Let people use it.
14022 dialog: true
14023 };
14024
14025 validatePropertiesInDevelopment = function (type, props) {
14026 validateProperties(type, props);
14027 validateProperties$1(type, props);
14028 validateProperties$2(type, props, /* canUseEventSystem */true);
14029 };
14030
14031 // HTML parsing normalizes CR and CRLF to LF.
14032 // It also can turn \u0000 into \uFFFD inside attributes.
14033 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
14034 // If we have a mismatch, it might be caused by that.
14035 // We will still patch up in this case but not fire the warning.
14036 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
14037 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
14038
14039 normalizeMarkupForTextOrAttribute = function (markup) {
14040 var markupString = typeof markup === 'string' ? markup : '' + markup;
14041 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
14042 };
14043
14044 warnForTextDifference = function (serverText, clientText) {
14045 if (didWarnInvalidHydration) {
14046 return;
14047 }
14048 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
14049 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
14050 if (normalizedServerText === normalizedClientText) {
14051 return;
14052 }
14053 didWarnInvalidHydration = true;
14054 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
14055 };
14056
14057 warnForPropDifference = function (propName, serverValue, clientValue) {
14058 if (didWarnInvalidHydration) {
14059 return;
14060 }
14061 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
14062 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
14063 if (normalizedServerValue === normalizedClientValue) {
14064 return;
14065 }
14066 didWarnInvalidHydration = true;
14067 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
14068 };
14069
14070 warnForExtraAttributes = function (attributeNames) {
14071 if (didWarnInvalidHydration) {
14072 return;
14073 }
14074 didWarnInvalidHydration = true;
14075 var names = [];
14076 attributeNames.forEach(function (name) {
14077 names.push(name);
14078 });
14079 warning_1(false, 'Extra attributes from the server: %s', names);
14080 };
14081
14082 warnForInvalidEventListener = function (registrationName, listener) {
14083 if (listener === false) {
14084 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());
14085 } else {
14086 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
14087 }
14088 };
14089
14090 // Parse the HTML and read it back to normalize the HTML string so that it
14091 // can be used for comparison.
14092 normalizeHTML = function (parent, html) {
14093 // We could have created a separate document here to avoid
14094 // re-initializing custom elements if they exist. But this breaks
14095 // how <noscript> is being handled. So we use the same document.
14096 // See the discussion in https://github.com/facebook/react/pull/11157.
14097 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
14098 testElement.innerHTML = html;
14099 return testElement.innerHTML;
14100 };
14101}
14102
14103function ensureListeningTo(rootContainerElement, registrationName) {
14104 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
14105 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
14106 listenTo(registrationName, doc);
14107}
14108
14109function getOwnerDocumentFromRootContainer(rootContainerElement) {
14110 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
14111}
14112
14113function trapClickOnNonInteractiveElement(node) {
14114 // Mobile Safari does not fire properly bubble click events on
14115 // non-interactive elements, which means delegated click listeners do not
14116 // fire. The workaround for this bug involves attaching an empty click
14117 // listener on the target node.
14118 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
14119 // Just set it using the onclick property so that we don't have to manage any
14120 // bookkeeping for it. Not sure if we need to clear it when the listener is
14121 // removed.
14122 // TODO: Only do this for the relevant Safaris maybe?
14123 node.onclick = emptyFunction_1;
14124}
14125
14126function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
14127 for (var propKey in nextProps) {
14128 if (!nextProps.hasOwnProperty(propKey)) {
14129 continue;
14130 }
14131 var nextProp = nextProps[propKey];
14132 if (propKey === STYLE) {
14133 {
14134 if (nextProp) {
14135 // Freeze the next style object so that we can assume it won't be
14136 // mutated. We have already warned for this in the past.
14137 Object.freeze(nextProp);
14138 }
14139 }
14140 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14141 setValueForStyles(domElement, nextProp, getStack);
14142 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14143 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14144 if (nextHtml != null) {
14145 setInnerHTML(domElement, nextHtml);
14146 }
14147 } else if (propKey === CHILDREN) {
14148 if (typeof nextProp === 'string') {
14149 // Avoid setting initial textContent when the text is empty. In IE11 setting
14150 // textContent on a <textarea> will cause the placeholder to not
14151 // show within the <textarea> until it has been focused and blurred again.
14152 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
14153 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
14154 if (canSetTextContent) {
14155 setTextContent(domElement, nextProp);
14156 }
14157 } else if (typeof nextProp === 'number') {
14158 setTextContent(domElement, '' + nextProp);
14159 }
14160 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14161 // Noop
14162 } else if (propKey === AUTOFOCUS) {
14163 // We polyfill it separately on the client during commit.
14164 // We blacklist it here rather than in the property list because we emit it in SSR.
14165 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14166 if (nextProp != null) {
14167 if (true && typeof nextProp !== 'function') {
14168 warnForInvalidEventListener(propKey, nextProp);
14169 }
14170 ensureListeningTo(rootContainerElement, propKey);
14171 }
14172 } else if (nextProp != null) {
14173 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14174 }
14175 }
14176}
14177
14178function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14179 // TODO: Handle wasCustomComponentTag
14180 for (var i = 0; i < updatePayload.length; i += 2) {
14181 var propKey = updatePayload[i];
14182 var propValue = updatePayload[i + 1];
14183 if (propKey === STYLE) {
14184 setValueForStyles(domElement, propValue, getStack);
14185 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14186 setInnerHTML(domElement, propValue);
14187 } else if (propKey === CHILDREN) {
14188 setTextContent(domElement, propValue);
14189 } else {
14190 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14191 }
14192 }
14193}
14194
14195function createElement$1(type, props, rootContainerElement, parentNamespace) {
14196 var isCustomComponentTag = void 0;
14197
14198 // We create tags in the namespace of their parent container, except HTML
14199 // tags get no namespace.
14200 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14201 var domElement = void 0;
14202 var namespaceURI = parentNamespace;
14203 if (namespaceURI === HTML_NAMESPACE) {
14204 namespaceURI = getIntrinsicNamespace(type);
14205 }
14206 if (namespaceURI === HTML_NAMESPACE) {
14207 {
14208 isCustomComponentTag = isCustomComponent(type, props);
14209 // Should this check be gated by parent namespace? Not sure we want to
14210 // allow <SVG> or <mATH>.
14211 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14212 }
14213
14214 if (type === 'script') {
14215 // Create the script via .innerHTML so its "parser-inserted" flag is
14216 // set to true and it does not execute
14217 var div = ownerDocument.createElement('div');
14218 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14219 // This is guaranteed to yield a script element.
14220 var firstChild = div.firstChild;
14221 domElement = div.removeChild(firstChild);
14222 } else if (typeof props.is === 'string') {
14223 // $FlowIssue `createElement` should be updated for Web Components
14224 domElement = ownerDocument.createElement(type, { is: props.is });
14225 } else {
14226 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14227 // See discussion in https://github.com/facebook/react/pull/6896
14228 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14229 domElement = ownerDocument.createElement(type);
14230 }
14231 } else {
14232 domElement = ownerDocument.createElementNS(namespaceURI, type);
14233 }
14234
14235 {
14236 if (namespaceURI === HTML_NAMESPACE) {
14237 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14238 warnedUnknownTags[type] = true;
14239 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);
14240 }
14241 }
14242 }
14243
14244 return domElement;
14245}
14246
14247function createTextNode$1(text, rootContainerElement) {
14248 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14249}
14250
14251function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14252 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14253 {
14254 validatePropertiesInDevelopment(tag, rawProps);
14255 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14256 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14257 didWarnShadyDOM = true;
14258 }
14259 }
14260
14261 // TODO: Make sure that we check isMounted before firing any of these events.
14262 var props = void 0;
14263 switch (tag) {
14264 case 'iframe':
14265 case 'object':
14266 trapBubbledEvent('topLoad', 'load', domElement);
14267 props = rawProps;
14268 break;
14269 case 'video':
14270 case 'audio':
14271 // Create listener for each media event
14272 for (var event in mediaEventTypes) {
14273 if (mediaEventTypes.hasOwnProperty(event)) {
14274 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14275 }
14276 }
14277 props = rawProps;
14278 break;
14279 case 'source':
14280 trapBubbledEvent('topError', 'error', domElement);
14281 props = rawProps;
14282 break;
14283 case 'img':
14284 case 'image':
14285 case 'link':
14286 trapBubbledEvent('topError', 'error', domElement);
14287 trapBubbledEvent('topLoad', 'load', domElement);
14288 props = rawProps;
14289 break;
14290 case 'form':
14291 trapBubbledEvent('topReset', 'reset', domElement);
14292 trapBubbledEvent('topSubmit', 'submit', domElement);
14293 props = rawProps;
14294 break;
14295 case 'details':
14296 trapBubbledEvent('topToggle', 'toggle', domElement);
14297 props = rawProps;
14298 break;
14299 case 'input':
14300 initWrapperState(domElement, rawProps);
14301 props = getHostProps(domElement, rawProps);
14302 trapBubbledEvent('topInvalid', 'invalid', domElement);
14303 // For controlled components we always need to ensure we're listening
14304 // to onChange. Even if there is no listener.
14305 ensureListeningTo(rootContainerElement, 'onChange');
14306 break;
14307 case 'option':
14308 validateProps(domElement, rawProps);
14309 props = getHostProps$1(domElement, rawProps);
14310 break;
14311 case 'select':
14312 initWrapperState$1(domElement, rawProps);
14313 props = getHostProps$2(domElement, rawProps);
14314 trapBubbledEvent('topInvalid', 'invalid', domElement);
14315 // For controlled components we always need to ensure we're listening
14316 // to onChange. Even if there is no listener.
14317 ensureListeningTo(rootContainerElement, 'onChange');
14318 break;
14319 case 'textarea':
14320 initWrapperState$2(domElement, rawProps);
14321 props = getHostProps$3(domElement, rawProps);
14322 trapBubbledEvent('topInvalid', 'invalid', domElement);
14323 // For controlled components we always need to ensure we're listening
14324 // to onChange. Even if there is no listener.
14325 ensureListeningTo(rootContainerElement, 'onChange');
14326 break;
14327 default:
14328 props = rawProps;
14329 }
14330
14331 assertValidProps(tag, props, getStack);
14332
14333 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
14334
14335 switch (tag) {
14336 case 'input':
14337 // TODO: Make sure we check if this is still unmounted or do any clean
14338 // up necessary since we never stop tracking anymore.
14339 track(domElement);
14340 postMountWrapper(domElement, rawProps);
14341 break;
14342 case 'textarea':
14343 // TODO: Make sure we check if this is still unmounted or do any clean
14344 // up necessary since we never stop tracking anymore.
14345 track(domElement);
14346 postMountWrapper$3(domElement, rawProps);
14347 break;
14348 case 'option':
14349 postMountWrapper$1(domElement, rawProps);
14350 break;
14351 case 'select':
14352 postMountWrapper$2(domElement, rawProps);
14353 break;
14354 default:
14355 if (typeof props.onClick === 'function') {
14356 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14357 trapClickOnNonInteractiveElement(domElement);
14358 }
14359 break;
14360 }
14361}
14362
14363// Calculate the diff between the two objects.
14364function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
14365 {
14366 validatePropertiesInDevelopment(tag, nextRawProps);
14367 }
14368
14369 var updatePayload = null;
14370
14371 var lastProps = void 0;
14372 var nextProps = void 0;
14373 switch (tag) {
14374 case 'input':
14375 lastProps = getHostProps(domElement, lastRawProps);
14376 nextProps = getHostProps(domElement, nextRawProps);
14377 updatePayload = [];
14378 break;
14379 case 'option':
14380 lastProps = getHostProps$1(domElement, lastRawProps);
14381 nextProps = getHostProps$1(domElement, nextRawProps);
14382 updatePayload = [];
14383 break;
14384 case 'select':
14385 lastProps = getHostProps$2(domElement, lastRawProps);
14386 nextProps = getHostProps$2(domElement, nextRawProps);
14387 updatePayload = [];
14388 break;
14389 case 'textarea':
14390 lastProps = getHostProps$3(domElement, lastRawProps);
14391 nextProps = getHostProps$3(domElement, nextRawProps);
14392 updatePayload = [];
14393 break;
14394 default:
14395 lastProps = lastRawProps;
14396 nextProps = nextRawProps;
14397 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
14398 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14399 trapClickOnNonInteractiveElement(domElement);
14400 }
14401 break;
14402 }
14403
14404 assertValidProps(tag, nextProps, getStack);
14405
14406 var propKey = void 0;
14407 var styleName = void 0;
14408 var styleUpdates = null;
14409 for (propKey in lastProps) {
14410 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
14411 continue;
14412 }
14413 if (propKey === STYLE) {
14414 var lastStyle = lastProps[propKey];
14415 for (styleName in lastStyle) {
14416 if (lastStyle.hasOwnProperty(styleName)) {
14417 if (!styleUpdates) {
14418 styleUpdates = {};
14419 }
14420 styleUpdates[styleName] = '';
14421 }
14422 }
14423 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
14424 // Noop. This is handled by the clear text mechanism.
14425 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14426 // Noop
14427 } else if (propKey === AUTOFOCUS) {
14428 // Noop. It doesn't work on updates anyway.
14429 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14430 // This is a special case. If any listener updates we need to ensure
14431 // that the "current" fiber pointer gets updated so we need a commit
14432 // to update this element.
14433 if (!updatePayload) {
14434 updatePayload = [];
14435 }
14436 } else {
14437 // For all other deleted properties we add it to the queue. We use
14438 // the whitelist in the commit phase instead.
14439 (updatePayload = updatePayload || []).push(propKey, null);
14440 }
14441 }
14442 for (propKey in nextProps) {
14443 var nextProp = nextProps[propKey];
14444 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
14445 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
14446 continue;
14447 }
14448 if (propKey === STYLE) {
14449 {
14450 if (nextProp) {
14451 // Freeze the next style object so that we can assume it won't be
14452 // mutated. We have already warned for this in the past.
14453 Object.freeze(nextProp);
14454 }
14455 }
14456 if (lastProp) {
14457 // Unset styles on `lastProp` but not on `nextProp`.
14458 for (styleName in lastProp) {
14459 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
14460 if (!styleUpdates) {
14461 styleUpdates = {};
14462 }
14463 styleUpdates[styleName] = '';
14464 }
14465 }
14466 // Update styles that changed since `lastProp`.
14467 for (styleName in nextProp) {
14468 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
14469 if (!styleUpdates) {
14470 styleUpdates = {};
14471 }
14472 styleUpdates[styleName] = nextProp[styleName];
14473 }
14474 }
14475 } else {
14476 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14477 if (!styleUpdates) {
14478 if (!updatePayload) {
14479 updatePayload = [];
14480 }
14481 updatePayload.push(propKey, styleUpdates);
14482 }
14483 styleUpdates = nextProp;
14484 }
14485 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14486 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14487 var lastHtml = lastProp ? lastProp[HTML] : undefined;
14488 if (nextHtml != null) {
14489 if (lastHtml !== nextHtml) {
14490 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
14491 }
14492 } else {
14493 // TODO: It might be too late to clear this if we have children
14494 // inserted already.
14495 }
14496 } else if (propKey === CHILDREN) {
14497 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
14498 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
14499 }
14500 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14501 // Noop
14502 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14503 if (nextProp != null) {
14504 // We eagerly listen to this even though we haven't committed yet.
14505 if (true && typeof nextProp !== 'function') {
14506 warnForInvalidEventListener(propKey, nextProp);
14507 }
14508 ensureListeningTo(rootContainerElement, propKey);
14509 }
14510 if (!updatePayload && lastProp !== nextProp) {
14511 // This is a special case. If any listener updates we need to ensure
14512 // that the "current" props pointer gets updated so we need a commit
14513 // to update this element.
14514 updatePayload = [];
14515 }
14516 } else {
14517 // For any other property we always add it to the queue and then we
14518 // filter it out using the whitelist during the commit.
14519 (updatePayload = updatePayload || []).push(propKey, nextProp);
14520 }
14521 }
14522 if (styleUpdates) {
14523 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
14524 }
14525 return updatePayload;
14526}
14527
14528// Apply the diff.
14529function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
14530 // Update checked *before* name.
14531 // In the middle of an update, it is possible to have multiple checked.
14532 // When a checked radio tries to change name, browser makes another radio's checked false.
14533 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
14534 updateChecked(domElement, nextRawProps);
14535 }
14536
14537 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
14538 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
14539 // Apply the diff.
14540 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
14541
14542 // TODO: Ensure that an update gets scheduled if any of the special props
14543 // changed.
14544 switch (tag) {
14545 case 'input':
14546 // Update the wrapper around inputs *after* updating props. This has to
14547 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
14548 // raise warnings and prevent the new value from being assigned.
14549 updateWrapper(domElement, nextRawProps);
14550 break;
14551 case 'textarea':
14552 updateWrapper$1(domElement, nextRawProps);
14553 break;
14554 case 'select':
14555 // <select> value update needs to occur after <option> children
14556 // reconciliation
14557 postUpdateWrapper(domElement, nextRawProps);
14558 break;
14559 }
14560}
14561
14562function getPossibleStandardName(propName) {
14563 {
14564 var lowerCasedName = propName.toLowerCase();
14565 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14566 return null;
14567 }
14568 return possibleStandardNames[lowerCasedName] || null;
14569 }
14570 return null;
14571}
14572
14573function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
14574 var isCustomComponentTag = void 0;
14575 var extraAttributeNames = void 0;
14576
14577 {
14578 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
14579 isCustomComponentTag = isCustomComponent(tag, rawProps);
14580 validatePropertiesInDevelopment(tag, rawProps);
14581 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14582 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14583 didWarnShadyDOM = true;
14584 }
14585 }
14586
14587 // TODO: Make sure that we check isMounted before firing any of these events.
14588 switch (tag) {
14589 case 'iframe':
14590 case 'object':
14591 trapBubbledEvent('topLoad', 'load', domElement);
14592 break;
14593 case 'video':
14594 case 'audio':
14595 // Create listener for each media event
14596 for (var event in mediaEventTypes) {
14597 if (mediaEventTypes.hasOwnProperty(event)) {
14598 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14599 }
14600 }
14601 break;
14602 case 'source':
14603 trapBubbledEvent('topError', 'error', domElement);
14604 break;
14605 case 'img':
14606 case 'image':
14607 case 'link':
14608 trapBubbledEvent('topError', 'error', domElement);
14609 trapBubbledEvent('topLoad', 'load', domElement);
14610 break;
14611 case 'form':
14612 trapBubbledEvent('topReset', 'reset', domElement);
14613 trapBubbledEvent('topSubmit', 'submit', domElement);
14614 break;
14615 case 'details':
14616 trapBubbledEvent('topToggle', 'toggle', domElement);
14617 break;
14618 case 'input':
14619 initWrapperState(domElement, rawProps);
14620 trapBubbledEvent('topInvalid', 'invalid', domElement);
14621 // For controlled components we always need to ensure we're listening
14622 // to onChange. Even if there is no listener.
14623 ensureListeningTo(rootContainerElement, 'onChange');
14624 break;
14625 case 'option':
14626 validateProps(domElement, rawProps);
14627 break;
14628 case 'select':
14629 initWrapperState$1(domElement, rawProps);
14630 trapBubbledEvent('topInvalid', 'invalid', domElement);
14631 // For controlled components we always need to ensure we're listening
14632 // to onChange. Even if there is no listener.
14633 ensureListeningTo(rootContainerElement, 'onChange');
14634 break;
14635 case 'textarea':
14636 initWrapperState$2(domElement, rawProps);
14637 trapBubbledEvent('topInvalid', 'invalid', domElement);
14638 // For controlled components we always need to ensure we're listening
14639 // to onChange. Even if there is no listener.
14640 ensureListeningTo(rootContainerElement, 'onChange');
14641 break;
14642 }
14643
14644 assertValidProps(tag, rawProps, getStack);
14645
14646 {
14647 extraAttributeNames = new Set();
14648 var attributes = domElement.attributes;
14649 for (var i = 0; i < attributes.length; i++) {
14650 var name = attributes[i].name.toLowerCase();
14651 switch (name) {
14652 // Built-in SSR attribute is whitelisted
14653 case 'data-reactroot':
14654 break;
14655 // Controlled attributes are not validated
14656 // TODO: Only ignore them on controlled tags.
14657 case 'value':
14658 break;
14659 case 'checked':
14660 break;
14661 case 'selected':
14662 break;
14663 default:
14664 // Intentionally use the original name.
14665 // See discussion in https://github.com/facebook/react/pull/10676.
14666 extraAttributeNames.add(attributes[i].name);
14667 }
14668 }
14669 }
14670
14671 var updatePayload = null;
14672 for (var propKey in rawProps) {
14673 if (!rawProps.hasOwnProperty(propKey)) {
14674 continue;
14675 }
14676 var nextProp = rawProps[propKey];
14677 if (propKey === CHILDREN) {
14678 // For text content children we compare against textContent. This
14679 // might match additional HTML that is hidden when we read it using
14680 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
14681 // satisfies our requirement. Our requirement is not to produce perfect
14682 // HTML and attributes. Ideally we should preserve structure but it's
14683 // ok not to if the visible content is still enough to indicate what
14684 // even listeners these nodes might be wired up to.
14685 // TODO: Warn if there is more than a single textNode as a child.
14686 // TODO: Should we use domElement.firstChild.nodeValue to compare?
14687 if (typeof nextProp === 'string') {
14688 if (domElement.textContent !== nextProp) {
14689 if (true && !suppressHydrationWarning) {
14690 warnForTextDifference(domElement.textContent, nextProp);
14691 }
14692 updatePayload = [CHILDREN, nextProp];
14693 }
14694 } else if (typeof nextProp === 'number') {
14695 if (domElement.textContent !== '' + nextProp) {
14696 if (true && !suppressHydrationWarning) {
14697 warnForTextDifference(domElement.textContent, nextProp);
14698 }
14699 updatePayload = [CHILDREN, '' + nextProp];
14700 }
14701 }
14702 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14703 if (nextProp != null) {
14704 if (true && typeof nextProp !== 'function') {
14705 warnForInvalidEventListener(propKey, nextProp);
14706 }
14707 ensureListeningTo(rootContainerElement, propKey);
14708 }
14709 } else if (true &&
14710 // Convince Flow we've calculated it (it's DEV-only in this method.)
14711 typeof isCustomComponentTag === 'boolean') {
14712 // Validate that the properties correspond to their expected values.
14713 var serverValue = void 0;
14714 var propertyInfo = getPropertyInfo(propKey);
14715 if (suppressHydrationWarning) {
14716 // Don't bother comparing. We're ignoring all these warnings.
14717 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
14718 // Controlled attributes are not validated
14719 // TODO: Only ignore them on controlled tags.
14720 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
14721 // Noop
14722 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14723 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
14724 var serverHTML = domElement.innerHTML;
14725 var expectedHTML = normalizeHTML(domElement, rawHtml);
14726 if (expectedHTML !== serverHTML) {
14727 warnForPropDifference(propKey, serverHTML, expectedHTML);
14728 }
14729 } else if (propKey === STYLE) {
14730 // $FlowFixMe - Should be inferred as not undefined.
14731 extraAttributeNames['delete'](propKey);
14732 var expectedStyle = createDangerousStringForStyles(nextProp);
14733 serverValue = domElement.getAttribute('style');
14734 if (expectedStyle !== serverValue) {
14735 warnForPropDifference(propKey, serverValue, expectedStyle);
14736 }
14737 } else if (isCustomComponentTag) {
14738 // $FlowFixMe - Should be inferred as not undefined.
14739 extraAttributeNames['delete'](propKey.toLowerCase());
14740 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14741
14742 if (nextProp !== serverValue) {
14743 warnForPropDifference(propKey, serverValue, nextProp);
14744 }
14745 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
14746 var isMismatchDueToBadCasing = false;
14747 if (propertyInfo !== null) {
14748 // $FlowFixMe - Should be inferred as not undefined.
14749 extraAttributeNames['delete'](propertyInfo.attributeName);
14750 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
14751 } else {
14752 var ownNamespace = parentNamespace;
14753 if (ownNamespace === HTML_NAMESPACE) {
14754 ownNamespace = getIntrinsicNamespace(tag);
14755 }
14756 if (ownNamespace === HTML_NAMESPACE) {
14757 // $FlowFixMe - Should be inferred as not undefined.
14758 extraAttributeNames['delete'](propKey.toLowerCase());
14759 } else {
14760 var standardName = getPossibleStandardName(propKey);
14761 if (standardName !== null && standardName !== propKey) {
14762 // If an SVG prop is supplied with bad casing, it will
14763 // be successfully parsed from HTML, but will produce a mismatch
14764 // (and would be incorrectly rendered on the client).
14765 // However, we already warn about bad casing elsewhere.
14766 // So we'll skip the misleading extra mismatch warning in this case.
14767 isMismatchDueToBadCasing = true;
14768 // $FlowFixMe - Should be inferred as not undefined.
14769 extraAttributeNames['delete'](standardName);
14770 }
14771 // $FlowFixMe - Should be inferred as not undefined.
14772 extraAttributeNames['delete'](propKey);
14773 }
14774 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14775 }
14776
14777 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
14778 warnForPropDifference(propKey, serverValue, nextProp);
14779 }
14780 }
14781 }
14782 }
14783
14784 {
14785 // $FlowFixMe - Should be inferred as not undefined.
14786 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
14787 // $FlowFixMe - Should be inferred as not undefined.
14788 warnForExtraAttributes(extraAttributeNames);
14789 }
14790 }
14791
14792 switch (tag) {
14793 case 'input':
14794 // TODO: Make sure we check if this is still unmounted or do any clean
14795 // up necessary since we never stop tracking anymore.
14796 track(domElement);
14797 postMountWrapper(domElement, rawProps);
14798 break;
14799 case 'textarea':
14800 // TODO: Make sure we check if this is still unmounted or do any clean
14801 // up necessary since we never stop tracking anymore.
14802 track(domElement);
14803 postMountWrapper$3(domElement, rawProps);
14804 break;
14805 case 'select':
14806 case 'option':
14807 // For input and textarea we current always set the value property at
14808 // post mount to force it to diverge from attributes. However, for
14809 // option and select we don't quite do the same thing and select
14810 // is not resilient to the DOM state changing so we don't do that here.
14811 // TODO: Consider not doing this for input and textarea.
14812 break;
14813 default:
14814 if (typeof rawProps.onClick === 'function') {
14815 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14816 trapClickOnNonInteractiveElement(domElement);
14817 }
14818 break;
14819 }
14820
14821 return updatePayload;
14822}
14823
14824function diffHydratedText$1(textNode, text) {
14825 var isDifferent = textNode.nodeValue !== text;
14826 return isDifferent;
14827}
14828
14829function warnForUnmatchedText$1(textNode, text) {
14830 {
14831 warnForTextDifference(textNode.nodeValue, text);
14832 }
14833}
14834
14835function warnForDeletedHydratableElement$1(parentNode, child) {
14836 {
14837 if (didWarnInvalidHydration) {
14838 return;
14839 }
14840 didWarnInvalidHydration = true;
14841 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
14842 }
14843}
14844
14845function warnForDeletedHydratableText$1(parentNode, child) {
14846 {
14847 if (didWarnInvalidHydration) {
14848 return;
14849 }
14850 didWarnInvalidHydration = true;
14851 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
14852 }
14853}
14854
14855function warnForInsertedHydratedElement$1(parentNode, tag, props) {
14856 {
14857 if (didWarnInvalidHydration) {
14858 return;
14859 }
14860 didWarnInvalidHydration = true;
14861 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
14862 }
14863}
14864
14865function warnForInsertedHydratedText$1(parentNode, text) {
14866 {
14867 if (text === '') {
14868 // We expect to insert empty text nodes since they're not represented in
14869 // the HTML.
14870 // TODO: Remove this special case if we can just avoid inserting empty
14871 // text nodes.
14872 return;
14873 }
14874 if (didWarnInvalidHydration) {
14875 return;
14876 }
14877 didWarnInvalidHydration = true;
14878 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
14879 }
14880}
14881
14882function restoreControlledState$1(domElement, tag, props) {
14883 switch (tag) {
14884 case 'input':
14885 restoreControlledState(domElement, props);
14886 return;
14887 case 'textarea':
14888 restoreControlledState$3(domElement, props);
14889 return;
14890 case 'select':
14891 restoreControlledState$2(domElement, props);
14892 return;
14893 }
14894}
14895
14896var ReactDOMFiberComponent = Object.freeze({
14897 createElement: createElement$1,
14898 createTextNode: createTextNode$1,
14899 setInitialProperties: setInitialProperties$1,
14900 diffProperties: diffProperties$1,
14901 updateProperties: updateProperties$1,
14902 diffHydratedProperties: diffHydratedProperties$1,
14903 diffHydratedText: diffHydratedText$1,
14904 warnForUnmatchedText: warnForUnmatchedText$1,
14905 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
14906 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
14907 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
14908 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
14909 restoreControlledState: restoreControlledState$1
14910});
14911
14912// TODO: direct imports like some-package/src/* are bad. Fix me.
14913var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14914
14915var validateDOMNesting = emptyFunction_1;
14916
14917{
14918 // This validation code was written based on the HTML5 parsing spec:
14919 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14920 //
14921 // Note: this does not catch all invalid nesting, nor does it try to (as it's
14922 // not clear what practical benefit doing so provides); instead, we warn only
14923 // for cases where the parser will give a parse tree differing from what React
14924 // intended. For example, <b><div></div></b> is invalid but we don't warn
14925 // because it still parses correctly; we do warn for other cases like nested
14926 // <p> tags where the beginning of the second element implicitly closes the
14927 // first, causing a confusing mess.
14928
14929 // https://html.spec.whatwg.org/multipage/syntax.html#special
14930 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'];
14931
14932 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14933 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
14934
14935 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
14936 // TODO: Distinguish by namespace here -- for <title>, including it here
14937 // errs on the side of fewer warnings
14938 'foreignObject', 'desc', 'title'];
14939
14940 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
14941 var buttonScopeTags = inScopeTags.concat(['button']);
14942
14943 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
14944 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
14945
14946 var emptyAncestorInfo = {
14947 current: null,
14948
14949 formTag: null,
14950 aTagInScope: null,
14951 buttonTagInScope: null,
14952 nobrTagInScope: null,
14953 pTagInButtonScope: null,
14954
14955 listItemTagAutoclosing: null,
14956 dlItemTagAutoclosing: null
14957 };
14958
14959 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
14960 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
14961 var info = { tag: tag, instance: instance };
14962
14963 if (inScopeTags.indexOf(tag) !== -1) {
14964 ancestorInfo.aTagInScope = null;
14965 ancestorInfo.buttonTagInScope = null;
14966 ancestorInfo.nobrTagInScope = null;
14967 }
14968 if (buttonScopeTags.indexOf(tag) !== -1) {
14969 ancestorInfo.pTagInButtonScope = null;
14970 }
14971
14972 // See rules for 'li', 'dd', 'dt' start tags in
14973 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14974 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
14975 ancestorInfo.listItemTagAutoclosing = null;
14976 ancestorInfo.dlItemTagAutoclosing = null;
14977 }
14978
14979 ancestorInfo.current = info;
14980
14981 if (tag === 'form') {
14982 ancestorInfo.formTag = info;
14983 }
14984 if (tag === 'a') {
14985 ancestorInfo.aTagInScope = info;
14986 }
14987 if (tag === 'button') {
14988 ancestorInfo.buttonTagInScope = info;
14989 }
14990 if (tag === 'nobr') {
14991 ancestorInfo.nobrTagInScope = info;
14992 }
14993 if (tag === 'p') {
14994 ancestorInfo.pTagInButtonScope = info;
14995 }
14996 if (tag === 'li') {
14997 ancestorInfo.listItemTagAutoclosing = info;
14998 }
14999 if (tag === 'dd' || tag === 'dt') {
15000 ancestorInfo.dlItemTagAutoclosing = info;
15001 }
15002
15003 return ancestorInfo;
15004 };
15005
15006 /**
15007 * Returns whether
15008 */
15009 var isTagValidWithParent = function (tag, parentTag) {
15010 // First, let's check if we're in an unusual parsing mode...
15011 switch (parentTag) {
15012 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
15013 case 'select':
15014 return tag === 'option' || tag === 'optgroup' || tag === '#text';
15015 case 'optgroup':
15016 return tag === 'option' || tag === '#text';
15017 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
15018 // but
15019 case 'option':
15020 return tag === '#text';
15021 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
15022 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
15023 // No special behavior since these rules fall back to "in body" mode for
15024 // all except special table nodes which cause bad parsing behavior anyway.
15025
15026 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
15027 case 'tr':
15028 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
15029 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
15030 case 'tbody':
15031 case 'thead':
15032 case 'tfoot':
15033 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
15034 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
15035 case 'colgroup':
15036 return tag === 'col' || tag === 'template';
15037 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
15038 case 'table':
15039 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
15040 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
15041 case 'head':
15042 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
15043 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
15044 case 'html':
15045 return tag === 'head' || tag === 'body';
15046 case '#document':
15047 return tag === 'html';
15048 }
15049
15050 // Probably in the "in body" parsing mode, so we outlaw only tag combos
15051 // where the parsing rules cause implicit opens or closes to be added.
15052 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15053 switch (tag) {
15054 case 'h1':
15055 case 'h2':
15056 case 'h3':
15057 case 'h4':
15058 case 'h5':
15059 case 'h6':
15060 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
15061
15062 case 'rp':
15063 case 'rt':
15064 return impliedEndTags.indexOf(parentTag) === -1;
15065
15066 case 'body':
15067 case 'caption':
15068 case 'col':
15069 case 'colgroup':
15070 case 'frame':
15071 case 'head':
15072 case 'html':
15073 case 'tbody':
15074 case 'td':
15075 case 'tfoot':
15076 case 'th':
15077 case 'thead':
15078 case 'tr':
15079 // These tags are only valid with a few parents that have special child
15080 // parsing rules -- if we're down here, then none of those matched and
15081 // so we allow it only if we don't know what the parent is, as all other
15082 // cases are invalid.
15083 return parentTag == null;
15084 }
15085
15086 return true;
15087 };
15088
15089 /**
15090 * Returns whether
15091 */
15092 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
15093 switch (tag) {
15094 case 'address':
15095 case 'article':
15096 case 'aside':
15097 case 'blockquote':
15098 case 'center':
15099 case 'details':
15100 case 'dialog':
15101 case 'dir':
15102 case 'div':
15103 case 'dl':
15104 case 'fieldset':
15105 case 'figcaption':
15106 case 'figure':
15107 case 'footer':
15108 case 'header':
15109 case 'hgroup':
15110 case 'main':
15111 case 'menu':
15112 case 'nav':
15113 case 'ol':
15114 case 'p':
15115 case 'section':
15116 case 'summary':
15117 case 'ul':
15118 case 'pre':
15119 case 'listing':
15120 case 'table':
15121 case 'hr':
15122 case 'xmp':
15123 case 'h1':
15124 case 'h2':
15125 case 'h3':
15126 case 'h4':
15127 case 'h5':
15128 case 'h6':
15129 return ancestorInfo.pTagInButtonScope;
15130
15131 case 'form':
15132 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
15133
15134 case 'li':
15135 return ancestorInfo.listItemTagAutoclosing;
15136
15137 case 'dd':
15138 case 'dt':
15139 return ancestorInfo.dlItemTagAutoclosing;
15140
15141 case 'button':
15142 return ancestorInfo.buttonTagInScope;
15143
15144 case 'a':
15145 // Spec says something about storing a list of markers, but it sounds
15146 // equivalent to this check.
15147 return ancestorInfo.aTagInScope;
15148
15149 case 'nobr':
15150 return ancestorInfo.nobrTagInScope;
15151 }
15152
15153 return null;
15154 };
15155
15156 var didWarn = {};
15157
15158 validateDOMNesting = function (childTag, childText, ancestorInfo) {
15159 ancestorInfo = ancestorInfo || emptyAncestorInfo;
15160 var parentInfo = ancestorInfo.current;
15161 var parentTag = parentInfo && parentInfo.tag;
15162
15163 if (childText != null) {
15164 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
15165 childTag = '#text';
15166 }
15167
15168 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15169 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15170 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15171 if (!invalidParentOrAncestor) {
15172 return;
15173 }
15174
15175 var ancestorTag = invalidParentOrAncestor.tag;
15176 var addendum = getCurrentFiberStackAddendum$6();
15177
15178 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15179 if (didWarn[warnKey]) {
15180 return;
15181 }
15182 didWarn[warnKey] = true;
15183
15184 var tagDisplayName = childTag;
15185 var whitespaceInfo = '';
15186 if (childTag === '#text') {
15187 if (/\S/.test(childText)) {
15188 tagDisplayName = 'Text nodes';
15189 } else {
15190 tagDisplayName = 'Whitespace text nodes';
15191 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15192 }
15193 } else {
15194 tagDisplayName = '<' + childTag + '>';
15195 }
15196
15197 if (invalidParent) {
15198 var info = '';
15199 if (ancestorTag === 'table' && childTag === 'tr') {
15200 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15201 }
15202 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15203 } else {
15204 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15205 }
15206 };
15207
15208 // TODO: turn this into a named export
15209 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15210}
15211
15212var validateDOMNesting$1 = validateDOMNesting;
15213
15214// TODO: This type is shared between the reconciler and ReactDOM, but will
15215// eventually be lifted out to the renderer.
15216
15217// TODO: direct imports like some-package/src/* are bad. Fix me.
15218var createElement = createElement$1;
15219var createTextNode = createTextNode$1;
15220var setInitialProperties = setInitialProperties$1;
15221var diffProperties = diffProperties$1;
15222var updateProperties = updateProperties$1;
15223var diffHydratedProperties = diffHydratedProperties$1;
15224var diffHydratedText = diffHydratedText$1;
15225var warnForUnmatchedText = warnForUnmatchedText$1;
15226var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15227var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15228var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15229var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15230var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15231var precacheFiberNode = precacheFiberNode$1;
15232var updateFiberProps = updateFiberProps$1;
15233
15234
15235var SUPPRESS_HYDRATION_WARNING = void 0;
15236var topLevelUpdateWarnings = void 0;
15237var warnOnInvalidCallback = void 0;
15238var didWarnAboutUnstableCreatePortal = false;
15239
15240{
15241 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15242 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') {
15243 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');
15244 }
15245
15246 topLevelUpdateWarnings = function (container) {
15247 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15248 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15249 if (hostInstance) {
15250 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.');
15251 }
15252 }
15253
15254 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15255 var rootEl = getReactRootElementInContainer(container);
15256 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15257
15258 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.');
15259
15260 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.');
15261 };
15262
15263 warnOnInvalidCallback = function (callback, callerName) {
15264 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
15265 };
15266}
15267
15268injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
15269
15270var eventsEnabled = null;
15271var selectionInformation = null;
15272
15273function ReactBatch(root) {
15274 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
15275 this._expirationTime = expirationTime;
15276 this._root = root;
15277 this._next = null;
15278 this._callbacks = null;
15279 this._didComplete = false;
15280 this._hasChildren = false;
15281 this._children = null;
15282 this._defer = true;
15283}
15284ReactBatch.prototype.render = function (children) {
15285 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
15286 this._hasChildren = true;
15287 this._children = children;
15288 var internalRoot = this._root._internalRoot;
15289 var expirationTime = this._expirationTime;
15290 var work = new ReactWork();
15291 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
15292 return work;
15293};
15294ReactBatch.prototype.then = function (onComplete) {
15295 if (this._didComplete) {
15296 onComplete();
15297 return;
15298 }
15299 var callbacks = this._callbacks;
15300 if (callbacks === null) {
15301 callbacks = this._callbacks = [];
15302 }
15303 callbacks.push(onComplete);
15304};
15305ReactBatch.prototype.commit = function () {
15306 var internalRoot = this._root._internalRoot;
15307 var firstBatch = internalRoot.firstBatch;
15308 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15309
15310 if (!this._hasChildren) {
15311 // This batch is empty. Return.
15312 this._next = null;
15313 this._defer = false;
15314 return;
15315 }
15316
15317 var expirationTime = this._expirationTime;
15318
15319 // Ensure this is the first batch in the list.
15320 if (firstBatch !== this) {
15321 // This batch is not the earliest batch. We need to move it to the front.
15322 // Update its expiration time to be the expiration time of the earliest
15323 // batch, so that we can flush it without flushing the other batches.
15324 if (this._hasChildren) {
15325 expirationTime = this._expirationTime = firstBatch._expirationTime;
15326 // Rendering this batch again ensures its children will be the final state
15327 // when we flush (updates are processed in insertion order: last
15328 // update wins).
15329 // TODO: This forces a restart. Should we print a warning?
15330 this.render(this._children);
15331 }
15332
15333 // Remove the batch from the list.
15334 var previous = null;
15335 var batch = firstBatch;
15336 while (batch !== this) {
15337 previous = batch;
15338 batch = batch._next;
15339 }
15340 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15341 previous._next = batch._next;
15342
15343 // Add it to the front.
15344 this._next = firstBatch;
15345 firstBatch = internalRoot.firstBatch = this;
15346 }
15347
15348 // Synchronously flush all the work up to this batch's expiration time.
15349 this._defer = false;
15350 DOMRenderer.flushRoot(internalRoot, expirationTime);
15351
15352 // Pop the batch from the list.
15353 var next = this._next;
15354 this._next = null;
15355 firstBatch = internalRoot.firstBatch = next;
15356
15357 // Append the next earliest batch's children to the update queue.
15358 if (firstBatch !== null && firstBatch._hasChildren) {
15359 firstBatch.render(firstBatch._children);
15360 }
15361};
15362ReactBatch.prototype._onComplete = function () {
15363 if (this._didComplete) {
15364 return;
15365 }
15366 this._didComplete = true;
15367 var callbacks = this._callbacks;
15368 if (callbacks === null) {
15369 return;
15370 }
15371 // TODO: Error handling.
15372 for (var i = 0; i < callbacks.length; i++) {
15373 var _callback = callbacks[i];
15374 _callback();
15375 }
15376};
15377
15378function ReactWork() {
15379 this._callbacks = null;
15380 this._didCommit = false;
15381 // TODO: Avoid need to bind by replacing callbacks in the update queue with
15382 // list of Work objects.
15383 this._onCommit = this._onCommit.bind(this);
15384}
15385ReactWork.prototype.then = function (onCommit) {
15386 if (this._didCommit) {
15387 onCommit();
15388 return;
15389 }
15390 var callbacks = this._callbacks;
15391 if (callbacks === null) {
15392 callbacks = this._callbacks = [];
15393 }
15394 callbacks.push(onCommit);
15395};
15396ReactWork.prototype._onCommit = function () {
15397 if (this._didCommit) {
15398 return;
15399 }
15400 this._didCommit = true;
15401 var callbacks = this._callbacks;
15402 if (callbacks === null) {
15403 return;
15404 }
15405 // TODO: Error handling.
15406 for (var i = 0; i < callbacks.length; i++) {
15407 var _callback2 = callbacks[i];
15408 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
15409 _callback2();
15410 }
15411};
15412
15413function ReactRoot(container, isAsync, hydrate) {
15414 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
15415 this._internalRoot = root;
15416}
15417ReactRoot.prototype.render = function (children, callback) {
15418 var root = this._internalRoot;
15419 var work = new ReactWork();
15420 callback = callback === undefined ? null : callback;
15421 {
15422 warnOnInvalidCallback(callback, 'render');
15423 }
15424 if (callback !== null) {
15425 work.then(callback);
15426 }
15427 DOMRenderer.updateContainer(children, root, null, work._onCommit);
15428 return work;
15429};
15430ReactRoot.prototype.unmount = function (callback) {
15431 var root = this._internalRoot;
15432 var work = new ReactWork();
15433 callback = callback === undefined ? null : callback;
15434 {
15435 warnOnInvalidCallback(callback, 'render');
15436 }
15437 if (callback !== null) {
15438 work.then(callback);
15439 }
15440 DOMRenderer.updateContainer(null, root, null, work._onCommit);
15441 return work;
15442};
15443ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
15444 var root = this._internalRoot;
15445 var work = new ReactWork();
15446 callback = callback === undefined ? null : callback;
15447 {
15448 warnOnInvalidCallback(callback, 'render');
15449 }
15450 if (callback !== null) {
15451 work.then(callback);
15452 }
15453 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
15454 return work;
15455};
15456ReactRoot.prototype.createBatch = function () {
15457 var batch = new ReactBatch(this);
15458 var expirationTime = batch._expirationTime;
15459
15460 var internalRoot = this._internalRoot;
15461 var firstBatch = internalRoot.firstBatch;
15462 if (firstBatch === null) {
15463 internalRoot.firstBatch = batch;
15464 batch._next = null;
15465 } else {
15466 // Insert sorted by expiration time then insertion order
15467 var insertAfter = null;
15468 var insertBefore = firstBatch;
15469 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
15470 insertAfter = insertBefore;
15471 insertBefore = insertBefore._next;
15472 }
15473 batch._next = insertBefore;
15474 if (insertAfter !== null) {
15475 insertAfter._next = batch;
15476 }
15477 }
15478
15479 return batch;
15480};
15481
15482/**
15483 * True if the supplied DOM node is a valid node element.
15484 *
15485 * @param {?DOMElement} node The candidate DOM node.
15486 * @return {boolean} True if the DOM is a valid DOM node.
15487 * @internal
15488 */
15489function isValidContainer(node) {
15490 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 '));
15491}
15492
15493function getReactRootElementInContainer(container) {
15494 if (!container) {
15495 return null;
15496 }
15497
15498 if (container.nodeType === DOCUMENT_NODE) {
15499 return container.documentElement;
15500 } else {
15501 return container.firstChild;
15502 }
15503}
15504
15505function shouldHydrateDueToLegacyHeuristic(container) {
15506 var rootElement = getReactRootElementInContainer(container);
15507 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
15508}
15509
15510function shouldAutoFocusHostComponent(type, props) {
15511 switch (type) {
15512 case 'button':
15513 case 'input':
15514 case 'select':
15515 case 'textarea':
15516 return !!props.autoFocus;
15517 }
15518 return false;
15519}
15520
15521var DOMRenderer = reactReconciler({
15522 getRootHostContext: function (rootContainerInstance) {
15523 var type = void 0;
15524 var namespace = void 0;
15525 var nodeType = rootContainerInstance.nodeType;
15526 switch (nodeType) {
15527 case DOCUMENT_NODE:
15528 case DOCUMENT_FRAGMENT_NODE:
15529 {
15530 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
15531 var root = rootContainerInstance.documentElement;
15532 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
15533 break;
15534 }
15535 default:
15536 {
15537 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
15538 var ownNamespace = container.namespaceURI || null;
15539 type = container.tagName;
15540 namespace = getChildNamespace(ownNamespace, type);
15541 break;
15542 }
15543 }
15544 {
15545 var validatedTag = type.toLowerCase();
15546 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
15547 return { namespace: namespace, ancestorInfo: _ancestorInfo };
15548 }
15549 return namespace;
15550 },
15551 getChildHostContext: function (parentHostContext, type) {
15552 {
15553 var parentHostContextDev = parentHostContext;
15554 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
15555 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
15556 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
15557 }
15558 var parentNamespace = parentHostContext;
15559 return getChildNamespace(parentNamespace, type);
15560 },
15561 getPublicInstance: function (instance) {
15562 return instance;
15563 },
15564 prepareForCommit: function () {
15565 eventsEnabled = isEnabled();
15566 selectionInformation = getSelectionInformation();
15567 setEnabled(false);
15568 },
15569 resetAfterCommit: function () {
15570 restoreSelection(selectionInformation);
15571 selectionInformation = null;
15572 setEnabled(eventsEnabled);
15573 eventsEnabled = null;
15574 },
15575 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15576 var parentNamespace = void 0;
15577 {
15578 // TODO: take namespace into account when validating.
15579 var hostContextDev = hostContext;
15580 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
15581 if (typeof props.children === 'string' || typeof props.children === 'number') {
15582 var string = '' + props.children;
15583 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15584 validateDOMNesting$1(null, string, ownAncestorInfo);
15585 }
15586 parentNamespace = hostContextDev.namespace;
15587 }
15588 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
15589 precacheFiberNode(internalInstanceHandle, domElement);
15590 updateFiberProps(domElement, props);
15591 return domElement;
15592 },
15593 appendInitialChild: function (parentInstance, child) {
15594 parentInstance.appendChild(child);
15595 },
15596 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
15597 setInitialProperties(domElement, type, props, rootContainerInstance);
15598 return shouldAutoFocusHostComponent(type, props);
15599 },
15600 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
15601 {
15602 var hostContextDev = hostContext;
15603 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
15604 var string = '' + newProps.children;
15605 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15606 validateDOMNesting$1(null, string, ownAncestorInfo);
15607 }
15608 }
15609 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
15610 },
15611 shouldSetTextContent: function (type, props) {
15612 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
15613 },
15614 shouldDeprioritizeSubtree: function (type, props) {
15615 return !!props.hidden;
15616 },
15617 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
15618 {
15619 var hostContextDev = hostContext;
15620 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
15621 }
15622 var textNode = createTextNode(text, rootContainerInstance);
15623 precacheFiberNode(internalInstanceHandle, textNode);
15624 return textNode;
15625 },
15626
15627
15628 now: now,
15629
15630 mutation: {
15631 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
15632 // Despite the naming that might imply otherwise, this method only
15633 // fires if there is an `Update` effect scheduled during mounting.
15634 // This happens if `finalizeInitialChildren` returns `true` (which it
15635 // does to implement the `autoFocus` attribute on the client). But
15636 // there are also other cases when this might happen (such as patching
15637 // up text content during hydration mismatch). So we'll check this again.
15638 if (shouldAutoFocusHostComponent(type, newProps)) {
15639 domElement.focus();
15640 }
15641 },
15642 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
15643 // Update the props handle so that we know which props are the ones with
15644 // with current event handlers.
15645 updateFiberProps(domElement, newProps);
15646 // Apply the diff to the DOM node.
15647 updateProperties(domElement, updatePayload, type, oldProps, newProps);
15648 },
15649 resetTextContent: function (domElement) {
15650 setTextContent(domElement, '');
15651 },
15652 commitTextUpdate: function (textInstance, oldText, newText) {
15653 textInstance.nodeValue = newText;
15654 },
15655 appendChild: function (parentInstance, child) {
15656 parentInstance.appendChild(child);
15657 },
15658 appendChildToContainer: function (container, child) {
15659 if (container.nodeType === COMMENT_NODE) {
15660 container.parentNode.insertBefore(child, container);
15661 } else {
15662 container.appendChild(child);
15663 }
15664 },
15665 insertBefore: function (parentInstance, child, beforeChild) {
15666 parentInstance.insertBefore(child, beforeChild);
15667 },
15668 insertInContainerBefore: function (container, child, beforeChild) {
15669 if (container.nodeType === COMMENT_NODE) {
15670 container.parentNode.insertBefore(child, beforeChild);
15671 } else {
15672 container.insertBefore(child, beforeChild);
15673 }
15674 },
15675 removeChild: function (parentInstance, child) {
15676 parentInstance.removeChild(child);
15677 },
15678 removeChildFromContainer: function (container, child) {
15679 if (container.nodeType === COMMENT_NODE) {
15680 container.parentNode.removeChild(child);
15681 } else {
15682 container.removeChild(child);
15683 }
15684 }
15685 },
15686
15687 hydration: {
15688 canHydrateInstance: function (instance, type, props) {
15689 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
15690 return null;
15691 }
15692 // This has now been refined to an element node.
15693 return instance;
15694 },
15695 canHydrateTextInstance: function (instance, text) {
15696 if (text === '' || instance.nodeType !== TEXT_NODE) {
15697 // Empty strings are not parsed by HTML so there won't be a correct match here.
15698 return null;
15699 }
15700 // This has now been refined to a text node.
15701 return instance;
15702 },
15703 getNextHydratableSibling: function (instance) {
15704 var node = instance.nextSibling;
15705 // Skip non-hydratable nodes.
15706 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
15707 node = node.nextSibling;
15708 }
15709 return node;
15710 },
15711 getFirstHydratableChild: function (parentInstance) {
15712 var next = parentInstance.firstChild;
15713 // Skip non-hydratable nodes.
15714 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
15715 next = next.nextSibling;
15716 }
15717 return next;
15718 },
15719 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15720 precacheFiberNode(internalInstanceHandle, instance);
15721 // TODO: Possibly defer this until the commit phase where all the events
15722 // get attached.
15723 updateFiberProps(instance, props);
15724 var parentNamespace = void 0;
15725 {
15726 var hostContextDev = hostContext;
15727 parentNamespace = hostContextDev.namespace;
15728 }
15729 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
15730 },
15731 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
15732 precacheFiberNode(internalInstanceHandle, textInstance);
15733 return diffHydratedText(textInstance, text);
15734 },
15735 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
15736 {
15737 warnForUnmatchedText(textInstance, text);
15738 }
15739 },
15740 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
15741 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15742 warnForUnmatchedText(textInstance, text);
15743 }
15744 },
15745 didNotHydrateContainerInstance: function (parentContainer, instance) {
15746 {
15747 if (instance.nodeType === 1) {
15748 warnForDeletedHydratableElement(parentContainer, instance);
15749 } else {
15750 warnForDeletedHydratableText(parentContainer, instance);
15751 }
15752 }
15753 },
15754 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
15755 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15756 if (instance.nodeType === 1) {
15757 warnForDeletedHydratableElement(parentInstance, instance);
15758 } else {
15759 warnForDeletedHydratableText(parentInstance, instance);
15760 }
15761 }
15762 },
15763 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
15764 {
15765 warnForInsertedHydratedElement(parentContainer, type, props);
15766 }
15767 },
15768 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
15769 {
15770 warnForInsertedHydratedText(parentContainer, text);
15771 }
15772 },
15773 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
15774 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15775 warnForInsertedHydratedElement(parentInstance, type, props);
15776 }
15777 },
15778 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
15779 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15780 warnForInsertedHydratedText(parentInstance, text);
15781 }
15782 }
15783 },
15784
15785 scheduleDeferredCallback: rIC,
15786 cancelDeferredCallback: cIC
15787});
15788
15789injection$3.injectFiberBatchedUpdates(DOMRenderer.batchedUpdates);
15790
15791var warnedAboutHydrateAPI = false;
15792
15793function legacyCreateRootFromDOMContainer(container, forceHydrate) {
15794 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
15795 // First clear any existing content.
15796 if (!shouldHydrate) {
15797 var warned = false;
15798 var rootSibling = void 0;
15799 while (rootSibling = container.lastChild) {
15800 {
15801 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
15802 warned = true;
15803 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.');
15804 }
15805 }
15806 container.removeChild(rootSibling);
15807 }
15808 }
15809 {
15810 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
15811 warnedAboutHydrateAPI = true;
15812 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.');
15813 }
15814 }
15815 // Legacy roots are not async by default.
15816 var isAsync = false;
15817 return new ReactRoot(container, isAsync, shouldHydrate);
15818}
15819
15820function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
15821 // TODO: Ensure all entry points contain this check
15822 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15823
15824 {
15825 topLevelUpdateWarnings(container);
15826 }
15827
15828 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
15829 // member of intersection type." Whyyyyyy.
15830 var root = container._reactRootContainer;
15831 if (!root) {
15832 // Initial mount
15833 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
15834 if (typeof callback === 'function') {
15835 var originalCallback = callback;
15836 callback = function () {
15837 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15838 originalCallback.call(instance);
15839 };
15840 }
15841 // Initial mount should not be batched.
15842 DOMRenderer.unbatchedUpdates(function () {
15843 if (parentComponent != null) {
15844 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15845 } else {
15846 root.render(children, callback);
15847 }
15848 });
15849 } else {
15850 if (typeof callback === 'function') {
15851 var _originalCallback = callback;
15852 callback = function () {
15853 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15854 _originalCallback.call(instance);
15855 };
15856 }
15857 // Update
15858 if (parentComponent != null) {
15859 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15860 } else {
15861 root.render(children, callback);
15862 }
15863 }
15864 return DOMRenderer.getPublicRootInstance(root._internalRoot);
15865}
15866
15867function createPortal(children, container) {
15868 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15869
15870 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15871 // TODO: pass ReactDOM portal implementation as third argument
15872 return createPortal$1(children, container, null, key);
15873}
15874
15875var ReactDOM = {
15876 createPortal: createPortal,
15877
15878 findDOMNode: function (componentOrElement) {
15879 {
15880 var owner = ReactCurrentOwner.current;
15881 if (owner !== null) {
15882 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
15883 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');
15884 owner.stateNode._warnedAboutRefsInRender = true;
15885 }
15886 }
15887 if (componentOrElement == null) {
15888 return null;
15889 }
15890 if (componentOrElement.nodeType === ELEMENT_NODE) {
15891 return componentOrElement;
15892 }
15893
15894 var inst = get(componentOrElement);
15895 if (inst) {
15896 return DOMRenderer.findHostInstance(inst);
15897 }
15898
15899 if (typeof componentOrElement.render === 'function') {
15900 invariant_1(false, 'Unable to find node on an unmounted component.');
15901 } else {
15902 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
15903 }
15904 },
15905 hydrate: function (element, container, callback) {
15906 // TODO: throw or warn if we couldn't hydrate?
15907 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
15908 },
15909 render: function (element, container, callback) {
15910 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
15911 },
15912 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
15913 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
15914 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
15915 },
15916 unmountComponentAtNode: function (container) {
15917 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
15918
15919 if (container._reactRootContainer) {
15920 {
15921 var rootEl = getReactRootElementInContainer(container);
15922 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
15923 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
15924 }
15925
15926 // Unmount should not be batched.
15927 DOMRenderer.unbatchedUpdates(function () {
15928 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
15929 container._reactRootContainer = null;
15930 });
15931 });
15932 // If you call unmountComponentAtNode twice in quick succession, you'll
15933 // get `true` twice. That's probably fine?
15934 return true;
15935 } else {
15936 {
15937 var _rootEl = getReactRootElementInContainer(container);
15938 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
15939
15940 // Check if the container itself is a React root node.
15941 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
15942
15943 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.');
15944 }
15945
15946 return false;
15947 }
15948 },
15949
15950
15951 // Temporary alias since we already shipped React 16 RC with it.
15952 // TODO: remove in React 17.
15953 unstable_createPortal: function () {
15954 if (!didWarnAboutUnstableCreatePortal) {
15955 didWarnAboutUnstableCreatePortal = true;
15956 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.');
15957 }
15958 return createPortal.apply(undefined, arguments);
15959 },
15960
15961
15962 unstable_batchedUpdates: batchedUpdates,
15963
15964 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
15965
15966 flushSync: DOMRenderer.flushSync,
15967
15968 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
15969 // For TapEventPlugin which is popular in open source
15970 EventPluginHub: EventPluginHub,
15971 // Used by test-utils
15972 EventPluginRegistry: EventPluginRegistry,
15973 EventPropagators: EventPropagators,
15974 ReactControlledComponent: ReactControlledComponent,
15975 ReactDOMComponentTree: ReactDOMComponentTree,
15976 ReactDOMEventListener: ReactDOMEventListener
15977 }
15978};
15979
15980{
15981 // Show deprecation warnings as we don't want to support injection forever.
15982 // We do it now to let the internal injection happen without warnings.
15983 // https://github.com/facebook/react/issues/11689
15984 enableWarningOnInjection();
15985}
15986
15987if (enableCreateRoot) {
15988 ReactDOM.createRoot = function createRoot(container, options) {
15989 var hydrate = options != null && options.hydrate === true;
15990 return new ReactRoot(container, true, hydrate);
15991 };
15992}
15993
15994var foundDevTools = DOMRenderer.injectIntoDevTools({
15995 findFiberByHostInstance: getClosestInstanceFromNode,
15996 bundleType: 1,
15997 version: ReactVersion,
15998 rendererPackageName: 'react-dom'
15999});
16000
16001{
16002 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
16003 // If we're in Chrome or Firefox, provide a download link if not installed.
16004 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
16005 var protocol = window.location.protocol;
16006 // Don't warn in exotic cases like chrome-extension://.
16007 if (/^(https?|file):$/.test(protocol)) {
16008 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');
16009 }
16010 }
16011 }
16012}
16013
16014
16015
16016var ReactDOM$2 = Object.freeze({
16017 default: ReactDOM
16018});
16019
16020var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
16021
16022// TODO: decide on the top-level export form.
16023// This is hacky but makes it work with both Rollup and Jest.
16024var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
16025
16026return reactDom;
16027
16028})));