· 8 years ago · Jan 22, 2018, 11:02 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 (CS):
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 = finishedWork.child !== null ? finishedWork.child.stateNode : null;
9482 commitCallbacks(_updateQueue, _instance);
9483 }
9484 return;
9485 }
9486 case HostComponent:
9487 {
9488 var _instance2 = finishedWork.stateNode;
9489
9490 // Renderers may schedule work to be done after host components are mounted
9491 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9492 // These effects should only be committed when components are first mounted,
9493 // aka when there is no current/alternate.
9494 if (current === null && finishedWork.effectTag & Update) {
9495 var type = finishedWork.type;
9496 var props = finishedWork.memoizedProps;
9497 commitMount(_instance2, type, props, finishedWork);
9498 }
9499
9500 return;
9501 }
9502 case HostText:
9503 {
9504 // We have no life-cycles associated with text.
9505 return;
9506 }
9507 case HostPortal:
9508 {
9509 // We have no life-cycles associated with portals.
9510 return;
9511 }
9512 default:
9513 {
9514 invariant_1(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
9515 }
9516 }
9517 }
9518
9519 function commitAttachRef(finishedWork) {
9520 var ref = finishedWork.ref;
9521 if (ref !== null) {
9522 var instance = finishedWork.stateNode;
9523 switch (finishedWork.tag) {
9524 case HostComponent:
9525 ref(getPublicInstance(instance));
9526 break;
9527 default:
9528 ref(instance);
9529 }
9530 }
9531 }
9532
9533 function commitDetachRef(current) {
9534 var currentRef = current.ref;
9535 if (currentRef !== null) {
9536 currentRef(null);
9537 }
9538 }
9539
9540 // User-originating errors (lifecycles and refs) should not interrupt
9541 // deletion, so don't let them throw. Host-originating errors should
9542 // interrupt deletion, so it's okay
9543 function commitUnmount(current) {
9544 if (typeof onCommitUnmount === 'function') {
9545 onCommitUnmount(current);
9546 }
9547
9548 switch (current.tag) {
9549 case ClassComponent:
9550 {
9551 safelyDetachRef(current);
9552 var instance = current.stateNode;
9553 if (typeof instance.componentWillUnmount === 'function') {
9554 safelyCallComponentWillUnmount(current, instance);
9555 }
9556 return;
9557 }
9558 case HostComponent:
9559 {
9560 safelyDetachRef(current);
9561 return;
9562 }
9563 case CallComponent:
9564 {
9565 commitNestedUnmounts(current.stateNode);
9566 return;
9567 }
9568 case HostPortal:
9569 {
9570 // TODO: this is recursive.
9571 // We are also not using this parent because
9572 // the portal will get pushed immediately.
9573 if (enableMutatingReconciler && mutation) {
9574 unmountHostComponents(current);
9575 } else if (enablePersistentReconciler && persistence) {
9576 emptyPortalContainer(current);
9577 }
9578 return;
9579 }
9580 }
9581 }
9582
9583 function commitNestedUnmounts(root) {
9584 // While we're inside a removed host node we don't want to call
9585 // removeChild on the inner nodes because they're removed by the top
9586 // call anyway. We also want to call componentWillUnmount on all
9587 // composites before this host node is removed from the tree. Therefore
9588 var node = root;
9589 while (true) {
9590 commitUnmount(node);
9591 // Visit children because they may contain more composite or host nodes.
9592 // Skip portals because commitUnmount() currently visits them recursively.
9593 if (node.child !== null && (
9594 // If we use mutation we drill down into portals using commitUnmount above.
9595 // If we don't use mutation we drill down into portals here instead.
9596 !mutation || node.tag !== HostPortal)) {
9597 node.child['return'] = node;
9598 node = node.child;
9599 continue;
9600 }
9601 if (node === root) {
9602 return;
9603 }
9604 while (node.sibling === null) {
9605 if (node['return'] === null || node['return'] === root) {
9606 return;
9607 }
9608 node = node['return'];
9609 }
9610 node.sibling['return'] = node['return'];
9611 node = node.sibling;
9612 }
9613 }
9614
9615 function detachFiber(current) {
9616 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9617 // should clear the child pointer of the parent alternate to let this
9618 // get GC:ed but we don't know which for sure which parent is the current
9619 // one so we'll settle for GC:ing the subtree of this child. This child
9620 // itself will be GC:ed when the parent updates the next time.
9621 current['return'] = null;
9622 current.child = null;
9623 if (current.alternate) {
9624 current.alternate.child = null;
9625 current.alternate['return'] = null;
9626 }
9627 }
9628
9629 var emptyPortalContainer = void 0;
9630
9631 if (!mutation) {
9632 var commitContainer = void 0;
9633 if (persistence) {
9634 var replaceContainerChildren = persistence.replaceContainerChildren,
9635 createContainerChildSet = persistence.createContainerChildSet;
9636
9637 emptyPortalContainer = function (current) {
9638 var portal = current.stateNode;
9639 var containerInfo = portal.containerInfo;
9640
9641 var emptyChildSet = createContainerChildSet(containerInfo);
9642 replaceContainerChildren(containerInfo, emptyChildSet);
9643 };
9644 commitContainer = function (finishedWork) {
9645 switch (finishedWork.tag) {
9646 case ClassComponent:
9647 {
9648 return;
9649 }
9650 case HostComponent:
9651 {
9652 return;
9653 }
9654 case HostText:
9655 {
9656 return;
9657 }
9658 case HostRoot:
9659 case HostPortal:
9660 {
9661 var portalOrRoot = finishedWork.stateNode;
9662 var containerInfo = portalOrRoot.containerInfo,
9663 _pendingChildren = portalOrRoot.pendingChildren;
9664
9665 replaceContainerChildren(containerInfo, _pendingChildren);
9666 return;
9667 }
9668 default:
9669 {
9670 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.');
9671 }
9672 }
9673 };
9674 } else {
9675 commitContainer = function (finishedWork) {
9676 // Noop
9677 };
9678 }
9679 if (enablePersistentReconciler || enableNoopReconciler) {
9680 return {
9681 commitResetTextContent: function (finishedWork) {},
9682 commitPlacement: function (finishedWork) {},
9683 commitDeletion: function (current) {
9684 // Detach refs and call componentWillUnmount() on the whole subtree.
9685 commitNestedUnmounts(current);
9686 detachFiber(current);
9687 },
9688 commitWork: function (current, finishedWork) {
9689 commitContainer(finishedWork);
9690 },
9691
9692 commitLifeCycles: commitLifeCycles,
9693 commitAttachRef: commitAttachRef,
9694 commitDetachRef: commitDetachRef
9695 };
9696 } else if (persistence) {
9697 invariant_1(false, 'Persistent reconciler is disabled.');
9698 } else {
9699 invariant_1(false, 'Noop reconciler is disabled.');
9700 }
9701 }
9702 var commitMount = mutation.commitMount,
9703 commitUpdate = mutation.commitUpdate,
9704 resetTextContent = mutation.resetTextContent,
9705 commitTextUpdate = mutation.commitTextUpdate,
9706 appendChild = mutation.appendChild,
9707 appendChildToContainer = mutation.appendChildToContainer,
9708 insertBefore = mutation.insertBefore,
9709 insertInContainerBefore = mutation.insertInContainerBefore,
9710 removeChild = mutation.removeChild,
9711 removeChildFromContainer = mutation.removeChildFromContainer;
9712
9713
9714 function getHostParentFiber(fiber) {
9715 var parent = fiber['return'];
9716 while (parent !== null) {
9717 if (isHostParent(parent)) {
9718 return parent;
9719 }
9720 parent = parent['return'];
9721 }
9722 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9723 }
9724
9725 function isHostParent(fiber) {
9726 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9727 }
9728
9729 function getHostSibling(fiber) {
9730 // We're going to search forward into the tree until we find a sibling host
9731 // node. Unfortunately, if multiple insertions are done in a row we have to
9732 // search past them. This leads to exponential search for the next sibling.
9733 var node = fiber;
9734 siblings: while (true) {
9735 // If we didn't find anything, let's try the next sibling.
9736 while (node.sibling === null) {
9737 if (node['return'] === null || isHostParent(node['return'])) {
9738 // If we pop out of the root or hit the parent the fiber we are the
9739 // last sibling.
9740 return null;
9741 }
9742 node = node['return'];
9743 }
9744 node.sibling['return'] = node['return'];
9745 node = node.sibling;
9746 while (node.tag !== HostComponent && node.tag !== HostText) {
9747 // If it is not host node and, we might have a host node inside it.
9748 // Try to search down until we find one.
9749 if (node.effectTag & Placement) {
9750 // If we don't have a child, try the siblings instead.
9751 continue siblings;
9752 }
9753 // If we don't have a child, try the siblings instead.
9754 // We also skip portals because they are not part of this host tree.
9755 if (node.child === null || node.tag === HostPortal) {
9756 continue siblings;
9757 } else {
9758 node.child['return'] = node;
9759 node = node.child;
9760 }
9761 }
9762 // Check if this host node is stable or about to be placed.
9763 if (!(node.effectTag & Placement)) {
9764 // Found it!
9765 return node.stateNode;
9766 }
9767 }
9768 }
9769
9770 function commitPlacement(finishedWork) {
9771 // Recursively insert all host nodes into the parent.
9772 var parentFiber = getHostParentFiber(finishedWork);
9773 var parent = void 0;
9774 var isContainer = void 0;
9775 switch (parentFiber.tag) {
9776 case HostComponent:
9777 parent = parentFiber.stateNode;
9778 isContainer = false;
9779 break;
9780 case HostRoot:
9781 parent = parentFiber.stateNode.containerInfo;
9782 isContainer = true;
9783 break;
9784 case HostPortal:
9785 parent = parentFiber.stateNode.containerInfo;
9786 isContainer = true;
9787 break;
9788 default:
9789 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9790 }
9791 if (parentFiber.effectTag & ContentReset) {
9792 // Reset the text content of the parent before doing any insertions
9793 resetTextContent(parent);
9794 // Clear ContentReset from the effect tag
9795 parentFiber.effectTag &= ~ContentReset;
9796 }
9797
9798 var before = getHostSibling(finishedWork);
9799 // We only have the top Fiber that was inserted but we need recurse down its
9800 // children to find all the terminal nodes.
9801 var node = finishedWork;
9802 while (true) {
9803 if (node.tag === HostComponent || node.tag === HostText) {
9804 if (before) {
9805 if (isContainer) {
9806 insertInContainerBefore(parent, node.stateNode, before);
9807 } else {
9808 insertBefore(parent, node.stateNode, before);
9809 }
9810 } else {
9811 if (isContainer) {
9812 appendChildToContainer(parent, node.stateNode);
9813 } else {
9814 appendChild(parent, node.stateNode);
9815 }
9816 }
9817 } else if (node.tag === HostPortal) {
9818 // If the insertion itself is a portal, then we don't want to traverse
9819 // down its children. Instead, we'll get insertions from each child in
9820 // the portal directly.
9821 } else if (node.child !== null) {
9822 node.child['return'] = node;
9823 node = node.child;
9824 continue;
9825 }
9826 if (node === finishedWork) {
9827 return;
9828 }
9829 while (node.sibling === null) {
9830 if (node['return'] === null || node['return'] === finishedWork) {
9831 return;
9832 }
9833 node = node['return'];
9834 }
9835 node.sibling['return'] = node['return'];
9836 node = node.sibling;
9837 }
9838 }
9839
9840 function unmountHostComponents(current) {
9841 // We only have the top Fiber that was inserted but we need recurse down its
9842 var node = current;
9843
9844 // Each iteration, currentParent is populated with node's host parent if not
9845 // currentParentIsValid.
9846 var currentParentIsValid = false;
9847 var currentParent = void 0;
9848 var currentParentIsContainer = void 0;
9849
9850 while (true) {
9851 if (!currentParentIsValid) {
9852 var parent = node['return'];
9853 findParent: while (true) {
9854 !(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;
9855 switch (parent.tag) {
9856 case HostComponent:
9857 currentParent = parent.stateNode;
9858 currentParentIsContainer = false;
9859 break findParent;
9860 case HostRoot:
9861 currentParent = parent.stateNode.containerInfo;
9862 currentParentIsContainer = true;
9863 break findParent;
9864 case HostPortal:
9865 currentParent = parent.stateNode.containerInfo;
9866 currentParentIsContainer = true;
9867 break findParent;
9868 }
9869 parent = parent['return'];
9870 }
9871 currentParentIsValid = true;
9872 }
9873
9874 if (node.tag === HostComponent || node.tag === HostText) {
9875 commitNestedUnmounts(node);
9876 // After all the children have unmounted, it is now safe to remove the
9877 // node from the tree.
9878 if (currentParentIsContainer) {
9879 removeChildFromContainer(currentParent, node.stateNode);
9880 } else {
9881 removeChild(currentParent, node.stateNode);
9882 }
9883 // Don't visit children because we already visited them.
9884 } else if (node.tag === HostPortal) {
9885 // When we go into a portal, it becomes the parent to remove from.
9886 // We will reassign it back when we pop the portal on the way up.
9887 currentParent = node.stateNode.containerInfo;
9888 // Visit children because portals might contain host components.
9889 if (node.child !== null) {
9890 node.child['return'] = node;
9891 node = node.child;
9892 continue;
9893 }
9894 } else {
9895 commitUnmount(node);
9896 // Visit children because we may find more host components below.
9897 if (node.child !== null) {
9898 node.child['return'] = node;
9899 node = node.child;
9900 continue;
9901 }
9902 }
9903 if (node === current) {
9904 return;
9905 }
9906 while (node.sibling === null) {
9907 if (node['return'] === null || node['return'] === current) {
9908 return;
9909 }
9910 node = node['return'];
9911 if (node.tag === HostPortal) {
9912 // When we go out of the portal, we need to restore the parent.
9913 // Since we don't keep a stack of them, we will search for it.
9914 currentParentIsValid = false;
9915 }
9916 }
9917 node.sibling['return'] = node['return'];
9918 node = node.sibling;
9919 }
9920 }
9921
9922 function commitDeletion(current) {
9923 // Recursively delete all host nodes from the parent.
9924 // Detach refs and call componentWillUnmount() on the whole subtree.
9925 unmountHostComponents(current);
9926 detachFiber(current);
9927 }
9928
9929 function commitWork(current, finishedWork) {
9930 switch (finishedWork.tag) {
9931 case ClassComponent:
9932 {
9933 return;
9934 }
9935 case HostComponent:
9936 {
9937 var instance = finishedWork.stateNode;
9938 if (instance != null) {
9939 // Commit the work prepared earlier.
9940 var newProps = finishedWork.memoizedProps;
9941 // For hydration we reuse the update path but we treat the oldProps
9942 // as the newProps. The updatePayload will contain the real change in
9943 // this case.
9944 var oldProps = current !== null ? current.memoizedProps : newProps;
9945 var type = finishedWork.type;
9946 // TODO: Type the updateQueue to be specific to host components.
9947 var updatePayload = finishedWork.updateQueue;
9948 finishedWork.updateQueue = null;
9949 if (updatePayload !== null) {
9950 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
9951 }
9952 }
9953 return;
9954 }
9955 case HostText:
9956 {
9957 !(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;
9958 var textInstance = finishedWork.stateNode;
9959 var newText = finishedWork.memoizedProps;
9960 // For hydration we reuse the update path but we treat the oldProps
9961 // as the newProps. The updatePayload will contain the real change in
9962 // this case.
9963 var oldText = current !== null ? current.memoizedProps : newText;
9964 commitTextUpdate(textInstance, oldText, newText);
9965 return;
9966 }
9967 case HostRoot:
9968 {
9969 return;
9970 }
9971 default:
9972 {
9973 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.');
9974 }
9975 }
9976 }
9977
9978 function commitResetTextContent(current) {
9979 resetTextContent(current.stateNode);
9980 }
9981
9982 if (enableMutatingReconciler) {
9983 return {
9984 commitResetTextContent: commitResetTextContent,
9985 commitPlacement: commitPlacement,
9986 commitDeletion: commitDeletion,
9987 commitWork: commitWork,
9988 commitLifeCycles: commitLifeCycles,
9989 commitAttachRef: commitAttachRef,
9990 commitDetachRef: commitDetachRef
9991 };
9992 } else {
9993 invariant_1(false, 'Mutating reconciler is disabled.');
9994 }
9995};
9996
9997var NO_CONTEXT = {};
9998
9999var ReactFiberHostContext = function (config) {
10000 var getChildHostContext = config.getChildHostContext,
10001 getRootHostContext = config.getRootHostContext;
10002
10003
10004 var contextStackCursor = createCursor(NO_CONTEXT);
10005 var contextFiberStackCursor = createCursor(NO_CONTEXT);
10006 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
10007
10008 function requiredContext(c) {
10009 !(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;
10010 return c;
10011 }
10012
10013 function getRootHostContainer() {
10014 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10015 return rootInstance;
10016 }
10017
10018 function pushHostContainer(fiber, nextRootInstance) {
10019 // Push current root instance onto the stack;
10020 // This allows us to reset root when portals are popped.
10021 push(rootInstanceStackCursor, nextRootInstance, fiber);
10022
10023 var nextRootContext = getRootHostContext(nextRootInstance);
10024
10025 // Track the context and the Fiber that provided it.
10026 // This enables us to pop only Fibers that provide unique contexts.
10027 push(contextFiberStackCursor, fiber, fiber);
10028 push(contextStackCursor, nextRootContext, fiber);
10029 }
10030
10031 function popHostContainer(fiber) {
10032 pop(contextStackCursor, fiber);
10033 pop(contextFiberStackCursor, fiber);
10034 pop(rootInstanceStackCursor, fiber);
10035 }
10036
10037 function getHostContext() {
10038 var context = requiredContext(contextStackCursor.current);
10039 return context;
10040 }
10041
10042 function pushHostContext(fiber) {
10043 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10044 var context = requiredContext(contextStackCursor.current);
10045 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
10046
10047 // Don't push this Fiber's context unless it's unique.
10048 if (context === nextContext) {
10049 return;
10050 }
10051
10052 // Track the context and the Fiber that provided it.
10053 // This enables us to pop only Fibers that provide unique contexts.
10054 push(contextFiberStackCursor, fiber, fiber);
10055 push(contextStackCursor, nextContext, fiber);
10056 }
10057
10058 function popHostContext(fiber) {
10059 // Do not pop unless this Fiber provided the current context.
10060 // pushHostContext() only pushes Fibers that provide unique contexts.
10061 if (contextFiberStackCursor.current !== fiber) {
10062 return;
10063 }
10064
10065 pop(contextStackCursor, fiber);
10066 pop(contextFiberStackCursor, fiber);
10067 }
10068
10069 function resetHostContainer() {
10070 contextStackCursor.current = NO_CONTEXT;
10071 rootInstanceStackCursor.current = NO_CONTEXT;
10072 }
10073
10074 return {
10075 getHostContext: getHostContext,
10076 getRootHostContainer: getRootHostContainer,
10077 popHostContainer: popHostContainer,
10078 popHostContext: popHostContext,
10079 pushHostContainer: pushHostContainer,
10080 pushHostContext: pushHostContext,
10081 resetHostContainer: resetHostContainer
10082 };
10083};
10084
10085var ReactFiberHydrationContext = function (config) {
10086 var shouldSetTextContent = config.shouldSetTextContent,
10087 hydration = config.hydration;
10088
10089 // If this doesn't have hydration mode.
10090
10091 if (!hydration) {
10092 return {
10093 enterHydrationState: function () {
10094 return false;
10095 },
10096 resetHydrationState: function () {},
10097 tryToClaimNextHydratableInstance: function () {},
10098 prepareToHydrateHostInstance: function () {
10099 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10100 },
10101 prepareToHydrateHostTextInstance: function () {
10102 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
10103 },
10104 popHydrationState: function (fiber) {
10105 return false;
10106 }
10107 };
10108 }
10109
10110 var canHydrateInstance = hydration.canHydrateInstance,
10111 canHydrateTextInstance = hydration.canHydrateTextInstance,
10112 getNextHydratableSibling = hydration.getNextHydratableSibling,
10113 getFirstHydratableChild = hydration.getFirstHydratableChild,
10114 hydrateInstance = hydration.hydrateInstance,
10115 hydrateTextInstance = hydration.hydrateTextInstance,
10116 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
10117 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
10118 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
10119 didNotHydrateInstance = hydration.didNotHydrateInstance,
10120 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
10121 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
10122 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
10123 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
10124
10125 // The deepest Fiber on the stack involved in a hydration context.
10126 // This may have been an insertion or a hydration.
10127
10128 var hydrationParentFiber = null;
10129 var nextHydratableInstance = null;
10130 var isHydrating = false;
10131
10132 function enterHydrationState(fiber) {
10133 var parentInstance = fiber.stateNode.containerInfo;
10134 nextHydratableInstance = getFirstHydratableChild(parentInstance);
10135 hydrationParentFiber = fiber;
10136 isHydrating = true;
10137 return true;
10138 }
10139
10140 function deleteHydratableInstance(returnFiber, instance) {
10141 {
10142 switch (returnFiber.tag) {
10143 case HostRoot:
10144 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
10145 break;
10146 case HostComponent:
10147 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
10148 break;
10149 }
10150 }
10151
10152 var childToDelete = createFiberFromHostInstanceForDeletion();
10153 childToDelete.stateNode = instance;
10154 childToDelete['return'] = returnFiber;
10155 childToDelete.effectTag = Deletion;
10156
10157 // This might seem like it belongs on progressedFirstDeletion. However,
10158 // these children are not part of the reconciliation list of children.
10159 // Even if we abort and rereconcile the children, that will try to hydrate
10160 // again and the nodes are still in the host tree so these will be
10161 // recreated.
10162 if (returnFiber.lastEffect !== null) {
10163 returnFiber.lastEffect.nextEffect = childToDelete;
10164 returnFiber.lastEffect = childToDelete;
10165 } else {
10166 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
10167 }
10168 }
10169
10170 function insertNonHydratedInstance(returnFiber, fiber) {
10171 fiber.effectTag |= Placement;
10172 {
10173 switch (returnFiber.tag) {
10174 case HostRoot:
10175 {
10176 var parentContainer = returnFiber.stateNode.containerInfo;
10177 switch (fiber.tag) {
10178 case HostComponent:
10179 var type = fiber.type;
10180 var props = fiber.pendingProps;
10181 didNotFindHydratableContainerInstance(parentContainer, type, props);
10182 break;
10183 case HostText:
10184 var text = fiber.pendingProps;
10185 didNotFindHydratableContainerTextInstance(parentContainer, text);
10186 break;
10187 }
10188 break;
10189 }
10190 case HostComponent:
10191 {
10192 var parentType = returnFiber.type;
10193 var parentProps = returnFiber.memoizedProps;
10194 var parentInstance = returnFiber.stateNode;
10195 switch (fiber.tag) {
10196 case HostComponent:
10197 var _type = fiber.type;
10198 var _props = fiber.pendingProps;
10199 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
10200 break;
10201 case HostText:
10202 var _text = fiber.pendingProps;
10203 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
10204 break;
10205 }
10206 break;
10207 }
10208 default:
10209 return;
10210 }
10211 }
10212 }
10213
10214 function tryHydrate(fiber, nextInstance) {
10215 switch (fiber.tag) {
10216 case HostComponent:
10217 {
10218 var type = fiber.type;
10219 var props = fiber.pendingProps;
10220 var instance = canHydrateInstance(nextInstance, type, props);
10221 if (instance !== null) {
10222 fiber.stateNode = instance;
10223 return true;
10224 }
10225 return false;
10226 }
10227 case HostText:
10228 {
10229 var text = fiber.pendingProps;
10230 var textInstance = canHydrateTextInstance(nextInstance, text);
10231 if (textInstance !== null) {
10232 fiber.stateNode = textInstance;
10233 return true;
10234 }
10235 return false;
10236 }
10237 default:
10238 return false;
10239 }
10240 }
10241
10242 function tryToClaimNextHydratableInstance(fiber) {
10243 if (!isHydrating) {
10244 return;
10245 }
10246 var nextInstance = nextHydratableInstance;
10247 if (!nextInstance) {
10248 // Nothing to hydrate. Make it an insertion.
10249 insertNonHydratedInstance(hydrationParentFiber, fiber);
10250 isHydrating = false;
10251 hydrationParentFiber = fiber;
10252 return;
10253 }
10254 if (!tryHydrate(fiber, nextInstance)) {
10255 // If we can't hydrate this instance let's try the next one.
10256 // We use this as a heuristic. It's based on intuition and not data so it
10257 // might be flawed or unnecessary.
10258 nextInstance = getNextHydratableSibling(nextInstance);
10259 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
10260 // Nothing to hydrate. Make it an insertion.
10261 insertNonHydratedInstance(hydrationParentFiber, fiber);
10262 isHydrating = false;
10263 hydrationParentFiber = fiber;
10264 return;
10265 }
10266 // We matched the next one, we'll now assume that the first one was
10267 // superfluous and we'll delete it. Since we can't eagerly delete it
10268 // we'll have to schedule a deletion. To do that, this node needs a dummy
10269 // fiber associated with it.
10270 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
10271 }
10272 hydrationParentFiber = fiber;
10273 nextHydratableInstance = getFirstHydratableChild(nextInstance);
10274 }
10275
10276 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
10277 var instance = fiber.stateNode;
10278 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
10279 // TODO: Type this specific to this type of component.
10280 fiber.updateQueue = updatePayload;
10281 // If the update payload indicates that there is a change or if there
10282 // is a new ref we mark this as an update.
10283 if (updatePayload !== null) {
10284 return true;
10285 }
10286 return false;
10287 }
10288
10289 function prepareToHydrateHostTextInstance(fiber) {
10290 var textInstance = fiber.stateNode;
10291 var textContent = fiber.memoizedProps;
10292 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
10293 {
10294 if (shouldUpdate) {
10295 // We assume that prepareToHydrateHostTextInstance is called in a context where the
10296 // hydration parent is the parent host component of this host text.
10297 var returnFiber = hydrationParentFiber;
10298 if (returnFiber !== null) {
10299 switch (returnFiber.tag) {
10300 case HostRoot:
10301 {
10302 var parentContainer = returnFiber.stateNode.containerInfo;
10303 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
10304 break;
10305 }
10306 case HostComponent:
10307 {
10308 var parentType = returnFiber.type;
10309 var parentProps = returnFiber.memoizedProps;
10310 var parentInstance = returnFiber.stateNode;
10311 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
10312 break;
10313 }
10314 }
10315 }
10316 }
10317 }
10318 return shouldUpdate;
10319 }
10320
10321 function popToNextHostParent(fiber) {
10322 var parent = fiber['return'];
10323 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
10324 parent = parent['return'];
10325 }
10326 hydrationParentFiber = parent;
10327 }
10328
10329 function popHydrationState(fiber) {
10330 if (fiber !== hydrationParentFiber) {
10331 // We're deeper than the current hydration context, inside an inserted
10332 // tree.
10333 return false;
10334 }
10335 if (!isHydrating) {
10336 // If we're not currently hydrating but we're in a hydration context, then
10337 // we were an insertion and now need to pop up reenter hydration of our
10338 // siblings.
10339 popToNextHostParent(fiber);
10340 isHydrating = true;
10341 return false;
10342 }
10343
10344 var type = fiber.type;
10345
10346 // If we have any remaining hydratable nodes, we need to delete them now.
10347 // We only do this deeper than head and body since they tend to have random
10348 // other nodes in them. We also ignore components with pure text content in
10349 // side of them.
10350 // TODO: Better heuristic.
10351 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
10352 var nextInstance = nextHydratableInstance;
10353 while (nextInstance) {
10354 deleteHydratableInstance(fiber, nextInstance);
10355 nextInstance = getNextHydratableSibling(nextInstance);
10356 }
10357 }
10358
10359 popToNextHostParent(fiber);
10360 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
10361 return true;
10362 }
10363
10364 function resetHydrationState() {
10365 hydrationParentFiber = null;
10366 nextHydratableInstance = null;
10367 isHydrating = false;
10368 }
10369
10370 return {
10371 enterHydrationState: enterHydrationState,
10372 resetHydrationState: resetHydrationState,
10373 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
10374 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
10375 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
10376 popHydrationState: popHydrationState
10377 };
10378};
10379
10380// This lets us hook into Fiber to debug what it's doing.
10381// See https://github.com/facebook/react/pull/8033.
10382// This is not part of the public API, not even for React DevTools.
10383// You may only inject a debugTool if you work on React Fiber itself.
10384var ReactFiberInstrumentation = {
10385 debugTool: null
10386};
10387
10388var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10389
10390// This module is forked in different environments.
10391// By default, return `true` to log errors to the console.
10392// Forks can return `false` if this isn't desirable.
10393function showErrorDialog(capturedError) {
10394 return true;
10395}
10396
10397function logCapturedError(capturedError) {
10398 var logError = showErrorDialog(capturedError);
10399
10400 // Allow injected showErrorDialog() to prevent default console.error logging.
10401 // This enables renderers like ReactNative to better manage redbox behavior.
10402 if (logError === false) {
10403 return;
10404 }
10405
10406 var error = capturedError.error;
10407 var suppressLogging = error && error.suppressReactErrorLogging;
10408 if (suppressLogging) {
10409 return;
10410 }
10411
10412 {
10413 var componentName = capturedError.componentName,
10414 componentStack = capturedError.componentStack,
10415 errorBoundaryName = capturedError.errorBoundaryName,
10416 errorBoundaryFound = capturedError.errorBoundaryFound,
10417 willRetry = capturedError.willRetry;
10418
10419
10420 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10421
10422 var errorBoundaryMessage = void 0;
10423 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10424 if (errorBoundaryFound && errorBoundaryName) {
10425 if (willRetry) {
10426 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10427 } else {
10428 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10429 }
10430 } else {
10431 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.';
10432 }
10433 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10434
10435 // In development, we provide our own message with just the component stack.
10436 // We don't include the original error message and JS stack because the browser
10437 // has already printed it. Even if the application swallows the error, it is still
10438 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10439 console.error(combinedMessage);
10440 }
10441}
10442
10443var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
10444var hasCaughtError = ReactErrorUtils.hasCaughtError;
10445var clearCaughtError = ReactErrorUtils.clearCaughtError;
10446
10447
10448var didWarnAboutStateTransition = void 0;
10449var didWarnSetStateChildContext = void 0;
10450var warnAboutUpdateOnUnmounted = void 0;
10451var warnAboutInvalidUpdates = void 0;
10452
10453{
10454 didWarnAboutStateTransition = false;
10455 didWarnSetStateChildContext = false;
10456 var didWarnStateUpdateForUnmountedComponent = {};
10457
10458 warnAboutUpdateOnUnmounted = function (fiber) {
10459 var componentName = getComponentName(fiber) || 'ReactClass';
10460 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10461 return;
10462 }
10463 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);
10464 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10465 };
10466
10467 warnAboutInvalidUpdates = function (instance) {
10468 switch (ReactDebugCurrentFiber.phase) {
10469 case 'getChildContext':
10470 if (didWarnSetStateChildContext) {
10471 return;
10472 }
10473 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10474 didWarnSetStateChildContext = true;
10475 break;
10476 case 'render':
10477 if (didWarnAboutStateTransition) {
10478 return;
10479 }
10480 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`.');
10481 didWarnAboutStateTransition = true;
10482 break;
10483 }
10484 };
10485}
10486
10487var ReactFiberScheduler = function (config) {
10488 var hostContext = ReactFiberHostContext(config);
10489 var hydrationContext = ReactFiberHydrationContext(config);
10490 var popHostContainer = hostContext.popHostContainer,
10491 popHostContext = hostContext.popHostContext,
10492 resetHostContainer = hostContext.resetHostContainer;
10493
10494 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
10495 beginWork = _ReactFiberBeginWork.beginWork,
10496 beginFailedWork = _ReactFiberBeginWork.beginFailedWork;
10497
10498 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
10499 completeWork = _ReactFiberCompleteWo.completeWork;
10500
10501 var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError),
10502 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
10503 commitPlacement = _ReactFiberCommitWork.commitPlacement,
10504 commitDeletion = _ReactFiberCommitWork.commitDeletion,
10505 commitWork = _ReactFiberCommitWork.commitWork,
10506 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
10507 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
10508 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
10509
10510 var now = config.now,
10511 scheduleDeferredCallback = config.scheduleDeferredCallback,
10512 cancelDeferredCallback = config.cancelDeferredCallback,
10513 prepareForCommit = config.prepareForCommit,
10514 resetAfterCommit = config.resetAfterCommit;
10515
10516 // Represents the current time in ms.
10517
10518 var startTime = now();
10519 var mostRecentCurrentTime = msToExpirationTime(0);
10520
10521 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
10522 var lastUniqueAsyncExpiration = 0;
10523
10524 // Represents the expiration time that incoming updates should use. (If this
10525 // is NoWork, use the default strategy: async updates in async mode, sync
10526 // updates in sync mode.)
10527 var expirationContext = NoWork;
10528
10529 var isWorking = false;
10530
10531 // The next work in progress fiber that we're currently working on.
10532 var nextUnitOfWork = null;
10533 var nextRoot = null;
10534 // The time at which we're currently rendering work.
10535 var nextRenderExpirationTime = NoWork;
10536
10537 // The next fiber with an effect that we're currently committing.
10538 var nextEffect = null;
10539
10540 // Keep track of which fibers have captured an error that need to be handled.
10541 // Work is removed from this collection after componentDidCatch is called.
10542 var capturedErrors = null;
10543 // Keep track of which fibers have failed during the current batch of work.
10544 // This is a different set than capturedErrors, because it is not reset until
10545 // the end of the batch. This is needed to propagate errors correctly if a
10546 // subtree fails more than once.
10547 var failedBoundaries = null;
10548 // Error boundaries that captured an error during the current commit.
10549 var commitPhaseBoundaries = null;
10550 var firstUncaughtError = null;
10551 var didFatal = false;
10552
10553 var isCommitting = false;
10554 var isUnmounting = false;
10555
10556 // Used for performance tracking.
10557 var interruptedBy = null;
10558
10559 function resetContextStack() {
10560 // Reset the stack
10561 reset$1();
10562 // Reset the cursors
10563 resetContext();
10564 resetHostContainer();
10565 }
10566
10567 function commitAllHostEffects() {
10568 while (nextEffect !== null) {
10569 {
10570 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
10571 }
10572 recordEffect();
10573
10574 var effectTag = nextEffect.effectTag;
10575 if (effectTag & ContentReset) {
10576 commitResetTextContent(nextEffect);
10577 }
10578
10579 if (effectTag & Ref) {
10580 var current = nextEffect.alternate;
10581 if (current !== null) {
10582 commitDetachRef(current);
10583 }
10584 }
10585
10586 // The following switch statement is only concerned about placement,
10587 // updates, and deletions. To avoid needing to add a case for every
10588 // possible bitmap value, we remove the secondary effects from the
10589 // effect tag and switch on that value.
10590 var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
10591 switch (primaryEffectTag) {
10592 case Placement:
10593 {
10594 commitPlacement(nextEffect);
10595 // Clear the "placement" from effect tag so that we know that this is inserted, before
10596 // any life-cycles like componentDidMount gets called.
10597 // TODO: findDOMNode doesn't rely on this any more but isMounted
10598 // does and isMounted is deprecated anyway so we should be able
10599 // to kill this.
10600 nextEffect.effectTag &= ~Placement;
10601 break;
10602 }
10603 case PlacementAndUpdate:
10604 {
10605 // Placement
10606 commitPlacement(nextEffect);
10607 // Clear the "placement" from effect tag so that we know that this is inserted, before
10608 // any life-cycles like componentDidMount gets called.
10609 nextEffect.effectTag &= ~Placement;
10610
10611 // Update
10612 var _current = nextEffect.alternate;
10613 commitWork(_current, nextEffect);
10614 break;
10615 }
10616 case Update:
10617 {
10618 var _current2 = nextEffect.alternate;
10619 commitWork(_current2, nextEffect);
10620 break;
10621 }
10622 case Deletion:
10623 {
10624 isUnmounting = true;
10625 commitDeletion(nextEffect);
10626 isUnmounting = false;
10627 break;
10628 }
10629 }
10630 nextEffect = nextEffect.nextEffect;
10631 }
10632
10633 {
10634 ReactDebugCurrentFiber.resetCurrentFiber();
10635 }
10636 }
10637
10638 function commitAllLifeCycles() {
10639 while (nextEffect !== null) {
10640 var effectTag = nextEffect.effectTag;
10641
10642 if (effectTag & (Update | Callback)) {
10643 recordEffect();
10644 var current = nextEffect.alternate;
10645 commitLifeCycles(current, nextEffect);
10646 }
10647
10648 if (effectTag & Ref) {
10649 recordEffect();
10650 commitAttachRef(nextEffect);
10651 }
10652
10653 if (effectTag & Err) {
10654 recordEffect();
10655 commitErrorHandling(nextEffect);
10656 }
10657
10658 var next = nextEffect.nextEffect;
10659 // Ensure that we clean these up so that we don't accidentally keep them.
10660 // I'm not actually sure this matters because we can't reset firstEffect
10661 // and lastEffect since they're on every node, not just the effectful
10662 // ones. So we have to clean everything as we reuse nodes anyway.
10663 nextEffect.nextEffect = null;
10664 // Ensure that we reset the effectTag here so that we can rely on effect
10665 // tags to reason about the current life-cycle.
10666 nextEffect = next;
10667 }
10668 }
10669
10670 function commitRoot(finishedWork) {
10671 // We keep track of this so that captureError can collect any boundaries
10672 // that capture an error during the commit phase. The reason these aren't
10673 // local to this function is because errors that occur during cWU are
10674 // captured elsewhere, to prevent the unmount from being interrupted.
10675 isWorking = true;
10676 isCommitting = true;
10677 startCommitTimer();
10678
10679 var root = finishedWork.stateNode;
10680 !(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;
10681 root.isReadyForCommit = false;
10682
10683 // Reset this to null before calling lifecycles
10684 ReactCurrentOwner.current = null;
10685
10686 var firstEffect = void 0;
10687 if (finishedWork.effectTag > PerformedWork) {
10688 // A fiber's effect list consists only of its children, not itself. So if
10689 // the root has an effect, we need to add it to the end of the list. The
10690 // resulting list is the set that would belong to the root's parent, if
10691 // it had one; that is, all the effects in the tree including the root.
10692 if (finishedWork.lastEffect !== null) {
10693 finishedWork.lastEffect.nextEffect = finishedWork;
10694 firstEffect = finishedWork.firstEffect;
10695 } else {
10696 firstEffect = finishedWork;
10697 }
10698 } else {
10699 // There is no effect on the root.
10700 firstEffect = finishedWork.firstEffect;
10701 }
10702
10703 prepareForCommit();
10704
10705 // Commit all the side-effects within a tree. We'll do this in two passes.
10706 // The first pass performs all the host insertions, updates, deletions and
10707 // ref unmounts.
10708 nextEffect = firstEffect;
10709 startCommitHostEffectsTimer();
10710 while (nextEffect !== null) {
10711 var didError = false;
10712 var _error = void 0;
10713 {
10714 invokeGuardedCallback$2(null, commitAllHostEffects, null);
10715 if (hasCaughtError()) {
10716 didError = true;
10717 _error = clearCaughtError();
10718 }
10719 }
10720 if (didError) {
10721 !(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;
10722 captureError(nextEffect, _error);
10723 // Clean-up
10724 if (nextEffect !== null) {
10725 nextEffect = nextEffect.nextEffect;
10726 }
10727 }
10728 }
10729 stopCommitHostEffectsTimer();
10730
10731 resetAfterCommit();
10732
10733 // The work-in-progress tree is now the current tree. This must come after
10734 // the first pass of the commit phase, so that the previous tree is still
10735 // current during componentWillUnmount, but before the second pass, so that
10736 // the finished work is current during componentDidMount/Update.
10737 root.current = finishedWork;
10738
10739 // In the second pass we'll perform all life-cycles and ref callbacks.
10740 // Life-cycles happen as a separate pass so that all placements, updates,
10741 // and deletions in the entire tree have already been invoked.
10742 // This pass also triggers any renderer-specific initial effects.
10743 nextEffect = firstEffect;
10744 startCommitLifeCyclesTimer();
10745 while (nextEffect !== null) {
10746 var _didError = false;
10747 var _error2 = void 0;
10748 {
10749 invokeGuardedCallback$2(null, commitAllLifeCycles, null);
10750 if (hasCaughtError()) {
10751 _didError = true;
10752 _error2 = clearCaughtError();
10753 }
10754 }
10755 if (_didError) {
10756 !(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;
10757 captureError(nextEffect, _error2);
10758 if (nextEffect !== null) {
10759 nextEffect = nextEffect.nextEffect;
10760 }
10761 }
10762 }
10763
10764 isCommitting = false;
10765 isWorking = false;
10766 stopCommitLifeCyclesTimer();
10767 stopCommitTimer();
10768 if (typeof onCommitRoot === 'function') {
10769 onCommitRoot(finishedWork.stateNode);
10770 }
10771 if (true && ReactFiberInstrumentation_1.debugTool) {
10772 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
10773 }
10774
10775 // If we caught any errors during this commit, schedule their boundaries
10776 // to update.
10777 if (commitPhaseBoundaries) {
10778 commitPhaseBoundaries.forEach(scheduleErrorRecovery);
10779 commitPhaseBoundaries = null;
10780 }
10781
10782 if (firstUncaughtError !== null) {
10783 var _error3 = firstUncaughtError;
10784 firstUncaughtError = null;
10785 onUncaughtError(_error3);
10786 }
10787
10788 var remainingTime = root.current.expirationTime;
10789
10790 if (remainingTime === NoWork) {
10791 capturedErrors = null;
10792 failedBoundaries = null;
10793 }
10794
10795 return remainingTime;
10796 }
10797
10798 function resetExpirationTime(workInProgress, renderTime) {
10799 if (renderTime !== Never && workInProgress.expirationTime === Never) {
10800 // The children of this component are hidden. Don't bubble their
10801 // expiration times.
10802 return;
10803 }
10804
10805 // Check for pending updates.
10806 var newExpirationTime = getUpdateExpirationTime(workInProgress);
10807
10808 // TODO: Calls need to visit stateNode
10809
10810 // Bubble up the earliest expiration time.
10811 var child = workInProgress.child;
10812 while (child !== null) {
10813 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
10814 newExpirationTime = child.expirationTime;
10815 }
10816 child = child.sibling;
10817 }
10818 workInProgress.expirationTime = newExpirationTime;
10819 }
10820
10821 function completeUnitOfWork(workInProgress) {
10822 while (true) {
10823 // The current, flushed, state of this fiber is the alternate.
10824 // Ideally nothing should rely on this, but relying on it here
10825 // means that we don't need an additional field on the work in
10826 // progress.
10827 var current = workInProgress.alternate;
10828 {
10829 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10830 }
10831 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
10832 {
10833 ReactDebugCurrentFiber.resetCurrentFiber();
10834 }
10835
10836 var returnFiber = workInProgress['return'];
10837 var siblingFiber = workInProgress.sibling;
10838
10839 resetExpirationTime(workInProgress, nextRenderExpirationTime);
10840
10841 if (next !== null) {
10842 stopWorkTimer(workInProgress);
10843 if (true && ReactFiberInstrumentation_1.debugTool) {
10844 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10845 }
10846 // If completing this work spawned new work, do that next. We'll come
10847 // back here again.
10848 return next;
10849 }
10850
10851 if (returnFiber !== null) {
10852 // Append all the effects of the subtree and this fiber onto the effect
10853 // list of the parent. The completion order of the children affects the
10854 // side-effect order.
10855 if (returnFiber.firstEffect === null) {
10856 returnFiber.firstEffect = workInProgress.firstEffect;
10857 }
10858 if (workInProgress.lastEffect !== null) {
10859 if (returnFiber.lastEffect !== null) {
10860 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
10861 }
10862 returnFiber.lastEffect = workInProgress.lastEffect;
10863 }
10864
10865 // If this fiber had side-effects, we append it AFTER the children's
10866 // side-effects. We can perform certain side-effects earlier if
10867 // needed, by doing multiple passes over the effect list. We don't want
10868 // to schedule our own side-effect on our own list because if end up
10869 // reusing children we'll schedule this effect onto itself since we're
10870 // at the end.
10871 var effectTag = workInProgress.effectTag;
10872 // Skip both NoWork and PerformedWork tags when creating the effect list.
10873 // PerformedWork effect is read by React DevTools but shouldn't be committed.
10874 if (effectTag > PerformedWork) {
10875 if (returnFiber.lastEffect !== null) {
10876 returnFiber.lastEffect.nextEffect = workInProgress;
10877 } else {
10878 returnFiber.firstEffect = workInProgress;
10879 }
10880 returnFiber.lastEffect = workInProgress;
10881 }
10882 }
10883
10884 stopWorkTimer(workInProgress);
10885 if (true && ReactFiberInstrumentation_1.debugTool) {
10886 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10887 }
10888
10889 if (siblingFiber !== null) {
10890 // If there is more work to do in this returnFiber, do that next.
10891 return siblingFiber;
10892 } else if (returnFiber !== null) {
10893 // If there's no more work in this returnFiber. Complete the returnFiber.
10894 workInProgress = returnFiber;
10895 continue;
10896 } else {
10897 // We've reached the root.
10898 var root = workInProgress.stateNode;
10899 root.isReadyForCommit = true;
10900 return null;
10901 }
10902 }
10903
10904 // Without this explicit null return Flow complains of invalid return type
10905 // TODO Remove the above while(true) loop
10906 // eslint-disable-next-line no-unreachable
10907 return null;
10908 }
10909
10910 function performUnitOfWork(workInProgress) {
10911 // The current, flushed, state of this fiber is the alternate.
10912 // Ideally nothing should rely on this, but relying on it here
10913 // means that we don't need an additional field on the work in
10914 // progress.
10915 var current = workInProgress.alternate;
10916
10917 // See if beginning this work spawns more work.
10918 startWorkTimer(workInProgress);
10919 {
10920 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10921 }
10922
10923 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
10924 {
10925 ReactDebugCurrentFiber.resetCurrentFiber();
10926 }
10927 if (true && ReactFiberInstrumentation_1.debugTool) {
10928 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10929 }
10930
10931 if (next === null) {
10932 // If this doesn't spawn new work, complete the current work.
10933 next = completeUnitOfWork(workInProgress);
10934 }
10935
10936 ReactCurrentOwner.current = null;
10937
10938 return next;
10939 }
10940
10941 function performFailedUnitOfWork(workInProgress) {
10942 // The current, flushed, state of this fiber is the alternate.
10943 // Ideally nothing should rely on this, but relying on it here
10944 // means that we don't need an additional field on the work in
10945 // progress.
10946 var current = workInProgress.alternate;
10947
10948 // See if beginning this work spawns more work.
10949 startWorkTimer(workInProgress);
10950 {
10951 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10952 }
10953 var next = beginFailedWork(current, workInProgress, nextRenderExpirationTime);
10954 {
10955 ReactDebugCurrentFiber.resetCurrentFiber();
10956 }
10957 if (true && ReactFiberInstrumentation_1.debugTool) {
10958 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10959 }
10960
10961 if (next === null) {
10962 // If this doesn't spawn new work, complete the current work.
10963 next = completeUnitOfWork(workInProgress);
10964 }
10965
10966 ReactCurrentOwner.current = null;
10967
10968 return next;
10969 }
10970
10971 function workLoop(expirationTime) {
10972 if (capturedErrors !== null) {
10973 // If there are unhandled errors, switch to the slow work loop.
10974 // TODO: How to avoid this check in the fast path? Maybe the renderer
10975 // could keep track of which roots have unhandled errors and call a
10976 // forked version of renderRoot.
10977 slowWorkLoopThatChecksForFailedWork(expirationTime);
10978 return;
10979 }
10980 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10981 return;
10982 }
10983
10984 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10985 // Flush all expired work.
10986 while (nextUnitOfWork !== null) {
10987 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10988 }
10989 } else {
10990 // Flush asynchronous work until the deadline runs out of time.
10991 while (nextUnitOfWork !== null && !shouldYield()) {
10992 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10993 }
10994 }
10995 }
10996
10997 function slowWorkLoopThatChecksForFailedWork(expirationTime) {
10998 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10999 return;
11000 }
11001
11002 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
11003 // Flush all expired work.
11004 while (nextUnitOfWork !== null) {
11005 if (hasCapturedError(nextUnitOfWork)) {
11006 // Use a forked version of performUnitOfWork
11007 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11008 } else {
11009 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11010 }
11011 }
11012 } else {
11013 // Flush asynchronous work until the deadline runs out of time.
11014 while (nextUnitOfWork !== null && !shouldYield()) {
11015 if (hasCapturedError(nextUnitOfWork)) {
11016 // Use a forked version of performUnitOfWork
11017 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
11018 } else {
11019 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11020 }
11021 }
11022 }
11023 }
11024
11025 function renderRootCatchBlock(root, failedWork, boundary, expirationTime) {
11026 // We're going to restart the error boundary that captured the error.
11027 // Conceptually, we're unwinding the stack. We need to unwind the
11028 // context stack, too.
11029 unwindContexts(failedWork, boundary);
11030
11031 // Restart the error boundary using a forked version of
11032 // performUnitOfWork that deletes the boundary's children. The entire
11033 // failed subree will be unmounted. During the commit phase, a special
11034 // lifecycle method is called on the error boundary, which triggers
11035 // a re-render.
11036 nextUnitOfWork = performFailedUnitOfWork(boundary);
11037
11038 // Continue working.
11039 workLoop(expirationTime);
11040 }
11041
11042 function renderRoot(root, expirationTime) {
11043 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11044 isWorking = true;
11045
11046 // We're about to mutate the work-in-progress tree. If the root was pending
11047 // commit, it no longer is: we'll need to complete it again.
11048 root.isReadyForCommit = false;
11049
11050 // Check if we're starting from a fresh stack, or if we're resuming from
11051 // previously yielded work.
11052 if (root !== nextRoot || expirationTime !== nextRenderExpirationTime || nextUnitOfWork === null) {
11053 // Reset the stack and start working from the root.
11054 resetContextStack();
11055 nextRoot = root;
11056 nextRenderExpirationTime = expirationTime;
11057 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, expirationTime);
11058 }
11059
11060 startWorkLoopTimer(nextUnitOfWork);
11061
11062 var didError = false;
11063 var error = null;
11064 {
11065 invokeGuardedCallback$2(null, workLoop, null, expirationTime);
11066 if (hasCaughtError()) {
11067 didError = true;
11068 error = clearCaughtError();
11069 }
11070 }
11071
11072 // An error was thrown during the render phase.
11073 while (didError) {
11074 if (didFatal) {
11075 // This was a fatal error. Don't attempt to recover from it.
11076 firstUncaughtError = error;
11077 break;
11078 }
11079
11080 var failedWork = nextUnitOfWork;
11081 if (failedWork === null) {
11082 // An error was thrown but there's no current unit of work. This can
11083 // happen during the commit phase if there's a bug in the renderer.
11084 didFatal = true;
11085 continue;
11086 }
11087
11088 // "Capture" the error by finding the nearest boundary. If there is no
11089 // error boundary, we use the root.
11090 var boundary = captureError(failedWork, error);
11091 !(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;
11092
11093 if (didFatal) {
11094 // The error we just captured was a fatal error. This happens
11095 // when the error propagates to the root more than once.
11096 continue;
11097 }
11098
11099 didError = false;
11100 error = null;
11101 {
11102 invokeGuardedCallback$2(null, renderRootCatchBlock, null, root, failedWork, boundary, expirationTime);
11103 if (hasCaughtError()) {
11104 didError = true;
11105 error = clearCaughtError();
11106 continue;
11107 }
11108 }
11109 // We're finished working. Exit the error loop.
11110 break;
11111 }
11112
11113 var uncaughtError = firstUncaughtError;
11114
11115 // We're done performing work. Time to clean up.
11116 stopWorkLoopTimer(interruptedBy);
11117 interruptedBy = null;
11118 isWorking = false;
11119 didFatal = false;
11120 firstUncaughtError = null;
11121
11122 if (uncaughtError !== null) {
11123 onUncaughtError(uncaughtError);
11124 }
11125
11126 return root.isReadyForCommit ? root.current.alternate : null;
11127 }
11128
11129 // Returns the boundary that captured the error, or null if the error is ignored
11130 function captureError(failedWork, error) {
11131 // It is no longer valid because we exited the user code.
11132 ReactCurrentOwner.current = null;
11133 {
11134 ReactDebugCurrentFiber.resetCurrentFiber();
11135 }
11136
11137 // Search for the nearest error boundary.
11138 var boundary = null;
11139
11140 // Passed to logCapturedError()
11141 var errorBoundaryFound = false;
11142 var willRetry = false;
11143 var errorBoundaryName = null;
11144
11145 // Host containers are a special case. If the failed work itself is a host
11146 // container, then it acts as its own boundary. In all other cases, we
11147 // ignore the work itself and only search through the parents.
11148 if (failedWork.tag === HostRoot) {
11149 boundary = failedWork;
11150
11151 if (isFailedBoundary(failedWork)) {
11152 // If this root already failed, there must have been an error when
11153 // attempting to unmount it. This is a worst-case scenario and
11154 // should only be possible if there's a bug in the renderer.
11155 didFatal = true;
11156 }
11157 } else {
11158 var node = failedWork['return'];
11159 while (node !== null && boundary === null) {
11160 if (node.tag === ClassComponent) {
11161 var instance = node.stateNode;
11162 if (typeof instance.componentDidCatch === 'function') {
11163 errorBoundaryFound = true;
11164 errorBoundaryName = getComponentName(node);
11165
11166 // Found an error boundary!
11167 boundary = node;
11168 willRetry = true;
11169 }
11170 } else if (node.tag === HostRoot) {
11171 // Treat the root like a no-op error boundary
11172 boundary = node;
11173 }
11174
11175 if (isFailedBoundary(node)) {
11176 // This boundary is already in a failed state.
11177
11178 // If we're currently unmounting, that means this error was
11179 // thrown while unmounting a failed subtree. We should ignore
11180 // the error.
11181 if (isUnmounting) {
11182 return null;
11183 }
11184
11185 // If we're in the commit phase, we should check to see if
11186 // this boundary already captured an error during this commit.
11187 // This case exists because multiple errors can be thrown during
11188 // a single commit without interruption.
11189 if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) {
11190 // If so, we should ignore this error.
11191 return null;
11192 }
11193
11194 // The error should propagate to the next boundary -? we keep looking.
11195 boundary = null;
11196 willRetry = false;
11197 }
11198
11199 node = node['return'];
11200 }
11201 }
11202
11203 if (boundary !== null) {
11204 // Add to the collection of failed boundaries. This lets us know that
11205 // subsequent errors in this subtree should propagate to the next boundary.
11206 if (failedBoundaries === null) {
11207 failedBoundaries = new Set();
11208 }
11209 failedBoundaries.add(boundary);
11210
11211 // This method is unsafe outside of the begin and complete phases.
11212 // We might be in the commit phase when an error is captured.
11213 // The risk is that the return path from this Fiber may not be accurate.
11214 // That risk is acceptable given the benefit of providing users more context.
11215 var _componentStack = getStackAddendumByWorkInProgressFiber(failedWork);
11216 var _componentName = getComponentName(failedWork);
11217
11218 // Add to the collection of captured errors. This is stored as a global
11219 // map of errors and their component stack location keyed by the boundaries
11220 // that capture them. We mostly use this Map as a Set; it's a Map only to
11221 // avoid adding a field to Fiber to store the error.
11222 if (capturedErrors === null) {
11223 capturedErrors = new Map();
11224 }
11225
11226 var capturedError = {
11227 componentName: _componentName,
11228 componentStack: _componentStack,
11229 error: error,
11230 errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
11231 errorBoundaryFound: errorBoundaryFound,
11232 errorBoundaryName: errorBoundaryName,
11233 willRetry: willRetry
11234 };
11235
11236 capturedErrors.set(boundary, capturedError);
11237
11238 try {
11239 logCapturedError(capturedError);
11240 } catch (e) {
11241 // Prevent cycle if logCapturedError() throws.
11242 // A cycle may still occur if logCapturedError renders a component that throws.
11243 var suppressLogging = e && e.suppressReactErrorLogging;
11244 if (!suppressLogging) {
11245 console.error(e);
11246 }
11247 }
11248
11249 // If we're in the commit phase, defer scheduling an update on the
11250 // boundary until after the commit is complete
11251 if (isCommitting) {
11252 if (commitPhaseBoundaries === null) {
11253 commitPhaseBoundaries = new Set();
11254 }
11255 commitPhaseBoundaries.add(boundary);
11256 } else {
11257 // Otherwise, schedule an update now.
11258 // TODO: Is this actually necessary during the render phase? Is it
11259 // possible to unwind and continue rendering at the same priority,
11260 // without corrupting internal state?
11261 scheduleErrorRecovery(boundary);
11262 }
11263 return boundary;
11264 } else if (firstUncaughtError === null) {
11265 // If no boundary is found, we'll need to throw the error
11266 firstUncaughtError = error;
11267 }
11268 return null;
11269 }
11270
11271 function hasCapturedError(fiber) {
11272 // TODO: capturedErrors should store the boundary instance, to avoid needing
11273 // to check the alternate.
11274 return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate));
11275 }
11276
11277 function isFailedBoundary(fiber) {
11278 // TODO: failedBoundaries should store the boundary instance, to avoid
11279 // needing to check the alternate.
11280 return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate));
11281 }
11282
11283 function commitErrorHandling(effectfulFiber) {
11284 var capturedError = void 0;
11285 if (capturedErrors !== null) {
11286 capturedError = capturedErrors.get(effectfulFiber);
11287 capturedErrors['delete'](effectfulFiber);
11288 if (capturedError == null) {
11289 if (effectfulFiber.alternate !== null) {
11290 effectfulFiber = effectfulFiber.alternate;
11291 capturedError = capturedErrors.get(effectfulFiber);
11292 capturedErrors['delete'](effectfulFiber);
11293 }
11294 }
11295 }
11296
11297 !(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;
11298
11299 switch (effectfulFiber.tag) {
11300 case ClassComponent:
11301 var instance = effectfulFiber.stateNode;
11302
11303 var info = {
11304 componentStack: capturedError.componentStack
11305 };
11306
11307 // Allow the boundary to handle the error, usually by scheduling
11308 // an update to itself
11309 instance.componentDidCatch(capturedError.error, info);
11310 return;
11311 case HostRoot:
11312 if (firstUncaughtError === null) {
11313 firstUncaughtError = capturedError.error;
11314 }
11315 return;
11316 default:
11317 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
11318 }
11319 }
11320
11321 function unwindContexts(from, to) {
11322 var node = from;
11323 while (node !== null) {
11324 switch (node.tag) {
11325 case ClassComponent:
11326 popContextProvider(node);
11327 break;
11328 case HostComponent:
11329 popHostContext(node);
11330 break;
11331 case HostRoot:
11332 popHostContainer(node);
11333 break;
11334 case HostPortal:
11335 popHostContainer(node);
11336 break;
11337 }
11338 if (node === to || node.alternate === to) {
11339 stopFailedWorkTimer(node);
11340 break;
11341 } else {
11342 stopWorkTimer(node);
11343 }
11344 node = node['return'];
11345 }
11346 }
11347
11348 function computeAsyncExpiration() {
11349 // Given the current clock time, returns an expiration time. We use rounding
11350 // to batch like updates together.
11351 // Should complete within ~1000ms. 1200ms max.
11352 var currentTime = recalculateCurrentTime();
11353 var expirationMs = 1000;
11354 var bucketSizeMs = 200;
11355 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11356 }
11357
11358 // Creates a unique async expiration time.
11359 function computeUniqueAsyncExpiration() {
11360 var result = computeAsyncExpiration();
11361 if (result <= lastUniqueAsyncExpiration) {
11362 // Since we assume the current time monotonically increases, we only hit
11363 // this branch when computeUniqueAsyncExpiration is fired multiple times
11364 // within a 200ms window (or whatever the async bucket size is).
11365 result = lastUniqueAsyncExpiration + 1;
11366 }
11367 lastUniqueAsyncExpiration = result;
11368 return lastUniqueAsyncExpiration;
11369 }
11370
11371 function computeExpirationForFiber(fiber) {
11372 var expirationTime = void 0;
11373 if (expirationContext !== NoWork) {
11374 // An explicit expiration context was set;
11375 expirationTime = expirationContext;
11376 } else if (isWorking) {
11377 if (isCommitting) {
11378 // Updates that occur during the commit phase should have sync priority
11379 // by default.
11380 expirationTime = Sync;
11381 } else {
11382 // Updates during the render phase should expire at the same time as
11383 // the work that is being rendered.
11384 expirationTime = nextRenderExpirationTime;
11385 }
11386 } else {
11387 // No explicit expiration context was set, and we're not currently
11388 // performing work. Calculate a new expiration time.
11389 if (fiber.internalContextTag & AsyncUpdates) {
11390 // This is an async update
11391 expirationTime = computeAsyncExpiration();
11392 } else {
11393 // This is a sync update
11394 expirationTime = Sync;
11395 }
11396 }
11397 return expirationTime;
11398 }
11399
11400 function scheduleWork(fiber, expirationTime) {
11401 return scheduleWorkImpl(fiber, expirationTime, false);
11402 }
11403
11404 function checkRootNeedsClearing(root, fiber, expirationTime) {
11405 if (!isWorking && root === nextRoot && expirationTime < nextRenderExpirationTime) {
11406 // Restart the root from the top.
11407 if (nextUnitOfWork !== null) {
11408 // This is an interruption. (Used for performance tracking.)
11409 interruptedBy = fiber;
11410 }
11411 nextRoot = null;
11412 nextUnitOfWork = null;
11413 nextRenderExpirationTime = NoWork;
11414 }
11415 }
11416
11417 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
11418 recordScheduleUpdate();
11419
11420 {
11421 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11422 var instance = fiber.stateNode;
11423 warnAboutInvalidUpdates(instance);
11424 }
11425 }
11426
11427 var node = fiber;
11428 while (node !== null) {
11429 // Walk the parent path to the root and update each node's
11430 // expiration time.
11431 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
11432 node.expirationTime = expirationTime;
11433 }
11434 if (node.alternate !== null) {
11435 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
11436 node.alternate.expirationTime = expirationTime;
11437 }
11438 }
11439 if (node['return'] === null) {
11440 if (node.tag === HostRoot) {
11441 var root = node.stateNode;
11442
11443 checkRootNeedsClearing(root, fiber, expirationTime);
11444 requestWork(root, expirationTime);
11445 checkRootNeedsClearing(root, fiber, expirationTime);
11446 } else {
11447 {
11448 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11449 warnAboutUpdateOnUnmounted(fiber);
11450 }
11451 }
11452 return;
11453 }
11454 }
11455 node = node['return'];
11456 }
11457 }
11458
11459 function scheduleErrorRecovery(fiber) {
11460 scheduleWorkImpl(fiber, Sync, true);
11461 }
11462
11463 function recalculateCurrentTime() {
11464 // Subtract initial time so it fits inside 32bits
11465 var ms = now() - startTime;
11466 mostRecentCurrentTime = msToExpirationTime(ms);
11467 return mostRecentCurrentTime;
11468 }
11469
11470 function deferredUpdates(fn) {
11471 var previousExpirationContext = expirationContext;
11472 expirationContext = computeAsyncExpiration();
11473 try {
11474 return fn();
11475 } finally {
11476 expirationContext = previousExpirationContext;
11477 }
11478 }
11479
11480 function syncUpdates(fn) {
11481 var previousExpirationContext = expirationContext;
11482 expirationContext = Sync;
11483 try {
11484 return fn();
11485 } finally {
11486 expirationContext = previousExpirationContext;
11487 }
11488 }
11489
11490 // TODO: Everything below this is written as if it has been lifted to the
11491 // renderers. I'll do this in a follow-up.
11492
11493 // Linked-list of roots
11494 var firstScheduledRoot = null;
11495 var lastScheduledRoot = null;
11496
11497 var callbackExpirationTime = NoWork;
11498 var callbackID = -1;
11499 var isRendering = false;
11500 var nextFlushedRoot = null;
11501 var nextFlushedExpirationTime = NoWork;
11502 var deadlineDidExpire = false;
11503 var hasUnhandledError = false;
11504 var unhandledError = null;
11505 var deadline = null;
11506
11507 var isBatchingUpdates = false;
11508 var isUnbatchingUpdates = false;
11509
11510 var completedBatches = null;
11511
11512 // Use these to prevent an infinite loop of nested updates
11513 var NESTED_UPDATE_LIMIT = 1000;
11514 var nestedUpdateCount = 0;
11515
11516 var timeHeuristicForUnitOfWork = 1;
11517
11518 function scheduleCallbackWithExpiration(expirationTime) {
11519 if (callbackExpirationTime !== NoWork) {
11520 // A callback is already scheduled. Check its expiration time (timeout).
11521 if (expirationTime > callbackExpirationTime) {
11522 // Existing callback has sufficient timeout. Exit.
11523 return;
11524 } else {
11525 // Existing callback has insufficient timeout. Cancel and schedule a
11526 // new one.
11527 cancelDeferredCallback(callbackID);
11528 }
11529 // The request callback timer is already running. Don't start a new one.
11530 } else {
11531 startRequestCallbackTimer();
11532 }
11533
11534 // Compute a timeout for the given expiration time.
11535 var currentMs = now() - startTime;
11536 var expirationMs = expirationTimeToMs(expirationTime);
11537 var timeout = expirationMs - currentMs;
11538
11539 callbackExpirationTime = expirationTime;
11540 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
11541 }
11542
11543 // requestWork is called by the scheduler whenever a root receives an update.
11544 // It's up to the renderer to call renderRoot at some point in the future.
11545 function requestWork(root, expirationTime) {
11546 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
11547 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.');
11548 }
11549
11550 // Add the root to the schedule.
11551 // Check if this root is already part of the schedule.
11552 if (root.nextScheduledRoot === null) {
11553 // This root is not already scheduled. Add it.
11554 root.remainingExpirationTime = expirationTime;
11555 if (lastScheduledRoot === null) {
11556 firstScheduledRoot = lastScheduledRoot = root;
11557 root.nextScheduledRoot = root;
11558 } else {
11559 lastScheduledRoot.nextScheduledRoot = root;
11560 lastScheduledRoot = root;
11561 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11562 }
11563 } else {
11564 // This root is already scheduled, but its priority may have increased.
11565 var remainingExpirationTime = root.remainingExpirationTime;
11566 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
11567 // Update the priority.
11568 root.remainingExpirationTime = expirationTime;
11569 }
11570 }
11571
11572 if (isRendering) {
11573 // Prevent reentrancy. Remaining work will be scheduled at the end of
11574 // the currently rendering batch.
11575 return;
11576 }
11577
11578 if (isBatchingUpdates) {
11579 // Flush work at the end of the batch.
11580 if (isUnbatchingUpdates) {
11581 // ...unless we're inside unbatchedUpdates, in which case we should
11582 // flush it now.
11583 nextFlushedRoot = root;
11584 nextFlushedExpirationTime = Sync;
11585 performWorkOnRoot(root, Sync, recalculateCurrentTime());
11586 }
11587 return;
11588 }
11589
11590 // TODO: Get rid of Sync and use current time?
11591 if (expirationTime === Sync) {
11592 performWork(Sync, null);
11593 } else {
11594 scheduleCallbackWithExpiration(expirationTime);
11595 }
11596 }
11597
11598 function findHighestPriorityRoot() {
11599 var highestPriorityWork = NoWork;
11600 var highestPriorityRoot = null;
11601
11602 if (lastScheduledRoot !== null) {
11603 var previousScheduledRoot = lastScheduledRoot;
11604 var root = firstScheduledRoot;
11605 while (root !== null) {
11606 var remainingExpirationTime = root.remainingExpirationTime;
11607 if (remainingExpirationTime === NoWork) {
11608 // This root no longer has work. Remove it from the scheduler.
11609
11610 // TODO: This check is redudant, but Flow is confused by the branch
11611 // below where we set lastScheduledRoot to null, even though we break
11612 // from the loop right after.
11613 !(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;
11614 if (root === root.nextScheduledRoot) {
11615 // This is the only root in the list.
11616 root.nextScheduledRoot = null;
11617 firstScheduledRoot = lastScheduledRoot = null;
11618 break;
11619 } else if (root === firstScheduledRoot) {
11620 // This is the first root in the list.
11621 var next = root.nextScheduledRoot;
11622 firstScheduledRoot = next;
11623 lastScheduledRoot.nextScheduledRoot = next;
11624 root.nextScheduledRoot = null;
11625 } else if (root === lastScheduledRoot) {
11626 // This is the last root in the list.
11627 lastScheduledRoot = previousScheduledRoot;
11628 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11629 root.nextScheduledRoot = null;
11630 break;
11631 } else {
11632 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
11633 root.nextScheduledRoot = null;
11634 }
11635 root = previousScheduledRoot.nextScheduledRoot;
11636 } else {
11637 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
11638 // Update the priority, if it's higher
11639 highestPriorityWork = remainingExpirationTime;
11640 highestPriorityRoot = root;
11641 }
11642 if (root === lastScheduledRoot) {
11643 break;
11644 }
11645 previousScheduledRoot = root;
11646 root = root.nextScheduledRoot;
11647 }
11648 }
11649 }
11650
11651 // If the next root is the same as the previous root, this is a nested
11652 // update. To prevent an infinite loop, increment the nested update count.
11653 var previousFlushedRoot = nextFlushedRoot;
11654 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot) {
11655 nestedUpdateCount++;
11656 } else {
11657 // Reset whenever we switch roots.
11658 nestedUpdateCount = 0;
11659 }
11660 nextFlushedRoot = highestPriorityRoot;
11661 nextFlushedExpirationTime = highestPriorityWork;
11662 }
11663
11664 function performAsyncWork(dl) {
11665 performWork(NoWork, dl);
11666 }
11667
11668 function performWork(minExpirationTime, dl) {
11669 deadline = dl;
11670
11671 // Keep working on roots until there's no more work, or until the we reach
11672 // the deadline.
11673 findHighestPriorityRoot();
11674
11675 if (enableUserTimingAPI && deadline !== null) {
11676 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
11677 stopRequestCallbackTimer(didExpire);
11678 }
11679
11680 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || nextFlushedExpirationTime <= minExpirationTime) && !deadlineDidExpire) {
11681 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, recalculateCurrentTime());
11682 // Find the next highest priority work.
11683 findHighestPriorityRoot();
11684 }
11685
11686 // We're done flushing work. Either we ran out of time in this callback,
11687 // or there's no more work left with sufficient priority.
11688
11689 // If we're inside a callback, set this to false since we just completed it.
11690 if (deadline !== null) {
11691 callbackExpirationTime = NoWork;
11692 callbackID = -1;
11693 }
11694 // If there's work left over, schedule a new callback.
11695 if (nextFlushedExpirationTime !== NoWork) {
11696 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
11697 }
11698
11699 // Clean-up.
11700 deadline = null;
11701 deadlineDidExpire = false;
11702 nestedUpdateCount = 0;
11703
11704 finishRendering();
11705 }
11706
11707 function flushRoot(root, expirationTime) {
11708 !!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;
11709 // Perform work on root as if the given expiration time is the current time.
11710 // This has the effect of synchronously flushing all work up to and
11711 // including the given time.
11712 performWorkOnRoot(root, expirationTime, expirationTime);
11713 finishRendering();
11714 }
11715
11716 function finishRendering() {
11717 if (completedBatches !== null) {
11718 var batches = completedBatches;
11719 completedBatches = null;
11720 for (var i = 0; i < batches.length; i++) {
11721 var batch = batches[i];
11722 try {
11723 batch._onComplete();
11724 } catch (error) {
11725 if (!hasUnhandledError) {
11726 hasUnhandledError = true;
11727 unhandledError = error;
11728 }
11729 }
11730 }
11731 }
11732
11733 if (hasUnhandledError) {
11734 var _error4 = unhandledError;
11735 unhandledError = null;
11736 hasUnhandledError = false;
11737 throw _error4;
11738 }
11739 }
11740
11741 function performWorkOnRoot(root, expirationTime, currentTime) {
11742 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11743
11744 isRendering = true;
11745
11746 // Check if this is async work or sync/expired work.
11747 if (expirationTime <= currentTime) {
11748 // Flush sync work.
11749 var finishedWork = root.finishedWork;
11750 if (finishedWork !== null) {
11751 // This root is already complete. We can commit it.
11752 completeRoot(root, finishedWork, expirationTime);
11753 } else {
11754 root.finishedWork = null;
11755 finishedWork = renderRoot(root, expirationTime);
11756 if (finishedWork !== null) {
11757 // We've completed the root. Commit it.
11758 completeRoot(root, finishedWork, expirationTime);
11759 }
11760 }
11761 } else {
11762 // Flush async work.
11763 var _finishedWork = root.finishedWork;
11764 if (_finishedWork !== null) {
11765 // This root is already complete. We can commit it.
11766 completeRoot(root, _finishedWork, expirationTime);
11767 } else {
11768 root.finishedWork = null;
11769 _finishedWork = renderRoot(root, expirationTime);
11770 if (_finishedWork !== null) {
11771 // We've completed the root. Check the deadline one more time
11772 // before committing.
11773 if (!shouldYield()) {
11774 // Still time left. Commit the root.
11775 completeRoot(root, _finishedWork, expirationTime);
11776 } else {
11777 // There's no time left. Mark this root as complete. We'll come
11778 // back and commit it later.
11779 root.finishedWork = _finishedWork;
11780 }
11781 }
11782 }
11783 }
11784
11785 isRendering = false;
11786 }
11787
11788 function completeRoot(root, finishedWork, expirationTime) {
11789 // Check if there's a batch that matches this expiration time.
11790 var firstBatch = root.firstBatch;
11791 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
11792 if (completedBatches === null) {
11793 completedBatches = [firstBatch];
11794 } else {
11795 completedBatches.push(firstBatch);
11796 }
11797 if (firstBatch._defer) {
11798 // This root is blocked from committing by a batch. Unschedule it until
11799 // we receive another update.
11800 root.finishedWork = finishedWork;
11801 root.remainingExpirationTime = NoWork;
11802 return;
11803 }
11804 }
11805
11806 // Commit the root.
11807 root.finishedWork = null;
11808 root.remainingExpirationTime = commitRoot(finishedWork);
11809 }
11810
11811 // When working on async work, the reconciler asks the renderer if it should
11812 // yield execution. For DOM, we implement this with requestIdleCallback.
11813 function shouldYield() {
11814 if (deadline === null) {
11815 return false;
11816 }
11817 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
11818 // Disregard deadline.didTimeout. Only expired work should be flushed
11819 // during a timeout. This path is only hit for non-expired work.
11820 return false;
11821 }
11822 deadlineDidExpire = true;
11823 return true;
11824 }
11825
11826 // TODO: Not happy about this hook. Conceptually, renderRoot should return a
11827 // tuple of (isReadyForCommit, didError, error)
11828 function onUncaughtError(error) {
11829 !(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;
11830 // Unschedule this root so we don't work on it again until there's
11831 // another update.
11832 nextFlushedRoot.remainingExpirationTime = NoWork;
11833 if (!hasUnhandledError) {
11834 hasUnhandledError = true;
11835 unhandledError = error;
11836 }
11837 }
11838
11839 // TODO: Batching should be implemented at the renderer level, not inside
11840 // the reconciler.
11841 function batchedUpdates(fn, a) {
11842 var previousIsBatchingUpdates = isBatchingUpdates;
11843 isBatchingUpdates = true;
11844 try {
11845 return fn(a);
11846 } finally {
11847 isBatchingUpdates = previousIsBatchingUpdates;
11848 if (!isBatchingUpdates && !isRendering) {
11849 performWork(Sync, null);
11850 }
11851 }
11852 }
11853
11854 // TODO: Batching should be implemented at the renderer level, not inside
11855 // the reconciler.
11856 function unbatchedUpdates(fn) {
11857 if (isBatchingUpdates && !isUnbatchingUpdates) {
11858 isUnbatchingUpdates = true;
11859 try {
11860 return fn();
11861 } finally {
11862 isUnbatchingUpdates = false;
11863 }
11864 }
11865 return fn();
11866 }
11867
11868 // TODO: Batching should be implemented at the renderer level, not within
11869 // the reconciler.
11870 function flushSync(fn) {
11871 var previousIsBatchingUpdates = isBatchingUpdates;
11872 isBatchingUpdates = true;
11873 try {
11874 return syncUpdates(fn);
11875 } finally {
11876 isBatchingUpdates = previousIsBatchingUpdates;
11877 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
11878 performWork(Sync, null);
11879 }
11880 }
11881
11882 return {
11883 computeExpirationForFiber: computeExpirationForFiber,
11884 scheduleWork: scheduleWork,
11885 requestWork: requestWork,
11886 flushRoot: flushRoot,
11887 batchedUpdates: batchedUpdates,
11888 unbatchedUpdates: unbatchedUpdates,
11889 flushSync: flushSync,
11890 deferredUpdates: deferredUpdates,
11891 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
11892 };
11893};
11894
11895var didWarnAboutNestedUpdates = void 0;
11896
11897{
11898 didWarnAboutNestedUpdates = false;
11899}
11900
11901// 0 is PROD, 1 is DEV.
11902// Might add PROFILE later.
11903
11904
11905function getContextForSubtree(parentComponent) {
11906 if (!parentComponent) {
11907 return emptyObject_1;
11908 }
11909
11910 var fiber = get(parentComponent);
11911 var parentContext = findCurrentUnmaskedContext(fiber);
11912 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
11913}
11914
11915var ReactFiberReconciler$1 = function (config) {
11916 var getPublicInstance = config.getPublicInstance;
11917
11918 var _ReactFiberScheduler = ReactFiberScheduler(config),
11919 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
11920 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
11921 scheduleWork = _ReactFiberScheduler.scheduleWork,
11922 requestWork = _ReactFiberScheduler.requestWork,
11923 flushRoot = _ReactFiberScheduler.flushRoot,
11924 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
11925 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
11926 flushSync = _ReactFiberScheduler.flushSync,
11927 deferredUpdates = _ReactFiberScheduler.deferredUpdates;
11928
11929 function scheduleRootUpdate(current, element, expirationTime, callback) {
11930 {
11931 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
11932 didWarnAboutNestedUpdates = true;
11933 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');
11934 }
11935 }
11936
11937 callback = callback === undefined ? null : callback;
11938 {
11939 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
11940 }
11941
11942 var update = {
11943 expirationTime: expirationTime,
11944 partialState: { element: element },
11945 callback: callback,
11946 isReplace: false,
11947 isForced: false,
11948 next: null
11949 };
11950 insertUpdateIntoFiber(current, update);
11951 scheduleWork(current, expirationTime);
11952
11953 return expirationTime;
11954 }
11955
11956 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
11957 // TODO: If this is a nested container, this won't be the root.
11958 var current = container.current;
11959
11960 {
11961 if (ReactFiberInstrumentation_1.debugTool) {
11962 if (current.alternate === null) {
11963 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
11964 } else if (element === null) {
11965 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
11966 } else {
11967 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
11968 }
11969 }
11970 }
11971
11972 var context = getContextForSubtree(parentComponent);
11973 if (container.context === null) {
11974 container.context = context;
11975 } else {
11976 container.pendingContext = context;
11977 }
11978
11979 return scheduleRootUpdate(current, element, expirationTime, callback);
11980 }
11981
11982 function findHostInstance(fiber) {
11983 var hostFiber = findCurrentHostFiber(fiber);
11984 if (hostFiber === null) {
11985 return null;
11986 }
11987 return hostFiber.stateNode;
11988 }
11989
11990 return {
11991 createContainer: function (containerInfo, isAsync, hydrate) {
11992 return createFiberRoot(containerInfo, isAsync, hydrate);
11993 },
11994 updateContainer: function (element, container, parentComponent, callback) {
11995 var current = container.current;
11996 var expirationTime = computeExpirationForFiber(current);
11997 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
11998 },
11999
12000
12001 updateContainerAtExpirationTime: updateContainerAtExpirationTime,
12002
12003 flushRoot: flushRoot,
12004
12005 requestWork: requestWork,
12006
12007 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
12008
12009 batchedUpdates: batchedUpdates,
12010
12011 unbatchedUpdates: unbatchedUpdates,
12012
12013 deferredUpdates: deferredUpdates,
12014
12015 flushSync: flushSync,
12016
12017 getPublicRootInstance: function (container) {
12018 var containerFiber = container.current;
12019 if (!containerFiber.child) {
12020 return null;
12021 }
12022 switch (containerFiber.child.tag) {
12023 case HostComponent:
12024 return getPublicInstance(containerFiber.child.stateNode);
12025 default:
12026 return containerFiber.child.stateNode;
12027 }
12028 },
12029
12030
12031 findHostInstance: findHostInstance,
12032
12033 findHostInstanceWithNoPortals: function (fiber) {
12034 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
12035 if (hostFiber === null) {
12036 return null;
12037 }
12038 return hostFiber.stateNode;
12039 },
12040 injectIntoDevTools: function (devToolsConfig) {
12041 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12042
12043 return injectInternals(_assign({}, devToolsConfig, {
12044 findHostInstanceByFiber: function (fiber) {
12045 return findHostInstance(fiber);
12046 },
12047 findFiberByHostInstance: function (instance) {
12048 if (!findFiberByHostInstance) {
12049 // Might not be implemented by the renderer.
12050 return null;
12051 }
12052 return findFiberByHostInstance(instance);
12053 }
12054 }));
12055 }
12056 };
12057};
12058
12059var ReactFiberReconciler$2 = Object.freeze({
12060 default: ReactFiberReconciler$1
12061});
12062
12063var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
12064
12065// TODO: bundle Flow types with the package.
12066
12067
12068
12069// TODO: decide on the top-level export form.
12070// This is hacky but makes it work with both Rollup and Jest.
12071var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
12072
12073function createPortal$1(children, containerInfo,
12074// TODO: figure out the API for cross-renderer implementation.
12075implementation) {
12076 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
12077
12078 return {
12079 // This tag allow us to uniquely identify this as a React Portal
12080 $$typeof: REACT_PORTAL_TYPE,
12081 key: key == null ? null : '' + key,
12082 children: children,
12083 containerInfo: containerInfo,
12084 implementation: implementation
12085 };
12086}
12087
12088// TODO: this is special because it gets imported during build.
12089
12090var ReactVersion = '16.2.0';
12091
12092// a requestAnimationFrame, storing the time for the start of the frame, then
12093// scheduling a postMessage which gets scheduled after paint. Within the
12094// postMessage handler do as much work as possible until time + frame rate.
12095// By separating the idle call into a separate event tick we ensure that
12096// layout, paint and other browser work is counted against the available time.
12097// The frame rate is dynamically adjusted.
12098
12099{
12100 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
12101 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
12102 }
12103}
12104
12105var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
12106
12107var now = void 0;
12108if (hasNativePerformanceNow) {
12109 now = function () {
12110 return performance.now();
12111 };
12112} else {
12113 now = function () {
12114 return Date.now();
12115 };
12116}
12117
12118// TODO: There's no way to cancel, because Fiber doesn't atm.
12119var rIC = void 0;
12120var cIC = void 0;
12121
12122if (!ExecutionEnvironment_1.canUseDOM) {
12123 rIC = function (frameCallback) {
12124 return setTimeout(function () {
12125 frameCallback({
12126 timeRemaining: function () {
12127 return Infinity;
12128 }
12129 });
12130 });
12131 };
12132 cIC = function (timeoutID) {
12133 clearTimeout(timeoutID);
12134 };
12135} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
12136 // Polyfill requestIdleCallback and cancelIdleCallback
12137
12138 var scheduledRICCallback = null;
12139 var isIdleScheduled = false;
12140 var timeoutTime = -1;
12141
12142 var isAnimationFrameScheduled = false;
12143
12144 var frameDeadline = 0;
12145 // We start out assuming that we run at 30fps but then the heuristic tracking
12146 // will adjust this value to a faster fps if we get more frequent animation
12147 // frames.
12148 var previousFrameTime = 33;
12149 var activeFrameTime = 33;
12150
12151 var frameDeadlineObject = void 0;
12152 if (hasNativePerformanceNow) {
12153 frameDeadlineObject = {
12154 didTimeout: false,
12155 timeRemaining: function () {
12156 // We assume that if we have a performance timer that the rAF callback
12157 // gets a performance timer value. Not sure if this is always true.
12158 var remaining = frameDeadline - performance.now();
12159 return remaining > 0 ? remaining : 0;
12160 }
12161 };
12162 } else {
12163 frameDeadlineObject = {
12164 didTimeout: false,
12165 timeRemaining: function () {
12166 // Fallback to Date.now()
12167 var remaining = frameDeadline - Date.now();
12168 return remaining > 0 ? remaining : 0;
12169 }
12170 };
12171 }
12172
12173 // We use the postMessage trick to defer idle work until after the repaint.
12174 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12175 var idleTick = function (event) {
12176 if (event.source !== window || event.data !== messageKey) {
12177 return;
12178 }
12179
12180 isIdleScheduled = false;
12181
12182 var currentTime = now();
12183 if (frameDeadline - currentTime <= 0) {
12184 // There's no time left in this idle period. Check if the callback has
12185 // a timeout and whether it's been exceeded.
12186 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12187 // Exceeded the timeout. Invoke the callback even though there's no
12188 // time left.
12189 frameDeadlineObject.didTimeout = true;
12190 } else {
12191 // No timeout.
12192 if (!isAnimationFrameScheduled) {
12193 // Schedule another animation callback so we retry later.
12194 isAnimationFrameScheduled = true;
12195 requestAnimationFrame(animationTick);
12196 }
12197 // Exit without invoking the callback.
12198 return;
12199 }
12200 } else {
12201 // There's still time left in this idle period.
12202 frameDeadlineObject.didTimeout = false;
12203 }
12204
12205 timeoutTime = -1;
12206 var callback = scheduledRICCallback;
12207 scheduledRICCallback = null;
12208 if (callback !== null) {
12209 callback(frameDeadlineObject);
12210 }
12211 };
12212 // Assumes that we have addEventListener in this environment. Might need
12213 // something better for old IE.
12214 window.addEventListener('message', idleTick, false);
12215
12216 var animationTick = function (rafTime) {
12217 isAnimationFrameScheduled = false;
12218 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12219 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12220 if (nextFrameTime < 8) {
12221 // Defensive coding. We don't support higher frame rates than 120hz.
12222 // If we get lower than that, it is probably a bug.
12223 nextFrameTime = 8;
12224 }
12225 // If one frame goes long, then the next one can be short to catch up.
12226 // If two frames are short in a row, then that's an indication that we
12227 // actually have a higher frame rate than what we're currently optimizing.
12228 // We adjust our heuristic dynamically accordingly. For example, if we're
12229 // running on 120hz display or 90hz VR display.
12230 // Take the max of the two in case one of them was an anomaly due to
12231 // missed frame deadlines.
12232 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12233 } else {
12234 previousFrameTime = nextFrameTime;
12235 }
12236 frameDeadline = rafTime + activeFrameTime;
12237 if (!isIdleScheduled) {
12238 isIdleScheduled = true;
12239 window.postMessage(messageKey, '*');
12240 }
12241 };
12242
12243 rIC = function (callback, options) {
12244 // This assumes that we only schedule one callback at a time because that's
12245 // how Fiber uses it.
12246 scheduledRICCallback = callback;
12247 if (options != null && typeof options.timeout === 'number') {
12248 timeoutTime = now() + options.timeout;
12249 }
12250 if (!isAnimationFrameScheduled) {
12251 // If rAF didn't already schedule one, we need to schedule a frame.
12252 // TODO: If this rAF doesn't materialize because the browser throttles, we
12253 // might want to still have setTimeout trigger rIC as a backup to ensure
12254 // that we keep performing work.
12255 isAnimationFrameScheduled = true;
12256 requestAnimationFrame(animationTick);
12257 }
12258 return 0;
12259 };
12260
12261 cIC = function () {
12262 scheduledRICCallback = null;
12263 isIdleScheduled = false;
12264 timeoutTime = -1;
12265 };
12266} else {
12267 rIC = window.requestIdleCallback;
12268 cIC = window.cancelIdleCallback;
12269}
12270
12271var didWarnSelectedSetOnOption = false;
12272
12273function flattenChildren(children) {
12274 var content = '';
12275
12276 // Flatten children and warn if they aren't strings or numbers;
12277 // invalid types are ignored.
12278 // We can silently skip them because invalid DOM nesting warning
12279 // catches these cases in Fiber.
12280 React.Children.forEach(children, function (child) {
12281 if (child == null) {
12282 return;
12283 }
12284 if (typeof child === 'string' || typeof child === 'number') {
12285 content += child;
12286 }
12287 });
12288
12289 return content;
12290}
12291
12292/**
12293 * Implements an <option> host component that warns when `selected` is set.
12294 */
12295
12296function validateProps(element, props) {
12297 // TODO (yungsters): Remove support for `selected` in <option>.
12298 {
12299 if (props.selected != null && !didWarnSelectedSetOnOption) {
12300 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
12301 didWarnSelectedSetOnOption = true;
12302 }
12303 }
12304}
12305
12306function postMountWrapper$1(element, props) {
12307 // value="" should make a value attribute (#6219)
12308 if (props.value != null) {
12309 element.setAttribute('value', props.value);
12310 }
12311}
12312
12313function getHostProps$1(element, props) {
12314 var hostProps = _assign({ children: undefined }, props);
12315 var content = flattenChildren(props.children);
12316
12317 if (content) {
12318 hostProps.children = content;
12319 }
12320
12321 return hostProps;
12322}
12323
12324// TODO: direct imports like some-package/src/* are bad. Fix me.
12325var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
12326var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12327
12328
12329var didWarnValueDefaultValue$1 = void 0;
12330
12331{
12332 didWarnValueDefaultValue$1 = false;
12333}
12334
12335function getDeclarationErrorAddendum() {
12336 var ownerName = getCurrentFiberOwnerName$3();
12337 if (ownerName) {
12338 return '\n\nCheck the render method of `' + ownerName + '`.';
12339 }
12340 return '';
12341}
12342
12343var valuePropNames = ['value', 'defaultValue'];
12344
12345/**
12346 * Validation function for `value` and `defaultValue`.
12347 */
12348function checkSelectPropTypes(props) {
12349 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
12350
12351 for (var i = 0; i < valuePropNames.length; i++) {
12352 var propName = valuePropNames[i];
12353 if (props[propName] == null) {
12354 continue;
12355 }
12356 var isArray = Array.isArray(props[propName]);
12357 if (props.multiple && !isArray) {
12358 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
12359 } else if (!props.multiple && isArray) {
12360 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
12361 }
12362 }
12363}
12364
12365function updateOptions(node, multiple, propValue, setDefaultSelected) {
12366 var options = node.options;
12367
12368 if (multiple) {
12369 var selectedValues = propValue;
12370 var selectedValue = {};
12371 for (var i = 0; i < selectedValues.length; i++) {
12372 // Prefix to avoid chaos with special keys.
12373 selectedValue['$' + selectedValues[i]] = true;
12374 }
12375 for (var _i = 0; _i < options.length; _i++) {
12376 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
12377 if (options[_i].selected !== selected) {
12378 options[_i].selected = selected;
12379 }
12380 if (selected && setDefaultSelected) {
12381 options[_i].defaultSelected = true;
12382 }
12383 }
12384 } else {
12385 // Do not set `select.value` as exact behavior isn't consistent across all
12386 // browsers for all cases.
12387 var _selectedValue = '' + propValue;
12388 var defaultSelected = null;
12389 for (var _i2 = 0; _i2 < options.length; _i2++) {
12390 if (options[_i2].value === _selectedValue) {
12391 options[_i2].selected = true;
12392 if (setDefaultSelected) {
12393 options[_i2].defaultSelected = true;
12394 }
12395 return;
12396 }
12397 if (defaultSelected === null && !options[_i2].disabled) {
12398 defaultSelected = options[_i2];
12399 }
12400 }
12401 if (defaultSelected !== null) {
12402 defaultSelected.selected = true;
12403 }
12404 }
12405}
12406
12407/**
12408 * Implements a <select> host component that allows optionally setting the
12409 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
12410 * stringable. If `multiple` is true, the prop must be an array of stringables.
12411 *
12412 * If `value` is not supplied (or null/undefined), user actions that change the
12413 * selected option will trigger updates to the rendered options.
12414 *
12415 * If it is supplied (and not null/undefined), the rendered options will not
12416 * update in response to user actions. Instead, the `value` prop must change in
12417 * order for the rendered options to update.
12418 *
12419 * If `defaultValue` is provided, any options with the supplied values will be
12420 * selected.
12421 */
12422
12423function getHostProps$2(element, props) {
12424 return _assign({}, props, {
12425 value: undefined
12426 });
12427}
12428
12429function initWrapperState$1(element, props) {
12430 var node = element;
12431 {
12432 checkSelectPropTypes(props);
12433 }
12434
12435 var value = props.value;
12436 node._wrapperState = {
12437 initialValue: value != null ? value : props.defaultValue,
12438 wasMultiple: !!props.multiple
12439 };
12440
12441 {
12442 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
12443 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');
12444 didWarnValueDefaultValue$1 = true;
12445 }
12446 }
12447}
12448
12449function postMountWrapper$2(element, props) {
12450 var node = element;
12451 node.multiple = !!props.multiple;
12452 var value = props.value;
12453 if (value != null) {
12454 updateOptions(node, !!props.multiple, value, false);
12455 } else if (props.defaultValue != null) {
12456 updateOptions(node, !!props.multiple, props.defaultValue, true);
12457 }
12458}
12459
12460function postUpdateWrapper(element, props) {
12461 var node = element;
12462 // After the initial mount, we control selected-ness manually so don't pass
12463 // this value down
12464 node._wrapperState.initialValue = undefined;
12465
12466 var wasMultiple = node._wrapperState.wasMultiple;
12467 node._wrapperState.wasMultiple = !!props.multiple;
12468
12469 var value = props.value;
12470 if (value != null) {
12471 updateOptions(node, !!props.multiple, value, false);
12472 } else if (wasMultiple !== !!props.multiple) {
12473 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
12474 if (props.defaultValue != null) {
12475 updateOptions(node, !!props.multiple, props.defaultValue, true);
12476 } else {
12477 // Revert the select back to its default unselected state.
12478 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
12479 }
12480 }
12481}
12482
12483function restoreControlledState$2(element, props) {
12484 var node = element;
12485 var value = props.value;
12486
12487 if (value != null) {
12488 updateOptions(node, !!props.multiple, value, false);
12489 }
12490}
12491
12492// TODO: direct imports like some-package/src/* are bad. Fix me.
12493var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12494
12495var didWarnValDefaultVal = false;
12496
12497/**
12498 * Implements a <textarea> host component that allows setting `value`, and
12499 * `defaultValue`. This differs from the traditional DOM API because value is
12500 * usually set as PCDATA children.
12501 *
12502 * If `value` is not supplied (or null/undefined), user actions that affect the
12503 * value will trigger updates to the element.
12504 *
12505 * If `value` is supplied (and not null/undefined), the rendered element will
12506 * not trigger updates to the element. Instead, the `value` prop must change in
12507 * order for the rendered element to be updated.
12508 *
12509 * The rendered element will be initialized with an empty value, the prop
12510 * `defaultValue` if specified, or the children content (deprecated).
12511 */
12512
12513function getHostProps$3(element, props) {
12514 var node = element;
12515 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
12516
12517 // Always set children to the same thing. In IE9, the selection range will
12518 // get reset if `textContent` is mutated. We could add a check in setTextContent
12519 // to only set the value if/when the value differs from the node value (which would
12520 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
12521 // solution. The value can be a boolean or object so that's why it's forced
12522 // to be a string.
12523 var hostProps = _assign({}, props, {
12524 value: undefined,
12525 defaultValue: undefined,
12526 children: '' + node._wrapperState.initialValue
12527 });
12528
12529 return hostProps;
12530}
12531
12532function initWrapperState$2(element, props) {
12533 var node = element;
12534 {
12535 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
12536 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
12537 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');
12538 didWarnValDefaultVal = true;
12539 }
12540 }
12541
12542 var initialValue = props.value;
12543
12544 // Only bother fetching default value if we're going to use it
12545 if (initialValue == null) {
12546 var defaultValue = props.defaultValue;
12547 // TODO (yungsters): Remove support for children content in <textarea>.
12548 var children = props.children;
12549 if (children != null) {
12550 {
12551 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
12552 }
12553 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
12554 if (Array.isArray(children)) {
12555 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
12556 children = children[0];
12557 }
12558
12559 defaultValue = '' + children;
12560 }
12561 if (defaultValue == null) {
12562 defaultValue = '';
12563 }
12564 initialValue = defaultValue;
12565 }
12566
12567 node._wrapperState = {
12568 initialValue: '' + initialValue
12569 };
12570}
12571
12572function updateWrapper$1(element, props) {
12573 var node = element;
12574 var value = props.value;
12575 if (value != null) {
12576 // Cast `value` to a string to ensure the value is set correctly. While
12577 // browsers typically do this as necessary, jsdom doesn't.
12578 var newValue = '' + value;
12579
12580 // To avoid side effects (such as losing text selection), only set value if changed
12581 if (newValue !== node.value) {
12582 node.value = newValue;
12583 }
12584 if (props.defaultValue == null) {
12585 node.defaultValue = newValue;
12586 }
12587 }
12588 if (props.defaultValue != null) {
12589 node.defaultValue = props.defaultValue;
12590 }
12591}
12592
12593function postMountWrapper$3(element, props) {
12594 var node = element;
12595 // This is in postMount because we need access to the DOM node, which is not
12596 // available until after the component has mounted.
12597 var textContent = node.textContent;
12598
12599 // Only set node.value if textContent is equal to the expected
12600 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
12601 // will populate textContent as well.
12602 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
12603 if (textContent === node._wrapperState.initialValue) {
12604 node.value = textContent;
12605 }
12606}
12607
12608function restoreControlledState$3(element, props) {
12609 // DOM component is still mounted; update
12610 updateWrapper$1(element, props);
12611}
12612
12613var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
12614var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
12615var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
12616
12617var Namespaces = {
12618 html: HTML_NAMESPACE$1,
12619 mathml: MATH_NAMESPACE,
12620 svg: SVG_NAMESPACE
12621};
12622
12623// Assumes there is no parent namespace.
12624function getIntrinsicNamespace(type) {
12625 switch (type) {
12626 case 'svg':
12627 return SVG_NAMESPACE;
12628 case 'math':
12629 return MATH_NAMESPACE;
12630 default:
12631 return HTML_NAMESPACE$1;
12632 }
12633}
12634
12635function getChildNamespace(parentNamespace, type) {
12636 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
12637 // No (or default) parent namespace: potential entry point.
12638 return getIntrinsicNamespace(type);
12639 }
12640 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
12641 // We're leaving SVG.
12642 return HTML_NAMESPACE$1;
12643 }
12644 // By default, pass namespace below.
12645 return parentNamespace;
12646}
12647
12648/* globals MSApp */
12649
12650/**
12651 * Create a function which has 'unsafe' privileges (required by windows8 apps)
12652 */
12653var createMicrosoftUnsafeLocalFunction = function (func) {
12654 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
12655 return function (arg0, arg1, arg2, arg3) {
12656 MSApp.execUnsafeLocalFunction(function () {
12657 return func(arg0, arg1, arg2, arg3);
12658 });
12659 };
12660 } else {
12661 return func;
12662 }
12663};
12664
12665// SVG temp container for IE lacking innerHTML
12666var reusableSVGContainer = void 0;
12667
12668/**
12669 * Set the innerHTML property of a node
12670 *
12671 * @param {DOMElement} node
12672 * @param {string} html
12673 * @internal
12674 */
12675var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
12676 // IE does not have innerHTML for SVG nodes, so instead we inject the
12677 // new markup in a temp node and then move the child nodes across into
12678 // the target node
12679
12680 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
12681 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
12682 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
12683 var svgNode = reusableSVGContainer.firstChild;
12684 while (node.firstChild) {
12685 node.removeChild(node.firstChild);
12686 }
12687 while (svgNode.firstChild) {
12688 node.appendChild(svgNode.firstChild);
12689 }
12690 } else {
12691 node.innerHTML = html;
12692 }
12693});
12694
12695/**
12696 * Set the textContent property of a node. For text updates, it's faster
12697 * to set the `nodeValue` of the Text node directly instead of using
12698 * `.textContent` which will remove the existing node and create a new one.
12699 *
12700 * @param {DOMElement} node
12701 * @param {string} text
12702 * @internal
12703 */
12704var setTextContent = function (node, text) {
12705 if (text) {
12706 var firstChild = node.firstChild;
12707
12708 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
12709 firstChild.nodeValue = text;
12710 return;
12711 }
12712 }
12713 node.textContent = text;
12714};
12715
12716/**
12717 * CSS properties which accept numbers but are not in units of "px".
12718 */
12719var isUnitlessNumber = {
12720 animationIterationCount: true,
12721 borderImageOutset: true,
12722 borderImageSlice: true,
12723 borderImageWidth: true,
12724 boxFlex: true,
12725 boxFlexGroup: true,
12726 boxOrdinalGroup: true,
12727 columnCount: true,
12728 columns: true,
12729 flex: true,
12730 flexGrow: true,
12731 flexPositive: true,
12732 flexShrink: true,
12733 flexNegative: true,
12734 flexOrder: true,
12735 gridRow: true,
12736 gridRowEnd: true,
12737 gridRowSpan: true,
12738 gridRowStart: true,
12739 gridColumn: true,
12740 gridColumnEnd: true,
12741 gridColumnSpan: true,
12742 gridColumnStart: true,
12743 fontWeight: true,
12744 lineClamp: true,
12745 lineHeight: true,
12746 opacity: true,
12747 order: true,
12748 orphans: true,
12749 tabSize: true,
12750 widows: true,
12751 zIndex: true,
12752 zoom: true,
12753
12754 // SVG-related properties
12755 fillOpacity: true,
12756 floodOpacity: true,
12757 stopOpacity: true,
12758 strokeDasharray: true,
12759 strokeDashoffset: true,
12760 strokeMiterlimit: true,
12761 strokeOpacity: true,
12762 strokeWidth: true
12763};
12764
12765/**
12766 * @param {string} prefix vendor-specific prefix, eg: Webkit
12767 * @param {string} key style name, eg: transitionDuration
12768 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
12769 * WebkitTransitionDuration
12770 */
12771function prefixKey(prefix, key) {
12772 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
12773}
12774
12775/**
12776 * Support style names that may come passed in prefixed by adding permutations
12777 * of vendor prefixes.
12778 */
12779var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
12780
12781// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
12782// infinite loop, because it iterates over the newly added props too.
12783Object.keys(isUnitlessNumber).forEach(function (prop) {
12784 prefixes.forEach(function (prefix) {
12785 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
12786 });
12787});
12788
12789/**
12790 * Convert a value into the proper css writable value. The style name `name`
12791 * should be logical (no hyphens), as specified
12792 * in `CSSProperty.isUnitlessNumber`.
12793 *
12794 * @param {string} name CSS property name such as `topMargin`.
12795 * @param {*} value CSS property value such as `10px`.
12796 * @return {string} Normalized style value with dimensions applied.
12797 */
12798function dangerousStyleValue(name, value, isCustomProperty) {
12799 // Note that we've removed escapeTextForBrowser() calls here since the
12800 // whole string will be escaped when the attribute is injected into
12801 // the markup. If you provide unsafe user data here they can inject
12802 // arbitrary CSS which may be problematic (I couldn't repro this):
12803 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
12804 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
12805 // This is not an XSS hole but instead a potential CSS injection issue
12806 // which has lead to a greater discussion about how we're going to
12807 // trust URLs moving forward. See #2115901
12808
12809 var isEmpty = value == null || typeof value === 'boolean' || value === '';
12810 if (isEmpty) {
12811 return '';
12812 }
12813
12814 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
12815 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
12816 }
12817
12818 return ('' + value).trim();
12819}
12820
12821/**
12822 * Copyright (c) 2013-present, Facebook, Inc.
12823 *
12824 * This source code is licensed under the MIT license found in the
12825 * LICENSE file in the root directory of this source tree.
12826 *
12827 * @typechecks
12828 */
12829
12830var _uppercasePattern = /([A-Z])/g;
12831
12832/**
12833 * Hyphenates a camelcased string, for example:
12834 *
12835 * > hyphenate('backgroundColor')
12836 * < "background-color"
12837 *
12838 * For CSS style names, use `hyphenateStyleName` instead which works properly
12839 * with all vendor prefixes, including `ms`.
12840 *
12841 * @param {string} string
12842 * @return {string}
12843 */
12844function hyphenate(string) {
12845 return string.replace(_uppercasePattern, '-$1').toLowerCase();
12846}
12847
12848var hyphenate_1 = hyphenate;
12849
12850/**
12851 * Copyright (c) 2013-present, Facebook, Inc.
12852 *
12853 * This source code is licensed under the MIT license found in the
12854 * LICENSE file in the root directory of this source tree.
12855 *
12856 * @typechecks
12857 */
12858
12859
12860
12861
12862
12863var msPattern = /^ms-/;
12864
12865/**
12866 * Hyphenates a camelcased CSS property name, for example:
12867 *
12868 * > hyphenateStyleName('backgroundColor')
12869 * < "background-color"
12870 * > hyphenateStyleName('MozTransition')
12871 * < "-moz-transition"
12872 * > hyphenateStyleName('msTransition')
12873 * < "-ms-transition"
12874 *
12875 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
12876 * is converted to `-ms-`.
12877 *
12878 * @param {string} string
12879 * @return {string}
12880 */
12881function hyphenateStyleName(string) {
12882 return hyphenate_1(string).replace(msPattern, '-ms-');
12883}
12884
12885var hyphenateStyleName_1 = hyphenateStyleName;
12886
12887/**
12888 * Copyright (c) 2013-present, Facebook, Inc.
12889 *
12890 * This source code is licensed under the MIT license found in the
12891 * LICENSE file in the root directory of this source tree.
12892 *
12893 * @typechecks
12894 */
12895
12896var _hyphenPattern = /-(.)/g;
12897
12898/**
12899 * Camelcases a hyphenated string, for example:
12900 *
12901 * > camelize('background-color')
12902 * < "backgroundColor"
12903 *
12904 * @param {string} string
12905 * @return {string}
12906 */
12907function camelize(string) {
12908 return string.replace(_hyphenPattern, function (_, character) {
12909 return character.toUpperCase();
12910 });
12911}
12912
12913var camelize_1 = camelize;
12914
12915/**
12916 * Copyright (c) 2013-present, Facebook, Inc.
12917 *
12918 * This source code is licensed under the MIT license found in the
12919 * LICENSE file in the root directory of this source tree.
12920 *
12921 * @typechecks
12922 */
12923
12924
12925
12926
12927
12928var msPattern$1 = /^-ms-/;
12929
12930/**
12931 * Camelcases a hyphenated CSS property name, for example:
12932 *
12933 * > camelizeStyleName('background-color')
12934 * < "backgroundColor"
12935 * > camelizeStyleName('-moz-transition')
12936 * < "MozTransition"
12937 * > camelizeStyleName('-ms-transition')
12938 * < "msTransition"
12939 *
12940 * As Andi Smith suggests
12941 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
12942 * is converted to lowercase `ms`.
12943 *
12944 * @param {string} string
12945 * @return {string}
12946 */
12947function camelizeStyleName(string) {
12948 return camelize_1(string.replace(msPattern$1, 'ms-'));
12949}
12950
12951var camelizeStyleName_1 = camelizeStyleName;
12952
12953var warnValidStyle = emptyFunction_1;
12954
12955{
12956 // 'msTransform' is correct, but the other prefixes should be capitalized
12957 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
12958
12959 // style values shouldn't contain a semicolon
12960 var badStyleValueWithSemicolonPattern = /;\s*$/;
12961
12962 var warnedStyleNames = {};
12963 var warnedStyleValues = {};
12964 var warnedForNaNValue = false;
12965 var warnedForInfinityValue = false;
12966
12967 var warnHyphenatedStyleName = function (name, getStack) {
12968 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12969 return;
12970 }
12971
12972 warnedStyleNames[name] = true;
12973 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
12974 };
12975
12976 var warnBadVendoredStyleName = function (name, getStack) {
12977 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12978 return;
12979 }
12980
12981 warnedStyleNames[name] = true;
12982 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
12983 };
12984
12985 var warnStyleValueWithSemicolon = function (name, value, getStack) {
12986 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
12987 return;
12988 }
12989
12990 warnedStyleValues[value] = true;
12991 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
12992 };
12993
12994 var warnStyleValueIsNaN = function (name, value, getStack) {
12995 if (warnedForNaNValue) {
12996 return;
12997 }
12998
12999 warnedForNaNValue = true;
13000 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
13001 };
13002
13003 var warnStyleValueIsInfinity = function (name, value, getStack) {
13004 if (warnedForInfinityValue) {
13005 return;
13006 }
13007
13008 warnedForInfinityValue = true;
13009 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
13010 };
13011
13012 warnValidStyle = function (name, value, getStack) {
13013 if (name.indexOf('-') > -1) {
13014 warnHyphenatedStyleName(name, getStack);
13015 } else if (badVendoredStyleNamePattern.test(name)) {
13016 warnBadVendoredStyleName(name, getStack);
13017 } else if (badStyleValueWithSemicolonPattern.test(value)) {
13018 warnStyleValueWithSemicolon(name, value, getStack);
13019 }
13020
13021 if (typeof value === 'number') {
13022 if (isNaN(value)) {
13023 warnStyleValueIsNaN(name, value, getStack);
13024 } else if (!isFinite(value)) {
13025 warnStyleValueIsInfinity(name, value, getStack);
13026 }
13027 }
13028 };
13029}
13030
13031var warnValidStyle$1 = warnValidStyle;
13032
13033/**
13034 * Operations for dealing with CSS properties.
13035 */
13036
13037/**
13038 * This creates a string that is expected to be equivalent to the style
13039 * attribute generated by server-side rendering. It by-passes warnings and
13040 * security checks so it's not safe to use this value for anything other than
13041 * comparison. It is only used in DEV for SSR validation.
13042 */
13043function createDangerousStringForStyles(styles) {
13044 {
13045 var serialized = '';
13046 var delimiter = '';
13047 for (var styleName in styles) {
13048 if (!styles.hasOwnProperty(styleName)) {
13049 continue;
13050 }
13051 var styleValue = styles[styleName];
13052 if (styleValue != null) {
13053 var isCustomProperty = styleName.indexOf('--') === 0;
13054 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
13055 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
13056
13057 delimiter = ';';
13058 }
13059 }
13060 return serialized || null;
13061 }
13062}
13063
13064/**
13065 * Sets the value for multiple styles on a node. If a value is specified as
13066 * '' (empty string), the corresponding style property will be unset.
13067 *
13068 * @param {DOMElement} node
13069 * @param {object} styles
13070 */
13071function setValueForStyles(node, styles, getStack) {
13072 var style = node.style;
13073 for (var styleName in styles) {
13074 if (!styles.hasOwnProperty(styleName)) {
13075 continue;
13076 }
13077 var isCustomProperty = styleName.indexOf('--') === 0;
13078 {
13079 if (!isCustomProperty) {
13080 warnValidStyle$1(styleName, styles[styleName], getStack);
13081 }
13082 }
13083 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
13084 if (styleName === 'float') {
13085 styleName = 'cssFloat';
13086 }
13087 if (isCustomProperty) {
13088 style.setProperty(styleName, styleValue);
13089 } else {
13090 style[styleName] = styleValue;
13091 }
13092 }
13093}
13094
13095// For HTML, certain tags should omit their close tag. We keep a whitelist for
13096// those special-case tags.
13097
13098var omittedCloseTags = {
13099 area: true,
13100 base: true,
13101 br: true,
13102 col: true,
13103 embed: true,
13104 hr: true,
13105 img: true,
13106 input: true,
13107 keygen: true,
13108 link: true,
13109 meta: true,
13110 param: true,
13111 source: true,
13112 track: true,
13113 wbr: true
13114};
13115
13116// For HTML, certain tags cannot have children. This has the same purpose as
13117// `omittedCloseTags` except that `menuitem` should still have its closing tag.
13118
13119var voidElementTags = _assign({
13120 menuitem: true
13121}, omittedCloseTags);
13122
13123var HTML$1 = '__html';
13124
13125function assertValidProps(tag, props, getStack) {
13126 if (!props) {
13127 return;
13128 }
13129 // Note the use of `==` which checks for null or undefined.
13130 if (voidElementTags[tag]) {
13131 !(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;
13132 }
13133 if (props.dangerouslySetInnerHTML != null) {
13134 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
13135 !(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;
13136 }
13137 {
13138 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());
13139 }
13140 !(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;
13141}
13142
13143function isCustomComponent(tagName, props) {
13144 if (tagName.indexOf('-') === -1) {
13145 return typeof props.is === 'string';
13146 }
13147 switch (tagName) {
13148 // These are reserved SVG and MathML elements.
13149 // We don't mind this whitelist too much because we expect it to never grow.
13150 // The alternative is to track the namespace in a few places which is convoluted.
13151 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
13152 case 'annotation-xml':
13153 case 'color-profile':
13154 case 'font-face':
13155 case 'font-face-src':
13156 case 'font-face-uri':
13157 case 'font-face-format':
13158 case 'font-face-name':
13159 case 'missing-glyph':
13160 return false;
13161 default:
13162 return true;
13163 }
13164}
13165
13166// When adding attributes to the HTML or SVG whitelist, be sure to
13167// also add them to this module to ensure casing and incorrect name
13168// warnings.
13169var possibleStandardNames = {
13170 // HTML
13171 accept: 'accept',
13172 acceptcharset: 'acceptCharset',
13173 'accept-charset': 'acceptCharset',
13174 accesskey: 'accessKey',
13175 action: 'action',
13176 allowfullscreen: 'allowFullScreen',
13177 alt: 'alt',
13178 as: 'as',
13179 async: 'async',
13180 autocapitalize: 'autoCapitalize',
13181 autocomplete: 'autoComplete',
13182 autocorrect: 'autoCorrect',
13183 autofocus: 'autoFocus',
13184 autoplay: 'autoPlay',
13185 autosave: 'autoSave',
13186 capture: 'capture',
13187 cellpadding: 'cellPadding',
13188 cellspacing: 'cellSpacing',
13189 challenge: 'challenge',
13190 charset: 'charSet',
13191 checked: 'checked',
13192 children: 'children',
13193 cite: 'cite',
13194 'class': 'className',
13195 classid: 'classID',
13196 classname: 'className',
13197 cols: 'cols',
13198 colspan: 'colSpan',
13199 content: 'content',
13200 contenteditable: 'contentEditable',
13201 contextmenu: 'contextMenu',
13202 controls: 'controls',
13203 controlslist: 'controlsList',
13204 coords: 'coords',
13205 crossorigin: 'crossOrigin',
13206 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13207 data: 'data',
13208 datetime: 'dateTime',
13209 'default': 'default',
13210 defaultchecked: 'defaultChecked',
13211 defaultvalue: 'defaultValue',
13212 defer: 'defer',
13213 dir: 'dir',
13214 disabled: 'disabled',
13215 download: 'download',
13216 draggable: 'draggable',
13217 enctype: 'encType',
13218 'for': 'htmlFor',
13219 form: 'form',
13220 formmethod: 'formMethod',
13221 formaction: 'formAction',
13222 formenctype: 'formEncType',
13223 formnovalidate: 'formNoValidate',
13224 formtarget: 'formTarget',
13225 frameborder: 'frameBorder',
13226 headers: 'headers',
13227 height: 'height',
13228 hidden: 'hidden',
13229 high: 'high',
13230 href: 'href',
13231 hreflang: 'hrefLang',
13232 htmlfor: 'htmlFor',
13233 httpequiv: 'httpEquiv',
13234 'http-equiv': 'httpEquiv',
13235 icon: 'icon',
13236 id: 'id',
13237 innerhtml: 'innerHTML',
13238 inputmode: 'inputMode',
13239 integrity: 'integrity',
13240 is: 'is',
13241 itemid: 'itemID',
13242 itemprop: 'itemProp',
13243 itemref: 'itemRef',
13244 itemscope: 'itemScope',
13245 itemtype: 'itemType',
13246 keyparams: 'keyParams',
13247 keytype: 'keyType',
13248 kind: 'kind',
13249 label: 'label',
13250 lang: 'lang',
13251 list: 'list',
13252 loop: 'loop',
13253 low: 'low',
13254 manifest: 'manifest',
13255 marginwidth: 'marginWidth',
13256 marginheight: 'marginHeight',
13257 max: 'max',
13258 maxlength: 'maxLength',
13259 media: 'media',
13260 mediagroup: 'mediaGroup',
13261 method: 'method',
13262 min: 'min',
13263 minlength: 'minLength',
13264 multiple: 'multiple',
13265 muted: 'muted',
13266 name: 'name',
13267 nomodule: 'noModule',
13268 nonce: 'nonce',
13269 novalidate: 'noValidate',
13270 open: 'open',
13271 optimum: 'optimum',
13272 pattern: 'pattern',
13273 placeholder: 'placeholder',
13274 playsinline: 'playsInline',
13275 poster: 'poster',
13276 preload: 'preload',
13277 profile: 'profile',
13278 radiogroup: 'radioGroup',
13279 readonly: 'readOnly',
13280 referrerpolicy: 'referrerPolicy',
13281 rel: 'rel',
13282 required: 'required',
13283 reversed: 'reversed',
13284 role: 'role',
13285 rows: 'rows',
13286 rowspan: 'rowSpan',
13287 sandbox: 'sandbox',
13288 scope: 'scope',
13289 scoped: 'scoped',
13290 scrolling: 'scrolling',
13291 seamless: 'seamless',
13292 selected: 'selected',
13293 shape: 'shape',
13294 size: 'size',
13295 sizes: 'sizes',
13296 span: 'span',
13297 spellcheck: 'spellCheck',
13298 src: 'src',
13299 srcdoc: 'srcDoc',
13300 srclang: 'srcLang',
13301 srcset: 'srcSet',
13302 start: 'start',
13303 step: 'step',
13304 style: 'style',
13305 summary: 'summary',
13306 tabindex: 'tabIndex',
13307 target: 'target',
13308 title: 'title',
13309 type: 'type',
13310 usemap: 'useMap',
13311 value: 'value',
13312 width: 'width',
13313 wmode: 'wmode',
13314 wrap: 'wrap',
13315
13316 // SVG
13317 about: 'about',
13318 accentheight: 'accentHeight',
13319 'accent-height': 'accentHeight',
13320 accumulate: 'accumulate',
13321 additive: 'additive',
13322 alignmentbaseline: 'alignmentBaseline',
13323 'alignment-baseline': 'alignmentBaseline',
13324 allowreorder: 'allowReorder',
13325 alphabetic: 'alphabetic',
13326 amplitude: 'amplitude',
13327 arabicform: 'arabicForm',
13328 'arabic-form': 'arabicForm',
13329 ascent: 'ascent',
13330 attributename: 'attributeName',
13331 attributetype: 'attributeType',
13332 autoreverse: 'autoReverse',
13333 azimuth: 'azimuth',
13334 basefrequency: 'baseFrequency',
13335 baselineshift: 'baselineShift',
13336 'baseline-shift': 'baselineShift',
13337 baseprofile: 'baseProfile',
13338 bbox: 'bbox',
13339 begin: 'begin',
13340 bias: 'bias',
13341 by: 'by',
13342 calcmode: 'calcMode',
13343 capheight: 'capHeight',
13344 'cap-height': 'capHeight',
13345 clip: 'clip',
13346 clippath: 'clipPath',
13347 'clip-path': 'clipPath',
13348 clippathunits: 'clipPathUnits',
13349 cliprule: 'clipRule',
13350 'clip-rule': 'clipRule',
13351 color: 'color',
13352 colorinterpolation: 'colorInterpolation',
13353 'color-interpolation': 'colorInterpolation',
13354 colorinterpolationfilters: 'colorInterpolationFilters',
13355 'color-interpolation-filters': 'colorInterpolationFilters',
13356 colorprofile: 'colorProfile',
13357 'color-profile': 'colorProfile',
13358 colorrendering: 'colorRendering',
13359 'color-rendering': 'colorRendering',
13360 contentscripttype: 'contentScriptType',
13361 contentstyletype: 'contentStyleType',
13362 cursor: 'cursor',
13363 cx: 'cx',
13364 cy: 'cy',
13365 d: 'd',
13366 datatype: 'datatype',
13367 decelerate: 'decelerate',
13368 descent: 'descent',
13369 diffuseconstant: 'diffuseConstant',
13370 direction: 'direction',
13371 display: 'display',
13372 divisor: 'divisor',
13373 dominantbaseline: 'dominantBaseline',
13374 'dominant-baseline': 'dominantBaseline',
13375 dur: 'dur',
13376 dx: 'dx',
13377 dy: 'dy',
13378 edgemode: 'edgeMode',
13379 elevation: 'elevation',
13380 enablebackground: 'enableBackground',
13381 'enable-background': 'enableBackground',
13382 end: 'end',
13383 exponent: 'exponent',
13384 externalresourcesrequired: 'externalResourcesRequired',
13385 fill: 'fill',
13386 fillopacity: 'fillOpacity',
13387 'fill-opacity': 'fillOpacity',
13388 fillrule: 'fillRule',
13389 'fill-rule': 'fillRule',
13390 filter: 'filter',
13391 filterres: 'filterRes',
13392 filterunits: 'filterUnits',
13393 floodopacity: 'floodOpacity',
13394 'flood-opacity': 'floodOpacity',
13395 floodcolor: 'floodColor',
13396 'flood-color': 'floodColor',
13397 focusable: 'focusable',
13398 fontfamily: 'fontFamily',
13399 'font-family': 'fontFamily',
13400 fontsize: 'fontSize',
13401 'font-size': 'fontSize',
13402 fontsizeadjust: 'fontSizeAdjust',
13403 'font-size-adjust': 'fontSizeAdjust',
13404 fontstretch: 'fontStretch',
13405 'font-stretch': 'fontStretch',
13406 fontstyle: 'fontStyle',
13407 'font-style': 'fontStyle',
13408 fontvariant: 'fontVariant',
13409 'font-variant': 'fontVariant',
13410 fontweight: 'fontWeight',
13411 'font-weight': 'fontWeight',
13412 format: 'format',
13413 from: 'from',
13414 fx: 'fx',
13415 fy: 'fy',
13416 g1: 'g1',
13417 g2: 'g2',
13418 glyphname: 'glyphName',
13419 'glyph-name': 'glyphName',
13420 glyphorientationhorizontal: 'glyphOrientationHorizontal',
13421 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
13422 glyphorientationvertical: 'glyphOrientationVertical',
13423 'glyph-orientation-vertical': 'glyphOrientationVertical',
13424 glyphref: 'glyphRef',
13425 gradienttransform: 'gradientTransform',
13426 gradientunits: 'gradientUnits',
13427 hanging: 'hanging',
13428 horizadvx: 'horizAdvX',
13429 'horiz-adv-x': 'horizAdvX',
13430 horizoriginx: 'horizOriginX',
13431 'horiz-origin-x': 'horizOriginX',
13432 ideographic: 'ideographic',
13433 imagerendering: 'imageRendering',
13434 'image-rendering': 'imageRendering',
13435 in2: 'in2',
13436 'in': 'in',
13437 inlist: 'inlist',
13438 intercept: 'intercept',
13439 k1: 'k1',
13440 k2: 'k2',
13441 k3: 'k3',
13442 k4: 'k4',
13443 k: 'k',
13444 kernelmatrix: 'kernelMatrix',
13445 kernelunitlength: 'kernelUnitLength',
13446 kerning: 'kerning',
13447 keypoints: 'keyPoints',
13448 keysplines: 'keySplines',
13449 keytimes: 'keyTimes',
13450 lengthadjust: 'lengthAdjust',
13451 letterspacing: 'letterSpacing',
13452 'letter-spacing': 'letterSpacing',
13453 lightingcolor: 'lightingColor',
13454 'lighting-color': 'lightingColor',
13455 limitingconeangle: 'limitingConeAngle',
13456 local: 'local',
13457 markerend: 'markerEnd',
13458 'marker-end': 'markerEnd',
13459 markerheight: 'markerHeight',
13460 markermid: 'markerMid',
13461 'marker-mid': 'markerMid',
13462 markerstart: 'markerStart',
13463 'marker-start': 'markerStart',
13464 markerunits: 'markerUnits',
13465 markerwidth: 'markerWidth',
13466 mask: 'mask',
13467 maskcontentunits: 'maskContentUnits',
13468 maskunits: 'maskUnits',
13469 mathematical: 'mathematical',
13470 mode: 'mode',
13471 numoctaves: 'numOctaves',
13472 offset: 'offset',
13473 opacity: 'opacity',
13474 operator: 'operator',
13475 order: 'order',
13476 orient: 'orient',
13477 orientation: 'orientation',
13478 origin: 'origin',
13479 overflow: 'overflow',
13480 overlineposition: 'overlinePosition',
13481 'overline-position': 'overlinePosition',
13482 overlinethickness: 'overlineThickness',
13483 'overline-thickness': 'overlineThickness',
13484 paintorder: 'paintOrder',
13485 'paint-order': 'paintOrder',
13486 panose1: 'panose1',
13487 'panose-1': 'panose1',
13488 pathlength: 'pathLength',
13489 patterncontentunits: 'patternContentUnits',
13490 patterntransform: 'patternTransform',
13491 patternunits: 'patternUnits',
13492 pointerevents: 'pointerEvents',
13493 'pointer-events': 'pointerEvents',
13494 points: 'points',
13495 pointsatx: 'pointsAtX',
13496 pointsaty: 'pointsAtY',
13497 pointsatz: 'pointsAtZ',
13498 prefix: 'prefix',
13499 preservealpha: 'preserveAlpha',
13500 preserveaspectratio: 'preserveAspectRatio',
13501 primitiveunits: 'primitiveUnits',
13502 property: 'property',
13503 r: 'r',
13504 radius: 'radius',
13505 refx: 'refX',
13506 refy: 'refY',
13507 renderingintent: 'renderingIntent',
13508 'rendering-intent': 'renderingIntent',
13509 repeatcount: 'repeatCount',
13510 repeatdur: 'repeatDur',
13511 requiredextensions: 'requiredExtensions',
13512 requiredfeatures: 'requiredFeatures',
13513 resource: 'resource',
13514 restart: 'restart',
13515 result: 'result',
13516 results: 'results',
13517 rotate: 'rotate',
13518 rx: 'rx',
13519 ry: 'ry',
13520 scale: 'scale',
13521 security: 'security',
13522 seed: 'seed',
13523 shaperendering: 'shapeRendering',
13524 'shape-rendering': 'shapeRendering',
13525 slope: 'slope',
13526 spacing: 'spacing',
13527 specularconstant: 'specularConstant',
13528 specularexponent: 'specularExponent',
13529 speed: 'speed',
13530 spreadmethod: 'spreadMethod',
13531 startoffset: 'startOffset',
13532 stddeviation: 'stdDeviation',
13533 stemh: 'stemh',
13534 stemv: 'stemv',
13535 stitchtiles: 'stitchTiles',
13536 stopcolor: 'stopColor',
13537 'stop-color': 'stopColor',
13538 stopopacity: 'stopOpacity',
13539 'stop-opacity': 'stopOpacity',
13540 strikethroughposition: 'strikethroughPosition',
13541 'strikethrough-position': 'strikethroughPosition',
13542 strikethroughthickness: 'strikethroughThickness',
13543 'strikethrough-thickness': 'strikethroughThickness',
13544 string: 'string',
13545 stroke: 'stroke',
13546 strokedasharray: 'strokeDasharray',
13547 'stroke-dasharray': 'strokeDasharray',
13548 strokedashoffset: 'strokeDashoffset',
13549 'stroke-dashoffset': 'strokeDashoffset',
13550 strokelinecap: 'strokeLinecap',
13551 'stroke-linecap': 'strokeLinecap',
13552 strokelinejoin: 'strokeLinejoin',
13553 'stroke-linejoin': 'strokeLinejoin',
13554 strokemiterlimit: 'strokeMiterlimit',
13555 'stroke-miterlimit': 'strokeMiterlimit',
13556 strokewidth: 'strokeWidth',
13557 'stroke-width': 'strokeWidth',
13558 strokeopacity: 'strokeOpacity',
13559 'stroke-opacity': 'strokeOpacity',
13560 suppresscontenteditablewarning: 'suppressContentEditableWarning',
13561 suppresshydrationwarning: 'suppressHydrationWarning',
13562 surfacescale: 'surfaceScale',
13563 systemlanguage: 'systemLanguage',
13564 tablevalues: 'tableValues',
13565 targetx: 'targetX',
13566 targety: 'targetY',
13567 textanchor: 'textAnchor',
13568 'text-anchor': 'textAnchor',
13569 textdecoration: 'textDecoration',
13570 'text-decoration': 'textDecoration',
13571 textlength: 'textLength',
13572 textrendering: 'textRendering',
13573 'text-rendering': 'textRendering',
13574 to: 'to',
13575 transform: 'transform',
13576 'typeof': 'typeof',
13577 u1: 'u1',
13578 u2: 'u2',
13579 underlineposition: 'underlinePosition',
13580 'underline-position': 'underlinePosition',
13581 underlinethickness: 'underlineThickness',
13582 'underline-thickness': 'underlineThickness',
13583 unicode: 'unicode',
13584 unicodebidi: 'unicodeBidi',
13585 'unicode-bidi': 'unicodeBidi',
13586 unicoderange: 'unicodeRange',
13587 'unicode-range': 'unicodeRange',
13588 unitsperem: 'unitsPerEm',
13589 'units-per-em': 'unitsPerEm',
13590 unselectable: 'unselectable',
13591 valphabetic: 'vAlphabetic',
13592 'v-alphabetic': 'vAlphabetic',
13593 values: 'values',
13594 vectoreffect: 'vectorEffect',
13595 'vector-effect': 'vectorEffect',
13596 version: 'version',
13597 vertadvy: 'vertAdvY',
13598 'vert-adv-y': 'vertAdvY',
13599 vertoriginx: 'vertOriginX',
13600 'vert-origin-x': 'vertOriginX',
13601 vertoriginy: 'vertOriginY',
13602 'vert-origin-y': 'vertOriginY',
13603 vhanging: 'vHanging',
13604 'v-hanging': 'vHanging',
13605 videographic: 'vIdeographic',
13606 'v-ideographic': 'vIdeographic',
13607 viewbox: 'viewBox',
13608 viewtarget: 'viewTarget',
13609 visibility: 'visibility',
13610 vmathematical: 'vMathematical',
13611 'v-mathematical': 'vMathematical',
13612 vocab: 'vocab',
13613 widths: 'widths',
13614 wordspacing: 'wordSpacing',
13615 'word-spacing': 'wordSpacing',
13616 writingmode: 'writingMode',
13617 'writing-mode': 'writingMode',
13618 x1: 'x1',
13619 x2: 'x2',
13620 x: 'x',
13621 xchannelselector: 'xChannelSelector',
13622 xheight: 'xHeight',
13623 'x-height': 'xHeight',
13624 xlinkactuate: 'xlinkActuate',
13625 'xlink:actuate': 'xlinkActuate',
13626 xlinkarcrole: 'xlinkArcrole',
13627 'xlink:arcrole': 'xlinkArcrole',
13628 xlinkhref: 'xlinkHref',
13629 'xlink:href': 'xlinkHref',
13630 xlinkrole: 'xlinkRole',
13631 'xlink:role': 'xlinkRole',
13632 xlinkshow: 'xlinkShow',
13633 'xlink:show': 'xlinkShow',
13634 xlinktitle: 'xlinkTitle',
13635 'xlink:title': 'xlinkTitle',
13636 xlinktype: 'xlinkType',
13637 'xlink:type': 'xlinkType',
13638 xmlbase: 'xmlBase',
13639 'xml:base': 'xmlBase',
13640 xmllang: 'xmlLang',
13641 'xml:lang': 'xmlLang',
13642 xmlns: 'xmlns',
13643 'xml:space': 'xmlSpace',
13644 xmlnsxlink: 'xmlnsXlink',
13645 'xmlns:xlink': 'xmlnsXlink',
13646 xmlspace: 'xmlSpace',
13647 y1: 'y1',
13648 y2: 'y2',
13649 y: 'y',
13650 ychannelselector: 'yChannelSelector',
13651 z: 'z',
13652 zoomandpan: 'zoomAndPan'
13653};
13654
13655var ariaProperties = {
13656 'aria-current': 0, // state
13657 'aria-details': 0,
13658 'aria-disabled': 0, // state
13659 'aria-hidden': 0, // state
13660 'aria-invalid': 0, // state
13661 'aria-keyshortcuts': 0,
13662 'aria-label': 0,
13663 'aria-roledescription': 0,
13664 // Widget Attributes
13665 'aria-autocomplete': 0,
13666 'aria-checked': 0,
13667 'aria-expanded': 0,
13668 'aria-haspopup': 0,
13669 'aria-level': 0,
13670 'aria-modal': 0,
13671 'aria-multiline': 0,
13672 'aria-multiselectable': 0,
13673 'aria-orientation': 0,
13674 'aria-placeholder': 0,
13675 'aria-pressed': 0,
13676 'aria-readonly': 0,
13677 'aria-required': 0,
13678 'aria-selected': 0,
13679 'aria-sort': 0,
13680 'aria-valuemax': 0,
13681 'aria-valuemin': 0,
13682 'aria-valuenow': 0,
13683 'aria-valuetext': 0,
13684 // Live Region Attributes
13685 'aria-atomic': 0,
13686 'aria-busy': 0,
13687 'aria-live': 0,
13688 'aria-relevant': 0,
13689 // Drag-and-Drop Attributes
13690 'aria-dropeffect': 0,
13691 'aria-grabbed': 0,
13692 // Relationship Attributes
13693 'aria-activedescendant': 0,
13694 'aria-colcount': 0,
13695 'aria-colindex': 0,
13696 'aria-colspan': 0,
13697 'aria-controls': 0,
13698 'aria-describedby': 0,
13699 'aria-errormessage': 0,
13700 'aria-flowto': 0,
13701 'aria-labelledby': 0,
13702 'aria-owns': 0,
13703 'aria-posinset': 0,
13704 'aria-rowcount': 0,
13705 'aria-rowindex': 0,
13706 'aria-rowspan': 0,
13707 'aria-setsize': 0
13708};
13709
13710var warnedProperties = {};
13711var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13712var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13713
13714var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
13715
13716function getStackAddendum() {
13717 var stack = ReactDebugCurrentFrame.getStackAddendum();
13718 return stack != null ? stack : '';
13719}
13720
13721function validateProperty(tagName, name) {
13722 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
13723 return true;
13724 }
13725
13726 if (rARIACamel.test(name)) {
13727 var ariaName = 'aria-' + name.slice(4).toLowerCase();
13728 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
13729
13730 // If this is an aria-* attribute, but is not listed in the known DOM
13731 // DOM properties, then it is an invalid aria-* attribute.
13732 if (correctName == null) {
13733 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
13734 warnedProperties[name] = true;
13735 return true;
13736 }
13737 // aria-* attributes should be lowercase; suggest the lowercase version.
13738 if (name !== correctName) {
13739 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
13740 warnedProperties[name] = true;
13741 return true;
13742 }
13743 }
13744
13745 if (rARIA.test(name)) {
13746 var lowerCasedName = name.toLowerCase();
13747 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
13748
13749 // If this is an aria-* attribute, but is not listed in the known DOM
13750 // DOM properties, then it is an invalid aria-* attribute.
13751 if (standardName == null) {
13752 warnedProperties[name] = true;
13753 return false;
13754 }
13755 // aria-* attributes should be lowercase; suggest the lowercase version.
13756 if (name !== standardName) {
13757 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
13758 warnedProperties[name] = true;
13759 return true;
13760 }
13761 }
13762
13763 return true;
13764}
13765
13766function warnInvalidARIAProps(type, props) {
13767 var invalidProps = [];
13768
13769 for (var key in props) {
13770 var isValid = validateProperty(type, key);
13771 if (!isValid) {
13772 invalidProps.push(key);
13773 }
13774 }
13775
13776 var unknownPropString = invalidProps.map(function (prop) {
13777 return '`' + prop + '`';
13778 }).join(', ');
13779
13780 if (invalidProps.length === 1) {
13781 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13782 } else if (invalidProps.length > 1) {
13783 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13784 }
13785}
13786
13787function validateProperties(type, props) {
13788 if (isCustomComponent(type, props)) {
13789 return;
13790 }
13791 warnInvalidARIAProps(type, props);
13792}
13793
13794var didWarnValueNull = false;
13795
13796function getStackAddendum$1() {
13797 var stack = ReactDebugCurrentFrame.getStackAddendum();
13798 return stack != null ? stack : '';
13799}
13800
13801function validateProperties$1(type, props) {
13802 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
13803 return;
13804 }
13805
13806 if (props != null && props.value === null && !didWarnValueNull) {
13807 didWarnValueNull = true;
13808 if (type === 'select' && props.multiple) {
13809 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());
13810 } else {
13811 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());
13812 }
13813 }
13814}
13815
13816function getStackAddendum$2() {
13817 var stack = ReactDebugCurrentFrame.getStackAddendum();
13818 return stack != null ? stack : '';
13819}
13820
13821var validateProperty$1 = function () {};
13822
13823{
13824 var warnedProperties$1 = {};
13825 var _hasOwnProperty = Object.prototype.hasOwnProperty;
13826 var EVENT_NAME_REGEX = /^on./;
13827 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
13828 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13829 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13830
13831 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
13832 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
13833 return true;
13834 }
13835
13836 var lowerCasedName = name.toLowerCase();
13837 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
13838 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.');
13839 warnedProperties$1[name] = true;
13840 return true;
13841 }
13842
13843 // We can't rely on the event system being injected on the server.
13844 if (canUseEventSystem) {
13845 if (registrationNameModules.hasOwnProperty(name)) {
13846 return true;
13847 }
13848 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
13849 if (registrationName != null) {
13850 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
13851 warnedProperties$1[name] = true;
13852 return true;
13853 }
13854 if (EVENT_NAME_REGEX.test(name)) {
13855 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
13856 warnedProperties$1[name] = true;
13857 return true;
13858 }
13859 } else if (EVENT_NAME_REGEX.test(name)) {
13860 // If no event plugins have been injected, we are in a server environment.
13861 // So we can't tell if the event name is correct for sure, but we can filter
13862 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
13863 if (INVALID_EVENT_NAME_REGEX.test(name)) {
13864 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
13865 }
13866 warnedProperties$1[name] = true;
13867 return true;
13868 }
13869
13870 // Let the ARIA attribute hook validate ARIA attributes
13871 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
13872 return true;
13873 }
13874
13875 if (lowerCasedName === 'innerhtml') {
13876 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
13877 warnedProperties$1[name] = true;
13878 return true;
13879 }
13880
13881 if (lowerCasedName === 'aria') {
13882 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
13883 warnedProperties$1[name] = true;
13884 return true;
13885 }
13886
13887 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
13888 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());
13889 warnedProperties$1[name] = true;
13890 return true;
13891 }
13892
13893 if (typeof value === 'number' && isNaN(value)) {
13894 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
13895 warnedProperties$1[name] = true;
13896 return true;
13897 }
13898
13899 var propertyInfo = getPropertyInfo(name);
13900 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
13901
13902 // Known attributes should match the casing specified in the property config.
13903 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
13904 var standardName = possibleStandardNames[lowerCasedName];
13905 if (standardName !== name) {
13906 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
13907 warnedProperties$1[name] = true;
13908 return true;
13909 }
13910 } else if (!isReserved && name !== lowerCasedName) {
13911 // Unknown attributes should have lowercase casing since that's how they
13912 // will be cased anyway with server rendering.
13913 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());
13914 warnedProperties$1[name] = true;
13915 return true;
13916 }
13917
13918 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13919 if (value) {
13920 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());
13921 } else {
13922 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());
13923 }
13924 warnedProperties$1[name] = true;
13925 return true;
13926 }
13927
13928 // Now that we've validated casing, do not validate
13929 // data types for reserved props
13930 if (isReserved) {
13931 return true;
13932 }
13933
13934 // Warn when a known attribute is a bad type
13935 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13936 warnedProperties$1[name] = true;
13937 return false;
13938 }
13939
13940 return true;
13941 };
13942}
13943
13944var warnUnknownProperties = function (type, props, canUseEventSystem) {
13945 var unknownProps = [];
13946 for (var key in props) {
13947 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
13948 if (!isValid) {
13949 unknownProps.push(key);
13950 }
13951 }
13952
13953 var unknownPropString = unknownProps.map(function (prop) {
13954 return '`' + prop + '`';
13955 }).join(', ');
13956 if (unknownProps.length === 1) {
13957 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());
13958 } else if (unknownProps.length > 1) {
13959 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());
13960 }
13961};
13962
13963function validateProperties$2(type, props, canUseEventSystem) {
13964 if (isCustomComponent(type, props)) {
13965 return;
13966 }
13967 warnUnknownProperties(type, props, canUseEventSystem);
13968}
13969
13970// TODO: direct imports like some-package/src/* are bad. Fix me.
13971var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
13972var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13973
13974var didWarnInvalidHydration = false;
13975var didWarnShadyDOM = false;
13976
13977var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
13978var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
13979var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
13980var AUTOFOCUS = 'autoFocus';
13981var CHILDREN = 'children';
13982var STYLE = 'style';
13983var HTML = '__html';
13984
13985var HTML_NAMESPACE = Namespaces.html;
13986
13987
13988var getStack = emptyFunction_1.thatReturns('');
13989
13990var warnedUnknownTags = void 0;
13991var suppressHydrationWarning = void 0;
13992
13993var validatePropertiesInDevelopment = void 0;
13994var warnForTextDifference = void 0;
13995var warnForPropDifference = void 0;
13996var warnForExtraAttributes = void 0;
13997var warnForInvalidEventListener = void 0;
13998
13999var normalizeMarkupForTextOrAttribute = void 0;
14000var normalizeHTML = void 0;
14001
14002{
14003 getStack = getCurrentFiberStackAddendum$3;
14004
14005 warnedUnknownTags = {
14006 // Chrome is the only major browser not shipping <time>. But as of July
14007 // 2017 it intends to ship it due to widespread usage. We intentionally
14008 // *don't* warn for <time> even if it's unrecognized by Chrome because
14009 // it soon will be, and many apps have been using it anyway.
14010 time: true,
14011 // There are working polyfills for <dialog>. Let people use it.
14012 dialog: true
14013 };
14014
14015 validatePropertiesInDevelopment = function (type, props) {
14016 validateProperties(type, props);
14017 validateProperties$1(type, props);
14018 validateProperties$2(type, props, /* canUseEventSystem */true);
14019 };
14020
14021 // HTML parsing normalizes CR and CRLF to LF.
14022 // It also can turn \u0000 into \uFFFD inside attributes.
14023 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
14024 // If we have a mismatch, it might be caused by that.
14025 // We will still patch up in this case but not fire the warning.
14026 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
14027 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
14028
14029 normalizeMarkupForTextOrAttribute = function (markup) {
14030 var markupString = typeof markup === 'string' ? markup : '' + markup;
14031 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
14032 };
14033
14034 warnForTextDifference = function (serverText, clientText) {
14035 if (didWarnInvalidHydration) {
14036 return;
14037 }
14038 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
14039 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
14040 if (normalizedServerText === normalizedClientText) {
14041 return;
14042 }
14043 didWarnInvalidHydration = true;
14044 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
14045 };
14046
14047 warnForPropDifference = function (propName, serverValue, clientValue) {
14048 if (didWarnInvalidHydration) {
14049 return;
14050 }
14051 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
14052 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
14053 if (normalizedServerValue === normalizedClientValue) {
14054 return;
14055 }
14056 didWarnInvalidHydration = true;
14057 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
14058 };
14059
14060 warnForExtraAttributes = function (attributeNames) {
14061 if (didWarnInvalidHydration) {
14062 return;
14063 }
14064 didWarnInvalidHydration = true;
14065 var names = [];
14066 attributeNames.forEach(function (name) {
14067 names.push(name);
14068 });
14069 warning_1(false, 'Extra attributes from the server: %s', names);
14070 };
14071
14072 warnForInvalidEventListener = function (registrationName, listener) {
14073 if (listener === false) {
14074 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());
14075 } else {
14076 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
14077 }
14078 };
14079
14080 // Parse the HTML and read it back to normalize the HTML string so that it
14081 // can be used for comparison.
14082 normalizeHTML = function (parent, html) {
14083 // We could have created a separate document here to avoid
14084 // re-initializing custom elements if they exist. But this breaks
14085 // how <noscript> is being handled. So we use the same document.
14086 // See the discussion in https://github.com/facebook/react/pull/11157.
14087 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
14088 testElement.innerHTML = html;
14089 return testElement.innerHTML;
14090 };
14091}
14092
14093function ensureListeningTo(rootContainerElement, registrationName) {
14094 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
14095 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
14096 listenTo(registrationName, doc);
14097}
14098
14099function getOwnerDocumentFromRootContainer(rootContainerElement) {
14100 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
14101}
14102
14103function trapClickOnNonInteractiveElement(node) {
14104 // Mobile Safari does not fire properly bubble click events on
14105 // non-interactive elements, which means delegated click listeners do not
14106 // fire. The workaround for this bug involves attaching an empty click
14107 // listener on the target node.
14108 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
14109 // Just set it using the onclick property so that we don't have to manage any
14110 // bookkeeping for it. Not sure if we need to clear it when the listener is
14111 // removed.
14112 // TODO: Only do this for the relevant Safaris maybe?
14113 node.onclick = emptyFunction_1;
14114}
14115
14116function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
14117 for (var propKey in nextProps) {
14118 if (!nextProps.hasOwnProperty(propKey)) {
14119 continue;
14120 }
14121 var nextProp = nextProps[propKey];
14122 if (propKey === STYLE) {
14123 {
14124 if (nextProp) {
14125 // Freeze the next style object so that we can assume it won't be
14126 // mutated. We have already warned for this in the past.
14127 Object.freeze(nextProp);
14128 }
14129 }
14130 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14131 setValueForStyles(domElement, nextProp, getStack);
14132 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14133 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14134 if (nextHtml != null) {
14135 setInnerHTML(domElement, nextHtml);
14136 }
14137 } else if (propKey === CHILDREN) {
14138 if (typeof nextProp === 'string') {
14139 // Avoid setting initial textContent when the text is empty. In IE11 setting
14140 // textContent on a <textarea> will cause the placeholder to not
14141 // show within the <textarea> until it has been focused and blurred again.
14142 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
14143 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
14144 if (canSetTextContent) {
14145 setTextContent(domElement, nextProp);
14146 }
14147 } else if (typeof nextProp === 'number') {
14148 setTextContent(domElement, '' + nextProp);
14149 }
14150 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14151 // Noop
14152 } else if (propKey === AUTOFOCUS) {
14153 // We polyfill it separately on the client during commit.
14154 // We blacklist it here rather than in the property list because we emit it in SSR.
14155 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14156 if (nextProp != null) {
14157 if (true && typeof nextProp !== 'function') {
14158 warnForInvalidEventListener(propKey, nextProp);
14159 }
14160 ensureListeningTo(rootContainerElement, propKey);
14161 }
14162 } else if (nextProp != null) {
14163 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14164 }
14165 }
14166}
14167
14168function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14169 // TODO: Handle wasCustomComponentTag
14170 for (var i = 0; i < updatePayload.length; i += 2) {
14171 var propKey = updatePayload[i];
14172 var propValue = updatePayload[i + 1];
14173 if (propKey === STYLE) {
14174 setValueForStyles(domElement, propValue, getStack);
14175 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14176 setInnerHTML(domElement, propValue);
14177 } else if (propKey === CHILDREN) {
14178 setTextContent(domElement, propValue);
14179 } else {
14180 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14181 }
14182 }
14183}
14184
14185function createElement$1(type, props, rootContainerElement, parentNamespace) {
14186 var isCustomComponentTag = void 0;
14187
14188 // We create tags in the namespace of their parent container, except HTML
14189 // tags get no namespace.
14190 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14191 var domElement = void 0;
14192 var namespaceURI = parentNamespace;
14193 if (namespaceURI === HTML_NAMESPACE) {
14194 namespaceURI = getIntrinsicNamespace(type);
14195 }
14196 if (namespaceURI === HTML_NAMESPACE) {
14197 {
14198 isCustomComponentTag = isCustomComponent(type, props);
14199 // Should this check be gated by parent namespace? Not sure we want to
14200 // allow <SVG> or <mATH>.
14201 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14202 }
14203
14204 if (type === 'script') {
14205 // Create the script via .innerHTML so its "parser-inserted" flag is
14206 // set to true and it does not execute
14207 var div = ownerDocument.createElement('div');
14208 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14209 // This is guaranteed to yield a script element.
14210 var firstChild = div.firstChild;
14211 domElement = div.removeChild(firstChild);
14212 } else if (typeof props.is === 'string') {
14213 // $FlowIssue `createElement` should be updated for Web Components
14214 domElement = ownerDocument.createElement(type, { is: props.is });
14215 } else {
14216 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14217 // See discussion in https://github.com/facebook/react/pull/6896
14218 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14219 domElement = ownerDocument.createElement(type);
14220 }
14221 } else {
14222 domElement = ownerDocument.createElementNS(namespaceURI, type);
14223 }
14224
14225 {
14226 if (namespaceURI === HTML_NAMESPACE) {
14227 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14228 warnedUnknownTags[type] = true;
14229 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);
14230 }
14231 }
14232 }
14233
14234 return domElement;
14235}
14236
14237function createTextNode$1(text, rootContainerElement) {
14238 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14239}
14240
14241function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14242 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14243 {
14244 validatePropertiesInDevelopment(tag, rawProps);
14245 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14246 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14247 didWarnShadyDOM = true;
14248 }
14249 }
14250
14251 // TODO: Make sure that we check isMounted before firing any of these events.
14252 var props = void 0;
14253 switch (tag) {
14254 case 'iframe':
14255 case 'object':
14256 trapBubbledEvent('topLoad', 'load', domElement);
14257 props = rawProps;
14258 break;
14259 case 'video':
14260 case 'audio':
14261 // Create listener for each media event
14262 for (var event in mediaEventTypes) {
14263 if (mediaEventTypes.hasOwnProperty(event)) {
14264 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14265 }
14266 }
14267 props = rawProps;
14268 break;
14269 case 'source':
14270 trapBubbledEvent('topError', 'error', domElement);
14271 props = rawProps;
14272 break;
14273 case 'img':
14274 case 'image':
14275 case 'link':
14276 trapBubbledEvent('topError', 'error', domElement);
14277 trapBubbledEvent('topLoad', 'load', domElement);
14278 props = rawProps;
14279 break;
14280 case 'form':
14281 trapBubbledEvent('topReset', 'reset', domElement);
14282 trapBubbledEvent('topSubmit', 'submit', domElement);
14283 props = rawProps;
14284 break;
14285 case 'details':
14286 trapBubbledEvent('topToggle', 'toggle', domElement);
14287 props = rawProps;
14288 break;
14289 case 'input':
14290 initWrapperState(domElement, rawProps);
14291 props = getHostProps(domElement, rawProps);
14292 trapBubbledEvent('topInvalid', 'invalid', domElement);
14293 // For controlled components we always need to ensure we're listening
14294 // to onChange. Even if there is no listener.
14295 ensureListeningTo(rootContainerElement, 'onChange');
14296 break;
14297 case 'option':
14298 validateProps(domElement, rawProps);
14299 props = getHostProps$1(domElement, rawProps);
14300 break;
14301 case 'select':
14302 initWrapperState$1(domElement, rawProps);
14303 props = getHostProps$2(domElement, rawProps);
14304 trapBubbledEvent('topInvalid', 'invalid', domElement);
14305 // For controlled components we always need to ensure we're listening
14306 // to onChange. Even if there is no listener.
14307 ensureListeningTo(rootContainerElement, 'onChange');
14308 break;
14309 case 'textarea':
14310 initWrapperState$2(domElement, rawProps);
14311 props = getHostProps$3(domElement, rawProps);
14312 trapBubbledEvent('topInvalid', 'invalid', domElement);
14313 // For controlled components we always need to ensure we're listening
14314 // to onChange. Even if there is no listener.
14315 ensureListeningTo(rootContainerElement, 'onChange');
14316 break;
14317 default:
14318 props = rawProps;
14319 }
14320
14321 assertValidProps(tag, props, getStack);
14322
14323 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
14324
14325 switch (tag) {
14326 case 'input':
14327 // TODO: Make sure we check if this is still unmounted or do any clean
14328 // up necessary since we never stop tracking anymore.
14329 track(domElement);
14330 postMountWrapper(domElement, rawProps);
14331 break;
14332 case 'textarea':
14333 // TODO: Make sure we check if this is still unmounted or do any clean
14334 // up necessary since we never stop tracking anymore.
14335 track(domElement);
14336 postMountWrapper$3(domElement, rawProps);
14337 break;
14338 case 'option':
14339 postMountWrapper$1(domElement, rawProps);
14340 break;
14341 case 'select':
14342 postMountWrapper$2(domElement, rawProps);
14343 break;
14344 default:
14345 if (typeof props.onClick === 'function') {
14346 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14347 trapClickOnNonInteractiveElement(domElement);
14348 }
14349 break;
14350 }
14351}
14352
14353// Calculate the diff between the two objects.
14354function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
14355 {
14356 validatePropertiesInDevelopment(tag, nextRawProps);
14357 }
14358
14359 var updatePayload = null;
14360
14361 var lastProps = void 0;
14362 var nextProps = void 0;
14363 switch (tag) {
14364 case 'input':
14365 lastProps = getHostProps(domElement, lastRawProps);
14366 nextProps = getHostProps(domElement, nextRawProps);
14367 updatePayload = [];
14368 break;
14369 case 'option':
14370 lastProps = getHostProps$1(domElement, lastRawProps);
14371 nextProps = getHostProps$1(domElement, nextRawProps);
14372 updatePayload = [];
14373 break;
14374 case 'select':
14375 lastProps = getHostProps$2(domElement, lastRawProps);
14376 nextProps = getHostProps$2(domElement, nextRawProps);
14377 updatePayload = [];
14378 break;
14379 case 'textarea':
14380 lastProps = getHostProps$3(domElement, lastRawProps);
14381 nextProps = getHostProps$3(domElement, nextRawProps);
14382 updatePayload = [];
14383 break;
14384 default:
14385 lastProps = lastRawProps;
14386 nextProps = nextRawProps;
14387 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
14388 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14389 trapClickOnNonInteractiveElement(domElement);
14390 }
14391 break;
14392 }
14393
14394 assertValidProps(tag, nextProps, getStack);
14395
14396 var propKey = void 0;
14397 var styleName = void 0;
14398 var styleUpdates = null;
14399 for (propKey in lastProps) {
14400 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
14401 continue;
14402 }
14403 if (propKey === STYLE) {
14404 var lastStyle = lastProps[propKey];
14405 for (styleName in lastStyle) {
14406 if (lastStyle.hasOwnProperty(styleName)) {
14407 if (!styleUpdates) {
14408 styleUpdates = {};
14409 }
14410 styleUpdates[styleName] = '';
14411 }
14412 }
14413 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
14414 // Noop. This is handled by the clear text mechanism.
14415 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14416 // Noop
14417 } else if (propKey === AUTOFOCUS) {
14418 // Noop. It doesn't work on updates anyway.
14419 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14420 // This is a special case. If any listener updates we need to ensure
14421 // that the "current" fiber pointer gets updated so we need a commit
14422 // to update this element.
14423 if (!updatePayload) {
14424 updatePayload = [];
14425 }
14426 } else {
14427 // For all other deleted properties we add it to the queue. We use
14428 // the whitelist in the commit phase instead.
14429 (updatePayload = updatePayload || []).push(propKey, null);
14430 }
14431 }
14432 for (propKey in nextProps) {
14433 var nextProp = nextProps[propKey];
14434 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
14435 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
14436 continue;
14437 }
14438 if (propKey === STYLE) {
14439 {
14440 if (nextProp) {
14441 // Freeze the next style object so that we can assume it won't be
14442 // mutated. We have already warned for this in the past.
14443 Object.freeze(nextProp);
14444 }
14445 }
14446 if (lastProp) {
14447 // Unset styles on `lastProp` but not on `nextProp`.
14448 for (styleName in lastProp) {
14449 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
14450 if (!styleUpdates) {
14451 styleUpdates = {};
14452 }
14453 styleUpdates[styleName] = '';
14454 }
14455 }
14456 // Update styles that changed since `lastProp`.
14457 for (styleName in nextProp) {
14458 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
14459 if (!styleUpdates) {
14460 styleUpdates = {};
14461 }
14462 styleUpdates[styleName] = nextProp[styleName];
14463 }
14464 }
14465 } else {
14466 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14467 if (!styleUpdates) {
14468 if (!updatePayload) {
14469 updatePayload = [];
14470 }
14471 updatePayload.push(propKey, styleUpdates);
14472 }
14473 styleUpdates = nextProp;
14474 }
14475 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14476 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14477 var lastHtml = lastProp ? lastProp[HTML] : undefined;
14478 if (nextHtml != null) {
14479 if (lastHtml !== nextHtml) {
14480 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
14481 }
14482 } else {
14483 // TODO: It might be too late to clear this if we have children
14484 // inserted already.
14485 }
14486 } else if (propKey === CHILDREN) {
14487 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
14488 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
14489 }
14490 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14491 // Noop
14492 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14493 if (nextProp != null) {
14494 // We eagerly listen to this even though we haven't committed yet.
14495 if (true && typeof nextProp !== 'function') {
14496 warnForInvalidEventListener(propKey, nextProp);
14497 }
14498 ensureListeningTo(rootContainerElement, propKey);
14499 }
14500 if (!updatePayload && lastProp !== nextProp) {
14501 // This is a special case. If any listener updates we need to ensure
14502 // that the "current" props pointer gets updated so we need a commit
14503 // to update this element.
14504 updatePayload = [];
14505 }
14506 } else {
14507 // For any other property we always add it to the queue and then we
14508 // filter it out using the whitelist during the commit.
14509 (updatePayload = updatePayload || []).push(propKey, nextProp);
14510 }
14511 }
14512 if (styleUpdates) {
14513 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
14514 }
14515 return updatePayload;
14516}
14517
14518// Apply the diff.
14519function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
14520 // Update checked *before* name.
14521 // In the middle of an update, it is possible to have multiple checked.
14522 // When a checked radio tries to change name, browser makes another radio's checked false.
14523 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
14524 updateChecked(domElement, nextRawProps);
14525 }
14526
14527 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
14528 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
14529 // Apply the diff.
14530 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
14531
14532 // TODO: Ensure that an update gets scheduled if any of the special props
14533 // changed.
14534 switch (tag) {
14535 case 'input':
14536 // Update the wrapper around inputs *after* updating props. This has to
14537 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
14538 // raise warnings and prevent the new value from being assigned.
14539 updateWrapper(domElement, nextRawProps);
14540 break;
14541 case 'textarea':
14542 updateWrapper$1(domElement, nextRawProps);
14543 break;
14544 case 'select':
14545 // <select> value update needs to occur after <option> children
14546 // reconciliation
14547 postUpdateWrapper(domElement, nextRawProps);
14548 break;
14549 }
14550}
14551
14552function getPossibleStandardName(propName) {
14553 {
14554 var lowerCasedName = propName.toLowerCase();
14555 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14556 return null;
14557 }
14558 return possibleStandardNames[lowerCasedName] || null;
14559 }
14560 return null;
14561}
14562
14563function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
14564 var isCustomComponentTag = void 0;
14565 var extraAttributeNames = void 0;
14566
14567 {
14568 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
14569 isCustomComponentTag = isCustomComponent(tag, rawProps);
14570 validatePropertiesInDevelopment(tag, rawProps);
14571 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14572 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14573 didWarnShadyDOM = true;
14574 }
14575 }
14576
14577 // TODO: Make sure that we check isMounted before firing any of these events.
14578 switch (tag) {
14579 case 'iframe':
14580 case 'object':
14581 trapBubbledEvent('topLoad', 'load', domElement);
14582 break;
14583 case 'video':
14584 case 'audio':
14585 // Create listener for each media event
14586 for (var event in mediaEventTypes) {
14587 if (mediaEventTypes.hasOwnProperty(event)) {
14588 trapBubbledEvent(event, mediaEventTypes[event], domElement);
14589 }
14590 }
14591 break;
14592 case 'source':
14593 trapBubbledEvent('topError', 'error', domElement);
14594 break;
14595 case 'img':
14596 case 'image':
14597 case 'link':
14598 trapBubbledEvent('topError', 'error', domElement);
14599 trapBubbledEvent('topLoad', 'load', domElement);
14600 break;
14601 case 'form':
14602 trapBubbledEvent('topReset', 'reset', domElement);
14603 trapBubbledEvent('topSubmit', 'submit', domElement);
14604 break;
14605 case 'details':
14606 trapBubbledEvent('topToggle', 'toggle', domElement);
14607 break;
14608 case 'input':
14609 initWrapperState(domElement, rawProps);
14610 trapBubbledEvent('topInvalid', 'invalid', domElement);
14611 // For controlled components we always need to ensure we're listening
14612 // to onChange. Even if there is no listener.
14613 ensureListeningTo(rootContainerElement, 'onChange');
14614 break;
14615 case 'option':
14616 validateProps(domElement, rawProps);
14617 break;
14618 case 'select':
14619 initWrapperState$1(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 'textarea':
14626 initWrapperState$2(domElement, rawProps);
14627 trapBubbledEvent('topInvalid', 'invalid', domElement);
14628 // For controlled components we always need to ensure we're listening
14629 // to onChange. Even if there is no listener.
14630 ensureListeningTo(rootContainerElement, 'onChange');
14631 break;
14632 }
14633
14634 assertValidProps(tag, rawProps, getStack);
14635
14636 {
14637 extraAttributeNames = new Set();
14638 var attributes = domElement.attributes;
14639 for (var i = 0; i < attributes.length; i++) {
14640 var name = attributes[i].name.toLowerCase();
14641 switch (name) {
14642 // Built-in SSR attribute is whitelisted
14643 case 'data-reactroot':
14644 break;
14645 // Controlled attributes are not validated
14646 // TODO: Only ignore them on controlled tags.
14647 case 'value':
14648 break;
14649 case 'checked':
14650 break;
14651 case 'selected':
14652 break;
14653 default:
14654 // Intentionally use the original name.
14655 // See discussion in https://github.com/facebook/react/pull/10676.
14656 extraAttributeNames.add(attributes[i].name);
14657 }
14658 }
14659 }
14660
14661 var updatePayload = null;
14662 for (var propKey in rawProps) {
14663 if (!rawProps.hasOwnProperty(propKey)) {
14664 continue;
14665 }
14666 var nextProp = rawProps[propKey];
14667 if (propKey === CHILDREN) {
14668 // For text content children we compare against textContent. This
14669 // might match additional HTML that is hidden when we read it using
14670 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
14671 // satisfies our requirement. Our requirement is not to produce perfect
14672 // HTML and attributes. Ideally we should preserve structure but it's
14673 // ok not to if the visible content is still enough to indicate what
14674 // even listeners these nodes might be wired up to.
14675 // TODO: Warn if there is more than a single textNode as a child.
14676 // TODO: Should we use domElement.firstChild.nodeValue to compare?
14677 if (typeof nextProp === 'string') {
14678 if (domElement.textContent !== nextProp) {
14679 if (true && !suppressHydrationWarning) {
14680 warnForTextDifference(domElement.textContent, nextProp);
14681 }
14682 updatePayload = [CHILDREN, nextProp];
14683 }
14684 } else if (typeof nextProp === 'number') {
14685 if (domElement.textContent !== '' + nextProp) {
14686 if (true && !suppressHydrationWarning) {
14687 warnForTextDifference(domElement.textContent, nextProp);
14688 }
14689 updatePayload = [CHILDREN, '' + nextProp];
14690 }
14691 }
14692 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14693 if (nextProp != null) {
14694 if (true && typeof nextProp !== 'function') {
14695 warnForInvalidEventListener(propKey, nextProp);
14696 }
14697 ensureListeningTo(rootContainerElement, propKey);
14698 }
14699 } else if (true &&
14700 // Convince Flow we've calculated it (it's DEV-only in this method.)
14701 typeof isCustomComponentTag === 'boolean') {
14702 // Validate that the properties correspond to their expected values.
14703 var serverValue = void 0;
14704 var propertyInfo = getPropertyInfo(propKey);
14705 if (suppressHydrationWarning) {
14706 // Don't bother comparing. We're ignoring all these warnings.
14707 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
14708 // Controlled attributes are not validated
14709 // TODO: Only ignore them on controlled tags.
14710 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
14711 // Noop
14712 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14713 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
14714 var serverHTML = domElement.innerHTML;
14715 var expectedHTML = normalizeHTML(domElement, rawHtml);
14716 if (expectedHTML !== serverHTML) {
14717 warnForPropDifference(propKey, serverHTML, expectedHTML);
14718 }
14719 } else if (propKey === STYLE) {
14720 // $FlowFixMe - Should be inferred as not undefined.
14721 extraAttributeNames['delete'](propKey);
14722 var expectedStyle = createDangerousStringForStyles(nextProp);
14723 serverValue = domElement.getAttribute('style');
14724 if (expectedStyle !== serverValue) {
14725 warnForPropDifference(propKey, serverValue, expectedStyle);
14726 }
14727 } else if (isCustomComponentTag) {
14728 // $FlowFixMe - Should be inferred as not undefined.
14729 extraAttributeNames['delete'](propKey.toLowerCase());
14730 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14731
14732 if (nextProp !== serverValue) {
14733 warnForPropDifference(propKey, serverValue, nextProp);
14734 }
14735 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
14736 var isMismatchDueToBadCasing = false;
14737 if (propertyInfo !== null) {
14738 // $FlowFixMe - Should be inferred as not undefined.
14739 extraAttributeNames['delete'](propertyInfo.attributeName);
14740 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
14741 } else {
14742 var ownNamespace = parentNamespace;
14743 if (ownNamespace === HTML_NAMESPACE) {
14744 ownNamespace = getIntrinsicNamespace(tag);
14745 }
14746 if (ownNamespace === HTML_NAMESPACE) {
14747 // $FlowFixMe - Should be inferred as not undefined.
14748 extraAttributeNames['delete'](propKey.toLowerCase());
14749 } else {
14750 var standardName = getPossibleStandardName(propKey);
14751 if (standardName !== null && standardName !== propKey) {
14752 // If an SVG prop is supplied with bad casing, it will
14753 // be successfully parsed from HTML, but will produce a mismatch
14754 // (and would be incorrectly rendered on the client).
14755 // However, we already warn about bad casing elsewhere.
14756 // So we'll skip the misleading extra mismatch warning in this case.
14757 isMismatchDueToBadCasing = true;
14758 // $FlowFixMe - Should be inferred as not undefined.
14759 extraAttributeNames['delete'](standardName);
14760 }
14761 // $FlowFixMe - Should be inferred as not undefined.
14762 extraAttributeNames['delete'](propKey);
14763 }
14764 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14765 }
14766
14767 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
14768 warnForPropDifference(propKey, serverValue, nextProp);
14769 }
14770 }
14771 }
14772 }
14773
14774 {
14775 // $FlowFixMe - Should be inferred as not undefined.
14776 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
14777 // $FlowFixMe - Should be inferred as not undefined.
14778 warnForExtraAttributes(extraAttributeNames);
14779 }
14780 }
14781
14782 switch (tag) {
14783 case 'input':
14784 // TODO: Make sure we check if this is still unmounted or do any clean
14785 // up necessary since we never stop tracking anymore.
14786 track(domElement);
14787 postMountWrapper(domElement, rawProps);
14788 break;
14789 case 'textarea':
14790 // TODO: Make sure we check if this is still unmounted or do any clean
14791 // up necessary since we never stop tracking anymore.
14792 track(domElement);
14793 postMountWrapper$3(domElement, rawProps);
14794 break;
14795 case 'select':
14796 case 'option':
14797 // For input and textarea we current always set the value property at
14798 // post mount to force it to diverge from attributes. However, for
14799 // option and select we don't quite do the same thing and select
14800 // is not resilient to the DOM state changing so we don't do that here.
14801 // TODO: Consider not doing this for input and textarea.
14802 break;
14803 default:
14804 if (typeof rawProps.onClick === 'function') {
14805 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14806 trapClickOnNonInteractiveElement(domElement);
14807 }
14808 break;
14809 }
14810
14811 return updatePayload;
14812}
14813
14814function diffHydratedText$1(textNode, text) {
14815 var isDifferent = textNode.nodeValue !== text;
14816 return isDifferent;
14817}
14818
14819function warnForUnmatchedText$1(textNode, text) {
14820 {
14821 warnForTextDifference(textNode.nodeValue, text);
14822 }
14823}
14824
14825function warnForDeletedHydratableElement$1(parentNode, child) {
14826 {
14827 if (didWarnInvalidHydration) {
14828 return;
14829 }
14830 didWarnInvalidHydration = true;
14831 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
14832 }
14833}
14834
14835function warnForDeletedHydratableText$1(parentNode, child) {
14836 {
14837 if (didWarnInvalidHydration) {
14838 return;
14839 }
14840 didWarnInvalidHydration = true;
14841 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
14842 }
14843}
14844
14845function warnForInsertedHydratedElement$1(parentNode, tag, props) {
14846 {
14847 if (didWarnInvalidHydration) {
14848 return;
14849 }
14850 didWarnInvalidHydration = true;
14851 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
14852 }
14853}
14854
14855function warnForInsertedHydratedText$1(parentNode, text) {
14856 {
14857 if (text === '') {
14858 // We expect to insert empty text nodes since they're not represented in
14859 // the HTML.
14860 // TODO: Remove this special case if we can just avoid inserting empty
14861 // text nodes.
14862 return;
14863 }
14864 if (didWarnInvalidHydration) {
14865 return;
14866 }
14867 didWarnInvalidHydration = true;
14868 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
14869 }
14870}
14871
14872function restoreControlledState$1(domElement, tag, props) {
14873 switch (tag) {
14874 case 'input':
14875 restoreControlledState(domElement, props);
14876 return;
14877 case 'textarea':
14878 restoreControlledState$3(domElement, props);
14879 return;
14880 case 'select':
14881 restoreControlledState$2(domElement, props);
14882 return;
14883 }
14884}
14885
14886var ReactDOMFiberComponent = Object.freeze({
14887 createElement: createElement$1,
14888 createTextNode: createTextNode$1,
14889 setInitialProperties: setInitialProperties$1,
14890 diffProperties: diffProperties$1,
14891 updateProperties: updateProperties$1,
14892 diffHydratedProperties: diffHydratedProperties$1,
14893 diffHydratedText: diffHydratedText$1,
14894 warnForUnmatchedText: warnForUnmatchedText$1,
14895 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
14896 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
14897 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
14898 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
14899 restoreControlledState: restoreControlledState$1
14900});
14901
14902// TODO: direct imports like some-package/src/* are bad. Fix me.
14903var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14904
14905var validateDOMNesting = emptyFunction_1;
14906
14907{
14908 // This validation code was written based on the HTML5 parsing spec:
14909 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14910 //
14911 // Note: this does not catch all invalid nesting, nor does it try to (as it's
14912 // not clear what practical benefit doing so provides); instead, we warn only
14913 // for cases where the parser will give a parse tree differing from what React
14914 // intended. For example, <b><div></div></b> is invalid but we don't warn
14915 // because it still parses correctly; we do warn for other cases like nested
14916 // <p> tags where the beginning of the second element implicitly closes the
14917 // first, causing a confusing mess.
14918
14919 // https://html.spec.whatwg.org/multipage/syntax.html#special
14920 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'];
14921
14922 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14923 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
14924
14925 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
14926 // TODO: Distinguish by namespace here -- for <title>, including it here
14927 // errs on the side of fewer warnings
14928 'foreignObject', 'desc', 'title'];
14929
14930 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
14931 var buttonScopeTags = inScopeTags.concat(['button']);
14932
14933 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
14934 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
14935
14936 var emptyAncestorInfo = {
14937 current: null,
14938
14939 formTag: null,
14940 aTagInScope: null,
14941 buttonTagInScope: null,
14942 nobrTagInScope: null,
14943 pTagInButtonScope: null,
14944
14945 listItemTagAutoclosing: null,
14946 dlItemTagAutoclosing: null
14947 };
14948
14949 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
14950 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
14951 var info = { tag: tag, instance: instance };
14952
14953 if (inScopeTags.indexOf(tag) !== -1) {
14954 ancestorInfo.aTagInScope = null;
14955 ancestorInfo.buttonTagInScope = null;
14956 ancestorInfo.nobrTagInScope = null;
14957 }
14958 if (buttonScopeTags.indexOf(tag) !== -1) {
14959 ancestorInfo.pTagInButtonScope = null;
14960 }
14961
14962 // See rules for 'li', 'dd', 'dt' start tags in
14963 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14964 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
14965 ancestorInfo.listItemTagAutoclosing = null;
14966 ancestorInfo.dlItemTagAutoclosing = null;
14967 }
14968
14969 ancestorInfo.current = info;
14970
14971 if (tag === 'form') {
14972 ancestorInfo.formTag = info;
14973 }
14974 if (tag === 'a') {
14975 ancestorInfo.aTagInScope = info;
14976 }
14977 if (tag === 'button') {
14978 ancestorInfo.buttonTagInScope = info;
14979 }
14980 if (tag === 'nobr') {
14981 ancestorInfo.nobrTagInScope = info;
14982 }
14983 if (tag === 'p') {
14984 ancestorInfo.pTagInButtonScope = info;
14985 }
14986 if (tag === 'li') {
14987 ancestorInfo.listItemTagAutoclosing = info;
14988 }
14989 if (tag === 'dd' || tag === 'dt') {
14990 ancestorInfo.dlItemTagAutoclosing = info;
14991 }
14992
14993 return ancestorInfo;
14994 };
14995
14996 /**
14997 * Returns whether
14998 */
14999 var isTagValidWithParent = function (tag, parentTag) {
15000 // First, let's check if we're in an unusual parsing mode...
15001 switch (parentTag) {
15002 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
15003 case 'select':
15004 return tag === 'option' || tag === 'optgroup' || tag === '#text';
15005 case 'optgroup':
15006 return tag === 'option' || tag === '#text';
15007 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
15008 // but
15009 case 'option':
15010 return tag === '#text';
15011 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
15012 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
15013 // No special behavior since these rules fall back to "in body" mode for
15014 // all except special table nodes which cause bad parsing behavior anyway.
15015
15016 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
15017 case 'tr':
15018 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
15019 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
15020 case 'tbody':
15021 case 'thead':
15022 case 'tfoot':
15023 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
15024 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
15025 case 'colgroup':
15026 return tag === 'col' || tag === 'template';
15027 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
15028 case 'table':
15029 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
15030 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
15031 case 'head':
15032 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
15033 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
15034 case 'html':
15035 return tag === 'head' || tag === 'body';
15036 case '#document':
15037 return tag === 'html';
15038 }
15039
15040 // Probably in the "in body" parsing mode, so we outlaw only tag combos
15041 // where the parsing rules cause implicit opens or closes to be added.
15042 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
15043 switch (tag) {
15044 case 'h1':
15045 case 'h2':
15046 case 'h3':
15047 case 'h4':
15048 case 'h5':
15049 case 'h6':
15050 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
15051
15052 case 'rp':
15053 case 'rt':
15054 return impliedEndTags.indexOf(parentTag) === -1;
15055
15056 case 'body':
15057 case 'caption':
15058 case 'col':
15059 case 'colgroup':
15060 case 'frame':
15061 case 'head':
15062 case 'html':
15063 case 'tbody':
15064 case 'td':
15065 case 'tfoot':
15066 case 'th':
15067 case 'thead':
15068 case 'tr':
15069 // These tags are only valid with a few parents that have special child
15070 // parsing rules -- if we're down here, then none of those matched and
15071 // so we allow it only if we don't know what the parent is, as all other
15072 // cases are invalid.
15073 return parentTag == null;
15074 }
15075
15076 return true;
15077 };
15078
15079 /**
15080 * Returns whether
15081 */
15082 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
15083 switch (tag) {
15084 case 'address':
15085 case 'article':
15086 case 'aside':
15087 case 'blockquote':
15088 case 'center':
15089 case 'details':
15090 case 'dialog':
15091 case 'dir':
15092 case 'div':
15093 case 'dl':
15094 case 'fieldset':
15095 case 'figcaption':
15096 case 'figure':
15097 case 'footer':
15098 case 'header':
15099 case 'hgroup':
15100 case 'main':
15101 case 'menu':
15102 case 'nav':
15103 case 'ol':
15104 case 'p':
15105 case 'section':
15106 case 'summary':
15107 case 'ul':
15108 case 'pre':
15109 case 'listing':
15110 case 'table':
15111 case 'hr':
15112 case 'xmp':
15113 case 'h1':
15114 case 'h2':
15115 case 'h3':
15116 case 'h4':
15117 case 'h5':
15118 case 'h6':
15119 return ancestorInfo.pTagInButtonScope;
15120
15121 case 'form':
15122 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
15123
15124 case 'li':
15125 return ancestorInfo.listItemTagAutoclosing;
15126
15127 case 'dd':
15128 case 'dt':
15129 return ancestorInfo.dlItemTagAutoclosing;
15130
15131 case 'button':
15132 return ancestorInfo.buttonTagInScope;
15133
15134 case 'a':
15135 // Spec says something about storing a list of markers, but it sounds
15136 // equivalent to this check.
15137 return ancestorInfo.aTagInScope;
15138
15139 case 'nobr':
15140 return ancestorInfo.nobrTagInScope;
15141 }
15142
15143 return null;
15144 };
15145
15146 var didWarn = {};
15147
15148 validateDOMNesting = function (childTag, childText, ancestorInfo) {
15149 ancestorInfo = ancestorInfo || emptyAncestorInfo;
15150 var parentInfo = ancestorInfo.current;
15151 var parentTag = parentInfo && parentInfo.tag;
15152
15153 if (childText != null) {
15154 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
15155 childTag = '#text';
15156 }
15157
15158 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15159 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15160 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15161 if (!invalidParentOrAncestor) {
15162 return;
15163 }
15164
15165 var ancestorTag = invalidParentOrAncestor.tag;
15166 var addendum = getCurrentFiberStackAddendum$6();
15167
15168 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15169 if (didWarn[warnKey]) {
15170 return;
15171 }
15172 didWarn[warnKey] = true;
15173
15174 var tagDisplayName = childTag;
15175 var whitespaceInfo = '';
15176 if (childTag === '#text') {
15177 if (/\S/.test(childText)) {
15178 tagDisplayName = 'Text nodes';
15179 } else {
15180 tagDisplayName = 'Whitespace text nodes';
15181 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15182 }
15183 } else {
15184 tagDisplayName = '<' + childTag + '>';
15185 }
15186
15187 if (invalidParent) {
15188 var info = '';
15189 if (ancestorTag === 'table' && childTag === 'tr') {
15190 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15191 }
15192 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15193 } else {
15194 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15195 }
15196 };
15197
15198 // TODO: turn this into a named export
15199 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15200}
15201
15202var validateDOMNesting$1 = validateDOMNesting;
15203
15204// TODO: This type is shared between the reconciler and ReactDOM, but will
15205// eventually be lifted out to the renderer.
15206
15207// TODO: direct imports like some-package/src/* are bad. Fix me.
15208var createElement = createElement$1;
15209var createTextNode = createTextNode$1;
15210var setInitialProperties = setInitialProperties$1;
15211var diffProperties = diffProperties$1;
15212var updateProperties = updateProperties$1;
15213var diffHydratedProperties = diffHydratedProperties$1;
15214var diffHydratedText = diffHydratedText$1;
15215var warnForUnmatchedText = warnForUnmatchedText$1;
15216var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15217var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15218var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15219var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15220var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15221var precacheFiberNode = precacheFiberNode$1;
15222var updateFiberProps = updateFiberProps$1;
15223
15224
15225var SUPPRESS_HYDRATION_WARNING = void 0;
15226var topLevelUpdateWarnings = void 0;
15227var warnOnInvalidCallback = void 0;
15228var didWarnAboutUnstableCreatePortal = false;
15229
15230{
15231 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15232 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') {
15233 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');
15234 }
15235
15236 topLevelUpdateWarnings = function (container) {
15237 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15238 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15239 if (hostInstance) {
15240 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.');
15241 }
15242 }
15243
15244 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15245 var rootEl = getReactRootElementInContainer(container);
15246 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15247
15248 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.');
15249
15250 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.');
15251 };
15252
15253 warnOnInvalidCallback = function (callback, callerName) {
15254 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
15255 };
15256}
15257
15258injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
15259
15260var eventsEnabled = null;
15261var selectionInformation = null;
15262
15263function ReactBatch(root) {
15264 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
15265 this._expirationTime = expirationTime;
15266 this._root = root;
15267 this._next = null;
15268 this._callbacks = null;
15269 this._didComplete = false;
15270 this._hasChildren = false;
15271 this._children = null;
15272 this._defer = true;
15273}
15274ReactBatch.prototype.render = function (children) {
15275 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
15276 this._hasChildren = true;
15277 this._children = children;
15278 var internalRoot = this._root._internalRoot;
15279 var expirationTime = this._expirationTime;
15280 var work = new ReactWork();
15281 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
15282 return work;
15283};
15284ReactBatch.prototype.then = function (onComplete) {
15285 if (this._didComplete) {
15286 onComplete();
15287 return;
15288 }
15289 var callbacks = this._callbacks;
15290 if (callbacks === null) {
15291 callbacks = this._callbacks = [];
15292 }
15293 callbacks.push(onComplete);
15294};
15295ReactBatch.prototype.commit = function () {
15296 var internalRoot = this._root._internalRoot;
15297 var firstBatch = internalRoot.firstBatch;
15298 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15299
15300 if (!this._hasChildren) {
15301 // This batch is empty. Return.
15302 this._next = null;
15303 this._defer = false;
15304 return;
15305 }
15306
15307 var expirationTime = this._expirationTime;
15308
15309 // Ensure this is the first batch in the list.
15310 if (firstBatch !== this) {
15311 // This batch is not the earliest batch. We need to move it to the front.
15312 // Update its expiration time to be the expiration time of the earliest
15313 // batch, so that we can flush it without flushing the other batches.
15314 if (this._hasChildren) {
15315 expirationTime = this._expirationTime = firstBatch._expirationTime;
15316 // Rendering this batch again ensures its children will be the final state
15317 // when we flush (updates are processed in insertion order: last
15318 // update wins).
15319 // TODO: This forces a restart. Should we print a warning?
15320 this.render(this._children);
15321 }
15322
15323 // Remove the batch from the list.
15324 var previous = null;
15325 var batch = firstBatch;
15326 while (batch !== this) {
15327 previous = batch;
15328 batch = batch._next;
15329 }
15330 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15331 previous._next = batch._next;
15332
15333 // Add it to the front.
15334 this._next = firstBatch;
15335 firstBatch = internalRoot.firstBatch = this;
15336 }
15337
15338 // Synchronously flush all the work up to this batch's expiration time.
15339 this._defer = false;
15340 DOMRenderer.flushRoot(internalRoot, expirationTime);
15341
15342 // Pop the batch from the list.
15343 var next = this._next;
15344 this._next = null;
15345 firstBatch = internalRoot.firstBatch = next;
15346
15347 // Append the next earliest batch's children to the update queue.
15348 if (firstBatch !== null && firstBatch._hasChildren) {
15349 firstBatch.render(firstBatch._children);
15350 }
15351};
15352ReactBatch.prototype._onComplete = function () {
15353 if (this._didComplete) {
15354 return;
15355 }
15356 this._didComplete = true;
15357 var callbacks = this._callbacks;
15358 if (callbacks === null) {
15359 return;
15360 }
15361 // TODO: Error handling.
15362 for (var i = 0; i < callbacks.length; i++) {
15363 var _callback = callbacks[i];
15364 _callback();
15365 }
15366};
15367
15368function ReactWork() {
15369 this._callbacks = null;
15370 this._didCommit = false;
15371 // TODO: Avoid need to bind by replacing callbacks in the update queue with
15372 // list of Work objects.
15373 this._onCommit = this._onCommit.bind(this);
15374}
15375ReactWork.prototype.then = function (onCommit) {
15376 if (this._didCommit) {
15377 onCommit();
15378 return;
15379 }
15380 var callbacks = this._callbacks;
15381 if (callbacks === null) {
15382 callbacks = this._callbacks = [];
15383 }
15384 callbacks.push(onCommit);
15385};
15386ReactWork.prototype._onCommit = function () {
15387 if (this._didCommit) {
15388 return;
15389 }
15390 this._didCommit = true;
15391 var callbacks = this._callbacks;
15392 if (callbacks === null) {
15393 return;
15394 }
15395 // TODO: Error handling.
15396 for (var i = 0; i < callbacks.length; i++) {
15397 var _callback2 = callbacks[i];
15398 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
15399 _callback2();
15400 }
15401};
15402
15403function ReactRoot(container, isAsync, hydrate) {
15404 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
15405 this._internalRoot = root;
15406}
15407ReactRoot.prototype.render = function (children, callback) {
15408 var root = this._internalRoot;
15409 var work = new ReactWork();
15410 callback = callback === undefined ? null : callback;
15411 {
15412 warnOnInvalidCallback(callback, 'render');
15413 }
15414 if (callback !== null) {
15415 work.then(callback);
15416 }
15417 DOMRenderer.updateContainer(children, root, null, work._onCommit);
15418 return work;
15419};
15420ReactRoot.prototype.unmount = function (callback) {
15421 var root = this._internalRoot;
15422 var work = new ReactWork();
15423 callback = callback === undefined ? null : callback;
15424 {
15425 warnOnInvalidCallback(callback, 'render');
15426 }
15427 if (callback !== null) {
15428 work.then(callback);
15429 }
15430 DOMRenderer.updateContainer(null, root, null, work._onCommit);
15431 return work;
15432};
15433ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
15434 var root = this._internalRoot;
15435 var work = new ReactWork();
15436 callback = callback === undefined ? null : callback;
15437 {
15438 warnOnInvalidCallback(callback, 'render');
15439 }
15440 if (callback !== null) {
15441 work.then(callback);
15442 }
15443 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
15444 return work;
15445};
15446ReactRoot.prototype.createBatch = function () {
15447 var batch = new ReactBatch(this);
15448 var expirationTime = batch._expirationTime;
15449
15450 var internalRoot = this._internalRoot;
15451 var firstBatch = internalRoot.firstBatch;
15452 if (firstBatch === null) {
15453 internalRoot.firstBatch = batch;
15454 batch._next = null;
15455 } else {
15456 // Insert sorted by expiration time then insertion order
15457 var insertAfter = null;
15458 var insertBefore = firstBatch;
15459 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
15460 insertAfter = insertBefore;
15461 insertBefore = insertBefore._next;
15462 }
15463 batch._next = insertBefore;
15464 if (insertAfter !== null) {
15465 insertAfter._next = batch;
15466 }
15467 }
15468
15469 return batch;
15470};
15471
15472/**
15473 * True if the supplied DOM node is a valid node element.
15474 *
15475 * @param {?DOMElement} node The candidate DOM node.
15476 * @return {boolean} True if the DOM is a valid DOM node.
15477 * @internal
15478 */
15479function isValidContainer(node) {
15480 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 '));
15481}
15482
15483function getReactRootElementInContainer(container) {
15484 if (!container) {
15485 return null;
15486 }
15487
15488 if (container.nodeType === DOCUMENT_NODE) {
15489 return container.documentElement;
15490 } else {
15491 return container.firstChild;
15492 }
15493}
15494
15495function shouldHydrateDueToLegacyHeuristic(container) {
15496 var rootElement = getReactRootElementInContainer(container);
15497 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
15498}
15499
15500function shouldAutoFocusHostComponent(type, props) {
15501 switch (type) {
15502 case 'button':
15503 case 'input':
15504 case 'select':
15505 case 'textarea':
15506 return !!props.autoFocus;
15507 }
15508 return false;
15509}
15510
15511var DOMRenderer = reactReconciler({
15512 getRootHostContext: function (rootContainerInstance) {
15513 var type = void 0;
15514 var namespace = void 0;
15515 var nodeType = rootContainerInstance.nodeType;
15516 switch (nodeType) {
15517 case DOCUMENT_NODE:
15518 case DOCUMENT_FRAGMENT_NODE:
15519 {
15520 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
15521 var root = rootContainerInstance.documentElement;
15522 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
15523 break;
15524 }
15525 default:
15526 {
15527 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
15528 var ownNamespace = container.namespaceURI || null;
15529 type = container.tagName;
15530 namespace = getChildNamespace(ownNamespace, type);
15531 break;
15532 }
15533 }
15534 {
15535 var validatedTag = type.toLowerCase();
15536 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
15537 return { namespace: namespace, ancestorInfo: _ancestorInfo };
15538 }
15539 return namespace;
15540 },
15541 getChildHostContext: function (parentHostContext, type) {
15542 {
15543 var parentHostContextDev = parentHostContext;
15544 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
15545 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
15546 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
15547 }
15548 var parentNamespace = parentHostContext;
15549 return getChildNamespace(parentNamespace, type);
15550 },
15551 getPublicInstance: function (instance) {
15552 return instance;
15553 },
15554 prepareForCommit: function () {
15555 eventsEnabled = isEnabled();
15556 selectionInformation = getSelectionInformation();
15557 setEnabled(false);
15558 },
15559 resetAfterCommit: function () {
15560 restoreSelection(selectionInformation);
15561 selectionInformation = null;
15562 setEnabled(eventsEnabled);
15563 eventsEnabled = null;
15564 },
15565 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15566 var parentNamespace = void 0;
15567 {
15568 // TODO: take namespace into account when validating.
15569 var hostContextDev = hostContext;
15570 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
15571 if (typeof props.children === 'string' || typeof props.children === 'number') {
15572 var string = '' + props.children;
15573 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15574 validateDOMNesting$1(null, string, ownAncestorInfo);
15575 }
15576 parentNamespace = hostContextDev.namespace;
15577 }
15578 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
15579 precacheFiberNode(internalInstanceHandle, domElement);
15580 updateFiberProps(domElement, props);
15581 return domElement;
15582 },
15583 appendInitialChild: function (parentInstance, child) {
15584 parentInstance.appendChild(child);
15585 },
15586 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
15587 setInitialProperties(domElement, type, props, rootContainerInstance);
15588 return shouldAutoFocusHostComponent(type, props);
15589 },
15590 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
15591 {
15592 var hostContextDev = hostContext;
15593 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
15594 var string = '' + newProps.children;
15595 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15596 validateDOMNesting$1(null, string, ownAncestorInfo);
15597 }
15598 }
15599 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
15600 },
15601 shouldSetTextContent: function (type, props) {
15602 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
15603 },
15604 shouldDeprioritizeSubtree: function (type, props) {
15605 return !!props.hidden;
15606 },
15607 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
15608 {
15609 var hostContextDev = hostContext;
15610 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
15611 }
15612 var textNode = createTextNode(text, rootContainerInstance);
15613 precacheFiberNode(internalInstanceHandle, textNode);
15614 return textNode;
15615 },
15616
15617
15618 now: now,
15619
15620 mutation: {
15621 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
15622 // Despite the naming that might imply otherwise, this method only
15623 // fires if there is an `Update` effect scheduled during mounting.
15624 // This happens if `finalizeInitialChildren` returns `true` (which it
15625 // does to implement the `autoFocus` attribute on the client). But
15626 // there are also other cases when this might happen (such as patching
15627 // up text content during hydration mismatch). So we'll check this again.
15628 if (shouldAutoFocusHostComponent(type, newProps)) {
15629 domElement.focus();
15630 }
15631 },
15632 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
15633 // Update the props handle so that we know which props are the ones with
15634 // with current event handlers.
15635 updateFiberProps(domElement, newProps);
15636 // Apply the diff to the DOM node.
15637 updateProperties(domElement, updatePayload, type, oldProps, newProps);
15638 },
15639 resetTextContent: function (domElement) {
15640 setTextContent(domElement, '');
15641 },
15642 commitTextUpdate: function (textInstance, oldText, newText) {
15643 textInstance.nodeValue = newText;
15644 },
15645 appendChild: function (parentInstance, child) {
15646 parentInstance.appendChild(child);
15647 },
15648 appendChildToContainer: function (container, child) {
15649 if (container.nodeType === COMMENT_NODE) {
15650 container.parentNode.insertBefore(child, container);
15651 } else {
15652 container.appendChild(child);
15653 }
15654 },
15655 insertBefore: function (parentInstance, child, beforeChild) {
15656 parentInstance.insertBefore(child, beforeChild);
15657 },
15658 insertInContainerBefore: function (container, child, beforeChild) {
15659 if (container.nodeType === COMMENT_NODE) {
15660 container.parentNode.insertBefore(child, beforeChild);
15661 } else {
15662 container.insertBefore(child, beforeChild);
15663 }
15664 },
15665 removeChild: function (parentInstance, child) {
15666 parentInstance.removeChild(child);
15667 },
15668 removeChildFromContainer: function (container, child) {
15669 if (container.nodeType === COMMENT_NODE) {
15670 container.parentNode.removeChild(child);
15671 } else {
15672 container.removeChild(child);
15673 }
15674 }
15675 },
15676
15677 hydration: {
15678 canHydrateInstance: function (instance, type, props) {
15679 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
15680 return null;
15681 }
15682 // This has now been refined to an element node.
15683 return instance;
15684 },
15685 canHydrateTextInstance: function (instance, text) {
15686 if (text === '' || instance.nodeType !== TEXT_NODE) {
15687 // Empty strings are not parsed by HTML so there won't be a correct match here.
15688 return null;
15689 }
15690 // This has now been refined to a text node.
15691 return instance;
15692 },
15693 getNextHydratableSibling: function (instance) {
15694 var node = instance.nextSibling;
15695 // Skip non-hydratable nodes.
15696 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
15697 node = node.nextSibling;
15698 }
15699 return node;
15700 },
15701 getFirstHydratableChild: function (parentInstance) {
15702 var next = parentInstance.firstChild;
15703 // Skip non-hydratable nodes.
15704 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
15705 next = next.nextSibling;
15706 }
15707 return next;
15708 },
15709 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15710 precacheFiberNode(internalInstanceHandle, instance);
15711 // TODO: Possibly defer this until the commit phase where all the events
15712 // get attached.
15713 updateFiberProps(instance, props);
15714 var parentNamespace = void 0;
15715 {
15716 var hostContextDev = hostContext;
15717 parentNamespace = hostContextDev.namespace;
15718 }
15719 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
15720 },
15721 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
15722 precacheFiberNode(internalInstanceHandle, textInstance);
15723 return diffHydratedText(textInstance, text);
15724 },
15725 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
15726 {
15727 warnForUnmatchedText(textInstance, text);
15728 }
15729 },
15730 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
15731 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15732 warnForUnmatchedText(textInstance, text);
15733 }
15734 },
15735 didNotHydrateContainerInstance: function (parentContainer, instance) {
15736 {
15737 if (instance.nodeType === 1) {
15738 warnForDeletedHydratableElement(parentContainer, instance);
15739 } else {
15740 warnForDeletedHydratableText(parentContainer, instance);
15741 }
15742 }
15743 },
15744 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
15745 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15746 if (instance.nodeType === 1) {
15747 warnForDeletedHydratableElement(parentInstance, instance);
15748 } else {
15749 warnForDeletedHydratableText(parentInstance, instance);
15750 }
15751 }
15752 },
15753 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
15754 {
15755 warnForInsertedHydratedElement(parentContainer, type, props);
15756 }
15757 },
15758 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
15759 {
15760 warnForInsertedHydratedText(parentContainer, text);
15761 }
15762 },
15763 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
15764 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15765 warnForInsertedHydratedElement(parentInstance, type, props);
15766 }
15767 },
15768 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
15769 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15770 warnForInsertedHydratedText(parentInstance, text);
15771 }
15772 }
15773 },
15774
15775 scheduleDeferredCallback: rIC,
15776 cancelDeferredCallback: cIC
15777});
15778
15779injection$3.injectFiberBatchedUpdates(DOMRenderer.batchedUpdates);
15780
15781var warnedAboutHydrateAPI = false;
15782
15783function legacyCreateRootFromDOMContainer(container, forceHydrate) {
15784 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
15785 // First clear any existing content.
15786 if (!shouldHydrate) {
15787 var warned = false;
15788 var rootSibling = void 0;
15789 while (rootSibling = container.lastChild) {
15790 {
15791 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
15792 warned = true;
15793 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.');
15794 }
15795 }
15796 container.removeChild(rootSibling);
15797 }
15798 }
15799 {
15800 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
15801 warnedAboutHydrateAPI = true;
15802 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.');
15803 }
15804 }
15805 // Legacy roots are not async by default.
15806 var isAsync = false;
15807 return new ReactRoot(container, isAsync, shouldHydrate);
15808}
15809
15810function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
15811 // TODO: Ensure all entry points contain this check
15812 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15813
15814 {
15815 topLevelUpdateWarnings(container);
15816 }
15817
15818 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
15819 // member of intersection type." Whyyyyyy.
15820 var root = container._reactRootContainer;
15821 if (!root) {
15822 // Initial mount
15823 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
15824 if (typeof callback === 'function') {
15825 var originalCallback = callback;
15826 callback = function () {
15827 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15828 originalCallback.call(instance);
15829 };
15830 }
15831 // Initial mount should not be batched.
15832 DOMRenderer.unbatchedUpdates(function () {
15833 if (parentComponent != null) {
15834 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15835 } else {
15836 root.render(children, callback);
15837 }
15838 });
15839 } else {
15840 if (typeof callback === 'function') {
15841 var _originalCallback = callback;
15842 callback = function () {
15843 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15844 _originalCallback.call(instance);
15845 };
15846 }
15847 // Update
15848 if (parentComponent != null) {
15849 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15850 } else {
15851 root.render(children, callback);
15852 }
15853 }
15854 return DOMRenderer.getPublicRootInstance(root._internalRoot);
15855}
15856
15857function createPortal(children, container) {
15858 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15859
15860 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15861 // TODO: pass ReactDOM portal implementation as third argument
15862 return createPortal$1(children, container, null, key);
15863}
15864
15865var ReactDOM = {
15866 createPortal: createPortal,
15867
15868 findDOMNode: function (componentOrElement) {
15869 {
15870 var owner = ReactCurrentOwner.current;
15871 if (owner !== null) {
15872 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
15873 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');
15874 owner.stateNode._warnedAboutRefsInRender = true;
15875 }
15876 }
15877 if (componentOrElement == null) {
15878 return null;
15879 }
15880 if (componentOrElement.nodeType === ELEMENT_NODE) {
15881 return componentOrElement;
15882 }
15883
15884 var inst = get(componentOrElement);
15885 if (inst) {
15886 return DOMRenderer.findHostInstance(inst);
15887 }
15888
15889 if (typeof componentOrElement.render === 'function') {
15890 invariant_1(false, 'Unable to find node on an unmounted component.');
15891 } else {
15892 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
15893 }
15894 },
15895 hydrate: function (element, container, callback) {
15896 // TODO: throw or warn if we couldn't hydrate?
15897 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
15898 },
15899 render: function (element, container, callback) {
15900 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
15901 },
15902 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
15903 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
15904 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
15905 },
15906 unmountComponentAtNode: function (container) {
15907 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
15908
15909 if (container._reactRootContainer) {
15910 {
15911 var rootEl = getReactRootElementInContainer(container);
15912 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
15913 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
15914 }
15915
15916 // Unmount should not be batched.
15917 DOMRenderer.unbatchedUpdates(function () {
15918 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
15919 container._reactRootContainer = null;
15920 });
15921 });
15922 // If you call unmountComponentAtNode twice in quick succession, you'll
15923 // get `true` twice. That's probably fine?
15924 return true;
15925 } else {
15926 {
15927 var _rootEl = getReactRootElementInContainer(container);
15928 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
15929
15930 // Check if the container itself is a React root node.
15931 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
15932
15933 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.');
15934 }
15935
15936 return false;
15937 }
15938 },
15939
15940
15941 // Temporary alias since we already shipped React 16 RC with it.
15942 // TODO: remove in React 17.
15943 unstable_createPortal: function () {
15944 if (!didWarnAboutUnstableCreatePortal) {
15945 didWarnAboutUnstableCreatePortal = true;
15946 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.');
15947 }
15948 return createPortal.apply(undefined, arguments);
15949 },
15950
15951
15952 unstable_batchedUpdates: batchedUpdates,
15953
15954 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
15955
15956 flushSync: DOMRenderer.flushSync,
15957
15958 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
15959 // For TapEventPlugin which is popular in open source
15960 EventPluginHub: EventPluginHub,
15961 // Used by test-utils
15962 EventPluginRegistry: EventPluginRegistry,
15963 EventPropagators: EventPropagators,
15964 ReactControlledComponent: ReactControlledComponent,
15965 ReactDOMComponentTree: ReactDOMComponentTree,
15966 ReactDOMEventListener: ReactDOMEventListener
15967 }
15968};
15969
15970{
15971 // Show deprecation warnings as we don't want to support injection forever.
15972 // We do it now to let the internal injection happen without warnings.
15973 // https://github.com/facebook/react/issues/11689
15974 enableWarningOnInjection();
15975}
15976
15977if (enableCreateRoot) {
15978 ReactDOM.createRoot = function createRoot(container, options) {
15979 var hydrate = options != null && options.hydrate === true;
15980 return new ReactRoot(container, true, hydrate);
15981 };
15982}
15983
15984var foundDevTools = DOMRenderer.injectIntoDevTools({
15985 findFiberByHostInstance: getClosestInstanceFromNode,
15986 bundleType: 1,
15987 version: ReactVersion,
15988 rendererPackageName: 'react-dom'
15989});
15990
15991{
15992 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
15993 // If we're in Chrome or Firefox, provide a download link if not installed.
15994 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
15995 var protocol = window.location.protocol;
15996 // Don't warn in exotic cases like chrome-extension://.
15997 if (/^(https?|file):$/.test(protocol)) {
15998 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');
15999 }
16000 }
16001 }
16002}
16003
16004
16005
16006var ReactDOM$2 = Object.freeze({
16007 default: ReactDOM
16008});
16009
16010var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
16011
16012// TODO: decide on the top-level export form.
16013// This is hacky but makes it work with both Rollup and Jest.
16014var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
16015
16016return reactDom;
16017
16018})));