· 8 years ago · Jan 10, 2018, 01:56 PM
1/** @license React v16.2.0
2 * react-dom.development.js
3 *
4 * Copyright (c) 2013-present, Facebook, Inc.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactDOM = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18/**
19 * WARNING: DO NOT manually require this module.
20 * This is a replacement for `invariant(...)` used by the error code system
21 * and will _only_ be required by the corresponding babel pass.
22 * It always throws.
23 */
24
25/**
26 * Copyright (c) 2013-present, Facebook, Inc.
27 *
28 * This source code is licensed under the MIT license found in the
29 * LICENSE file in the root directory of this source tree.
30 *
31 */
32
33
34
35/**
36 * Use invariant() to assert state which your program assumes to be true.
37 *
38 * Provide sprintf-style format (only %s is supported) and arguments
39 * to provide information about what broke and what you were
40 * expecting.
41 *
42 * The invariant message will be stripped in production, but the invariant
43 * will remain to ensure logic does not differ in production.
44 */
45
46var validateFormat = function validateFormat(format) {};
47
48{
49 validateFormat = function validateFormat(format) {
50 if (format === undefined) {
51 throw new Error('invariant requires an error message argument');
52 }
53 };
54}
55
56function invariant(condition, format, a, b, c, d, e, f) {
57 validateFormat(format);
58
59 if (!condition) {
60 var error;
61 if (format === undefined) {
62 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
63 } else {
64 var args = [a, b, c, d, e, f];
65 var argIndex = 0;
66 error = new Error(format.replace(/%s/g, function () {
67 return args[argIndex++];
68 }));
69 error.name = 'Invariant Violation';
70 }
71
72 error.framesToPop = 1; // we don't care about invariant's own frame
73 throw error;
74 }
75}
76
77var invariant_1 = invariant;
78
79!React ? invariant_1(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
80
81var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) {
82 this._hasCaughtError = false;
83 this._caughtError = null;
84 var funcArgs = Array.prototype.slice.call(arguments, 3);
85 try {
86 func.apply(context, funcArgs);
87 } catch (error) {
88 this._caughtError = error;
89 this._hasCaughtError = true;
90 }
91};
92
93{
94 // In DEV mode, we swap out invokeGuardedCallback for a special version
95 // that plays more nicely with the browser's DevTools. The idea is to preserve
96 // "Pause on exceptions" behavior. Because React wraps all user-provided
97 // functions in invokeGuardedCallback, and the production version of
98 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
99 // like caught exceptions, and the DevTools won't pause unless the developer
100 // takes the extra step of enabling pause on caught exceptions. This is
101 // untintuitive, though, because even though React has caught the error, from
102 // the developer's perspective, the error is uncaught.
103 //
104 // To preserve the expected "Pause on exceptions" behavior, we don't use a
105 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
106 // DOM node, and call the user-provided callback from inside an event handler
107 // for that fake event. If the callback throws, the error is "captured" using
108 // a global event handler. But because the error happens in a different
109 // event loop context, it does not interrupt the normal program flow.
110 // Effectively, this gives us try-catch behavior without actually using
111 // try-catch. Neat!
112
113 // Check that the browser supports the APIs we need to implement our special
114 // DEV version of invokeGuardedCallback
115 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
116 var fakeNode = document.createElement('react');
117
118 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
119 // If document doesn't exist we know for sure we will crash in this method
120 // when we call document.createEvent(). However this can cause confusing
121 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
122 // So we preemptively throw with a better message instead.
123 !(typeof document !== 'undefined') ? invariant_1(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0;
124 var evt = document.createEvent('Event');
125
126 // Keeps track of whether the user-provided callback threw an error. We
127 // set this to true at the beginning, then set it to false right after
128 // calling the function. If the function errors, `didError` will never be
129 // set to false. This strategy works even if the browser is flaky and
130 // fails to call our global error handler, because it doesn't rely on
131 // the error event at all.
132 var didError = true;
133
134 // Create an event handler for our fake event. We will synchronously
135 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
136 // call the user-provided callback.
137 var funcArgs = Array.prototype.slice.call(arguments, 3);
138 function callCallback() {
139 // We immediately remove the callback from event listeners so that
140 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
141 // nested call would trigger the fake event handlers of any call higher
142 // in the stack.
143 fakeNode.removeEventListener(evtType, callCallback, false);
144 func.apply(context, funcArgs);
145 didError = false;
146 }
147
148 // Create a global error event handler. We use this to capture the value
149 // that was thrown. It's possible that this error handler will fire more
150 // than once; for example, if non-React code also calls `dispatchEvent`
151 // and a handler for that event throws. We should be resilient to most of
152 // those cases. Even if our error event handler fires more than once, the
153 // last error event is always used. If the callback actually does error,
154 // we know that the last error event is the correct one, because it's not
155 // possible for anything else to have happened in between our callback
156 // erroring and the code that follows the `dispatchEvent` call below. If
157 // the callback doesn't error, but the error event was fired, we know to
158 // ignore it because `didError` will be false, as described above.
159 var error = void 0;
160 // Use this to track whether the error event is ever called.
161 var didSetError = false;
162 var isCrossOriginError = false;
163
164 function onError(event) {
165 error = event.error;
166 didSetError = true;
167 if (error === null && event.colno === 0 && event.lineno === 0) {
168 isCrossOriginError = true;
169 }
170 }
171
172 // Create a fake event type.
173 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
174
175 // Attach our event handlers
176 window.addEventListener('error', onError);
177 fakeNode.addEventListener(evtType, callCallback, false);
178
179 // Synchronously dispatch our fake event. If the user-provided function
180 // errors, it will trigger our global error handler.
181 evt.initEvent(evtType, false, false);
182 fakeNode.dispatchEvent(evt);
183
184 if (didError) {
185 if (!didSetError) {
186 // The callback errored, but the error event never fired.
187 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
188 } else if (isCrossOriginError) {
189 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
190 }
191 this._hasCaughtError = true;
192 this._caughtError = error;
193 } else {
194 this._hasCaughtError = false;
195 this._caughtError = null;
196 }
197
198 // Remove our event listeners
199 window.removeEventListener('error', onError);
200 };
201
202 invokeGuardedCallback = invokeGuardedCallbackDev;
203 }
204}
205
206var invokeGuardedCallback$1 = invokeGuardedCallback;
207
208var ReactErrorUtils = {
209 // Used by Fiber to simulate a try-catch.
210 _caughtError: null,
211 _hasCaughtError: false,
212
213 // Used by event system to capture/rethrow the first error.
214 _rethrowError: null,
215 _hasRethrowError: false,
216
217 /**
218 * Call a function while guarding against errors that happens within it.
219 * Returns an error if it throws, otherwise null.
220 *
221 * In production, this is implemented using a try-catch. The reason we don't
222 * use a try-catch directly is so that we can swap out a different
223 * implementation in DEV mode.
224 *
225 * @param {String} name of the guard to use for logging or debugging
226 * @param {Function} func The function to invoke
227 * @param {*} context The context to use when calling the function
228 * @param {...*} args Arguments for function
229 */
230 invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) {
231 invokeGuardedCallback$1.apply(ReactErrorUtils, arguments);
232 },
233
234 /**
235 * Same as invokeGuardedCallback, but instead of returning an error, it stores
236 * it in a global so it can be rethrown by `rethrowCaughtError` later.
237 * TODO: See if _caughtError and _rethrowError can be unified.
238 *
239 * @param {String} name of the guard to use for logging or debugging
240 * @param {Function} func The function to invoke
241 * @param {*} context The context to use when calling the function
242 * @param {...*} args Arguments for function
243 */
244 invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) {
245 ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
246 if (ReactErrorUtils.hasCaughtError()) {
247 var error = ReactErrorUtils.clearCaughtError();
248 if (!ReactErrorUtils._hasRethrowError) {
249 ReactErrorUtils._hasRethrowError = true;
250 ReactErrorUtils._rethrowError = error;
251 }
252 }
253 },
254
255 /**
256 * During execution of guarded functions we will capture the first error which
257 * we will rethrow to be handled by the top level error handler.
258 */
259 rethrowCaughtError: function () {
260 return rethrowCaughtError.apply(ReactErrorUtils, arguments);
261 },
262
263 hasCaughtError: function () {
264 return ReactErrorUtils._hasCaughtError;
265 },
266
267 clearCaughtError: function () {
268 if (ReactErrorUtils._hasCaughtError) {
269 var error = ReactErrorUtils._caughtError;
270 ReactErrorUtils._caughtError = null;
271 ReactErrorUtils._hasCaughtError = false;
272 return error;
273 } else {
274 invariant_1(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
275 }
276 }
277};
278
279var rethrowCaughtError = function () {
280 if (ReactErrorUtils._hasRethrowError) {
281 var error = ReactErrorUtils._rethrowError;
282 ReactErrorUtils._rethrowError = null;
283 ReactErrorUtils._hasRethrowError = false;
284 throw error;
285 }
286};
287
288/**
289 * Forked from fbjs/warning:
290 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
291 *
292 * Only change is we use console.warn instead of console.error,
293 * and do nothing when 'console' is not supported.
294 * This really simplifies the code.
295 * ---
296 * Similar to invariant but only logs a warning if the condition is not met.
297 * This can be used to log issues in development environments in critical
298 * paths. Removing the logging code for production environments will keep the
299 * same logic and follow the same code paths.
300 */
301
302var lowPriorityWarning = function () {};
303
304{
305 var printWarning = function (format) {
306 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
307 args[_key - 1] = arguments[_key];
308 }
309
310 var argIndex = 0;
311 var message = 'Warning: ' + format.replace(/%s/g, function () {
312 return args[argIndex++];
313 });
314 if (typeof console !== 'undefined') {
315 console.warn(message);
316 }
317 try {
318 // --- Welcome to debugging React ---
319 // This error was thrown as a convenience so that you can use this stack
320 // to find the callsite that caused this warning to fire.
321 throw new Error(message);
322 } catch (x) {}
323 };
324
325 lowPriorityWarning = function (condition, format) {
326 if (format === undefined) {
327 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
328 }
329 if (!condition) {
330 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
331 args[_key2 - 2] = arguments[_key2];
332 }
333
334 printWarning.apply(undefined, [format].concat(args));
335 }
336 };
337}
338
339var lowPriorityWarning$1 = lowPriorityWarning;
340
341var shouldWarnOnInjection = false;
342
343/**
344 * Injectable ordering of event plugins.
345 */
346var eventPluginOrder = null;
347
348/**
349 * Injectable mapping from names to event plugin modules.
350 */
351var namesToPlugins = {};
352
353function enableWarningOnInjection() {
354 shouldWarnOnInjection = true;
355}
356
357/**
358 * Recomputes the plugin list using the injected plugins and plugin ordering.
359 *
360 * @private
361 */
362function recomputePluginOrdering() {
363 if (!eventPluginOrder) {
364 // Wait until an `eventPluginOrder` is injected.
365 return;
366 }
367 for (var pluginName in namesToPlugins) {
368 var pluginModule = namesToPlugins[pluginName];
369 var pluginIndex = eventPluginOrder.indexOf(pluginName);
370 !(pluginIndex > -1) ? invariant_1(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
371 if (plugins[pluginIndex]) {
372 continue;
373 }
374 !pluginModule.extractEvents ? invariant_1(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
375 plugins[pluginIndex] = pluginModule;
376 var publishedEvents = pluginModule.eventTypes;
377 for (var eventName in publishedEvents) {
378 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant_1(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
379 }
380 }
381}
382
383/**
384 * Publishes an event so that it can be dispatched by the supplied plugin.
385 *
386 * @param {object} dispatchConfig Dispatch configuration for the event.
387 * @param {object} PluginModule Plugin publishing the event.
388 * @return {boolean} True if the event was successfully published.
389 * @private
390 */
391function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
392 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
393 eventNameDispatchConfigs[eventName] = dispatchConfig;
394
395 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
396 if (phasedRegistrationNames) {
397 for (var phaseName in phasedRegistrationNames) {
398 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
399 var phasedRegistrationName = phasedRegistrationNames[phaseName];
400 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
401 }
402 }
403 return true;
404 } else if (dispatchConfig.registrationName) {
405 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
406 return true;
407 }
408 return false;
409}
410
411/**
412 * Publishes a registration name that is used to identify dispatched events.
413 *
414 * @param {string} registrationName Registration name to add.
415 * @param {object} PluginModule Plugin publishing the event.
416 * @private
417 */
418function publishRegistrationName(registrationName, pluginModule, eventName) {
419 !!registrationNameModules[registrationName] ? invariant_1(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
420 registrationNameModules[registrationName] = pluginModule;
421 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
422
423 {
424 var lowerCasedName = registrationName.toLowerCase();
425 possibleRegistrationNames[lowerCasedName] = registrationName;
426
427 if (registrationName === 'onDoubleClick') {
428 possibleRegistrationNames.ondblclick = registrationName;
429 }
430 }
431}
432
433/**
434 * Registers plugins so that they can extract and dispatch events.
435 *
436 * @see {EventPluginHub}
437 */
438
439/**
440 * Ordered list of injected plugins.
441 */
442var plugins = [];
443
444/**
445 * Mapping from event name to dispatch config
446 */
447var eventNameDispatchConfigs = {};
448
449/**
450 * Mapping from registration name to plugin module
451 */
452var registrationNameModules = {};
453
454/**
455 * Mapping from registration name to event name
456 */
457var registrationNameDependencies = {};
458
459/**
460 * Mapping from lowercase registration names to the properly cased version,
461 * used to warn in the case of missing event handlers. Available
462 * only in true.
463 * @type {Object}
464 */
465var possibleRegistrationNames = {};
466// Trust the developer to only use possibleRegistrationNames in true
467
468/**
469 * Injects an ordering of plugins (by plugin name). This allows the ordering
470 * to be decoupled from injection of the actual plugins so that ordering is
471 * always deterministic regardless of packaging, on-the-fly injection, etc.
472 *
473 * @param {array} InjectedEventPluginOrder
474 * @internal
475 * @see {EventPluginHub.injection.injectEventPluginOrder}
476 */
477function injectEventPluginOrder(injectedEventPluginOrder) {
478 !!eventPluginOrder ? invariant_1(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
479 // Clone the ordering so it cannot be dynamically mutated.
480 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
481 recomputePluginOrdering();
482}
483
484/**
485 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
486 * in the ordering injected by `injectEventPluginOrder`.
487 *
488 * Plugins can be injected as part of page initialization or on-the-fly.
489 *
490 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
491 * @internal
492 * @see {EventPluginHub.injection.injectEventPluginsByName}
493 */
494function injectEventPluginsByName(injectedNamesToPlugins) {
495 {
496 if (shouldWarnOnInjection) {
497 var names = Object.keys(injectedNamesToPlugins).join(', ');
498 lowPriorityWarning$1(false, 'Injecting custom event plugins (%s) is deprecated ' + 'and will not work in React 17+. Please update your code ' + 'to not depend on React internals. The stack trace for this ' + 'warning should reveal the library that is using them. ' + 'See https://github.com/facebook/react/issues/11689 for a discussion.', names);
499 }
500 }
501
502 var isOrderingDirty = false;
503 for (var pluginName in injectedNamesToPlugins) {
504 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
505 continue;
506 }
507 var pluginModule = injectedNamesToPlugins[pluginName];
508 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
509 !!namesToPlugins[pluginName] ? invariant_1(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
510 namesToPlugins[pluginName] = pluginModule;
511 isOrderingDirty = true;
512 }
513 }
514 if (isOrderingDirty) {
515 recomputePluginOrdering();
516 }
517}
518
519var EventPluginRegistry = Object.freeze({
520 enableWarningOnInjection: enableWarningOnInjection,
521 plugins: plugins,
522 eventNameDispatchConfigs: eventNameDispatchConfigs,
523 registrationNameModules: registrationNameModules,
524 registrationNameDependencies: registrationNameDependencies,
525 possibleRegistrationNames: possibleRegistrationNames,
526 injectEventPluginOrder: injectEventPluginOrder,
527 injectEventPluginsByName: injectEventPluginsByName
528});
529
530/**
531 * Copyright (c) 2013-present, Facebook, Inc.
532 *
533 * This source code is licensed under the MIT license found in the
534 * LICENSE file in the root directory of this source tree.
535 *
536 *
537 */
538
539function makeEmptyFunction(arg) {
540 return function () {
541 return arg;
542 };
543}
544
545/**
546 * This function accepts and discards inputs; it has no side effects. This is
547 * primarily useful idiomatically for overridable function endpoints which
548 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
549 */
550var emptyFunction = function emptyFunction() {};
551
552emptyFunction.thatReturns = makeEmptyFunction;
553emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
554emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
555emptyFunction.thatReturnsNull = makeEmptyFunction(null);
556emptyFunction.thatReturnsThis = function () {
557 return this;
558};
559emptyFunction.thatReturnsArgument = function (arg) {
560 return arg;
561};
562
563var emptyFunction_1 = emptyFunction;
564
565/**
566 * Copyright (c) 2014-present, Facebook, Inc.
567 *
568 * This source code is licensed under the MIT license found in the
569 * LICENSE file in the root directory of this source tree.
570 *
571 */
572
573
574
575
576
577/**
578 * Similar to invariant but only logs a warning if the condition is not met.
579 * This can be used to log issues in development environments in critical
580 * paths. Removing the logging code for production environments will keep the
581 * same logic and follow the same code paths.
582 */
583
584var warning = emptyFunction_1;
585
586{
587 var printWarning$1 = function printWarning(format) {
588 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
589 args[_key - 1] = arguments[_key];
590 }
591
592 var argIndex = 0;
593 var message = 'Warning: ' + format.replace(/%s/g, function () {
594 return args[argIndex++];
595 });
596 if (typeof console !== 'undefined') {
597 console.error(message);
598 }
599 try {
600 // --- Welcome to debugging React ---
601 // This error was thrown as a convenience so that you can use this stack
602 // to find the callsite that caused this warning to fire.
603 throw new Error(message);
604 } catch (x) {}
605 };
606
607 warning = function warning(condition, format) {
608 if (format === undefined) {
609 throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
610 }
611
612 if (format.indexOf('Failed Composite propType: ') === 0) {
613 return; // Ignore CompositeComponent proptype check.
614 }
615
616 if (!condition) {
617 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
618 args[_key2 - 2] = arguments[_key2];
619 }
620
621 printWarning$1.apply(undefined, [format].concat(args));
622 }
623 };
624}
625
626var warning_1 = warning;
627
628var getFiberCurrentPropsFromNode = null;
629var getInstanceFromNode = null;
630var getNodeFromInstance = null;
631
632var injection$1 = {
633 injectComponentTree: function (Injected) {
634 getFiberCurrentPropsFromNode = Injected.getFiberCurrentPropsFromNode;
635 getInstanceFromNode = Injected.getInstanceFromNode;
636 getNodeFromInstance = Injected.getNodeFromInstance;
637
638 {
639 warning_1(getNodeFromInstance && getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
640 }
641 }
642};
643
644
645
646
647
648
649var validateEventDispatches = void 0;
650{
651 validateEventDispatches = function (event) {
652 var dispatchListeners = event._dispatchListeners;
653 var dispatchInstances = event._dispatchInstances;
654
655 var listenersIsArr = Array.isArray(dispatchListeners);
656 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
657
658 var instancesIsArr = Array.isArray(dispatchInstances);
659 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
660
661 warning_1(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.');
662 };
663}
664
665/**
666 * Dispatch the event to the listener.
667 * @param {SyntheticEvent} event SyntheticEvent to handle
668 * @param {boolean} simulated If the event is simulated (changes exn behavior)
669 * @param {function} listener Application-level callback
670 * @param {*} inst Internal component instance
671 */
672function executeDispatch(event, simulated, listener, inst) {
673 var type = event.type || 'unknown-event';
674 event.currentTarget = getNodeFromInstance(inst);
675 ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
676 event.currentTarget = null;
677}
678
679/**
680 * Standard/simple iteration through an event's collected dispatches.
681 */
682function executeDispatchesInOrder(event, simulated) {
683 var dispatchListeners = event._dispatchListeners;
684 var dispatchInstances = event._dispatchInstances;
685 {
686 validateEventDispatches(event);
687 }
688 if (Array.isArray(dispatchListeners)) {
689 for (var i = 0; i < dispatchListeners.length; i++) {
690 if (event.isPropagationStopped()) {
691 break;
692 }
693 // Listeners and Instances are two parallel arrays that are always in sync.
694 executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
695 }
696 } else if (dispatchListeners) {
697 executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
698 }
699 event._dispatchListeners = null;
700 event._dispatchInstances = null;
701}
702
703/**
704 * @see executeDispatchesInOrderStopAtTrueImpl
705 */
706
707
708/**
709 * Execution of a "direct" dispatch - there must be at most one dispatch
710 * accumulated on the event or it is considered an error. It doesn't really make
711 * sense for an event with multiple dispatches (bubbled) to keep track of the
712 * return values at each dispatch execution, but it does tend to make sense when
713 * dealing with "direct" dispatches.
714 *
715 * @return {*} The return value of executing the single dispatch.
716 */
717
718
719/**
720 * @param {SyntheticEvent} event
721 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
722 */
723
724/**
725 * Accumulates items that must not be null or undefined into the first one. This
726 * is used to conserve memory by avoiding array allocations, and thus sacrifices
727 * API cleanness. Since `current` can be null before being passed in and not
728 * null after this function, make sure to assign it back to `current`:
729 *
730 * `a = accumulateInto(a, b);`
731 *
732 * This API should be sparingly used. Try `accumulate` for something cleaner.
733 *
734 * @return {*|array<*>} An accumulation of items.
735 */
736
737function accumulateInto(current, next) {
738 !(next != null) ? invariant_1(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
739
740 if (current == null) {
741 return next;
742 }
743
744 // Both are not empty. Warning: Never call x.concat(y) when you are not
745 // certain that x is an Array (x could be a string with concat method).
746 if (Array.isArray(current)) {
747 if (Array.isArray(next)) {
748 current.push.apply(current, next);
749 return current;
750 }
751 current.push(next);
752 return current;
753 }
754
755 if (Array.isArray(next)) {
756 // A bit too dangerous to mutate `next`.
757 return [current].concat(next);
758 }
759
760 return [current, next];
761}
762
763/**
764 * @param {array} arr an "accumulation" of items which is either an Array or
765 * a single item. Useful when paired with the `accumulate` module. This is a
766 * simple utility that allows us to reason about a collection of items, but
767 * handling the case when there is exactly one item (and we do not need to
768 * allocate an array).
769 * @param {function} cb Callback invoked with each element or a collection.
770 * @param {?} [scope] Scope used as `this` in a callback.
771 */
772function forEachAccumulated(arr, cb, scope) {
773 if (Array.isArray(arr)) {
774 arr.forEach(cb, scope);
775 } else if (arr) {
776 cb.call(scope, arr);
777 }
778}
779
780/**
781 * Internal queue of events that have accumulated their dispatches and are
782 * waiting to have their dispatches executed.
783 */
784var eventQueue = null;
785
786/**
787 * Dispatches an event and releases it back into the pool, unless persistent.
788 *
789 * @param {?object} event Synthetic event to be dispatched.
790 * @param {boolean} simulated If the event is simulated (changes exn behavior)
791 * @private
792 */
793var executeDispatchesAndRelease = function (event, simulated) {
794 if (event) {
795 executeDispatchesInOrder(event, simulated);
796
797 if (!event.isPersistent()) {
798 event.constructor.release(event);
799 }
800 }
801};
802var executeDispatchesAndReleaseSimulated = function (e) {
803 return executeDispatchesAndRelease(e, true);
804};
805var executeDispatchesAndReleaseTopLevel = function (e) {
806 return executeDispatchesAndRelease(e, false);
807};
808
809function isInteractive(tag) {
810 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
811}
812
813function shouldPreventMouseEvent(name, type, props) {
814 switch (name) {
815 case 'onClick':
816 case 'onClickCapture':
817 case 'onDoubleClick':
818 case 'onDoubleClickCapture':
819 case 'onMouseDown':
820 case 'onMouseDownCapture':
821 case 'onMouseMove':
822 case 'onMouseMoveCapture':
823 case 'onMouseUp':
824 case 'onMouseUpCapture':
825 return !!(props.disabled && isInteractive(type));
826 default:
827 return false;
828 }
829}
830
831/**
832 * This is a unified interface for event plugins to be installed and configured.
833 *
834 * Event plugins can implement the following properties:
835 *
836 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
837 * Required. When a top-level event is fired, this method is expected to
838 * extract synthetic events that will in turn be queued and dispatched.
839 *
840 * `eventTypes` {object}
841 * Optional, plugins that fire events must publish a mapping of registration
842 * names that are used to register listeners. Values of this mapping must
843 * be objects that contain `registrationName` or `phasedRegistrationNames`.
844 *
845 * `executeDispatch` {function(object, function, string)}
846 * Optional, allows plugins to override how an event gets dispatched. By
847 * default, the listener is simply invoked.
848 *
849 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
850 *
851 * @public
852 */
853
854/**
855 * Methods for injecting dependencies.
856 */
857var injection = {
858 /**
859 * @param {array} InjectedEventPluginOrder
860 * @public
861 */
862 injectEventPluginOrder: injectEventPluginOrder,
863
864 /**
865 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
866 */
867 injectEventPluginsByName: injectEventPluginsByName
868};
869
870/**
871 * @param {object} inst The instance, which is the source of events.
872 * @param {string} registrationName Name of listener (e.g. `onClick`).
873 * @return {?function} The stored callback.
874 */
875function getListener(inst, registrationName) {
876 var listener = void 0;
877
878 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
879 // live here; needs to be moved to a better place soon
880 var stateNode = inst.stateNode;
881 if (!stateNode) {
882 // Work in progress (ex: onload events in incremental mode).
883 return null;
884 }
885 var props = getFiberCurrentPropsFromNode(stateNode);
886 if (!props) {
887 // Work in progress.
888 return null;
889 }
890 listener = props[registrationName];
891 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
892 return null;
893 }
894 !(!listener || typeof listener === 'function') ? invariant_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
895 return listener;
896}
897
898/**
899 * Allows registered plugins an opportunity to extract events from top-level
900 * native browser events.
901 *
902 * @return {*} An accumulation of synthetic events.
903 * @internal
904 */
905function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
906 var events = null;
907 for (var i = 0; i < plugins.length; i++) {
908 // Not every plugin in the ordering may be loaded at runtime.
909 var possiblePlugin = plugins[i];
910 if (possiblePlugin) {
911 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
912 if (extractedEvents) {
913 events = accumulateInto(events, extractedEvents);
914 }
915 }
916 }
917 return events;
918}
919
920function runEventsInBatch(events, simulated) {
921 if (events !== null) {
922 eventQueue = accumulateInto(eventQueue, events);
923 }
924
925 // Set `eventQueue` to null before processing it so that we can tell if more
926 // events get enqueued while processing.
927 var processingEventQueue = eventQueue;
928 eventQueue = null;
929
930 if (!processingEventQueue) {
931 return;
932 }
933
934 if (simulated) {
935 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
936 } else {
937 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
938 }
939 !!eventQueue ? invariant_1(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
940 // This would be a good time to rethrow if any of the event handlers threw.
941 ReactErrorUtils.rethrowCaughtError();
942}
943
944function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
945 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
946 runEventsInBatch(events, false);
947}
948
949var EventPluginHub = Object.freeze({
950 injection: injection,
951 getListener: getListener,
952 runEventsInBatch: runEventsInBatch,
953 runExtractedEventsInBatch: runExtractedEventsInBatch
954});
955
956var IndeterminateComponent = 0; // Before we know whether it is functional or class
957var FunctionalComponent = 1;
958var ClassComponent = 2;
959var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
960var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
961var HostComponent = 5;
962var HostText = 6;
963var CallComponent = 7;
964var CallHandlerPhase = 8;
965var ReturnComponent = 9;
966var Fragment = 10;
967
968var randomKey = Math.random().toString(36).slice(2);
969var internalInstanceKey = '__reactInternalInstance$' + randomKey;
970var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
971
972function precacheFiberNode$1(hostInst, node) {
973 node[internalInstanceKey] = hostInst;
974}
975
976/**
977 * Given a DOM node, return the closest ReactDOMComponent or
978 * ReactDOMTextComponent instance ancestor.
979 */
980function getClosestInstanceFromNode(node) {
981 if (node[internalInstanceKey]) {
982 return node[internalInstanceKey];
983 }
984
985 while (!node[internalInstanceKey]) {
986 if (node.parentNode) {
987 node = node.parentNode;
988 } else {
989 // Top of the tree. This node must not be part of a React tree (or is
990 // unmounted, potentially).
991 return null;
992 }
993 }
994
995 var inst = node[internalInstanceKey];
996 if (inst.tag === HostComponent || inst.tag === HostText) {
997 // In Fiber, this will always be the deepest root.
998 return inst;
999 }
1000
1001 return null;
1002}
1003
1004/**
1005 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
1006 * instance, or null if the node was not rendered by this React.
1007 */
1008function getInstanceFromNode$1(node) {
1009 var inst = node[internalInstanceKey];
1010 if (inst) {
1011 if (inst.tag === HostComponent || inst.tag === HostText) {
1012 return inst;
1013 } else {
1014 return null;
1015 }
1016 }
1017 return null;
1018}
1019
1020/**
1021 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
1022 * DOM node.
1023 */
1024function getNodeFromInstance$1(inst) {
1025 if (inst.tag === HostComponent || inst.tag === HostText) {
1026 // In Fiber this, is just the state node right now. We assume it will be
1027 // a host component or host text.
1028 return inst.stateNode;
1029 }
1030
1031 // Without this first invariant, passing a non-DOM-component triggers the next
1032 // invariant for a missing parent, which is super confusing.
1033 invariant_1(false, 'getNodeFromInstance: Invalid argument.');
1034}
1035
1036function getFiberCurrentPropsFromNode$1(node) {
1037 return node[internalEventHandlersKey] || null;
1038}
1039
1040function updateFiberProps$1(node, props) {
1041 node[internalEventHandlersKey] = props;
1042}
1043
1044var ReactDOMComponentTree = Object.freeze({
1045 precacheFiberNode: precacheFiberNode$1,
1046 getClosestInstanceFromNode: getClosestInstanceFromNode,
1047 getInstanceFromNode: getInstanceFromNode$1,
1048 getNodeFromInstance: getNodeFromInstance$1,
1049 getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode$1,
1050 updateFiberProps: updateFiberProps$1
1051});
1052
1053function getParent(inst) {
1054 do {
1055 inst = inst['return'];
1056 // TODO: If this is a HostRoot we might want to bail out.
1057 // That is depending on if we want nested subtrees (layers) to bubble
1058 // events to their parent. We could also go through parentNode on the
1059 // host node but that wouldn't work for React Native and doesn't let us
1060 // do the portal feature.
1061 } while (inst && inst.tag !== HostComponent);
1062 if (inst) {
1063 return inst;
1064 }
1065 return null;
1066}
1067
1068/**
1069 * Return the lowest common ancestor of A and B, or null if they are in
1070 * different trees.
1071 */
1072function getLowestCommonAncestor(instA, instB) {
1073 var depthA = 0;
1074 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1075 depthA++;
1076 }
1077 var depthB = 0;
1078 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1079 depthB++;
1080 }
1081
1082 // If A is deeper, crawl up.
1083 while (depthA - depthB > 0) {
1084 instA = getParent(instA);
1085 depthA--;
1086 }
1087
1088 // If B is deeper, crawl up.
1089 while (depthB - depthA > 0) {
1090 instB = getParent(instB);
1091 depthB--;
1092 }
1093
1094 // Walk in lockstep until we find a match.
1095 var depth = depthA;
1096 while (depth--) {
1097 if (instA === instB || instA === instB.alternate) {
1098 return instA;
1099 }
1100 instA = getParent(instA);
1101 instB = getParent(instB);
1102 }
1103 return null;
1104}
1105
1106/**
1107 * Return if A is an ancestor of B.
1108 */
1109
1110
1111/**
1112 * Return the parent instance of the passed-in instance.
1113 */
1114function getParentInstance(inst) {
1115 return getParent(inst);
1116}
1117
1118/**
1119 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1120 */
1121function traverseTwoPhase(inst, fn, arg) {
1122 var path = [];
1123 while (inst) {
1124 path.push(inst);
1125 inst = getParent(inst);
1126 }
1127 var i = void 0;
1128 for (i = path.length; i-- > 0;) {
1129 fn(path[i], 'captured', arg);
1130 }
1131 for (i = 0; i < path.length; i++) {
1132 fn(path[i], 'bubbled', arg);
1133 }
1134}
1135
1136/**
1137 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1138 * should would receive a `mouseEnter` or `mouseLeave` event.
1139 *
1140 * Does not invoke the callback on the nearest common ancestor because nothing
1141 * "entered" or "left" that element.
1142 */
1143function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1144 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1145 var pathFrom = [];
1146 while (true) {
1147 if (!from) {
1148 break;
1149 }
1150 if (from === common) {
1151 break;
1152 }
1153 var alternate = from.alternate;
1154 if (alternate !== null && alternate === common) {
1155 break;
1156 }
1157 pathFrom.push(from);
1158 from = getParent(from);
1159 }
1160 var pathTo = [];
1161 while (true) {
1162 if (!to) {
1163 break;
1164 }
1165 if (to === common) {
1166 break;
1167 }
1168 var _alternate = to.alternate;
1169 if (_alternate !== null && _alternate === common) {
1170 break;
1171 }
1172 pathTo.push(to);
1173 to = getParent(to);
1174 }
1175 for (var i = 0; i < pathFrom.length; i++) {
1176 fn(pathFrom[i], 'bubbled', argFrom);
1177 }
1178 for (var _i = pathTo.length; _i-- > 0;) {
1179 fn(pathTo[_i], 'captured', argTo);
1180 }
1181}
1182
1183/**
1184 * Some event types have a notion of different registration names for different
1185 * "phases" of propagation. This finds listeners by a given phase.
1186 */
1187function listenerAtPhase(inst, event, propagationPhase) {
1188 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1189 return getListener(inst, registrationName);
1190}
1191
1192/**
1193 * A small set of propagation patterns, each of which will accept a small amount
1194 * of information, and generate a set of "dispatch ready event objects" - which
1195 * are sets of events that have already been annotated with a set of dispatched
1196 * listener functions/ids. The API is designed this way to discourage these
1197 * propagation strategies from actually executing the dispatches, since we
1198 * always want to collect the entire set of dispatches before executing even a
1199 * single one.
1200 */
1201
1202/**
1203 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1204 * here, allows us to not have to bind or create functions for each event.
1205 * Mutating the event's members allows us to not have to create a wrapping
1206 * "dispatch" object that pairs the event with the listener.
1207 */
1208function accumulateDirectionalDispatches(inst, phase, event) {
1209 {
1210 warning_1(inst, 'Dispatching inst must not be null');
1211 }
1212 var listener = listenerAtPhase(inst, event, phase);
1213 if (listener) {
1214 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1215 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1216 }
1217}
1218
1219/**
1220 * Collect dispatches (must be entirely collected before dispatching - see unit
1221 * tests). Lazily allocate the array to conserve memory. We must loop through
1222 * each event and perform the traversal for each one. We cannot perform a
1223 * single traversal for the entire collection of events because each event may
1224 * have a different target.
1225 */
1226function accumulateTwoPhaseDispatchesSingle(event) {
1227 if (event && event.dispatchConfig.phasedRegistrationNames) {
1228 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1229 }
1230}
1231
1232/**
1233 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
1234 */
1235function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
1236 if (event && event.dispatchConfig.phasedRegistrationNames) {
1237 var targetInst = event._targetInst;
1238 var parentInst = targetInst ? getParentInstance(targetInst) : null;
1239 traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
1240 }
1241}
1242
1243/**
1244 * Accumulates without regard to direction, does not look for phased
1245 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1246 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1247 */
1248function accumulateDispatches(inst, ignoredDirection, event) {
1249 if (inst && event && event.dispatchConfig.registrationName) {
1250 var registrationName = event.dispatchConfig.registrationName;
1251 var listener = getListener(inst, registrationName);
1252 if (listener) {
1253 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1254 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1255 }
1256 }
1257}
1258
1259/**
1260 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1261 * `dispatchMarker`.
1262 * @param {SyntheticEvent} event
1263 */
1264function accumulateDirectDispatchesSingle(event) {
1265 if (event && event.dispatchConfig.registrationName) {
1266 accumulateDispatches(event._targetInst, null, event);
1267 }
1268}
1269
1270function accumulateTwoPhaseDispatches(events) {
1271 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1272}
1273
1274function accumulateTwoPhaseDispatchesSkipTarget(events) {
1275 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
1276}
1277
1278function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1279 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1280}
1281
1282function accumulateDirectDispatches(events) {
1283 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1284}
1285
1286var EventPropagators = Object.freeze({
1287 accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
1288 accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
1289 accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
1290 accumulateDirectDispatches: accumulateDirectDispatches
1291});
1292
1293/**
1294 * Copyright (c) 2013-present, Facebook, Inc.
1295 *
1296 * This source code is licensed under the MIT license found in the
1297 * LICENSE file in the root directory of this source tree.
1298 *
1299 */
1300
1301
1302
1303var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1304
1305/**
1306 * Simple, lightweight module assisting with the detection and context of
1307 * Worker. Helps avoid circular dependencies and allows code to reason about
1308 * whether or not they are in a Worker, even if they never include the main
1309 * `ReactWorker` dependency.
1310 */
1311var ExecutionEnvironment = {
1312
1313 canUseDOM: canUseDOM,
1314
1315 canUseWorkers: typeof Worker !== 'undefined',
1316
1317 canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
1318
1319 canUseViewport: canUseDOM && !!window.screen,
1320
1321 isInWorker: !canUseDOM // For now, this is true - might change in the future.
1322
1323};
1324
1325var ExecutionEnvironment_1 = ExecutionEnvironment;
1326
1327var contentKey = null;
1328
1329/**
1330 * Gets the key used to access text content on a DOM node.
1331 *
1332 * @return {?string} Key used to access text content.
1333 * @internal
1334 */
1335function getTextContentAccessor() {
1336 if (!contentKey && ExecutionEnvironment_1.canUseDOM) {
1337 // Prefer textContent to innerText because many browsers support both but
1338 // SVG <text> elements don't support innerText even when <div> does.
1339 contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
1340 }
1341 return contentKey;
1342}
1343
1344/**
1345 * This helper object stores information about text content of a target node,
1346 * allowing comparison of content before and after a given event.
1347 *
1348 * Identify the node where selection currently begins, then observe
1349 * both its text content and its current position in the DOM. Since the
1350 * browser may natively replace the target node during composition, we can
1351 * use its position to find its replacement.
1352 *
1353 *
1354 */
1355var compositionState = {
1356 _root: null,
1357 _startText: null,
1358 _fallbackText: null
1359};
1360
1361function initialize(nativeEventTarget) {
1362 compositionState._root = nativeEventTarget;
1363 compositionState._startText = getText();
1364 return true;
1365}
1366
1367function reset() {
1368 compositionState._root = null;
1369 compositionState._startText = null;
1370 compositionState._fallbackText = null;
1371}
1372
1373function getData() {
1374 if (compositionState._fallbackText) {
1375 return compositionState._fallbackText;
1376 }
1377
1378 var start = void 0;
1379 var startValue = compositionState._startText;
1380 var startLength = startValue.length;
1381 var end = void 0;
1382 var endValue = getText();
1383 var endLength = endValue.length;
1384
1385 for (start = 0; start < startLength; start++) {
1386 if (startValue[start] !== endValue[start]) {
1387 break;
1388 }
1389 }
1390
1391 var minEnd = startLength - start;
1392 for (end = 1; end <= minEnd; end++) {
1393 if (startValue[startLength - end] !== endValue[endLength - end]) {
1394 break;
1395 }
1396 }
1397
1398 var sliceTail = end > 1 ? 1 - end : undefined;
1399 compositionState._fallbackText = endValue.slice(start, sliceTail);
1400 return compositionState._fallbackText;
1401}
1402
1403function getText() {
1404 if ('value' in compositionState._root) {
1405 return compositionState._root.value;
1406 }
1407 return compositionState._root[getTextContentAccessor()];
1408}
1409
1410var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1411
1412var _assign = ReactInternals.assign;
1413
1414/* eslint valid-typeof: 0 */
1415
1416var didWarnForAddedNewProperty = false;
1417var isProxySupported = typeof Proxy === 'function';
1418var EVENT_POOL_SIZE = 10;
1419
1420var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
1421
1422/**
1423 * @interface Event
1424 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1425 */
1426var EventInterface = {
1427 type: null,
1428 target: null,
1429 // currentTarget is set when dispatching; no use in copying it here
1430 currentTarget: emptyFunction_1.thatReturnsNull,
1431 eventPhase: null,
1432 bubbles: null,
1433 cancelable: null,
1434 timeStamp: function (event) {
1435 return event.timeStamp || Date.now();
1436 },
1437 defaultPrevented: null,
1438 isTrusted: null
1439};
1440
1441/**
1442 * Synthetic events are dispatched by event plugins, typically in response to a
1443 * top-level event delegation handler.
1444 *
1445 * These systems should generally use pooling to reduce the frequency of garbage
1446 * collection. The system should check `isPersistent` to determine whether the
1447 * event should be released into the pool after being dispatched. Users that
1448 * need a persisted event should invoke `persist`.
1449 *
1450 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1451 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1452 * DOM interface; custom application-specific events can also subclass this.
1453 *
1454 * @param {object} dispatchConfig Configuration used to dispatch this event.
1455 * @param {*} targetInst Marker identifying the event target.
1456 * @param {object} nativeEvent Native browser event.
1457 * @param {DOMEventTarget} nativeEventTarget Target node.
1458 */
1459function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1460 {
1461 // these have a getter/setter for warnings
1462 delete this.nativeEvent;
1463 delete this.preventDefault;
1464 delete this.stopPropagation;
1465 }
1466
1467 this.dispatchConfig = dispatchConfig;
1468 this._targetInst = targetInst;
1469 this.nativeEvent = nativeEvent;
1470
1471 var Interface = this.constructor.Interface;
1472 for (var propName in Interface) {
1473 if (!Interface.hasOwnProperty(propName)) {
1474 continue;
1475 }
1476 {
1477 delete this[propName]; // this has a getter/setter for warnings
1478 }
1479 var normalize = Interface[propName];
1480 if (normalize) {
1481 this[propName] = normalize(nativeEvent);
1482 } else {
1483 if (propName === 'target') {
1484 this.target = nativeEventTarget;
1485 } else {
1486 this[propName] = nativeEvent[propName];
1487 }
1488 }
1489 }
1490
1491 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1492 if (defaultPrevented) {
1493 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1494 } else {
1495 this.isDefaultPrevented = emptyFunction_1.thatReturnsFalse;
1496 }
1497 this.isPropagationStopped = emptyFunction_1.thatReturnsFalse;
1498 return this;
1499}
1500
1501_assign(SyntheticEvent.prototype, {
1502 preventDefault: function () {
1503 this.defaultPrevented = true;
1504 var event = this.nativeEvent;
1505 if (!event) {
1506 return;
1507 }
1508
1509 if (event.preventDefault) {
1510 event.preventDefault();
1511 } else if (typeof event.returnValue !== 'unknown') {
1512 event.returnValue = false;
1513 }
1514 this.isDefaultPrevented = emptyFunction_1.thatReturnsTrue;
1515 },
1516
1517 stopPropagation: function () {
1518 var event = this.nativeEvent;
1519 if (!event) {
1520 return;
1521 }
1522
1523 if (event.stopPropagation) {
1524 event.stopPropagation();
1525 } else if (typeof event.cancelBubble !== 'unknown') {
1526 // The ChangeEventPlugin registers a "propertychange" event for
1527 // IE. This event does not support bubbling or cancelling, and
1528 // any references to cancelBubble throw "Member not found". A
1529 // typeof check of "unknown" circumvents this issue (and is also
1530 // IE specific).
1531 event.cancelBubble = true;
1532 }
1533
1534 this.isPropagationStopped = emptyFunction_1.thatReturnsTrue;
1535 },
1536
1537 /**
1538 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1539 * them back into the pool. This allows a way to hold onto a reference that
1540 * won't be added back into the pool.
1541 */
1542 persist: function () {
1543 this.isPersistent = emptyFunction_1.thatReturnsTrue;
1544 },
1545
1546 /**
1547 * Checks if this event should be released back into the pool.
1548 *
1549 * @return {boolean} True if this should not be released, false otherwise.
1550 */
1551 isPersistent: emptyFunction_1.thatReturnsFalse,
1552
1553 /**
1554 * `PooledClass` looks for `destructor` on each instance it releases.
1555 */
1556 destructor: function () {
1557 var Interface = this.constructor.Interface;
1558 for (var propName in Interface) {
1559 {
1560 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1561 }
1562 }
1563 for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
1564 this[shouldBeReleasedProperties[i]] = null;
1565 }
1566 {
1567 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1568 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction_1));
1569 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction_1));
1570 }
1571 }
1572});
1573
1574SyntheticEvent.Interface = EventInterface;
1575
1576/**
1577 * Helper to reduce boilerplate when creating subclasses.
1578 */
1579SyntheticEvent.extend = function (Interface) {
1580 var Super = this;
1581
1582 var E = function () {};
1583 E.prototype = Super.prototype;
1584 var prototype = new E();
1585
1586 function Class() {
1587 return Super.apply(this, arguments);
1588 }
1589 _assign(prototype, Class.prototype);
1590 Class.prototype = prototype;
1591 Class.prototype.constructor = Class;
1592
1593 Class.Interface = _assign({}, Super.Interface, Interface);
1594 Class.extend = Super.extend;
1595 addEventPoolingTo(Class);
1596
1597 return Class;
1598};
1599
1600/** Proxying after everything set on SyntheticEvent
1601 * to resolve Proxy issue on some WebKit browsers
1602 * in which some Event properties are set to undefined (GH#10010)
1603 */
1604{
1605 if (isProxySupported) {
1606 /*eslint-disable no-func-assign */
1607 SyntheticEvent = new Proxy(SyntheticEvent, {
1608 construct: function (target, args) {
1609 return this.apply(target, Object.create(target.prototype), args);
1610 },
1611 apply: function (constructor, that, args) {
1612 return new Proxy(constructor.apply(that, args), {
1613 set: function (target, prop, value) {
1614 if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
1615 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.');
1616 didWarnForAddedNewProperty = true;
1617 }
1618 target[prop] = value;
1619 return true;
1620 }
1621 });
1622 }
1623 });
1624 /*eslint-enable no-func-assign */
1625 }
1626}
1627
1628addEventPoolingTo(SyntheticEvent);
1629
1630/**
1631 * Helper to nullify syntheticEvent instance properties when destructing
1632 *
1633 * @param {String} propName
1634 * @param {?object} getVal
1635 * @return {object} defineProperty object
1636 */
1637function getPooledWarningPropertyDefinition(propName, getVal) {
1638 var isFunction = typeof getVal === 'function';
1639 return {
1640 configurable: true,
1641 set: set,
1642 get: get
1643 };
1644
1645 function set(val) {
1646 var action = isFunction ? 'setting the method' : 'setting the property';
1647 warn(action, 'This is effectively a no-op');
1648 return val;
1649 }
1650
1651 function get() {
1652 var action = isFunction ? 'accessing the method' : 'accessing the property';
1653 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1654 warn(action, result);
1655 return getVal;
1656 }
1657
1658 function warn(action, result) {
1659 var warningCondition = false;
1660 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);
1661 }
1662}
1663
1664function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1665 var EventConstructor = this;
1666 if (EventConstructor.eventPool.length) {
1667 var instance = EventConstructor.eventPool.pop();
1668 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1669 return instance;
1670 }
1671 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1672}
1673
1674function releasePooledEvent(event) {
1675 var EventConstructor = this;
1676 !(event instanceof EventConstructor) ? invariant_1(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1677 event.destructor();
1678 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1679 EventConstructor.eventPool.push(event);
1680 }
1681}
1682
1683function addEventPoolingTo(EventConstructor) {
1684 EventConstructor.eventPool = [];
1685 EventConstructor.getPooled = getPooledEvent;
1686 EventConstructor.release = releasePooledEvent;
1687}
1688
1689var SyntheticEvent$1 = SyntheticEvent;
1690
1691/**
1692 * @interface Event
1693 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1694 */
1695var SyntheticCompositionEvent = SyntheticEvent$1.extend({
1696 data: null
1697});
1698
1699/**
1700 * @interface Event
1701 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1702 * /#events-inputevents
1703 */
1704var SyntheticInputEvent = SyntheticEvent$1.extend({
1705 data: null
1706});
1707
1708var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1709var START_KEYCODE = 229;
1710
1711var canUseCompositionEvent = ExecutionEnvironment_1.canUseDOM && 'CompositionEvent' in window;
1712
1713var documentMode = null;
1714if (ExecutionEnvironment_1.canUseDOM && 'documentMode' in document) {
1715 documentMode = document.documentMode;
1716}
1717
1718// Webkit offers a very useful `textInput` event that can be used to
1719// directly represent `beforeInput`. The IE `textinput` event is not as
1720// useful, so we don't use it.
1721var canUseTextInputEvent = ExecutionEnvironment_1.canUseDOM && 'TextEvent' in window && !documentMode;
1722
1723// In IE9+, we have access to composition events, but the data supplied
1724// by the native compositionend event may be incorrect. Japanese ideographic
1725// spaces, for instance (\u3000) are not recorded correctly.
1726var useFallbackCompositionData = ExecutionEnvironment_1.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1727
1728var SPACEBAR_CODE = 32;
1729var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1730
1731// Events and their corresponding property names.
1732var eventTypes = {
1733 beforeInput: {
1734 phasedRegistrationNames: {
1735 bubbled: 'onBeforeInput',
1736 captured: 'onBeforeInputCapture'
1737 },
1738 dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste']
1739 },
1740 compositionEnd: {
1741 phasedRegistrationNames: {
1742 bubbled: 'onCompositionEnd',
1743 captured: 'onCompositionEndCapture'
1744 },
1745 dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1746 },
1747 compositionStart: {
1748 phasedRegistrationNames: {
1749 bubbled: 'onCompositionStart',
1750 captured: 'onCompositionStartCapture'
1751 },
1752 dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1753 },
1754 compositionUpdate: {
1755 phasedRegistrationNames: {
1756 bubbled: 'onCompositionUpdate',
1757 captured: 'onCompositionUpdateCapture'
1758 },
1759 dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
1760 }
1761};
1762
1763// Track whether we've ever handled a keypress on the space key.
1764var hasSpaceKeypress = false;
1765
1766/**
1767 * Return whether a native keypress event is assumed to be a command.
1768 * This is required because Firefox fires `keypress` events for key commands
1769 * (cut, copy, select-all, etc.) even though no character is inserted.
1770 */
1771function isKeypressCommand(nativeEvent) {
1772 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1773 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1774 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1775}
1776
1777/**
1778 * Translate native top level events into event types.
1779 *
1780 * @param {string} topLevelType
1781 * @return {object}
1782 */
1783function getCompositionEventType(topLevelType) {
1784 switch (topLevelType) {
1785 case 'topCompositionStart':
1786 return eventTypes.compositionStart;
1787 case 'topCompositionEnd':
1788 return eventTypes.compositionEnd;
1789 case 'topCompositionUpdate':
1790 return eventTypes.compositionUpdate;
1791 }
1792}
1793
1794/**
1795 * Does our fallback best-guess model think this event signifies that
1796 * composition has begun?
1797 *
1798 * @param {string} topLevelType
1799 * @param {object} nativeEvent
1800 * @return {boolean}
1801 */
1802function isFallbackCompositionStart(topLevelType, nativeEvent) {
1803 return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
1804}
1805
1806/**
1807 * Does our fallback mode think that this event is the end of composition?
1808 *
1809 * @param {string} topLevelType
1810 * @param {object} nativeEvent
1811 * @return {boolean}
1812 */
1813function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1814 switch (topLevelType) {
1815 case 'topKeyUp':
1816 // Command keys insert or clear IME input.
1817 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1818 case 'topKeyDown':
1819 // Expect IME keyCode on each keydown. If we get any other
1820 // code we must have exited earlier.
1821 return nativeEvent.keyCode !== START_KEYCODE;
1822 case 'topKeyPress':
1823 case 'topMouseDown':
1824 case 'topBlur':
1825 // Events are not possible without cancelling IME.
1826 return true;
1827 default:
1828 return false;
1829 }
1830}
1831
1832/**
1833 * Google Input Tools provides composition data via a CustomEvent,
1834 * with the `data` property populated in the `detail` object. If this
1835 * is available on the event object, use it. If not, this is a plain
1836 * composition event and we have nothing special to extract.
1837 *
1838 * @param {object} nativeEvent
1839 * @return {?string}
1840 */
1841function getDataFromCustomEvent(nativeEvent) {
1842 var detail = nativeEvent.detail;
1843 if (typeof detail === 'object' && 'data' in detail) {
1844 return detail.data;
1845 }
1846 return null;
1847}
1848
1849// Track the current IME composition status, if any.
1850var isComposing = false;
1851
1852/**
1853 * @return {?object} A SyntheticCompositionEvent.
1854 */
1855function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1856 var eventType = void 0;
1857 var fallbackData = void 0;
1858
1859 if (canUseCompositionEvent) {
1860 eventType = getCompositionEventType(topLevelType);
1861 } else if (!isComposing) {
1862 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1863 eventType = eventTypes.compositionStart;
1864 }
1865 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1866 eventType = eventTypes.compositionEnd;
1867 }
1868
1869 if (!eventType) {
1870 return null;
1871 }
1872
1873 if (useFallbackCompositionData) {
1874 // The current composition is stored statically and must not be
1875 // overwritten while composition continues.
1876 if (!isComposing && eventType === eventTypes.compositionStart) {
1877 isComposing = initialize(nativeEventTarget);
1878 } else if (eventType === eventTypes.compositionEnd) {
1879 if (isComposing) {
1880 fallbackData = getData();
1881 }
1882 }
1883 }
1884
1885 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1886
1887 if (fallbackData) {
1888 // Inject data generated from fallback path into the synthetic event.
1889 // This matches the property of native CompositionEventInterface.
1890 event.data = fallbackData;
1891 } else {
1892 var customData = getDataFromCustomEvent(nativeEvent);
1893 if (customData !== null) {
1894 event.data = customData;
1895 }
1896 }
1897
1898 accumulateTwoPhaseDispatches(event);
1899 return event;
1900}
1901
1902/**
1903 * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
1904 * @param {object} nativeEvent Native browser event.
1905 * @return {?string} The string corresponding to this `beforeInput` event.
1906 */
1907function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1908 switch (topLevelType) {
1909 case 'topCompositionEnd':
1910 return getDataFromCustomEvent(nativeEvent);
1911 case 'topKeyPress':
1912 /**
1913 * If native `textInput` events are available, our goal is to make
1914 * use of them. However, there is a special case: the spacebar key.
1915 * In Webkit, preventing default on a spacebar `textInput` event
1916 * cancels character insertion, but it *also* causes the browser
1917 * to fall back to its default spacebar behavior of scrolling the
1918 * page.
1919 *
1920 * Tracking at:
1921 * https://code.google.com/p/chromium/issues/detail?id=355103
1922 *
1923 * To avoid this issue, use the keypress event as if no `textInput`
1924 * event is available.
1925 */
1926 var which = nativeEvent.which;
1927 if (which !== SPACEBAR_CODE) {
1928 return null;
1929 }
1930
1931 hasSpaceKeypress = true;
1932 return SPACEBAR_CHAR;
1933
1934 case 'topTextInput':
1935 // Record the characters to be added to the DOM.
1936 var chars = nativeEvent.data;
1937
1938 // If it's a spacebar character, assume that we have already handled
1939 // it at the keypress level and bail immediately. Android Chrome
1940 // doesn't give us keycodes, so we need to blacklist it.
1941 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1942 return null;
1943 }
1944
1945 return chars;
1946
1947 default:
1948 // For other native event types, do nothing.
1949 return null;
1950 }
1951}
1952
1953/**
1954 * For browsers that do not provide the `textInput` event, extract the
1955 * appropriate string to use for SyntheticInputEvent.
1956 *
1957 * @param {string} topLevelType Record from `BrowserEventConstants`.
1958 * @param {object} nativeEvent Native browser event.
1959 * @return {?string} The fallback string for this `beforeInput` event.
1960 */
1961function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1962 // If we are currently composing (IME) and using a fallback to do so,
1963 // try to extract the composed characters from the fallback object.
1964 // If composition event is available, we extract a string only at
1965 // compositionevent, otherwise extract it at fallback events.
1966 if (isComposing) {
1967 if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1968 var chars = getData();
1969 reset();
1970 isComposing = false;
1971 return chars;
1972 }
1973 return null;
1974 }
1975
1976 switch (topLevelType) {
1977 case 'topPaste':
1978 // If a paste event occurs after a keypress, throw out the input
1979 // chars. Paste events should not lead to BeforeInput events.
1980 return null;
1981 case 'topKeyPress':
1982 /**
1983 * As of v27, Firefox may fire keypress events even when no character
1984 * will be inserted. A few possibilities:
1985 *
1986 * - `which` is `0`. Arrow keys, Esc key, etc.
1987 *
1988 * - `which` is the pressed key code, but no char is available.
1989 * Ex: 'AltGr + d` in Polish. There is no modified character for
1990 * this key combination and no character is inserted into the
1991 * document, but FF fires the keypress for char code `100` anyway.
1992 * No `input` event will occur.
1993 *
1994 * - `which` is the pressed key code, but a command combination is
1995 * being used. Ex: `Cmd+C`. No character is inserted, and no
1996 * `input` event will occur.
1997 */
1998 if (!isKeypressCommand(nativeEvent)) {
1999 // IE fires the `keypress` event when a user types an emoji via
2000 // Touch keyboard of Windows. In such a case, the `char` property
2001 // holds an emoji character like `\uD83D\uDE0A`. Because its length
2002 // is 2, the property `which` does not represent an emoji correctly.
2003 // In such a case, we directly return the `char` property instead of
2004 // using `which`.
2005 if (nativeEvent.char && nativeEvent.char.length > 1) {
2006 return nativeEvent.char;
2007 } else if (nativeEvent.which) {
2008 return String.fromCharCode(nativeEvent.which);
2009 }
2010 }
2011 return null;
2012 case 'topCompositionEnd':
2013 return useFallbackCompositionData ? null : nativeEvent.data;
2014 default:
2015 return null;
2016 }
2017}
2018
2019/**
2020 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2021 * `textInput` or fallback behavior.
2022 *
2023 * @return {?object} A SyntheticInputEvent.
2024 */
2025function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2026 var chars = void 0;
2027
2028 if (canUseTextInputEvent) {
2029 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2030 } else {
2031 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2032 }
2033
2034 // If no characters are being inserted, no BeforeInput event should
2035 // be fired.
2036 if (!chars) {
2037 return null;
2038 }
2039
2040 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2041
2042 event.data = chars;
2043 accumulateTwoPhaseDispatches(event);
2044 return event;
2045}
2046
2047/**
2048 * Create an `onBeforeInput` event to match
2049 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2050 *
2051 * This event plugin is based on the native `textInput` event
2052 * available in Chrome, Safari, Opera, and IE. This event fires after
2053 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2054 *
2055 * `beforeInput` is spec'd but not implemented in any browsers, and
2056 * the `input` event does not provide any useful information about what has
2057 * actually been added, contrary to the spec. Thus, `textInput` is the best
2058 * available event to identify the characters that have actually been inserted
2059 * into the target node.
2060 *
2061 * This plugin is also responsible for emitting `composition` events, thus
2062 * allowing us to share composition fallback code for both `beforeInput` and
2063 * `composition` event types.
2064 */
2065var BeforeInputEventPlugin = {
2066 eventTypes: eventTypes,
2067
2068 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2069 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2070
2071 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2072
2073 if (composition === null) {
2074 return beforeInput;
2075 }
2076
2077 if (beforeInput === null) {
2078 return composition;
2079 }
2080
2081 return [composition, beforeInput];
2082 }
2083};
2084
2085// Use to restore controlled state after a change event has fired.
2086
2087var fiberHostComponent = null;
2088
2089var ReactControlledComponentInjection = {
2090 injectFiberControlledHostComponent: function (hostComponentImpl) {
2091 // The fiber implementation doesn't use dynamic dispatch so we need to
2092 // inject the implementation.
2093 fiberHostComponent = hostComponentImpl;
2094 }
2095};
2096
2097var restoreTarget = null;
2098var restoreQueue = null;
2099
2100function restoreStateOfTarget(target) {
2101 // We perform this translation at the end of the event loop so that we
2102 // always receive the correct fiber here
2103 var internalInstance = getInstanceFromNode(target);
2104 if (!internalInstance) {
2105 // Unmounted
2106 return;
2107 }
2108 !(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;
2109 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2110 fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props);
2111}
2112
2113var injection$2 = ReactControlledComponentInjection;
2114
2115function enqueueStateRestore(target) {
2116 if (restoreTarget) {
2117 if (restoreQueue) {
2118 restoreQueue.push(target);
2119 } else {
2120 restoreQueue = [target];
2121 }
2122 } else {
2123 restoreTarget = target;
2124 }
2125}
2126
2127function restoreStateIfNeeded() {
2128 if (!restoreTarget) {
2129 return;
2130 }
2131 var target = restoreTarget;
2132 var queuedTargets = restoreQueue;
2133 restoreTarget = null;
2134 restoreQueue = null;
2135
2136 restoreStateOfTarget(target);
2137 if (queuedTargets) {
2138 for (var i = 0; i < queuedTargets.length; i++) {
2139 restoreStateOfTarget(queuedTargets[i]);
2140 }
2141 }
2142}
2143
2144var ReactControlledComponent = Object.freeze({
2145 injection: injection$2,
2146 enqueueStateRestore: enqueueStateRestore,
2147 restoreStateIfNeeded: restoreStateIfNeeded
2148});
2149
2150// Used as a way to call batchedUpdates when we don't have a reference to
2151// the renderer. Such as when we're dispatching events or if third party
2152// libraries need to call batchedUpdates. Eventually, this API will go away when
2153// everything is batched by default. We'll then have a similar API to opt-out of
2154// scheduled work and instead do synchronous work.
2155
2156// Defaults
2157var fiberBatchedUpdates = function (fn, bookkeeping) {
2158 return fn(bookkeeping);
2159};
2160
2161var isNestingBatched = false;
2162function batchedUpdates(fn, bookkeeping) {
2163 if (isNestingBatched) {
2164 // If we are currently inside another batch, we need to wait until it
2165 // fully completes before restoring state. Therefore, we add the target to
2166 // a queue of work.
2167 return fiberBatchedUpdates(fn, bookkeeping);
2168 }
2169 isNestingBatched = true;
2170 try {
2171 return fiberBatchedUpdates(fn, bookkeeping);
2172 } finally {
2173 // Here we wait until all updates have propagated, which is important
2174 // when using controlled components within layers:
2175 // https://github.com/facebook/react/issues/1698
2176 // Then we restore state of any controlled component.
2177 isNestingBatched = false;
2178 restoreStateIfNeeded();
2179 }
2180}
2181
2182var ReactGenericBatchingInjection = {
2183 injectFiberBatchedUpdates: function (_batchedUpdates) {
2184 fiberBatchedUpdates = _batchedUpdates;
2185 }
2186};
2187
2188var injection$3 = ReactGenericBatchingInjection;
2189
2190/**
2191 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2192 */
2193var supportedInputTypes = {
2194 color: true,
2195 date: true,
2196 datetime: true,
2197 'datetime-local': true,
2198 email: true,
2199 month: true,
2200 number: true,
2201 password: true,
2202 range: true,
2203 search: true,
2204 tel: true,
2205 text: true,
2206 time: true,
2207 url: true,
2208 week: true
2209};
2210
2211function isTextInputElement(elem) {
2212 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2213
2214 if (nodeName === 'input') {
2215 return !!supportedInputTypes[elem.type];
2216 }
2217
2218 if (nodeName === 'textarea') {
2219 return true;
2220 }
2221
2222 return false;
2223}
2224
2225/**
2226 * HTML nodeType values that represent the type of the node
2227 */
2228
2229var ELEMENT_NODE = 1;
2230var TEXT_NODE = 3;
2231var COMMENT_NODE = 8;
2232var DOCUMENT_NODE = 9;
2233var DOCUMENT_FRAGMENT_NODE = 11;
2234
2235/**
2236 * Gets the target node from a native browser event by accounting for
2237 * inconsistencies in browser DOM APIs.
2238 *
2239 * @param {object} nativeEvent Native browser event.
2240 * @return {DOMEventTarget} Target node.
2241 */
2242function getEventTarget(nativeEvent) {
2243 var target = nativeEvent.target || window;
2244
2245 // Normalize SVG <use> element events #4963
2246 if (target.correspondingUseElement) {
2247 target = target.correspondingUseElement;
2248 }
2249
2250 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2251 // @see http://www.quirksmode.org/js/events_properties.html
2252 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2253}
2254
2255/**
2256 * Checks if an event is supported in the current execution environment.
2257 *
2258 * NOTE: This will not work correctly for non-generic events such as `change`,
2259 * `reset`, `load`, `error`, and `select`.
2260 *
2261 * Borrows from Modernizr.
2262 *
2263 * @param {string} eventNameSuffix Event name, e.g. "click".
2264 * @param {?boolean} capture Check if the capture phase is supported.
2265 * @return {boolean} True if the event is supported.
2266 * @internal
2267 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2268 */
2269function isEventSupported(eventNameSuffix, capture) {
2270 if (!ExecutionEnvironment_1.canUseDOM || capture && !('addEventListener' in document)) {
2271 return false;
2272 }
2273
2274 var eventName = 'on' + eventNameSuffix;
2275 var isSupported = eventName in document;
2276
2277 if (!isSupported) {
2278 var element = document.createElement('div');
2279 element.setAttribute(eventName, 'return;');
2280 isSupported = typeof element[eventName] === 'function';
2281 }
2282
2283 return isSupported;
2284}
2285
2286function isCheckable(elem) {
2287 var type = elem.type;
2288 var nodeName = elem.nodeName;
2289 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2290}
2291
2292function getTracker(node) {
2293 return node._valueTracker;
2294}
2295
2296function detachTracker(node) {
2297 node._valueTracker = null;
2298}
2299
2300function getValueFromNode(node) {
2301 var value = '';
2302 if (!node) {
2303 return value;
2304 }
2305
2306 if (isCheckable(node)) {
2307 value = node.checked ? 'true' : 'false';
2308 } else {
2309 value = node.value;
2310 }
2311
2312 return value;
2313}
2314
2315function trackValueOnNode(node) {
2316 var valueField = isCheckable(node) ? 'checked' : 'value';
2317 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2318
2319 var currentValue = '' + node[valueField];
2320
2321 // if someone has already defined a value or Safari, then bail
2322 // and don't track value will cause over reporting of changes,
2323 // but it's better then a hard failure
2324 // (needed for certain tests that spyOn input values and Safari)
2325 if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2326 return;
2327 }
2328
2329 Object.defineProperty(node, valueField, {
2330 configurable: true,
2331 get: function () {
2332 return descriptor.get.call(this);
2333 },
2334 set: function (value) {
2335 currentValue = '' + value;
2336 descriptor.set.call(this, value);
2337 }
2338 });
2339 // We could've passed this the first time
2340 // but it triggers a bug in IE11 and Edge 14/15.
2341 // Calling defineProperty() again should be equivalent.
2342 // https://github.com/facebook/react/issues/11768
2343 Object.defineProperty(node, valueField, {
2344 enumerable: descriptor.enumerable
2345 });
2346
2347 var tracker = {
2348 getValue: function () {
2349 return currentValue;
2350 },
2351 setValue: function (value) {
2352 currentValue = '' + value;
2353 },
2354 stopTracking: function () {
2355 detachTracker(node);
2356 delete node[valueField];
2357 }
2358 };
2359 return tracker;
2360}
2361
2362function track(node) {
2363 if (getTracker(node)) {
2364 return;
2365 }
2366
2367 // TODO: Once it's just Fiber we can move this to node._wrapperState
2368 node._valueTracker = trackValueOnNode(node);
2369}
2370
2371function updateValueIfChanged(node) {
2372 if (!node) {
2373 return false;
2374 }
2375
2376 var tracker = getTracker(node);
2377 // if there is no tracker at this point it's unlikely
2378 // that trying again will succeed
2379 if (!tracker) {
2380 return true;
2381 }
2382
2383 var lastValue = tracker.getValue();
2384 var nextValue = getValueFromNode(node);
2385 if (nextValue !== lastValue) {
2386 tracker.setValue(nextValue);
2387 return true;
2388 }
2389 return false;
2390}
2391
2392var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2393
2394var ReactCurrentOwner = ReactInternals$1.ReactCurrentOwner;
2395var ReactDebugCurrentFrame = ReactInternals$1.ReactDebugCurrentFrame;
2396
2397var describeComponentFrame = function (name, source, ownerName) {
2398 return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
2399};
2400
2401// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2402// nor polyfill, then a plain number is used for performance.
2403var hasSymbol = typeof Symbol === 'function' && Symbol['for'];
2404
2405var REACT_ELEMENT_TYPE = hasSymbol ? Symbol['for']('react.element') : 0xeac7;
2406var REACT_CALL_TYPE = hasSymbol ? Symbol['for']('react.call') : 0xeac8;
2407var REACT_RETURN_TYPE = hasSymbol ? Symbol['for']('react.return') : 0xeac9;
2408var REACT_PORTAL_TYPE = hasSymbol ? Symbol['for']('react.portal') : 0xeaca;
2409var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb;
2410
2411var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2412var FAUX_ITERATOR_SYMBOL = '@@iterator';
2413
2414function getIteratorFn(maybeIterable) {
2415 if (maybeIterable === null || typeof maybeIterable === 'undefined') {
2416 return null;
2417 }
2418 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2419 if (typeof maybeIterator === 'function') {
2420 return maybeIterator;
2421 }
2422 return null;
2423}
2424
2425function getComponentName(fiber) {
2426 var type = fiber.type;
2427
2428 if (typeof type === 'function') {
2429 return type.displayName || type.name;
2430 }
2431 if (typeof type === 'string') {
2432 return type;
2433 }
2434 switch (type) {
2435 case REACT_FRAGMENT_TYPE:
2436 return 'ReactFragment';
2437 case REACT_PORTAL_TYPE:
2438 return 'ReactPortal';
2439 case REACT_CALL_TYPE:
2440 return 'ReactCall';
2441 case REACT_RETURN_TYPE:
2442 return 'ReactReturn';
2443 }
2444 return null;
2445}
2446
2447function describeFiber(fiber) {
2448 switch (fiber.tag) {
2449 case IndeterminateComponent:
2450 case FunctionalComponent:
2451 case ClassComponent:
2452 case HostComponent:
2453 var owner = fiber._debugOwner;
2454 var source = fiber._debugSource;
2455 var name = getComponentName(fiber);
2456 var ownerName = null;
2457 if (owner) {
2458 ownerName = getComponentName(owner);
2459 }
2460 return describeComponentFrame(name, source, ownerName);
2461 default:
2462 return '';
2463 }
2464}
2465
2466// This function can only be called with a work-in-progress fiber and
2467// only during begin or complete phase. Do not call it under any other
2468// circumstances.
2469function getStackAddendumByWorkInProgressFiber(workInProgress) {
2470 var info = '';
2471 var node = workInProgress;
2472 do {
2473 info += describeFiber(node);
2474 // Otherwise this return pointer might point to the wrong tree:
2475 node = node['return'];
2476 } while (node);
2477 return info;
2478}
2479
2480function getCurrentFiberOwnerName$1() {
2481 {
2482 var fiber = ReactDebugCurrentFiber.current;
2483 if (fiber === null) {
2484 return null;
2485 }
2486 var owner = fiber._debugOwner;
2487 if (owner !== null && typeof owner !== 'undefined') {
2488 return getComponentName(owner);
2489 }
2490 }
2491 return null;
2492}
2493
2494function getCurrentFiberStackAddendum$1() {
2495 {
2496 var fiber = ReactDebugCurrentFiber.current;
2497 if (fiber === null) {
2498 return null;
2499 }
2500 // Safe because if current fiber exists, we are reconciling,
2501 // and it is guaranteed to be the work-in-progress version.
2502 return getStackAddendumByWorkInProgressFiber(fiber);
2503 }
2504 return null;
2505}
2506
2507function resetCurrentFiber() {
2508 ReactDebugCurrentFrame.getCurrentStack = null;
2509 ReactDebugCurrentFiber.current = null;
2510 ReactDebugCurrentFiber.phase = null;
2511}
2512
2513function setCurrentFiber(fiber) {
2514 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1;
2515 ReactDebugCurrentFiber.current = fiber;
2516 ReactDebugCurrentFiber.phase = null;
2517}
2518
2519function setCurrentPhase(phase) {
2520 ReactDebugCurrentFiber.phase = phase;
2521}
2522
2523var ReactDebugCurrentFiber = {
2524 current: null,
2525 phase: null,
2526 resetCurrentFiber: resetCurrentFiber,
2527 setCurrentFiber: setCurrentFiber,
2528 setCurrentPhase: setCurrentPhase,
2529 getCurrentFiberOwnerName: getCurrentFiberOwnerName$1,
2530 getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1
2531};
2532
2533// A reserved attribute.
2534// It is handled by React separately and shouldn't be written to the DOM.
2535var RESERVED = 0;
2536
2537// A simple string attribute.
2538// Attributes that aren't in the whitelist are presumed to have this type.
2539var STRING = 1;
2540
2541// A string attribute that accepts booleans in React. In HTML, these are called
2542// "enumerated" attributes with "true" and "false" as possible values.
2543// When true, it should be set to a "true" string.
2544// When false, it should be set to a "false" string.
2545var BOOLEANISH_STRING = 2;
2546
2547// A real boolean attribute.
2548// When true, it should be present (set either to an empty string or its name).
2549// When false, it should be omitted.
2550var BOOLEAN = 3;
2551
2552// An attribute that can be used as a flag as well as with a value.
2553// When true, it should be present (set either to an empty string or its name).
2554// When false, it should be omitted.
2555// For any other value, should be present with that value.
2556var OVERLOADED_BOOLEAN = 4;
2557
2558// An attribute that must be numeric or parse as a numeric.
2559// When falsy, it should be removed.
2560var NUMERIC = 5;
2561
2562// An attribute that must be positive numeric or parse as a positive numeric.
2563// When falsy, it should be removed.
2564var POSITIVE_NUMERIC = 6;
2565
2566/* eslint-disable max-len */
2567var 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';
2568/* eslint-enable max-len */
2569var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2570
2571
2572var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2573var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2574
2575var illegalAttributeNameCache = {};
2576var validatedAttributeNameCache = {};
2577
2578function isAttributeNameSafe(attributeName) {
2579 if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
2580 return true;
2581 }
2582 if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
2583 return false;
2584 }
2585 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2586 validatedAttributeNameCache[attributeName] = true;
2587 return true;
2588 }
2589 illegalAttributeNameCache[attributeName] = true;
2590 {
2591 warning_1(false, 'Invalid attribute name: `%s`', attributeName);
2592 }
2593 return false;
2594}
2595
2596function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2597 if (propertyInfo !== null) {
2598 return propertyInfo.type === RESERVED;
2599 }
2600 if (isCustomComponentTag) {
2601 return false;
2602 }
2603 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2604 return true;
2605 }
2606 return false;
2607}
2608
2609function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2610 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2611 return false;
2612 }
2613 switch (typeof value) {
2614 case 'function':
2615 // $FlowIssue symbol is perfectly valid here
2616 case 'symbol':
2617 // eslint-disable-line
2618 return true;
2619 case 'boolean':
2620 {
2621 if (isCustomComponentTag) {
2622 return false;
2623 }
2624 if (propertyInfo !== null) {
2625 return !propertyInfo.acceptsBooleans;
2626 } else {
2627 var prefix = name.toLowerCase().slice(0, 5);
2628 return prefix !== 'data-' && prefix !== 'aria-';
2629 }
2630 }
2631 default:
2632 return false;
2633 }
2634}
2635
2636function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2637 if (value === null || typeof value === 'undefined') {
2638 return true;
2639 }
2640 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2641 return true;
2642 }
2643 if (propertyInfo !== null) {
2644 switch (propertyInfo.type) {
2645 case BOOLEAN:
2646 return !value;
2647 case OVERLOADED_BOOLEAN:
2648 return value === false;
2649 case NUMERIC:
2650 return isNaN(value);
2651 case POSITIVE_NUMERIC:
2652 return isNaN(value) || value < 1;
2653 }
2654 }
2655 return false;
2656}
2657
2658function getPropertyInfo(name) {
2659 return properties.hasOwnProperty(name) ? properties[name] : null;
2660}
2661
2662function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2663 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2664 this.attributeName = attributeName;
2665 this.attributeNamespace = attributeNamespace;
2666 this.mustUseProperty = mustUseProperty;
2667 this.propertyName = name;
2668 this.type = type;
2669}
2670
2671// When adding attributes to this list, be sure to also add them to
2672// the `possibleStandardNames` module to ensure casing and incorrect
2673// name warnings.
2674var properties = {};
2675
2676// These props are reserved by React. They shouldn't be written to the DOM.
2677['children', 'dangerouslySetInnerHTML',
2678// TODO: This prevents the assignment of defaultValue to regular
2679// elements (not just inputs). Now that ReactDOMInput assigns to the
2680// defaultValue property -- do we need this?
2681'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2682 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2683 name, // attributeName
2684 null);
2685});
2686
2687// A few React string attributes have a different name.
2688// This is a mapping from React prop names to the attribute names.
2689new Map([['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']]).forEach(function (attributeName, name) {
2690 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2691 attributeName, // attributeName
2692 null);
2693});
2694
2695// These are "enumerated" HTML attributes that accept "true" and "false".
2696// In React, we let users pass `true` and `false` even though technically
2697// these aren't boolean attributes (they are coerced to strings).
2698['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2699 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2700 name.toLowerCase(), // attributeName
2701 null);
2702});
2703
2704// These are "enumerated" SVG attributes that accept "true" and "false".
2705// In React, we let users pass `true` and `false` even though technically
2706// these aren't boolean attributes (they are coerced to strings).
2707// Since these are SVG attributes, their attribute names are case-sensitive.
2708['autoReverse', 'externalResourcesRequired', 'preserveAlpha'].forEach(function (name) {
2709 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2710 name, // attributeName
2711 null);
2712});
2713
2714// These are HTML boolean attributes.
2715['allowFullScreen', 'async',
2716// Note: there is a special case that prevents it from being written to the DOM
2717// on the client side because the browsers are inconsistent. Instead we call focus().
2718'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2719// Microdata
2720'itemScope'].forEach(function (name) {
2721 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2722 name.toLowerCase(), // attributeName
2723 null);
2724});
2725
2726// These are the few React props that we set as DOM properties
2727// rather than attributes. These are all booleans.
2728['checked',
2729// Note: `option.selected` is not updated if `select.multiple` is
2730// disabled with `removeAttribute`. We have special logic for handling this.
2731'multiple', 'muted', 'selected'].forEach(function (name) {
2732 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2733 name.toLowerCase(), // attributeName
2734 null);
2735});
2736
2737// These are HTML attributes that are "overloaded booleans": they behave like
2738// booleans, but can also accept a string value.
2739['capture', 'download'].forEach(function (name) {
2740 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2741 name.toLowerCase(), // attributeName
2742 null);
2743});
2744
2745// These are HTML attributes that must be positive numbers.
2746['cols', 'rows', 'size', 'span'].forEach(function (name) {
2747 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2748 name.toLowerCase(), // attributeName
2749 null);
2750});
2751
2752// These are HTML attributes that must be numbers.
2753['rowSpan', 'start'].forEach(function (name) {
2754 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2755 name.toLowerCase(), // attributeName
2756 null);
2757});
2758
2759var CAMELIZE = /[\-\:]([a-z])/g;
2760var capitalize = function (token) {
2761 return token[1].toUpperCase();
2762};
2763
2764// This is a list of all SVG attributes that need special casing, namespacing,
2765// or boolean value assignment. Regular attributes that just accept strings
2766// and have the same names are omitted, just like in the HTML whitelist.
2767// Some of these attributes can be hard to find. This list was created by
2768// scrapping the MDN documentation.
2769['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) {
2770 var name = attributeName.replace(CAMELIZE, capitalize);
2771 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2772 attributeName, null);
2773});
2774
2775// String SVG attributes with the xlink namespace.
2776['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2777 var name = attributeName.replace(CAMELIZE, capitalize);
2778 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2779 attributeName, 'http://www.w3.org/1999/xlink');
2780});
2781
2782// String SVG attributes with the xml namespace.
2783['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2784 var name = attributeName.replace(CAMELIZE, capitalize);
2785 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2786 attributeName, 'http://www.w3.org/XML/1998/namespace');
2787});
2788
2789// Special case: this attribute exists both in HTML and SVG.
2790// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2791// its React `tabIndex` name, like we do for attributes that exist only in HTML.
2792properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2793'tabindex', // attributeName
2794null);
2795
2796/**
2797 * Get the value for a property on a node. Only used in DEV for SSR validation.
2798 * The "expected" argument is used as a hint of what the expected value is.
2799 * Some properties have multiple equivalent values.
2800 */
2801function getValueForProperty(node, name, expected, propertyInfo) {
2802 {
2803 if (propertyInfo.mustUseProperty) {
2804 var propertyName = propertyInfo.propertyName;
2805
2806 return node[propertyName];
2807 } else {
2808 var attributeName = propertyInfo.attributeName;
2809
2810 var stringValue = null;
2811
2812 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2813 if (node.hasAttribute(attributeName)) {
2814 var value = node.getAttribute(attributeName);
2815 if (value === '') {
2816 return true;
2817 }
2818 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2819 return value;
2820 }
2821 if (value === '' + expected) {
2822 return expected;
2823 }
2824 return value;
2825 }
2826 } else if (node.hasAttribute(attributeName)) {
2827 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2828 // We had an attribute but shouldn't have had one, so read it
2829 // for the error message.
2830 return node.getAttribute(attributeName);
2831 }
2832 if (propertyInfo.type === BOOLEAN) {
2833 // If this was a boolean, it doesn't matter what the value is
2834 // the fact that we have it is the same as the expected.
2835 return expected;
2836 }
2837 // Even if this property uses a namespace we use getAttribute
2838 // because we assume its namespaced name is the same as our config.
2839 // To use getAttributeNS we need the local name which we don't have
2840 // in our config atm.
2841 stringValue = node.getAttribute(attributeName);
2842 }
2843
2844 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2845 return stringValue === null ? expected : stringValue;
2846 } else if (stringValue === '' + expected) {
2847 return expected;
2848 } else {
2849 return stringValue;
2850 }
2851 }
2852 }
2853}
2854
2855/**
2856 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2857 * The third argument is used as a hint of what the expected value is. Some
2858 * attributes have multiple equivalent values.
2859 */
2860function getValueForAttribute(node, name, expected) {
2861 {
2862 if (!isAttributeNameSafe(name)) {
2863 return;
2864 }
2865 if (!node.hasAttribute(name)) {
2866 return expected === undefined ? undefined : null;
2867 }
2868 var value = node.getAttribute(name);
2869 if (value === '' + expected) {
2870 return expected;
2871 }
2872 return value;
2873 }
2874}
2875
2876/**
2877 * Sets the value for a property on a node.
2878 *
2879 * @param {DOMElement} node
2880 * @param {string} name
2881 * @param {*} value
2882 */
2883function setValueForProperty(node, name, value, isCustomComponentTag) {
2884 var propertyInfo = getPropertyInfo(name);
2885 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2886 return;
2887 }
2888 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2889 value = null;
2890 }
2891 // If the prop isn't in the special list, treat it as a simple attribute.
2892 if (isCustomComponentTag || propertyInfo === null) {
2893 if (isAttributeNameSafe(name)) {
2894 var _attributeName = name;
2895 if (value === null) {
2896 node.removeAttribute(_attributeName);
2897 } else {
2898 node.setAttribute(_attributeName, '' + value);
2899 }
2900 }
2901 return;
2902 }
2903 var mustUseProperty = propertyInfo.mustUseProperty;
2904
2905 if (mustUseProperty) {
2906 var propertyName = propertyInfo.propertyName;
2907
2908 if (value === null) {
2909 var type = propertyInfo.type;
2910
2911 node[propertyName] = type === BOOLEAN ? false : '';
2912 } else {
2913 // Contrary to `setAttribute`, object properties are properly
2914 // `toString`ed by IE8/9.
2915 node[propertyName] = value;
2916 }
2917 return;
2918 }
2919 // The rest are treated as attributes with special cases.
2920 var attributeName = propertyInfo.attributeName,
2921 attributeNamespace = propertyInfo.attributeNamespace;
2922
2923 if (value === null) {
2924 node.removeAttribute(attributeName);
2925 } else {
2926 var _type = propertyInfo.type;
2927
2928 var attributeValue = void 0;
2929 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
2930 attributeValue = '';
2931 } else {
2932 // `setAttribute` with objects becomes only `[object]` in IE8/9,
2933 // ('' + value) makes it output the correct toString()-value.
2934 attributeValue = '' + value;
2935 }
2936 if (attributeNamespace) {
2937 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
2938 } else {
2939 node.setAttribute(attributeName, attributeValue);
2940 }
2941 }
2942}
2943
2944/**
2945 * Copyright (c) 2013-present, Facebook, Inc.
2946 *
2947 * This source code is licensed under the MIT license found in the
2948 * LICENSE file in the root directory of this source tree.
2949 */
2950
2951
2952
2953var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
2954
2955var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
2956
2957/**
2958 * Copyright (c) 2013-present, Facebook, Inc.
2959 *
2960 * This source code is licensed under the MIT license found in the
2961 * LICENSE file in the root directory of this source tree.
2962 */
2963
2964
2965
2966{
2967 var invariant$2 = invariant_1;
2968 var warning$2 = warning_1;
2969 var ReactPropTypesSecret = ReactPropTypesSecret_1;
2970 var loggedTypeFailures = {};
2971}
2972
2973/**
2974 * Assert that the values match with the type specs.
2975 * Error messages are memorized and will only be shown once.
2976 *
2977 * @param {object} typeSpecs Map of name to a ReactPropType
2978 * @param {object} values Runtime values that need to be type-checked
2979 * @param {string} location e.g. "prop", "context", "child context"
2980 * @param {string} componentName Name of the component for error messages.
2981 * @param {?Function} getStack Returns the component stack.
2982 * @private
2983 */
2984function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
2985 {
2986 for (var typeSpecName in typeSpecs) {
2987 if (typeSpecs.hasOwnProperty(typeSpecName)) {
2988 var error;
2989 // Prop type validation may throw. In case they do, we don't want to
2990 // fail the render phase where it didn't fail before. So we log it.
2991 // After these have been cleaned up, we'll let them throw.
2992 try {
2993 // This is intentionally an invariant that gets caught. It's the same
2994 // behavior as without this statement except with a better message.
2995 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]);
2996 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
2997 } catch (ex) {
2998 error = ex;
2999 }
3000 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);
3001 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
3002 // Only monitor this failure once because there tends to be a lot of the
3003 // same error.
3004 loggedTypeFailures[error.message] = true;
3005
3006 var stack = getStack ? getStack() : '';
3007
3008 warning$2(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
3009 }
3010 }
3011 }
3012 }
3013}
3014
3015var checkPropTypes_1 = checkPropTypes;
3016
3017var ReactControlledValuePropTypes = {
3018 checkPropTypes: null
3019};
3020
3021{
3022 var hasReadOnlyValue = {
3023 button: true,
3024 checkbox: true,
3025 image: true,
3026 hidden: true,
3027 radio: true,
3028 reset: true,
3029 submit: true
3030 };
3031
3032 var propTypes = {
3033 value: function (props, propName, componentName) {
3034 if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
3035 return null;
3036 }
3037 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`.');
3038 },
3039 checked: function (props, propName, componentName) {
3040 if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
3041 return null;
3042 }
3043 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`.');
3044 }
3045 };
3046
3047 /**
3048 * Provide a linked `value` attribute for controlled forms. You should not use
3049 * this outside of the ReactDOM controlled form components.
3050 */
3051 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) {
3052 checkPropTypes_1(propTypes, props, 'prop', tagName, getStack);
3053 };
3054}
3055
3056// TODO: direct imports like some-package/src/* are bad. Fix me.
3057var getCurrentFiberOwnerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
3058var getCurrentFiberStackAddendum = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
3059
3060var didWarnValueDefaultValue = false;
3061var didWarnCheckedDefaultChecked = false;
3062var didWarnControlledToUncontrolled = false;
3063var didWarnUncontrolledToControlled = false;
3064
3065function isControlled(props) {
3066 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3067 return usesChecked ? props.checked != null : props.value != null;
3068}
3069
3070/**
3071 * Implements an <input> host component that allows setting these optional
3072 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3073 *
3074 * If `checked` or `value` are not supplied (or null/undefined), user actions
3075 * that affect the checked state or value will trigger updates to the element.
3076 *
3077 * If they are supplied (and not null/undefined), the rendered element will not
3078 * trigger updates to the element. Instead, the props must change in order for
3079 * the rendered element to be updated.
3080 *
3081 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3082 * with an empty value (or `defaultValue`).
3083 *
3084 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3085 */
3086
3087function getHostProps(element, props) {
3088 var node = element;
3089 var checked = props.checked;
3090
3091 var hostProps = _assign({}, props, {
3092 defaultChecked: undefined,
3093 defaultValue: undefined,
3094 value: undefined,
3095 checked: checked != null ? checked : node._wrapperState.initialChecked
3096 });
3097
3098 return hostProps;
3099}
3100
3101function initWrapperState(element, props) {
3102 {
3103 ReactControlledValuePropTypes.checkPropTypes('input', props, getCurrentFiberStackAddendum);
3104
3105 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3106 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);
3107 didWarnCheckedDefaultChecked = true;
3108 }
3109 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3110 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);
3111 didWarnValueDefaultValue = true;
3112 }
3113 }
3114
3115 var node = element;
3116 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3117
3118 node._wrapperState = {
3119 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3120 initialValue: getSafeValue(props.value != null ? props.value : defaultValue),
3121 controlled: isControlled(props)
3122 };
3123}
3124
3125function updateChecked(element, props) {
3126 var node = element;
3127 var checked = props.checked;
3128 if (checked != null) {
3129 setValueForProperty(node, 'checked', checked, false);
3130 }
3131}
3132
3133function updateWrapper(element, props) {
3134 var node = element;
3135 {
3136 var _controlled = isControlled(props);
3137
3138 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3139 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());
3140 didWarnUncontrolledToControlled = true;
3141 }
3142 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3143 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());
3144 didWarnControlledToUncontrolled = true;
3145 }
3146 }
3147
3148 updateChecked(element, props);
3149
3150 var value = getSafeValue(props.value);
3151
3152 if (value != null) {
3153 if (props.type === 'number') {
3154 if (value === 0 && node.value === '' ||
3155 // eslint-disable-next-line
3156 node.value != value) {
3157 node.value = '' + value;
3158 }
3159 } else if (node.value !== '' + value) {
3160 node.value = '' + value;
3161 }
3162 }
3163
3164 if (props.hasOwnProperty('value')) {
3165 setDefaultValue(node, props.type, value);
3166 } else if (props.hasOwnProperty('defaultValue')) {
3167 setDefaultValue(node, props.type, getSafeValue(props.defaultValue));
3168 }
3169
3170 if (props.checked == null && props.defaultChecked != null) {
3171 node.defaultChecked = !!props.defaultChecked;
3172 }
3173}
3174
3175function postMountWrapper(element, props) {
3176 var node = element;
3177
3178 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3179 // Do not assign value if it is already set. This prevents user text input
3180 // from being lost during SSR hydration.
3181 if (node.value === '') {
3182 node.value = '' + node._wrapperState.initialValue;
3183 }
3184
3185 // value must be assigned before defaultValue. This fixes an issue where the
3186 // visually displayed value of date inputs disappears on mobile Safari and Chrome:
3187 // https://github.com/facebook/react/issues/7233
3188 node.defaultValue = '' + node._wrapperState.initialValue;
3189 }
3190
3191 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3192 // this is needed to work around a chrome bug where setting defaultChecked
3193 // will sometimes influence the value of checked (even after detachment).
3194 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3195 // We need to temporarily unset name to avoid disrupting radio button groups.
3196 var name = node.name;
3197 if (name !== '') {
3198 node.name = '';
3199 }
3200 node.defaultChecked = !node.defaultChecked;
3201 node.defaultChecked = !node.defaultChecked;
3202 if (name !== '') {
3203 node.name = name;
3204 }
3205}
3206
3207function restoreControlledState(element, props) {
3208 var node = element;
3209 updateWrapper(node, props);
3210 updateNamedCousins(node, props);
3211}
3212
3213function updateNamedCousins(rootNode, props) {
3214 var name = props.name;
3215 if (props.type === 'radio' && name != null) {
3216 var queryRoot = rootNode;
3217
3218 while (queryRoot.parentNode) {
3219 queryRoot = queryRoot.parentNode;
3220 }
3221
3222 // If `rootNode.form` was non-null, then we could try `form.elements`,
3223 // but that sometimes behaves strangely in IE8. We could also try using
3224 // `form.getElementsByName`, but that will only return direct children
3225 // and won't include inputs that use the HTML5 `form=` attribute. Since
3226 // the input might not even be in a form. It might not even be in the
3227 // document. Let's just use the local `querySelectorAll` to ensure we don't
3228 // miss anything.
3229 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3230
3231 for (var i = 0; i < group.length; i++) {
3232 var otherNode = group[i];
3233 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3234 continue;
3235 }
3236 // This will throw if radio buttons rendered by different copies of React
3237 // and the same name are rendered into the same form (same as #1939).
3238 // That's probably okay; we don't support it just as we don't support
3239 // mixing React radio buttons with non-React ones.
3240 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3241 !otherProps ? invariant_1(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3242
3243 // We need update the tracked value on the named cousin since the value
3244 // was changed but the input saw no event or value set
3245 updateValueIfChanged(otherNode);
3246
3247 // If this is a controlled radio button group, forcing the input that
3248 // was previously checked to update will cause it to be come re-checked
3249 // as appropriate.
3250 updateWrapper(otherNode, otherProps);
3251 }
3252 }
3253}
3254
3255// In Chrome, assigning defaultValue to certain input types triggers input validation.
3256// For number inputs, the display value loses trailing decimal points. For email inputs,
3257// Chrome raises "The specified value <x> is not a valid email address".
3258//
3259// Here we check to see if the defaultValue has actually changed, avoiding these problems
3260// when the user is inputting text
3261//
3262// https://github.com/facebook/react/issues/7253
3263function setDefaultValue(node, type, value) {
3264 if (
3265 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3266 type !== 'number' || node.ownerDocument.activeElement !== node) {
3267 if (value == null) {
3268 node.defaultValue = '' + node._wrapperState.initialValue;
3269 } else if (node.defaultValue !== '' + value) {
3270 node.defaultValue = '' + value;
3271 }
3272 }
3273}
3274
3275function getSafeValue(value) {
3276 switch (typeof value) {
3277 case 'boolean':
3278 case 'number':
3279 case 'object':
3280 case 'string':
3281 case 'undefined':
3282 return value;
3283 default:
3284 // function, symbol are assigned as empty strings
3285 return '';
3286 }
3287}
3288
3289var eventTypes$1 = {
3290 change: {
3291 phasedRegistrationNames: {
3292 bubbled: 'onChange',
3293 captured: 'onChangeCapture'
3294 },
3295 dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange']
3296 }
3297};
3298
3299function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3300 var event = SyntheticEvent$1.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3301 event.type = 'change';
3302 // Flag this event loop as needing state restore.
3303 enqueueStateRestore(target);
3304 accumulateTwoPhaseDispatches(event);
3305 return event;
3306}
3307/**
3308 * For IE shims
3309 */
3310var activeElement = null;
3311var activeElementInst = null;
3312
3313/**
3314 * SECTION: handle `change` event
3315 */
3316function shouldUseChangeEvent(elem) {
3317 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3318 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3319}
3320
3321function manualDispatchChangeEvent(nativeEvent) {
3322 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3323
3324 // If change and propertychange bubbled, we'd just bind to it like all the
3325 // other events and have it go through ReactBrowserEventEmitter. Since it
3326 // doesn't, we manually listen for the events and so we have to enqueue and
3327 // process the abstract event manually.
3328 //
3329 // Batching is necessary here in order to ensure that all event handlers run
3330 // before the next rerender (including event handlers attached to ancestor
3331 // elements instead of directly on the input). Without this, controlled
3332 // components don't work properly in conjunction with event bubbling because
3333 // the component is rerendered and the value reverted before all the event
3334 // handlers can run. See https://github.com/facebook/react/issues/708.
3335 batchedUpdates(runEventInBatch, event);
3336}
3337
3338function runEventInBatch(event) {
3339 runEventsInBatch(event, false);
3340}
3341
3342function getInstIfValueChanged(targetInst) {
3343 var targetNode = getNodeFromInstance$1(targetInst);
3344 if (updateValueIfChanged(targetNode)) {
3345 return targetInst;
3346 }
3347}
3348
3349function getTargetInstForChangeEvent(topLevelType, targetInst) {
3350 if (topLevelType === 'topChange') {
3351 return targetInst;
3352 }
3353}
3354
3355/**
3356 * SECTION: handle `input` event
3357 */
3358var isInputEventSupported = false;
3359if (ExecutionEnvironment_1.canUseDOM) {
3360 // IE9 claims to support the input event but fails to trigger it when
3361 // deleting text, so we ignore its input events.
3362 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3363}
3364
3365/**
3366 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3367 * and override the value property so that we can distinguish user events from
3368 * value changes in JS.
3369 */
3370function startWatchingForValueChange(target, targetInst) {
3371 activeElement = target;
3372 activeElementInst = targetInst;
3373 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3374}
3375
3376/**
3377 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3378 * if any exists.
3379 */
3380function stopWatchingForValueChange() {
3381 if (!activeElement) {
3382 return;
3383 }
3384 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3385 activeElement = null;
3386 activeElementInst = null;
3387}
3388
3389/**
3390 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3391 * the value of the active element has changed.
3392 */
3393function handlePropertyChange(nativeEvent) {
3394 if (nativeEvent.propertyName !== 'value') {
3395 return;
3396 }
3397 if (getInstIfValueChanged(activeElementInst)) {
3398 manualDispatchChangeEvent(nativeEvent);
3399 }
3400}
3401
3402function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3403 if (topLevelType === 'topFocus') {
3404 // In IE9, propertychange fires for most input events but is buggy and
3405 // doesn't fire when text is deleted, but conveniently, selectionchange
3406 // appears to fire in all of the remaining cases so we catch those and
3407 // forward the event if the value has changed
3408 // In either case, we don't want to call the event handler if the value
3409 // is changed from JS so we redefine a setter for `.value` that updates
3410 // our activeElementValue variable, allowing us to ignore those changes
3411 //
3412 // stopWatching() should be a noop here but we call it just in case we
3413 // missed a blur event somehow.
3414 stopWatchingForValueChange();
3415 startWatchingForValueChange(target, targetInst);
3416 } else if (topLevelType === 'topBlur') {
3417 stopWatchingForValueChange();
3418 }
3419}
3420
3421// For IE8 and IE9.
3422function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3423 if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') {
3424 // On the selectionchange event, the target is just document which isn't
3425 // helpful for us so just check activeElement instead.
3426 //
3427 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3428 // propertychange on the first input event after setting `value` from a
3429 // script and fires only keydown, keypress, keyup. Catching keyup usually
3430 // gets it and catching keydown lets us fire an event for the first
3431 // keystroke if user does a key repeat (it'll be a little delayed: right
3432 // before the second keystroke). Other input methods (e.g., paste) seem to
3433 // fire selectionchange normally.
3434 return getInstIfValueChanged(activeElementInst);
3435 }
3436}
3437
3438/**
3439 * SECTION: handle `click` event
3440 */
3441function shouldUseClickEvent(elem) {
3442 // Use the `click` event to detect changes to checkbox and radio inputs.
3443 // This approach works across all browsers, whereas `change` does not fire
3444 // until `blur` in IE8.
3445 var nodeName = elem.nodeName;
3446 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3447}
3448
3449function getTargetInstForClickEvent(topLevelType, targetInst) {
3450 if (topLevelType === 'topClick') {
3451 return getInstIfValueChanged(targetInst);
3452 }
3453}
3454
3455function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3456 if (topLevelType === 'topInput' || topLevelType === 'topChange') {
3457 return getInstIfValueChanged(targetInst);
3458 }
3459}
3460
3461function handleControlledInputBlur(inst, node) {
3462 // TODO: In IE, inst is occasionally null. Why?
3463 if (inst == null) {
3464 return;
3465 }
3466
3467 // Fiber and ReactDOM keep wrapper state in separate places
3468 var state = inst._wrapperState || node._wrapperState;
3469
3470 if (!state || !state.controlled || node.type !== 'number') {
3471 return;
3472 }
3473
3474 // If controlled, assign the value attribute to the current value on blur
3475 setDefaultValue(node, 'number', node.value);
3476}
3477
3478/**
3479 * This plugin creates an `onChange` event that normalizes change events
3480 * across form elements. This event fires at a time when it's possible to
3481 * change the element's value without seeing a flicker.
3482 *
3483 * Supported elements are:
3484 * - input (see `isTextInputElement`)
3485 * - textarea
3486 * - select
3487 */
3488var ChangeEventPlugin = {
3489 eventTypes: eventTypes$1,
3490
3491 _isInputEventSupported: isInputEventSupported,
3492
3493 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3494 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3495
3496 var getTargetInstFunc = void 0,
3497 handleEventFunc = void 0;
3498 if (shouldUseChangeEvent(targetNode)) {
3499 getTargetInstFunc = getTargetInstForChangeEvent;
3500 } else if (isTextInputElement(targetNode)) {
3501 if (isInputEventSupported) {
3502 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3503 } else {
3504 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3505 handleEventFunc = handleEventsForInputEventPolyfill;
3506 }
3507 } else if (shouldUseClickEvent(targetNode)) {
3508 getTargetInstFunc = getTargetInstForClickEvent;
3509 }
3510
3511 if (getTargetInstFunc) {
3512 var inst = getTargetInstFunc(topLevelType, targetInst);
3513 if (inst) {
3514 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3515 return event;
3516 }
3517 }
3518
3519 if (handleEventFunc) {
3520 handleEventFunc(topLevelType, targetNode, targetInst);
3521 }
3522
3523 // When blurring, set the value attribute for number inputs
3524 if (topLevelType === 'topBlur') {
3525 handleControlledInputBlur(targetInst, targetNode);
3526 }
3527 }
3528};
3529
3530/**
3531 * Module that is injectable into `EventPluginHub`, that specifies a
3532 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3533 * plugins, without having to package every one of them. This is better than
3534 * having plugins be ordered in the same order that they are injected because
3535 * that ordering would be influenced by the packaging order.
3536 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3537 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3538 */
3539var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3540
3541var SyntheticUIEvent = SyntheticEvent$1.extend({
3542 view: null,
3543 detail: null
3544});
3545
3546/**
3547 * Translation from modifier key to the associated property in the event.
3548 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3549 */
3550
3551var modifierKeyToProp = {
3552 Alt: 'altKey',
3553 Control: 'ctrlKey',
3554 Meta: 'metaKey',
3555 Shift: 'shiftKey'
3556};
3557
3558// IE8 does not implement getModifierState so we simply map it to the only
3559// modifier keys exposed by the event itself, does not support Lock-keys.
3560// Currently, all major browsers except Chrome seems to support Lock-keys.
3561function modifierStateGetter(keyArg) {
3562 var syntheticEvent = this;
3563 var nativeEvent = syntheticEvent.nativeEvent;
3564 if (nativeEvent.getModifierState) {
3565 return nativeEvent.getModifierState(keyArg);
3566 }
3567 var keyProp = modifierKeyToProp[keyArg];
3568 return keyProp ? !!nativeEvent[keyProp] : false;
3569}
3570
3571function getEventModifierState(nativeEvent) {
3572 return modifierStateGetter;
3573}
3574
3575/**
3576 * @interface MouseEvent
3577 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3578 */
3579var SyntheticMouseEvent = SyntheticUIEvent.extend({
3580 screenX: null,
3581 screenY: null,
3582 clientX: null,
3583 clientY: null,
3584 pageX: null,
3585 pageY: null,
3586 ctrlKey: null,
3587 shiftKey: null,
3588 altKey: null,
3589 metaKey: null,
3590 getModifierState: getEventModifierState,
3591 button: null,
3592 buttons: null,
3593 relatedTarget: function (event) {
3594 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3595 }
3596});
3597
3598var eventTypes$2 = {
3599 mouseEnter: {
3600 registrationName: 'onMouseEnter',
3601 dependencies: ['topMouseOut', 'topMouseOver']
3602 },
3603 mouseLeave: {
3604 registrationName: 'onMouseLeave',
3605 dependencies: ['topMouseOut', 'topMouseOver']
3606 }
3607};
3608
3609var EnterLeaveEventPlugin = {
3610 eventTypes: eventTypes$2,
3611
3612 /**
3613 * For almost every interaction we care about, there will be both a top-level
3614 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3615 * we do not extract duplicate events. However, moving the mouse into the
3616 * browser from outside will not fire a `mouseout` event. In this case, we use
3617 * the `mouseover` top-level event.
3618 */
3619 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3620 if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3621 return null;
3622 }
3623 if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') {
3624 // Must not be a mouse in or mouse out - ignoring.
3625 return null;
3626 }
3627
3628 var win = void 0;
3629 if (nativeEventTarget.window === nativeEventTarget) {
3630 // `nativeEventTarget` is probably a window object.
3631 win = nativeEventTarget;
3632 } else {
3633 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3634 var doc = nativeEventTarget.ownerDocument;
3635 if (doc) {
3636 win = doc.defaultView || doc.parentWindow;
3637 } else {
3638 win = window;
3639 }
3640 }
3641
3642 var from = void 0;
3643 var to = void 0;
3644 if (topLevelType === 'topMouseOut') {
3645 from = targetInst;
3646 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
3647 to = related ? getClosestInstanceFromNode(related) : null;
3648 } else {
3649 // Moving to a node from outside the window.
3650 from = null;
3651 to = targetInst;
3652 }
3653
3654 if (from === to) {
3655 // Nothing pertains to our managed components.
3656 return null;
3657 }
3658
3659 var fromNode = from == null ? win : getNodeFromInstance$1(from);
3660 var toNode = to == null ? win : getNodeFromInstance$1(to);
3661
3662 var leave = SyntheticMouseEvent.getPooled(eventTypes$2.mouseLeave, from, nativeEvent, nativeEventTarget);
3663 leave.type = 'mouseleave';
3664 leave.target = fromNode;
3665 leave.relatedTarget = toNode;
3666
3667 var enter = SyntheticMouseEvent.getPooled(eventTypes$2.mouseEnter, to, nativeEvent, nativeEventTarget);
3668 enter.type = 'mouseenter';
3669 enter.target = toNode;
3670 enter.relatedTarget = fromNode;
3671
3672 accumulateEnterLeaveDispatches(leave, enter, from, to);
3673
3674 return [leave, enter];
3675 }
3676};
3677
3678/**
3679 * Copyright (c) 2013-present, Facebook, Inc.
3680 *
3681 * This source code is licensed under the MIT license found in the
3682 * LICENSE file in the root directory of this source tree.
3683 *
3684 * @typechecks
3685 */
3686
3687/* eslint-disable fb-www/typeof-undefined */
3688
3689/**
3690 * Same as document.activeElement but wraps in a try-catch block. In IE it is
3691 * not safe to call document.activeElement if there is nothing focused.
3692 *
3693 * The activeElement will be null only if the document or document body is not
3694 * yet defined.
3695 *
3696 * @param {?DOMDocument} doc Defaults to current document.
3697 * @return {?DOMElement}
3698 */
3699function getActiveElement(doc) /*?DOMElement*/{
3700 doc = doc || (typeof document !== 'undefined' ? document : undefined);
3701 if (typeof doc === 'undefined') {
3702 return null;
3703 }
3704 try {
3705 return doc.activeElement || doc.body;
3706 } catch (e) {
3707 return doc.body;
3708 }
3709}
3710
3711var getActiveElement_1 = getActiveElement;
3712
3713/**
3714 * Copyright (c) 2013-present, Facebook, Inc.
3715 *
3716 * This source code is licensed under the MIT license found in the
3717 * LICENSE file in the root directory of this source tree.
3718 *
3719 * @typechecks
3720 *
3721 */
3722
3723/*eslint-disable no-self-compare */
3724
3725
3726
3727var hasOwnProperty = Object.prototype.hasOwnProperty;
3728
3729/**
3730 * inlined Object.is polyfill to avoid requiring consumers ship their own
3731 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3732 */
3733function is(x, y) {
3734 // SameValue algorithm
3735 if (x === y) {
3736 // Steps 1-5, 7-10
3737 // Steps 6.b-6.e: +0 != -0
3738 // Added the nonzero y check to make Flow happy, but it is redundant
3739 return x !== 0 || y !== 0 || 1 / x === 1 / y;
3740 } else {
3741 // Step 6.a: NaN == NaN
3742 return x !== x && y !== y;
3743 }
3744}
3745
3746/**
3747 * Performs equality by iterating through keys on an object and returning false
3748 * when any key has values which are not strictly equal between the arguments.
3749 * Returns true when the values of all keys are strictly equal.
3750 */
3751function shallowEqual(objA, objB) {
3752 if (is(objA, objB)) {
3753 return true;
3754 }
3755
3756 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3757 return false;
3758 }
3759
3760 var keysA = Object.keys(objA);
3761 var keysB = Object.keys(objB);
3762
3763 if (keysA.length !== keysB.length) {
3764 return false;
3765 }
3766
3767 // Test for A's keys different from B.
3768 for (var i = 0; i < keysA.length; i++) {
3769 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3770 return false;
3771 }
3772 }
3773
3774 return true;
3775}
3776
3777var shallowEqual_1 = shallowEqual;
3778
3779/**
3780 * `ReactInstanceMap` maintains a mapping from a public facing stateful
3781 * instance (key) and the internal representation (value). This allows public
3782 * methods to accept the user facing instance as an argument and map them back
3783 * to internal methods.
3784 *
3785 * Note that this module is currently shared and assumed to be stateless.
3786 * If this becomes an actual Map, that will break.
3787 */
3788
3789/**
3790 * This API should be called `delete` but we'd have to make sure to always
3791 * transform these to strings for IE support. When this transform is fully
3792 * supported we can rename it.
3793 */
3794
3795
3796function get(key) {
3797 return key._reactInternalFiber;
3798}
3799
3800function has(key) {
3801 return key._reactInternalFiber !== undefined;
3802}
3803
3804function set(key, value) {
3805 key._reactInternalFiber = value;
3806}
3807
3808// Don't change these two values:
3809var NoEffect = 0;
3810var PerformedWork = 1;
3811
3812// You can change the rest (and add more).
3813var Placement = 2;
3814var Update = 4;
3815var PlacementAndUpdate = 6;
3816var Deletion = 8;
3817var ContentReset = 16;
3818var Callback = 32;
3819var Err = 64;
3820var Ref = 128;
3821
3822var MOUNTING = 1;
3823var MOUNTED = 2;
3824var UNMOUNTED = 3;
3825
3826function isFiberMountedImpl(fiber) {
3827 var node = fiber;
3828 if (!fiber.alternate) {
3829 // If there is no alternate, this might be a new tree that isn't inserted
3830 // yet. If it is, then it will have a pending insertion effect on it.
3831 if ((node.effectTag & Placement) !== NoEffect) {
3832 return MOUNTING;
3833 }
3834 while (node['return']) {
3835 node = node['return'];
3836 if ((node.effectTag & Placement) !== NoEffect) {
3837 return MOUNTING;
3838 }
3839 }
3840 } else {
3841 while (node['return']) {
3842 node = node['return'];
3843 }
3844 }
3845 if (node.tag === HostRoot) {
3846 // TODO: Check if this was a nested HostRoot when used with
3847 // renderContainerIntoSubtree.
3848 return MOUNTED;
3849 }
3850 // If we didn't hit the root, that means that we're in an disconnected tree
3851 // that has been unmounted.
3852 return UNMOUNTED;
3853}
3854
3855function isFiberMounted(fiber) {
3856 return isFiberMountedImpl(fiber) === MOUNTED;
3857}
3858
3859function isMounted(component) {
3860 {
3861 var owner = ReactCurrentOwner.current;
3862 if (owner !== null && owner.tag === ClassComponent) {
3863 var ownerFiber = owner;
3864 var instance = ownerFiber.stateNode;
3865 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');
3866 instance._warnedAboutRefsInRender = true;
3867 }
3868 }
3869
3870 var fiber = get(component);
3871 if (!fiber) {
3872 return false;
3873 }
3874 return isFiberMountedImpl(fiber) === MOUNTED;
3875}
3876
3877function assertIsMounted(fiber) {
3878 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3879}
3880
3881function findCurrentFiberUsingSlowPath(fiber) {
3882 var alternate = fiber.alternate;
3883 if (!alternate) {
3884 // If there is no alternate, then we only need to check if it is mounted.
3885 var state = isFiberMountedImpl(fiber);
3886 !(state !== UNMOUNTED) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3887 if (state === MOUNTING) {
3888 return null;
3889 }
3890 return fiber;
3891 }
3892 // If we have two possible branches, we'll walk backwards up to the root
3893 // to see what path the root points to. On the way we may hit one of the
3894 // special cases and we'll deal with them.
3895 var a = fiber;
3896 var b = alternate;
3897 while (true) {
3898 var parentA = a['return'];
3899 var parentB = parentA ? parentA.alternate : null;
3900 if (!parentA || !parentB) {
3901 // We're at the root.
3902 break;
3903 }
3904
3905 // If both copies of the parent fiber point to the same child, we can
3906 // assume that the child is current. This happens when we bailout on low
3907 // priority: the bailed out fiber's child reuses the current child.
3908 if (parentA.child === parentB.child) {
3909 var child = parentA.child;
3910 while (child) {
3911 if (child === a) {
3912 // We've determined that A is the current branch.
3913 assertIsMounted(parentA);
3914 return fiber;
3915 }
3916 if (child === b) {
3917 // We've determined that B is the current branch.
3918 assertIsMounted(parentA);
3919 return alternate;
3920 }
3921 child = child.sibling;
3922 }
3923 // We should never have an alternate for any mounting node. So the only
3924 // way this could possibly happen is if this was unmounted, if at all.
3925 invariant_1(false, 'Unable to find node on an unmounted component.');
3926 }
3927
3928 if (a['return'] !== b['return']) {
3929 // The return pointer of A and the return pointer of B point to different
3930 // fibers. We assume that return pointers never criss-cross, so A must
3931 // belong to the child set of A.return, and B must belong to the child
3932 // set of B.return.
3933 a = parentA;
3934 b = parentB;
3935 } else {
3936 // The return pointers point to the same fiber. We'll have to use the
3937 // default, slow path: scan the child sets of each parent alternate to see
3938 // which child belongs to which set.
3939 //
3940 // Search parent A's child set
3941 var didFindChild = false;
3942 var _child = parentA.child;
3943 while (_child) {
3944 if (_child === a) {
3945 didFindChild = true;
3946 a = parentA;
3947 b = parentB;
3948 break;
3949 }
3950 if (_child === b) {
3951 didFindChild = true;
3952 b = parentA;
3953 a = parentB;
3954 break;
3955 }
3956 _child = _child.sibling;
3957 }
3958 if (!didFindChild) {
3959 // Search parent B's child set
3960 _child = parentB.child;
3961 while (_child) {
3962 if (_child === a) {
3963 didFindChild = true;
3964 a = parentB;
3965 b = parentA;
3966 break;
3967 }
3968 if (_child === b) {
3969 didFindChild = true;
3970 b = parentB;
3971 a = parentA;
3972 break;
3973 }
3974 _child = _child.sibling;
3975 }
3976 !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;
3977 }
3978 }
3979
3980 !(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;
3981 }
3982 // If the root is not a host container, we're in a disconnected tree. I.e.
3983 // unmounted.
3984 !(a.tag === HostRoot) ? invariant_1(false, 'Unable to find node on an unmounted component.') : void 0;
3985 if (a.stateNode.current === a) {
3986 // We've determined that A is the current branch.
3987 return fiber;
3988 }
3989 // Otherwise B has to be current branch.
3990 return alternate;
3991}
3992
3993function findCurrentHostFiber(parent) {
3994 var currentParent = findCurrentFiberUsingSlowPath(parent);
3995 if (!currentParent) {
3996 return null;
3997 }
3998
3999 // Next we'll drill down this component to find the first HostComponent/Text.
4000 var node = currentParent;
4001 while (true) {
4002 if (node.tag === HostComponent || node.tag === HostText) {
4003 return node;
4004 } else if (node.child) {
4005 node.child['return'] = node;
4006 node = node.child;
4007 continue;
4008 }
4009 if (node === currentParent) {
4010 return null;
4011 }
4012 while (!node.sibling) {
4013 if (!node['return'] || node['return'] === currentParent) {
4014 return null;
4015 }
4016 node = node['return'];
4017 }
4018 node.sibling['return'] = node['return'];
4019 node = node.sibling;
4020 }
4021 // Flow needs the return null here, but ESLint complains about it.
4022 // eslint-disable-next-line no-unreachable
4023 return null;
4024}
4025
4026function findCurrentHostFiberWithNoPortals(parent) {
4027 var currentParent = findCurrentFiberUsingSlowPath(parent);
4028 if (!currentParent) {
4029 return null;
4030 }
4031
4032 // Next we'll drill down this component to find the first HostComponent/Text.
4033 var node = currentParent;
4034 while (true) {
4035 if (node.tag === HostComponent || node.tag === HostText) {
4036 return node;
4037 } else if (node.child && node.tag !== HostPortal) {
4038 node.child['return'] = node;
4039 node = node.child;
4040 continue;
4041 }
4042 if (node === currentParent) {
4043 return null;
4044 }
4045 while (!node.sibling) {
4046 if (!node['return'] || node['return'] === currentParent) {
4047 return null;
4048 }
4049 node = node['return'];
4050 }
4051 node.sibling['return'] = node['return'];
4052 node = node.sibling;
4053 }
4054 // Flow needs the return null here, but ESLint complains about it.
4055 // eslint-disable-next-line no-unreachable
4056 return null;
4057}
4058
4059function addEventBubbleListener(element, eventType, listener) {
4060 element.addEventListener(eventType, listener, false);
4061}
4062
4063function addEventCaptureListener(element, eventType, listener) {
4064 element.addEventListener(eventType, listener, true);
4065}
4066
4067var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4068var callbackBookkeepingPool = [];
4069
4070/**
4071 * Find the deepest React component completely containing the root of the
4072 * passed-in instance (for use when entire React trees are nested within each
4073 * other). If React trees are not nested, returns null.
4074 */
4075function findRootContainerNode(inst) {
4076 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4077 // traversal, but caching is difficult to do correctly without using a
4078 // mutation observer to listen for all DOM changes.
4079 while (inst['return']) {
4080 inst = inst['return'];
4081 }
4082 if (inst.tag !== HostRoot) {
4083 // This can happen if we're in a detached tree.
4084 return null;
4085 }
4086 return inst.stateNode.containerInfo;
4087}
4088
4089// Used to store ancestor hierarchy in top level callback
4090function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4091 if (callbackBookkeepingPool.length) {
4092 var instance = callbackBookkeepingPool.pop();
4093 instance.topLevelType = topLevelType;
4094 instance.nativeEvent = nativeEvent;
4095 instance.targetInst = targetInst;
4096 return instance;
4097 }
4098 return {
4099 topLevelType: topLevelType,
4100 nativeEvent: nativeEvent,
4101 targetInst: targetInst,
4102 ancestors: []
4103 };
4104}
4105
4106function releaseTopLevelCallbackBookKeeping(instance) {
4107 instance.topLevelType = null;
4108 instance.nativeEvent = null;
4109 instance.targetInst = null;
4110 instance.ancestors.length = 0;
4111 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4112 callbackBookkeepingPool.push(instance);
4113 }
4114}
4115
4116function handleTopLevel(bookKeeping) {
4117 var targetInst = bookKeeping.targetInst;
4118
4119 // Loop through the hierarchy, in case there's any nested components.
4120 // It's important that we build the array of ancestors before calling any
4121 // event handlers, because event handlers can modify the DOM, leading to
4122 // inconsistencies with ReactMount's node cache. See #1105.
4123 var ancestor = targetInst;
4124 do {
4125 if (!ancestor) {
4126 bookKeeping.ancestors.push(ancestor);
4127 break;
4128 }
4129 var root = findRootContainerNode(ancestor);
4130 if (!root) {
4131 break;
4132 }
4133 bookKeeping.ancestors.push(ancestor);
4134 ancestor = getClosestInstanceFromNode(root);
4135 } while (ancestor);
4136
4137 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4138 targetInst = bookKeeping.ancestors[i];
4139 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4140 }
4141}
4142
4143// TODO: can we stop exporting these?
4144var _enabled = true;
4145
4146function setEnabled(enabled) {
4147 _enabled = !!enabled;
4148}
4149
4150function isEnabled() {
4151 return _enabled;
4152}
4153
4154/**
4155 * Traps top-level events by using event bubbling.
4156 *
4157 * @param {string} topLevelType Record from `BrowserEventConstants`.
4158 * @param {string} handlerBaseName Event name (e.g. "click").
4159 * @param {object} element Element on which to attach listener.
4160 * @return {?object} An object with a remove function which will forcefully
4161 * remove the listener.
4162 * @internal
4163 */
4164function trapBubbledEvent(topLevelType, handlerBaseName, element) {
4165 if (!element) {
4166 return null;
4167 }
4168 addEventBubbleListener(element, handlerBaseName, dispatchEvent.bind(null, topLevelType));
4169}
4170
4171/**
4172 * Traps a top-level event by using event capturing.
4173 *
4174 * @param {string} topLevelType Record from `BrowserEventConstants`.
4175 * @param {string} handlerBaseName Event name (e.g. "click").
4176 * @param {object} element Element on which to attach listener.
4177 * @return {?object} An object with a remove function which will forcefully
4178 * remove the listener.
4179 * @internal
4180 */
4181function trapCapturedEvent(topLevelType, handlerBaseName, element) {
4182 if (!element) {
4183 return null;
4184 }
4185 addEventCaptureListener(element, handlerBaseName, dispatchEvent.bind(null, topLevelType));
4186}
4187
4188function dispatchEvent(topLevelType, nativeEvent) {
4189 if (!_enabled) {
4190 return;
4191 }
4192
4193 var nativeEventTarget = getEventTarget(nativeEvent);
4194 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4195 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4196 // If we get an event (ex: img onload) before committing that
4197 // component's mount, ignore it for now (that is, treat it as if it was an
4198 // event on a non-React tree). We might also consider queueing events and
4199 // dispatching them after the mount.
4200 targetInst = null;
4201 }
4202
4203 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4204
4205 try {
4206 // Event queue being processed in the same cycle allows
4207 // `preventDefault`.
4208 batchedUpdates(handleTopLevel, bookKeeping);
4209 } finally {
4210 releaseTopLevelCallbackBookKeeping(bookKeeping);
4211 }
4212}
4213
4214var ReactDOMEventListener = Object.freeze({
4215 get _enabled () { return _enabled; },
4216 setEnabled: setEnabled,
4217 isEnabled: isEnabled,
4218 trapBubbledEvent: trapBubbledEvent,
4219 trapCapturedEvent: trapCapturedEvent,
4220 dispatchEvent: dispatchEvent
4221});
4222
4223/**
4224 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
4225 *
4226 * @param {string} styleProp
4227 * @param {string} eventName
4228 * @returns {object}
4229 */
4230function makePrefixMap(styleProp, eventName) {
4231 var prefixes = {};
4232
4233 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
4234 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
4235 prefixes['Moz' + styleProp] = 'moz' + eventName;
4236 prefixes['ms' + styleProp] = 'MS' + eventName;
4237 prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
4238
4239 return prefixes;
4240}
4241
4242/**
4243 * A list of event names to a configurable list of vendor prefixes.
4244 */
4245var vendorPrefixes = {
4246 animationend: makePrefixMap('Animation', 'AnimationEnd'),
4247 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
4248 animationstart: makePrefixMap('Animation', 'AnimationStart'),
4249 transitionend: makePrefixMap('Transition', 'TransitionEnd')
4250};
4251
4252/**
4253 * Event names that have already been detected and prefixed (if applicable).
4254 */
4255var prefixedEventNames = {};
4256
4257/**
4258 * Element to check for prefixes on.
4259 */
4260var style = {};
4261
4262/**
4263 * Bootstrap if a DOM exists.
4264 */
4265if (ExecutionEnvironment_1.canUseDOM) {
4266 style = document.createElement('div').style;
4267
4268 // On some platforms, in particular some releases of Android 4.x,
4269 // the un-prefixed "animation" and "transition" properties are defined on the
4270 // style object but the events that fire will still be prefixed, so we need
4271 // to check if the un-prefixed events are usable, and if not remove them from the map.
4272 if (!('AnimationEvent' in window)) {
4273 delete vendorPrefixes.animationend.animation;
4274 delete vendorPrefixes.animationiteration.animation;
4275 delete vendorPrefixes.animationstart.animation;
4276 }
4277
4278 // Same as above
4279 if (!('TransitionEvent' in window)) {
4280 delete vendorPrefixes.transitionend.transition;
4281 }
4282}
4283
4284/**
4285 * Attempts to determine the correct vendor prefixed event name.
4286 *
4287 * @param {string} eventName
4288 * @returns {string}
4289 */
4290function getVendorPrefixedEventName(eventName) {
4291 if (prefixedEventNames[eventName]) {
4292 return prefixedEventNames[eventName];
4293 } else if (!vendorPrefixes[eventName]) {
4294 return eventName;
4295 }
4296
4297 var prefixMap = vendorPrefixes[eventName];
4298
4299 for (var styleProp in prefixMap) {
4300 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
4301 return prefixedEventNames[eventName] = prefixMap[styleProp];
4302 }
4303 }
4304
4305 return eventName;
4306}
4307
4308/**
4309 * Types of raw signals from the browser caught at the top level.
4310 *
4311 * For events like 'submit' which don't consistently bubble (which we
4312 * trap at a lower node than `document`), binding at `document` would
4313 * cause duplicate events so we don't include them here.
4314 */
4315var topLevelTypes$1 = {
4316 topAbort: 'abort',
4317 topAnimationEnd: getVendorPrefixedEventName('animationend'),
4318 topAnimationIteration: getVendorPrefixedEventName('animationiteration'),
4319 topAnimationStart: getVendorPrefixedEventName('animationstart'),
4320 topBlur: 'blur',
4321 topCancel: 'cancel',
4322 topCanPlay: 'canplay',
4323 topCanPlayThrough: 'canplaythrough',
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 topDurationChange: 'durationchange',
4343 topEmptied: 'emptied',
4344 topEncrypted: 'encrypted',
4345 topEnded: 'ended',
4346 topError: 'error',
4347 topFocus: 'focus',
4348 topInput: 'input',
4349 topKeyDown: 'keydown',
4350 topKeyPress: 'keypress',
4351 topKeyUp: 'keyup',
4352 topLoadedData: 'loadeddata',
4353 topLoad: 'load',
4354 topLoadedMetadata: 'loadedmetadata',
4355 topLoadStart: 'loadstart',
4356 topMouseDown: 'mousedown',
4357 topMouseMove: 'mousemove',
4358 topMouseOut: 'mouseout',
4359 topMouseOver: 'mouseover',
4360 topMouseUp: 'mouseup',
4361 topPaste: 'paste',
4362 topPause: 'pause',
4363 topPlay: 'play',
4364 topPlaying: 'playing',
4365 topProgress: 'progress',
4366 topRateChange: 'ratechange',
4367 topScroll: 'scroll',
4368 topSeeked: 'seeked',
4369 topSeeking: 'seeking',
4370 topSelectionChange: 'selectionchange',
4371 topStalled: 'stalled',
4372 topSuspend: 'suspend',
4373 topTextInput: 'textInput',
4374 topTimeUpdate: 'timeupdate',
4375 topToggle: 'toggle',
4376 topTouchCancel: 'touchcancel',
4377 topTouchEnd: 'touchend',
4378 topTouchMove: 'touchmove',
4379 topTouchStart: 'touchstart',
4380 topTransitionEnd: getVendorPrefixedEventName('transitionend'),
4381 topVolumeChange: 'volumechange',
4382 topWaiting: 'waiting',
4383 topWheel: 'wheel'
4384};
4385
4386var BrowserEventConstants = {
4387 topLevelTypes: topLevelTypes$1
4388};
4389
4390var topLevelTypes = BrowserEventConstants.topLevelTypes;
4391
4392/**
4393 * Summary of `ReactBrowserEventEmitter` event handling:
4394 *
4395 * - Top-level delegation is used to trap most native browser events. This
4396 * may only occur in the main thread and is the responsibility of
4397 * ReactDOMEventListener, which is injected and can therefore support
4398 * pluggable event sources. This is the only work that occurs in the main
4399 * thread.
4400 *
4401 * - We normalize and de-duplicate events to account for browser quirks. This
4402 * may be done in the worker thread.
4403 *
4404 * - Forward these native events (with the associated top-level type used to
4405 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4406 * to extract any synthetic events.
4407 *
4408 * - The `EventPluginHub` will then process each event by annotating them with
4409 * "dispatches", a sequence of listeners and IDs that care about that event.
4410 *
4411 * - The `EventPluginHub` then dispatches the events.
4412 *
4413 * Overview of React and the event system:
4414 *
4415 * +------------+ .
4416 * | DOM | .
4417 * +------------+ .
4418 * | .
4419 * v .
4420 * +------------+ .
4421 * | ReactEvent | .
4422 * | Listener | .
4423 * +------------+ . +-----------+
4424 * | . +--------+|SimpleEvent|
4425 * | . | |Plugin |
4426 * +-----|------+ . v +-----------+
4427 * | | | . +--------------+ +------------+
4428 * | +-----------.--->|EventPluginHub| | Event |
4429 * | | . | | +-----------+ | Propagators|
4430 * | ReactEvent | . | | |TapEvent | |------------|
4431 * | Emitter | . | |<---+|Plugin | |other plugin|
4432 * | | . | | +-----------+ | utilities |
4433 * | +-----------.--->| | +------------+
4434 * | | | . +--------------+
4435 * +-----|------+ . ^ +-----------+
4436 * | . | |Enter/Leave|
4437 * + . +-------+|Plugin |
4438 * +-------------+ . +-----------+
4439 * | application | .
4440 * |-------------| .
4441 * | | .
4442 * | | .
4443 * +-------------+ .
4444 * .
4445 * React Core . General Purpose Event Plugin System
4446 */
4447
4448var alreadyListeningTo = {};
4449var reactTopListenersCounter = 0;
4450
4451/**
4452 * To ensure no conflicts with other potential React instances on the page
4453 */
4454var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4455
4456function getListeningForDocument(mountAt) {
4457 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4458 // directly.
4459 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4460 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4461 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4462 }
4463 return alreadyListeningTo[mountAt[topListenersIDKey]];
4464}
4465
4466/**
4467 * We listen for bubbled touch events on the document object.
4468 *
4469 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4470 * mounting `onmousemove` events at some node that was not the document
4471 * element. The symptoms were that if your mouse is not moving over something
4472 * contained within that mount point (for example on the background) the
4473 * top-level listeners for `onmousemove` won't be called. However, if you
4474 * register the `mousemove` on the document object, then it will of course
4475 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4476 * top-level listeners to the document object only, at least for these
4477 * movement types of events and possibly all events.
4478 *
4479 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4480 *
4481 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
4482 * they bubble to document.
4483 *
4484 * @param {string} registrationName Name of listener (e.g. `onClick`).
4485 * @param {object} contentDocumentHandle Document which owns the container
4486 */
4487function listenTo(registrationName, contentDocumentHandle) {
4488 var mountAt = contentDocumentHandle;
4489 var isListening = getListeningForDocument(mountAt);
4490 var dependencies = registrationNameDependencies[registrationName];
4491
4492 for (var i = 0; i < dependencies.length; i++) {
4493 var dependency = dependencies[i];
4494 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4495 if (dependency === 'topScroll') {
4496 trapCapturedEvent('topScroll', 'scroll', mountAt);
4497 } else if (dependency === 'topFocus' || dependency === 'topBlur') {
4498 trapCapturedEvent('topFocus', 'focus', mountAt);
4499 trapCapturedEvent('topBlur', 'blur', mountAt);
4500
4501 // to make sure blur and focus event listeners are only attached once
4502 isListening.topBlur = true;
4503 isListening.topFocus = true;
4504 } else if (dependency === 'topCancel') {
4505 if (isEventSupported('cancel', true)) {
4506 trapCapturedEvent('topCancel', 'cancel', mountAt);
4507 }
4508 isListening.topCancel = true;
4509 } else if (dependency === 'topClose') {
4510 if (isEventSupported('close', true)) {
4511 trapCapturedEvent('topClose', 'close', mountAt);
4512 }
4513 isListening.topClose = true;
4514 } else if (topLevelTypes.hasOwnProperty(dependency)) {
4515 trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
4516 }
4517
4518 isListening[dependency] = true;
4519 }
4520 }
4521}
4522
4523function isListeningToAllDependencies(registrationName, mountAt) {
4524 var isListening = getListeningForDocument(mountAt);
4525 var dependencies = registrationNameDependencies[registrationName];
4526 for (var i = 0; i < dependencies.length; i++) {
4527 var dependency = dependencies[i];
4528 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
4529 return false;
4530 }
4531 }
4532 return true;
4533}
4534
4535/**
4536 * Copyright (c) 2013-present, Facebook, Inc.
4537 *
4538 * This source code is licensed under the MIT license found in the
4539 * LICENSE file in the root directory of this source tree.
4540 *
4541 * @typechecks
4542 */
4543
4544/**
4545 * @param {*} object The object to check.
4546 * @return {boolean} Whether or not the object is a DOM node.
4547 */
4548function isNode(object) {
4549 var doc = object ? object.ownerDocument || object : document;
4550 var defaultView = doc.defaultView || window;
4551 return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
4552}
4553
4554var isNode_1 = isNode;
4555
4556/**
4557 * Copyright (c) 2013-present, Facebook, Inc.
4558 *
4559 * This source code is licensed under the MIT license found in the
4560 * LICENSE file in the root directory of this source tree.
4561 *
4562 * @typechecks
4563 */
4564
4565
4566
4567/**
4568 * @param {*} object The object to check.
4569 * @return {boolean} Whether or not the object is a DOM text node.
4570 */
4571function isTextNode(object) {
4572 return isNode_1(object) && object.nodeType == 3;
4573}
4574
4575var isTextNode_1 = isTextNode;
4576
4577/**
4578 * Copyright (c) 2013-present, Facebook, Inc.
4579 *
4580 * This source code is licensed under the MIT license found in the
4581 * LICENSE file in the root directory of this source tree.
4582 *
4583 *
4584 */
4585
4586
4587
4588/*eslint-disable no-bitwise */
4589
4590/**
4591 * Checks if a given DOM node contains or is another DOM node.
4592 */
4593function containsNode(outerNode, innerNode) {
4594 if (!outerNode || !innerNode) {
4595 return false;
4596 } else if (outerNode === innerNode) {
4597 return true;
4598 } else if (isTextNode_1(outerNode)) {
4599 return false;
4600 } else if (isTextNode_1(innerNode)) {
4601 return containsNode(outerNode, innerNode.parentNode);
4602 } else if ('contains' in outerNode) {
4603 return outerNode.contains(innerNode);
4604 } else if (outerNode.compareDocumentPosition) {
4605 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
4606 } else {
4607 return false;
4608 }
4609}
4610
4611var containsNode_1 = containsNode;
4612
4613/**
4614 * Given any node return the first leaf node without children.
4615 *
4616 * @param {DOMElement|DOMTextNode} node
4617 * @return {DOMElement|DOMTextNode}
4618 */
4619function getLeafNode(node) {
4620 while (node && node.firstChild) {
4621 node = node.firstChild;
4622 }
4623 return node;
4624}
4625
4626/**
4627 * Get the next sibling within a container. This will walk up the
4628 * DOM if a node's siblings have been exhausted.
4629 *
4630 * @param {DOMElement|DOMTextNode} node
4631 * @return {?DOMElement|DOMTextNode}
4632 */
4633function getSiblingNode(node) {
4634 while (node) {
4635 if (node.nextSibling) {
4636 return node.nextSibling;
4637 }
4638 node = node.parentNode;
4639 }
4640}
4641
4642/**
4643 * Get object describing the nodes which contain characters at offset.
4644 *
4645 * @param {DOMElement|DOMTextNode} root
4646 * @param {number} offset
4647 * @return {?object}
4648 */
4649function getNodeForCharacterOffset(root, offset) {
4650 var node = getLeafNode(root);
4651 var nodeStart = 0;
4652 var nodeEnd = 0;
4653
4654 while (node) {
4655 if (node.nodeType === TEXT_NODE) {
4656 nodeEnd = nodeStart + node.textContent.length;
4657
4658 if (nodeStart <= offset && nodeEnd >= offset) {
4659 return {
4660 node: node,
4661 offset: offset - nodeStart
4662 };
4663 }
4664
4665 nodeStart = nodeEnd;
4666 }
4667
4668 node = getLeafNode(getSiblingNode(node));
4669 }
4670}
4671
4672/**
4673 * @param {DOMElement} outerNode
4674 * @return {?object}
4675 */
4676function getOffsets(outerNode) {
4677 var selection = window.getSelection && window.getSelection();
4678
4679 if (!selection || selection.rangeCount === 0) {
4680 return null;
4681 }
4682
4683 var anchorNode = selection.anchorNode,
4684 anchorOffset = selection.anchorOffset,
4685 focusNode = selection.focusNode,
4686 focusOffset = selection.focusOffset;
4687
4688 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
4689 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
4690 // expose properties, triggering a "Permission denied error" if any of its
4691 // properties are accessed. The only seemingly possible way to avoid erroring
4692 // is to access a property that typically works for non-anonymous divs and
4693 // catch any error that may otherwise arise. See
4694 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
4695
4696 try {
4697 /* eslint-disable no-unused-expressions */
4698 anchorNode.nodeType;
4699 focusNode.nodeType;
4700 /* eslint-enable no-unused-expressions */
4701 } catch (e) {
4702 return null;
4703 }
4704
4705 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
4706}
4707
4708/**
4709 * Returns {start, end} where `start` is the character/codepoint index of
4710 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
4711 * `end` is the index of (focusNode, focusOffset).
4712 *
4713 * Returns null if you pass in garbage input but we should probably just crash.
4714 *
4715 * Exported only for testing.
4716 */
4717function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
4718 var length = 0;
4719 var start = -1;
4720 var end = -1;
4721 var indexWithinAnchor = 0;
4722 var indexWithinFocus = 0;
4723 var node = outerNode;
4724 var parentNode = null;
4725
4726 outer: while (true) {
4727 var next = null;
4728
4729 while (true) {
4730 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
4731 start = length + anchorOffset;
4732 }
4733 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
4734 end = length + focusOffset;
4735 }
4736
4737 if (node.nodeType === TEXT_NODE) {
4738 length += node.nodeValue.length;
4739 }
4740
4741 if ((next = node.firstChild) === null) {
4742 break;
4743 }
4744 // Moving from `node` to its first child `next`.
4745 parentNode = node;
4746 node = next;
4747 }
4748
4749 while (true) {
4750 if (node === outerNode) {
4751 // If `outerNode` has children, this is always the second time visiting
4752 // it. If it has no children, this is still the first loop, and the only
4753 // valid selection is anchorNode and focusNode both equal to this node
4754 // and both offsets 0, in which case we will have handled above.
4755 break outer;
4756 }
4757 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
4758 start = length;
4759 }
4760 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
4761 end = length;
4762 }
4763 if ((next = node.nextSibling) !== null) {
4764 break;
4765 }
4766 node = parentNode;
4767 parentNode = node.parentNode;
4768 }
4769
4770 // Moving from `node` to its next sibling `next`.
4771 node = next;
4772 }
4773
4774 if (start === -1 || end === -1) {
4775 // This should never happen. (Would happen if the anchor/focus nodes aren't
4776 // actually inside the passed-in node.)
4777 return null;
4778 }
4779
4780 return {
4781 start: start,
4782 end: end
4783 };
4784}
4785
4786/**
4787 * In modern non-IE browsers, we can support both forward and backward
4788 * selections.
4789 *
4790 * Note: IE10+ supports the Selection object, but it does not support
4791 * the `extend` method, which means that even in modern IE, it's not possible
4792 * to programmatically create a backward selection. Thus, for all IE
4793 * versions, we use the old IE API to create our selections.
4794 *
4795 * @param {DOMElement|DOMTextNode} node
4796 * @param {object} offsets
4797 */
4798function setOffsets(node, offsets) {
4799 if (!window.getSelection) {
4800 return;
4801 }
4802
4803 var selection = window.getSelection();
4804 var length = node[getTextContentAccessor()].length;
4805 var start = Math.min(offsets.start, length);
4806 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
4807
4808 // IE 11 uses modern selection, but doesn't support the extend method.
4809 // Flip backward selections, so we can set with a single range.
4810 if (!selection.extend && start > end) {
4811 var temp = end;
4812 end = start;
4813 start = temp;
4814 }
4815
4816 var startMarker = getNodeForCharacterOffset(node, start);
4817 var endMarker = getNodeForCharacterOffset(node, end);
4818
4819 if (startMarker && endMarker) {
4820 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
4821 return;
4822 }
4823 var range = document.createRange();
4824 range.setStart(startMarker.node, startMarker.offset);
4825 selection.removeAllRanges();
4826
4827 if (start > end) {
4828 selection.addRange(range);
4829 selection.extend(endMarker.node, endMarker.offset);
4830 } else {
4831 range.setEnd(endMarker.node, endMarker.offset);
4832 selection.addRange(range);
4833 }
4834 }
4835}
4836
4837function isInDocument(node) {
4838 return containsNode_1(document.documentElement, node);
4839}
4840
4841/**
4842 * @ReactInputSelection: React input selection module. Based on Selection.js,
4843 * but modified to be suitable for react and has a couple of bug fixes (doesn't
4844 * assume buttons have range selections allowed).
4845 * Input selection module for React.
4846 */
4847
4848function hasSelectionCapabilities(elem) {
4849 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
4850 return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
4851}
4852
4853function getSelectionInformation() {
4854 var focusedElem = getActiveElement_1();
4855 return {
4856 focusedElem: focusedElem,
4857 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
4858 };
4859}
4860
4861/**
4862 * @restoreSelection: If any selection information was potentially lost,
4863 * restore it. This is useful when performing operations that could remove dom
4864 * nodes and place them back in, resulting in focus being lost.
4865 */
4866function restoreSelection(priorSelectionInformation) {
4867 var curFocusedElem = getActiveElement_1();
4868 var priorFocusedElem = priorSelectionInformation.focusedElem;
4869 var priorSelectionRange = priorSelectionInformation.selectionRange;
4870 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
4871 if (hasSelectionCapabilities(priorFocusedElem)) {
4872 setSelection(priorFocusedElem, priorSelectionRange);
4873 }
4874
4875 // Focusing a node can change the scroll position, which is undesirable
4876 var ancestors = [];
4877 var ancestor = priorFocusedElem;
4878 while (ancestor = ancestor.parentNode) {
4879 if (ancestor.nodeType === ELEMENT_NODE) {
4880 ancestors.push({
4881 element: ancestor,
4882 left: ancestor.scrollLeft,
4883 top: ancestor.scrollTop
4884 });
4885 }
4886 }
4887
4888 priorFocusedElem.focus();
4889
4890 for (var i = 0; i < ancestors.length; i++) {
4891 var info = ancestors[i];
4892 info.element.scrollLeft = info.left;
4893 info.element.scrollTop = info.top;
4894 }
4895 }
4896}
4897
4898/**
4899 * @getSelection: Gets the selection bounds of a focused textarea, input or
4900 * contentEditable node.
4901 * -@input: Look up selection bounds of this input
4902 * -@return {start: selectionStart, end: selectionEnd}
4903 */
4904function getSelection$1(input) {
4905 var selection = void 0;
4906
4907 if ('selectionStart' in input) {
4908 // Modern browser with input or textarea.
4909 selection = {
4910 start: input.selectionStart,
4911 end: input.selectionEnd
4912 };
4913 } else {
4914 // Content editable or old IE textarea.
4915 selection = getOffsets(input);
4916 }
4917
4918 return selection || { start: 0, end: 0 };
4919}
4920
4921/**
4922 * @setSelection: Sets the selection bounds of a textarea or input and focuses
4923 * the input.
4924 * -@input Set selection bounds of this input or textarea
4925 * -@offsets Object of same form that is returned from get*
4926 */
4927function setSelection(input, offsets) {
4928 var start = offsets.start,
4929 end = offsets.end;
4930
4931 if (end === undefined) {
4932 end = start;
4933 }
4934
4935 if ('selectionStart' in input) {
4936 input.selectionStart = start;
4937 input.selectionEnd = Math.min(end, input.value.length);
4938 } else {
4939 setOffsets(input, offsets);
4940 }
4941}
4942
4943var skipSelectionChangeEvent = ExecutionEnvironment_1.canUseDOM && 'documentMode' in document && document.documentMode <= 11;
4944
4945var eventTypes$3 = {
4946 select: {
4947 phasedRegistrationNames: {
4948 bubbled: 'onSelect',
4949 captured: 'onSelectCapture'
4950 },
4951 dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange']
4952 }
4953};
4954
4955var activeElement$1 = null;
4956var activeElementInst$1 = null;
4957var lastSelection = null;
4958var mouseDown = false;
4959
4960/**
4961 * Get an object which is a unique representation of the current selection.
4962 *
4963 * The return value will not be consistent across nodes or browsers, but
4964 * two identical selections on the same node will return identical objects.
4965 *
4966 * @param {DOMElement} node
4967 * @return {object}
4968 */
4969function getSelection(node) {
4970 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
4971 return {
4972 start: node.selectionStart,
4973 end: node.selectionEnd
4974 };
4975 } else if (window.getSelection) {
4976 var selection = window.getSelection();
4977 return {
4978 anchorNode: selection.anchorNode,
4979 anchorOffset: selection.anchorOffset,
4980 focusNode: selection.focusNode,
4981 focusOffset: selection.focusOffset
4982 };
4983 }
4984}
4985
4986/**
4987 * Poll selection to see whether it's changed.
4988 *
4989 * @param {object} nativeEvent
4990 * @return {?SyntheticEvent}
4991 */
4992function constructSelectEvent(nativeEvent, nativeEventTarget) {
4993 // Ensure we have the right element, and that the user is not dragging a
4994 // selection (this matches native `select` event behavior). In HTML5, select
4995 // fires only on input and textarea thus if there's no focused element we
4996 // won't dispatch.
4997 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement_1()) {
4998 return null;
4999 }
5000
5001 // Only fire when selection has actually changed.
5002 var currentSelection = getSelection(activeElement$1);
5003 if (!lastSelection || !shallowEqual_1(lastSelection, currentSelection)) {
5004 lastSelection = currentSelection;
5005
5006 var syntheticEvent = SyntheticEvent$1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5007
5008 syntheticEvent.type = 'select';
5009 syntheticEvent.target = activeElement$1;
5010
5011 accumulateTwoPhaseDispatches(syntheticEvent);
5012
5013 return syntheticEvent;
5014 }
5015
5016 return null;
5017}
5018
5019/**
5020 * This plugin creates an `onSelect` event that normalizes select events
5021 * across form elements.
5022 *
5023 * Supported elements are:
5024 * - input (see `isTextInputElement`)
5025 * - textarea
5026 * - contentEditable
5027 *
5028 * This differs from native browser implementations in the following ways:
5029 * - Fires on contentEditable fields as well as inputs.
5030 * - Fires for collapsed selection.
5031 * - Fires after user input.
5032 */
5033var SelectEventPlugin = {
5034 eventTypes: eventTypes$3,
5035
5036 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5037 var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE ? nativeEventTarget : nativeEventTarget.ownerDocument;
5038 // Track whether all listeners exists for this plugin. If none exist, we do
5039 // not extract events. See #3639.
5040 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5041 return null;
5042 }
5043
5044 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5045
5046 switch (topLevelType) {
5047 // Track the input node that has focus.
5048 case 'topFocus':
5049 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5050 activeElement$1 = targetNode;
5051 activeElementInst$1 = targetInst;
5052 lastSelection = null;
5053 }
5054 break;
5055 case 'topBlur':
5056 activeElement$1 = null;
5057 activeElementInst$1 = null;
5058 lastSelection = null;
5059 break;
5060 // Don't fire the event while the user is dragging. This matches the
5061 // semantics of the native select event.
5062 case 'topMouseDown':
5063 mouseDown = true;
5064 break;
5065 case 'topContextMenu':
5066 case 'topMouseUp':
5067 mouseDown = false;
5068 return constructSelectEvent(nativeEvent, nativeEventTarget);
5069 // Chrome and IE fire non-standard event when selection is changed (and
5070 // sometimes when it hasn't). IE's event fires out of order with respect
5071 // to key and input events on deletion, so we discard it.
5072 //
5073 // Firefox doesn't support selectionchange, so check selection status
5074 // after each key entry. The selection changes after keydown and before
5075 // keyup, but we check on keydown as well in the case of holding down a
5076 // key, when multiple keydown events are fired but only one keyup is.
5077 // This is also our approach for IE handling, for the reason above.
5078 case 'topSelectionChange':
5079 if (skipSelectionChangeEvent) {
5080 break;
5081 }
5082 // falls through
5083 case 'topKeyDown':
5084 case 'topKeyUp':
5085 return constructSelectEvent(nativeEvent, nativeEventTarget);
5086 }
5087
5088 return null;
5089 }
5090};
5091
5092/**
5093 * @interface Event
5094 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
5095 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
5096 */
5097var SyntheticAnimationEvent = SyntheticEvent$1.extend({
5098 animationName: null,
5099 elapsedTime: null,
5100 pseudoElement: null
5101});
5102
5103/**
5104 * @interface Event
5105 * @see http://www.w3.org/TR/clipboard-apis/
5106 */
5107var SyntheticClipboardEvent = SyntheticEvent$1.extend({
5108 clipboardData: function (event) {
5109 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
5110 }
5111});
5112
5113/**
5114 * @interface FocusEvent
5115 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5116 */
5117var SyntheticFocusEvent = SyntheticUIEvent.extend({
5118 relatedTarget: null
5119});
5120
5121/**
5122 * `charCode` represents the actual "character code" and is safe to use with
5123 * `String.fromCharCode`. As such, only keys that correspond to printable
5124 * characters produce a valid `charCode`, the only exception to this is Enter.
5125 * The Tab-key is considered non-printable and does not have a `charCode`,
5126 * presumably because it does not produce a tab-character in browsers.
5127 *
5128 * @param {object} nativeEvent Native browser event.
5129 * @return {number} Normalized `charCode` property.
5130 */
5131function getEventCharCode(nativeEvent) {
5132 var charCode = void 0;
5133 var keyCode = nativeEvent.keyCode;
5134
5135 if ('charCode' in nativeEvent) {
5136 charCode = nativeEvent.charCode;
5137
5138 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
5139 if (charCode === 0 && keyCode === 13) {
5140 charCode = 13;
5141 }
5142 } else {
5143 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
5144 charCode = keyCode;
5145 }
5146
5147 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
5148 // report Enter as charCode 10 when ctrl is pressed.
5149 if (charCode === 10) {
5150 charCode = 13;
5151 }
5152
5153 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
5154 // Must not discard the (non-)printable Enter-key.
5155 if (charCode >= 32 || charCode === 13) {
5156 return charCode;
5157 }
5158
5159 return 0;
5160}
5161
5162/**
5163 * Normalization of deprecated HTML5 `key` values
5164 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5165 */
5166var normalizeKey = {
5167 Esc: 'Escape',
5168 Spacebar: ' ',
5169 Left: 'ArrowLeft',
5170 Up: 'ArrowUp',
5171 Right: 'ArrowRight',
5172 Down: 'ArrowDown',
5173 Del: 'Delete',
5174 Win: 'OS',
5175 Menu: 'ContextMenu',
5176 Apps: 'ContextMenu',
5177 Scroll: 'ScrollLock',
5178 MozPrintableKey: 'Unidentified'
5179};
5180
5181/**
5182 * Translation from legacy `keyCode` to HTML5 `key`
5183 * Only special keys supported, all others depend on keyboard layout or browser
5184 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5185 */
5186var translateToKey = {
5187 '8': 'Backspace',
5188 '9': 'Tab',
5189 '12': 'Clear',
5190 '13': 'Enter',
5191 '16': 'Shift',
5192 '17': 'Control',
5193 '18': 'Alt',
5194 '19': 'Pause',
5195 '20': 'CapsLock',
5196 '27': 'Escape',
5197 '32': ' ',
5198 '33': 'PageUp',
5199 '34': 'PageDown',
5200 '35': 'End',
5201 '36': 'Home',
5202 '37': 'ArrowLeft',
5203 '38': 'ArrowUp',
5204 '39': 'ArrowRight',
5205 '40': 'ArrowDown',
5206 '45': 'Insert',
5207 '46': 'Delete',
5208 '112': 'F1',
5209 '113': 'F2',
5210 '114': 'F3',
5211 '115': 'F4',
5212 '116': 'F5',
5213 '117': 'F6',
5214 '118': 'F7',
5215 '119': 'F8',
5216 '120': 'F9',
5217 '121': 'F10',
5218 '122': 'F11',
5219 '123': 'F12',
5220 '144': 'NumLock',
5221 '145': 'ScrollLock',
5222 '224': 'Meta'
5223};
5224
5225/**
5226 * @param {object} nativeEvent Native browser event.
5227 * @return {string} Normalized `key` property.
5228 */
5229function getEventKey(nativeEvent) {
5230 if (nativeEvent.key) {
5231 // Normalize inconsistent values reported by browsers due to
5232 // implementations of a working draft specification.
5233
5234 // FireFox implements `key` but returns `MozPrintableKey` for all
5235 // printable characters (normalized to `Unidentified`), ignore it.
5236 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
5237 if (key !== 'Unidentified') {
5238 return key;
5239 }
5240 }
5241
5242 // Browser does not implement `key`, polyfill as much of it as we can.
5243 if (nativeEvent.type === 'keypress') {
5244 var charCode = getEventCharCode(nativeEvent);
5245
5246 // The enter-key is technically both printable and non-printable and can
5247 // thus be captured by `keypress`, no other non-printable key should.
5248 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
5249 }
5250 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
5251 // While user keyboard layout determines the actual meaning of each
5252 // `keyCode` value, almost all function keys have a universal value.
5253 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
5254 }
5255 return '';
5256}
5257
5258/**
5259 * @interface KeyboardEvent
5260 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5261 */
5262var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
5263 key: getEventKey,
5264 location: null,
5265 ctrlKey: null,
5266 shiftKey: null,
5267 altKey: null,
5268 metaKey: null,
5269 repeat: null,
5270 locale: null,
5271 getModifierState: getEventModifierState,
5272 // Legacy Interface
5273 charCode: function (event) {
5274 // `charCode` is the result of a KeyPress event and represents the value of
5275 // the actual printable character.
5276
5277 // KeyPress is deprecated, but its replacement is not yet final and not
5278 // implemented in any major browser. Only KeyPress has charCode.
5279 if (event.type === 'keypress') {
5280 return getEventCharCode(event);
5281 }
5282 return 0;
5283 },
5284 keyCode: function (event) {
5285 // `keyCode` is the result of a KeyDown/Up event and represents the value of
5286 // physical keyboard key.
5287
5288 // The actual meaning of the value depends on the users' keyboard layout
5289 // which cannot be detected. Assuming that it is a US keyboard layout
5290 // provides a surprisingly accurate mapping for US and European users.
5291 // Due to this, it is left to the user to implement at this time.
5292 if (event.type === 'keydown' || event.type === 'keyup') {
5293 return event.keyCode;
5294 }
5295 return 0;
5296 },
5297 which: function (event) {
5298 // `which` is an alias for either `keyCode` or `charCode` depending on the
5299 // type of the event.
5300 if (event.type === 'keypress') {
5301 return getEventCharCode(event);
5302 }
5303 if (event.type === 'keydown' || event.type === 'keyup') {
5304 return event.keyCode;
5305 }
5306 return 0;
5307 }
5308});
5309
5310/**
5311 * @interface DragEvent
5312 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5313 */
5314var SyntheticDragEvent = SyntheticMouseEvent.extend({
5315 dataTransfer: null
5316});
5317
5318/**
5319 * @interface TouchEvent
5320 * @see http://www.w3.org/TR/touch-events/
5321 */
5322var SyntheticTouchEvent = SyntheticUIEvent.extend({
5323 touches: null,
5324 targetTouches: null,
5325 changedTouches: null,
5326 altKey: null,
5327 metaKey: null,
5328 ctrlKey: null,
5329 shiftKey: null,
5330 getModifierState: getEventModifierState
5331});
5332
5333/**
5334 * @interface Event
5335 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
5336 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
5337 */
5338var SyntheticTransitionEvent = SyntheticEvent$1.extend({
5339 propertyName: null,
5340 elapsedTime: null,
5341 pseudoElement: null
5342});
5343
5344/**
5345 * @interface WheelEvent
5346 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5347 */
5348var SyntheticWheelEvent = SyntheticMouseEvent.extend({
5349 deltaX: function (event) {
5350 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
5351 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
5352 },
5353 deltaY: function (event) {
5354 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
5355 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
5356 'wheelDelta' in event ? -event.wheelDelta : 0;
5357 },
5358
5359 deltaZ: null,
5360
5361 // Browsers without "deltaMode" is reporting in raw wheel delta where one
5362 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
5363 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
5364 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
5365 deltaMode: null
5366});
5367
5368/**
5369 * Turns
5370 * ['abort', ...]
5371 * into
5372 * eventTypes = {
5373 * 'abort': {
5374 * phasedRegistrationNames: {
5375 * bubbled: 'onAbort',
5376 * captured: 'onAbortCapture',
5377 * },
5378 * dependencies: ['topAbort'],
5379 * },
5380 * ...
5381 * };
5382 * topLevelEventsToDispatchConfig = {
5383 * 'topAbort': { sameConfig }
5384 * };
5385 */
5386var eventTypes$4 = {};
5387var topLevelEventsToDispatchConfig = {};
5388['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) {
5389 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5390 var onEvent = 'on' + capitalizedEvent;
5391 var topEvent = 'top' + capitalizedEvent;
5392
5393 var type = {
5394 phasedRegistrationNames: {
5395 bubbled: onEvent,
5396 captured: onEvent + 'Capture'
5397 },
5398 dependencies: [topEvent]
5399 };
5400 eventTypes$4[event] = type;
5401 topLevelEventsToDispatchConfig[topEvent] = type;
5402});
5403
5404// Only used in DEV for exhaustiveness validation.
5405var 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'];
5406
5407var SimpleEventPlugin = {
5408 eventTypes: eventTypes$4,
5409
5410 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5411 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
5412 if (!dispatchConfig) {
5413 return null;
5414 }
5415 var EventConstructor = void 0;
5416 switch (topLevelType) {
5417 case 'topKeyPress':
5418 // Firefox creates a keypress event for function keys too. This removes
5419 // the unwanted keypress events. Enter is however both printable and
5420 // non-printable. One would expect Tab to be as well (but it isn't).
5421 if (getEventCharCode(nativeEvent) === 0) {
5422 return null;
5423 }
5424 /* falls through */
5425 case 'topKeyDown':
5426 case 'topKeyUp':
5427 EventConstructor = SyntheticKeyboardEvent;
5428 break;
5429 case 'topBlur':
5430 case 'topFocus':
5431 EventConstructor = SyntheticFocusEvent;
5432 break;
5433 case 'topClick':
5434 // Firefox creates a click event on right mouse clicks. This removes the
5435 // unwanted click events.
5436 if (nativeEvent.button === 2) {
5437 return null;
5438 }
5439 /* falls through */
5440 case 'topDoubleClick':
5441 case 'topMouseDown':
5442 case 'topMouseMove':
5443 case 'topMouseUp':
5444 // TODO: Disabled elements should not respond to mouse events
5445 /* falls through */
5446 case 'topMouseOut':
5447 case 'topMouseOver':
5448 case 'topContextMenu':
5449 EventConstructor = SyntheticMouseEvent;
5450 break;
5451 case 'topDrag':
5452 case 'topDragEnd':
5453 case 'topDragEnter':
5454 case 'topDragExit':
5455 case 'topDragLeave':
5456 case 'topDragOver':
5457 case 'topDragStart':
5458 case 'topDrop':
5459 EventConstructor = SyntheticDragEvent;
5460 break;
5461 case 'topTouchCancel':
5462 case 'topTouchEnd':
5463 case 'topTouchMove':
5464 case 'topTouchStart':
5465 EventConstructor = SyntheticTouchEvent;
5466 break;
5467 case 'topAnimationEnd':
5468 case 'topAnimationIteration':
5469 case 'topAnimationStart':
5470 EventConstructor = SyntheticAnimationEvent;
5471 break;
5472 case 'topTransitionEnd':
5473 EventConstructor = SyntheticTransitionEvent;
5474 break;
5475 case 'topScroll':
5476 EventConstructor = SyntheticUIEvent;
5477 break;
5478 case 'topWheel':
5479 EventConstructor = SyntheticWheelEvent;
5480 break;
5481 case 'topCopy':
5482 case 'topCut':
5483 case 'topPaste':
5484 EventConstructor = SyntheticClipboardEvent;
5485 break;
5486 default:
5487 {
5488 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
5489 warning_1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
5490 }
5491 }
5492 // HTML Events
5493 // @see http://www.w3.org/TR/html5/index.html#events-0
5494 EventConstructor = SyntheticEvent$1;
5495 break;
5496 }
5497 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
5498 accumulateTwoPhaseDispatches(event);
5499 return event;
5500 }
5501};
5502
5503/**
5504 * Inject modules for resolving DOM hierarchy and plugin ordering.
5505 */
5506injection.injectEventPluginOrder(DOMEventPluginOrder);
5507injection$1.injectComponentTree(ReactDOMComponentTree);
5508
5509/**
5510 * Some important event plugins included by default (without having to require
5511 * them).
5512 */
5513injection.injectEventPluginsByName({
5514 SimpleEventPlugin: SimpleEventPlugin,
5515 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5516 ChangeEventPlugin: ChangeEventPlugin,
5517 SelectEventPlugin: SelectEventPlugin,
5518 BeforeInputEventPlugin: BeforeInputEventPlugin
5519});
5520
5521/**
5522 * Copyright (c) 2013-present, Facebook, Inc.
5523 *
5524 * This source code is licensed under the MIT license found in the
5525 * LICENSE file in the root directory of this source tree.
5526 *
5527 */
5528
5529
5530
5531var emptyObject = {};
5532
5533{
5534 Object.freeze(emptyObject);
5535}
5536
5537var emptyObject_1 = emptyObject;
5538
5539var valueStack = [];
5540
5541var fiberStack = void 0;
5542
5543{
5544 fiberStack = [];
5545}
5546
5547var index = -1;
5548
5549function createCursor(defaultValue) {
5550 return {
5551 current: defaultValue
5552 };
5553}
5554
5555
5556
5557function pop(cursor, fiber) {
5558 if (index < 0) {
5559 {
5560 warning_1(false, 'Unexpected pop.');
5561 }
5562 return;
5563 }
5564
5565 {
5566 if (fiber !== fiberStack[index]) {
5567 warning_1(false, 'Unexpected Fiber popped.');
5568 }
5569 }
5570
5571 cursor.current = valueStack[index];
5572
5573 valueStack[index] = null;
5574
5575 {
5576 fiberStack[index] = null;
5577 }
5578
5579 index--;
5580}
5581
5582function push(cursor, value, fiber) {
5583 index++;
5584
5585 valueStack[index] = cursor.current;
5586
5587 {
5588 fiberStack[index] = fiber;
5589 }
5590
5591 cursor.current = value;
5592}
5593
5594function reset$1() {
5595 while (index > -1) {
5596 valueStack[index] = null;
5597
5598 {
5599 fiberStack[index] = null;
5600 }
5601
5602 index--;
5603 }
5604}
5605
5606var enableAsyncSubtreeAPI = true;
5607// Exports ReactDOM.createRoot
5608var enableCreateRoot = false;
5609var enableUserTimingAPI = true;
5610
5611// Mutating mode (React DOM, React ART, React Native):
5612var enableMutatingReconciler = true;
5613// Experimental noop mode (currently unused):
5614var enableNoopReconciler = false;
5615// Experimental persistent mode (CS):
5616var enablePersistentReconciler = false;
5617
5618// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
5619var debugRenderPhaseSideEffects = false;
5620
5621// Only used in www builds.
5622
5623// Prefix measurements so that it's possible to filter them.
5624// Longer prefixes are hard to read in DevTools.
5625var reactEmoji = '\u269B';
5626var warningEmoji = '\u26D4';
5627var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
5628
5629// Keep track of current fiber so that we know the path to unwind on pause.
5630// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5631var currentFiber = null;
5632// If we're in the middle of user code, which fiber and method is it?
5633// Reusing `currentFiber` would be confusing for this because user code fiber
5634// can change during commit phase too, but we don't need to unwind it (since
5635// lifecycles in the commit phase don't resemble a tree).
5636var currentPhase = null;
5637var currentPhaseFiber = null;
5638// Did lifecycle hook schedule an update? This is often a performance problem,
5639// so we will keep track of it, and include it in the report.
5640// Track commits caused by cascading updates.
5641var isCommitting = false;
5642var hasScheduledUpdateInCurrentCommit = false;
5643var hasScheduledUpdateInCurrentPhase = false;
5644var commitCountInCurrentWorkLoop = 0;
5645var effectCountInCurrentCommit = 0;
5646var isWaitingForCallback = false;
5647// During commits, we only show a measurement once per method name
5648// to avoid stretch the commit phase with measurement overhead.
5649var labelsInCurrentCommit = new Set();
5650
5651var formatMarkName = function (markName) {
5652 return reactEmoji + ' ' + markName;
5653};
5654
5655var formatLabel = function (label, warning) {
5656 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
5657 var suffix = warning ? ' Warning: ' + warning : '';
5658 return '' + prefix + label + suffix;
5659};
5660
5661var beginMark = function (markName) {
5662 performance.mark(formatMarkName(markName));
5663};
5664
5665var clearMark = function (markName) {
5666 performance.clearMarks(formatMarkName(markName));
5667};
5668
5669var endMark = function (label, markName, warning) {
5670 var formattedMarkName = formatMarkName(markName);
5671 var formattedLabel = formatLabel(label, warning);
5672 try {
5673 performance.measure(formattedLabel, formattedMarkName);
5674 } catch (err) {}
5675 // If previous mark was missing for some reason, this will throw.
5676 // This could only happen if React crashed in an unexpected place earlier.
5677 // Don't pile on with more errors.
5678
5679 // Clear marks immediately to avoid growing buffer.
5680 performance.clearMarks(formattedMarkName);
5681 performance.clearMeasures(formattedLabel);
5682};
5683
5684var getFiberMarkName = function (label, debugID) {
5685 return label + ' (#' + debugID + ')';
5686};
5687
5688var getFiberLabel = function (componentName, isMounted, phase) {
5689 if (phase === null) {
5690 // These are composite component total time measurements.
5691 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
5692 } else {
5693 // Composite component methods.
5694 return componentName + '.' + phase;
5695 }
5696};
5697
5698var beginFiberMark = function (fiber, phase) {
5699 var componentName = getComponentName(fiber) || 'Unknown';
5700 var debugID = fiber._debugID;
5701 var isMounted = fiber.alternate !== null;
5702 var label = getFiberLabel(componentName, isMounted, phase);
5703
5704 if (isCommitting && labelsInCurrentCommit.has(label)) {
5705 // During the commit phase, we don't show duplicate labels because
5706 // there is a fixed overhead for every measurement, and we don't
5707 // want to stretch the commit phase beyond necessary.
5708 return false;
5709 }
5710 labelsInCurrentCommit.add(label);
5711
5712 var markName = getFiberMarkName(label, debugID);
5713 beginMark(markName);
5714 return true;
5715};
5716
5717var clearFiberMark = function (fiber, phase) {
5718 var componentName = getComponentName(fiber) || 'Unknown';
5719 var debugID = fiber._debugID;
5720 var isMounted = fiber.alternate !== null;
5721 var label = getFiberLabel(componentName, isMounted, phase);
5722 var markName = getFiberMarkName(label, debugID);
5723 clearMark(markName);
5724};
5725
5726var endFiberMark = function (fiber, phase, warning) {
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 endMark(label, markName, warning);
5733};
5734
5735var shouldIgnoreFiber = function (fiber) {
5736 // Host components should be skipped in the timeline.
5737 // We could check typeof fiber.type, but does this work with RN?
5738 switch (fiber.tag) {
5739 case HostRoot:
5740 case HostComponent:
5741 case HostText:
5742 case HostPortal:
5743 case CallComponent:
5744 case ReturnComponent:
5745 case Fragment:
5746 return true;
5747 default:
5748 return false;
5749 }
5750};
5751
5752var clearPendingPhaseMeasurement = function () {
5753 if (currentPhase !== null && currentPhaseFiber !== null) {
5754 clearFiberMark(currentPhaseFiber, currentPhase);
5755 }
5756 currentPhaseFiber = null;
5757 currentPhase = null;
5758 hasScheduledUpdateInCurrentPhase = false;
5759};
5760
5761var pauseTimers = function () {
5762 // Stops all currently active measurements so that they can be resumed
5763 // if we continue in a later deferred loop from the same unit of work.
5764 var fiber = currentFiber;
5765 while (fiber) {
5766 if (fiber._debugIsCurrentlyTiming) {
5767 endFiberMark(fiber, null, null);
5768 }
5769 fiber = fiber['return'];
5770 }
5771};
5772
5773var resumeTimersRecursively = function (fiber) {
5774 if (fiber['return'] !== null) {
5775 resumeTimersRecursively(fiber['return']);
5776 }
5777 if (fiber._debugIsCurrentlyTiming) {
5778 beginFiberMark(fiber, null);
5779 }
5780};
5781
5782var resumeTimers = function () {
5783 // Resumes all measurements that were active during the last deferred loop.
5784 if (currentFiber !== null) {
5785 resumeTimersRecursively(currentFiber);
5786 }
5787};
5788
5789function recordEffect() {
5790 if (enableUserTimingAPI) {
5791 effectCountInCurrentCommit++;
5792 }
5793}
5794
5795function recordScheduleUpdate() {
5796 if (enableUserTimingAPI) {
5797 if (isCommitting) {
5798 hasScheduledUpdateInCurrentCommit = true;
5799 }
5800 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
5801 hasScheduledUpdateInCurrentPhase = true;
5802 }
5803 }
5804}
5805
5806function startRequestCallbackTimer() {
5807 if (enableUserTimingAPI) {
5808 if (supportsUserTiming && !isWaitingForCallback) {
5809 isWaitingForCallback = true;
5810 beginMark('(Waiting for async callback...)');
5811 }
5812 }
5813}
5814
5815function stopRequestCallbackTimer(didExpire) {
5816 if (enableUserTimingAPI) {
5817 if (supportsUserTiming) {
5818 isWaitingForCallback = false;
5819 var warning = didExpire ? 'React was blocked by main thread' : null;
5820 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
5821 }
5822 }
5823}
5824
5825function startWorkTimer(fiber) {
5826 if (enableUserTimingAPI) {
5827 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5828 return;
5829 }
5830 // If we pause, this is the fiber to unwind from.
5831 currentFiber = fiber;
5832 if (!beginFiberMark(fiber, null)) {
5833 return;
5834 }
5835 fiber._debugIsCurrentlyTiming = true;
5836 }
5837}
5838
5839function cancelWorkTimer(fiber) {
5840 if (enableUserTimingAPI) {
5841 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5842 return;
5843 }
5844 // Remember we shouldn't complete measurement for this fiber.
5845 // Otherwise flamechart will be deep even for small updates.
5846 fiber._debugIsCurrentlyTiming = false;
5847 clearFiberMark(fiber, null);
5848 }
5849}
5850
5851function stopWorkTimer(fiber) {
5852 if (enableUserTimingAPI) {
5853 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5854 return;
5855 }
5856 // If we pause, its parent is the fiber to unwind from.
5857 currentFiber = fiber['return'];
5858 if (!fiber._debugIsCurrentlyTiming) {
5859 return;
5860 }
5861 fiber._debugIsCurrentlyTiming = false;
5862 endFiberMark(fiber, null, null);
5863 }
5864}
5865
5866function stopFailedWorkTimer(fiber) {
5867 if (enableUserTimingAPI) {
5868 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5869 return;
5870 }
5871 // If we pause, its parent is the fiber to unwind from.
5872 currentFiber = fiber['return'];
5873 if (!fiber._debugIsCurrentlyTiming) {
5874 return;
5875 }
5876 fiber._debugIsCurrentlyTiming = false;
5877 var warning = 'An error was thrown inside this error boundary';
5878 endFiberMark(fiber, null, warning);
5879 }
5880}
5881
5882function startPhaseTimer(fiber, phase) {
5883 if (enableUserTimingAPI) {
5884 if (!supportsUserTiming) {
5885 return;
5886 }
5887 clearPendingPhaseMeasurement();
5888 if (!beginFiberMark(fiber, phase)) {
5889 return;
5890 }
5891 currentPhaseFiber = fiber;
5892 currentPhase = phase;
5893 }
5894}
5895
5896function stopPhaseTimer() {
5897 if (enableUserTimingAPI) {
5898 if (!supportsUserTiming) {
5899 return;
5900 }
5901 if (currentPhase !== null && currentPhaseFiber !== null) {
5902 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
5903 endFiberMark(currentPhaseFiber, currentPhase, warning);
5904 }
5905 currentPhase = null;
5906 currentPhaseFiber = null;
5907 }
5908}
5909
5910function startWorkLoopTimer(nextUnitOfWork) {
5911 if (enableUserTimingAPI) {
5912 currentFiber = nextUnitOfWork;
5913 if (!supportsUserTiming) {
5914 return;
5915 }
5916 commitCountInCurrentWorkLoop = 0;
5917 // This is top level call.
5918 // Any other measurements are performed within.
5919 beginMark('(React Tree Reconciliation)');
5920 // Resume any measurements that were in progress during the last loop.
5921 resumeTimers();
5922 }
5923}
5924
5925function stopWorkLoopTimer(interruptedBy) {
5926 if (enableUserTimingAPI) {
5927 if (!supportsUserTiming) {
5928 return;
5929 }
5930 var warning = null;
5931 if (interruptedBy !== null) {
5932 if (interruptedBy.tag === HostRoot) {
5933 warning = 'A top-level update interrupted the previous render';
5934 } else {
5935 var componentName = getComponentName(interruptedBy) || 'Unknown';
5936 warning = 'An update to ' + componentName + ' interrupted the previous render';
5937 }
5938 } else if (commitCountInCurrentWorkLoop > 1) {
5939 warning = 'There were cascading updates';
5940 }
5941 commitCountInCurrentWorkLoop = 0;
5942 // Pause any measurements until the next loop.
5943 pauseTimers();
5944 endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning);
5945 }
5946}
5947
5948function startCommitTimer() {
5949 if (enableUserTimingAPI) {
5950 if (!supportsUserTiming) {
5951 return;
5952 }
5953 isCommitting = true;
5954 hasScheduledUpdateInCurrentCommit = false;
5955 labelsInCurrentCommit.clear();
5956 beginMark('(Committing Changes)');
5957 }
5958}
5959
5960function stopCommitTimer() {
5961 if (enableUserTimingAPI) {
5962 if (!supportsUserTiming) {
5963 return;
5964 }
5965
5966 var warning = null;
5967 if (hasScheduledUpdateInCurrentCommit) {
5968 warning = 'Lifecycle hook scheduled a cascading update';
5969 } else if (commitCountInCurrentWorkLoop > 0) {
5970 warning = 'Caused by a cascading update in earlier commit';
5971 }
5972 hasScheduledUpdateInCurrentCommit = false;
5973 commitCountInCurrentWorkLoop++;
5974 isCommitting = false;
5975 labelsInCurrentCommit.clear();
5976
5977 endMark('(Committing Changes)', '(Committing Changes)', warning);
5978 }
5979}
5980
5981function startCommitHostEffectsTimer() {
5982 if (enableUserTimingAPI) {
5983 if (!supportsUserTiming) {
5984 return;
5985 }
5986 effectCountInCurrentCommit = 0;
5987 beginMark('(Committing Host Effects)');
5988 }
5989}
5990
5991function stopCommitHostEffectsTimer() {
5992 if (enableUserTimingAPI) {
5993 if (!supportsUserTiming) {
5994 return;
5995 }
5996 var count = effectCountInCurrentCommit;
5997 effectCountInCurrentCommit = 0;
5998 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
5999 }
6000}
6001
6002function startCommitLifeCyclesTimer() {
6003 if (enableUserTimingAPI) {
6004 if (!supportsUserTiming) {
6005 return;
6006 }
6007 effectCountInCurrentCommit = 0;
6008 beginMark('(Calling Lifecycle Methods)');
6009 }
6010}
6011
6012function stopCommitLifeCyclesTimer() {
6013 if (enableUserTimingAPI) {
6014 if (!supportsUserTiming) {
6015 return;
6016 }
6017 var count = effectCountInCurrentCommit;
6018 effectCountInCurrentCommit = 0;
6019 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
6020 }
6021}
6022
6023var warnedAboutMissingGetChildContext = void 0;
6024
6025{
6026 warnedAboutMissingGetChildContext = {};
6027}
6028
6029// A cursor to the current merged context object on the stack.
6030var contextStackCursor = createCursor(emptyObject_1);
6031// A cursor to a boolean indicating whether the context has changed.
6032var didPerformWorkStackCursor = createCursor(false);
6033// Keep track of the previous context object that was on the stack.
6034// We use this to get access to the parent context after we have already
6035// pushed the next context provider, and now need to merge their contexts.
6036var previousContext = emptyObject_1;
6037
6038function getUnmaskedContext(workInProgress) {
6039 var hasOwnContext = isContextProvider(workInProgress);
6040 if (hasOwnContext) {
6041 // If the fiber is a context provider itself, when we read its context
6042 // we have already pushed its own child context on the stack. A context
6043 // provider should not "see" its own child context. Therefore we read the
6044 // previous (parent) context instead for a context provider.
6045 return previousContext;
6046 }
6047 return contextStackCursor.current;
6048}
6049
6050function cacheContext(workInProgress, unmaskedContext, maskedContext) {
6051 var instance = workInProgress.stateNode;
6052 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
6053 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
6054}
6055
6056function getMaskedContext(workInProgress, unmaskedContext) {
6057 var type = workInProgress.type;
6058 var contextTypes = type.contextTypes;
6059 if (!contextTypes) {
6060 return emptyObject_1;
6061 }
6062
6063 // Avoid recreating masked context unless unmasked context has changed.
6064 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
6065 // This may trigger infinite loops if componentWillReceiveProps calls setState.
6066 var instance = workInProgress.stateNode;
6067 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
6068 return instance.__reactInternalMemoizedMaskedChildContext;
6069 }
6070
6071 var context = {};
6072 for (var key in contextTypes) {
6073 context[key] = unmaskedContext[key];
6074 }
6075
6076 {
6077 var name = getComponentName(workInProgress) || 'Unknown';
6078 checkPropTypes_1(contextTypes, context, 'context', name, ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6079 }
6080
6081 // Cache unmasked context so we can avoid recreating masked context unless necessary.
6082 // Context is created before the class component is instantiated so check for instance.
6083 if (instance) {
6084 cacheContext(workInProgress, unmaskedContext, context);
6085 }
6086
6087 return context;
6088}
6089
6090function hasContextChanged() {
6091 return didPerformWorkStackCursor.current;
6092}
6093
6094function isContextConsumer(fiber) {
6095 return fiber.tag === ClassComponent && fiber.type.contextTypes != null;
6096}
6097
6098function isContextProvider(fiber) {
6099 return fiber.tag === ClassComponent && fiber.type.childContextTypes != null;
6100}
6101
6102function popContextProvider(fiber) {
6103 if (!isContextProvider(fiber)) {
6104 return;
6105 }
6106
6107 pop(didPerformWorkStackCursor, fiber);
6108 pop(contextStackCursor, fiber);
6109}
6110
6111function popTopLevelContextObject(fiber) {
6112 pop(didPerformWorkStackCursor, fiber);
6113 pop(contextStackCursor, fiber);
6114}
6115
6116function pushTopLevelContextObject(fiber, context, didChange) {
6117 !(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;
6118
6119 push(contextStackCursor, context, fiber);
6120 push(didPerformWorkStackCursor, didChange, fiber);
6121}
6122
6123function processChildContext(fiber, parentContext) {
6124 var instance = fiber.stateNode;
6125 var childContextTypes = fiber.type.childContextTypes;
6126
6127 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
6128 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
6129 if (typeof instance.getChildContext !== 'function') {
6130 {
6131 var componentName = getComponentName(fiber) || 'Unknown';
6132
6133 if (!warnedAboutMissingGetChildContext[componentName]) {
6134 warnedAboutMissingGetChildContext[componentName] = true;
6135 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);
6136 }
6137 }
6138 return parentContext;
6139 }
6140
6141 var childContext = void 0;
6142 {
6143 ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
6144 }
6145 startPhaseTimer(fiber, 'getChildContext');
6146 childContext = instance.getChildContext();
6147 stopPhaseTimer();
6148 {
6149 ReactDebugCurrentFiber.setCurrentPhase(null);
6150 }
6151 for (var contextKey in childContext) {
6152 !(contextKey in childContextTypes) ? invariant_1(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(fiber) || 'Unknown', contextKey) : void 0;
6153 }
6154 {
6155 var name = getComponentName(fiber) || 'Unknown';
6156 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
6157 // In practice, there is one case in which we won't get a stack. It's when
6158 // somebody calls unstable_renderSubtreeIntoContainer() and we process
6159 // context from the parent component instance. The stack will be missing
6160 // because it's outside of the reconciliation, and so the pointer has not
6161 // been set. This is rare and doesn't matter. We'll also remove that API.
6162 ReactDebugCurrentFiber.getCurrentFiberStackAddendum);
6163 }
6164
6165 return _assign({}, parentContext, childContext);
6166}
6167
6168function pushContextProvider(workInProgress) {
6169 if (!isContextProvider(workInProgress)) {
6170 return false;
6171 }
6172
6173 var instance = workInProgress.stateNode;
6174 // We push the context as early as possible to ensure stack integrity.
6175 // If the instance does not exist yet, we will push null at first,
6176 // and replace it on the stack later when invalidating the context.
6177 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject_1;
6178
6179 // Remember the parent context so we can merge with it later.
6180 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
6181 previousContext = contextStackCursor.current;
6182 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
6183 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
6184
6185 return true;
6186}
6187
6188function invalidateContextProvider(workInProgress, didChange) {
6189 var instance = workInProgress.stateNode;
6190 !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;
6191
6192 if (didChange) {
6193 // Merge parent and own context.
6194 // Skip this if we're not updating due to sCU.
6195 // This avoids unnecessarily recomputing memoized values.
6196 var mergedContext = processChildContext(workInProgress, previousContext);
6197 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
6198
6199 // Replace the old (or empty) context with the new one.
6200 // It is important to unwind the context in the reverse order.
6201 pop(didPerformWorkStackCursor, workInProgress);
6202 pop(contextStackCursor, workInProgress);
6203 // Now push the new context and mark that it has changed.
6204 push(contextStackCursor, mergedContext, workInProgress);
6205 push(didPerformWorkStackCursor, didChange, workInProgress);
6206 } else {
6207 pop(didPerformWorkStackCursor, workInProgress);
6208 push(didPerformWorkStackCursor, didChange, workInProgress);
6209 }
6210}
6211
6212function resetContext() {
6213 previousContext = emptyObject_1;
6214 contextStackCursor.current = emptyObject_1;
6215 didPerformWorkStackCursor.current = false;
6216}
6217
6218function findCurrentUnmaskedContext(fiber) {
6219 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
6220 // makes sense elsewhere
6221 !(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;
6222
6223 var node = fiber;
6224 while (node.tag !== HostRoot) {
6225 if (isContextProvider(node)) {
6226 return node.stateNode.__reactInternalMemoizedMergedChildContext;
6227 }
6228 var parent = node['return'];
6229 !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;
6230 node = parent;
6231 }
6232 return node.stateNode.context;
6233}
6234
6235var NoWork = 0; // TODO: Use an opaque type once ESLint et al support the syntax
6236
6237var Sync = 1;
6238var Never = 2147483647; // Max int32: Math.pow(2, 31) - 1
6239
6240var UNIT_SIZE = 10;
6241var MAGIC_NUMBER_OFFSET = 2;
6242
6243// 1 unit of expiration time represents 10ms.
6244function msToExpirationTime(ms) {
6245 // Always add an offset so that we don't clash with the magic number for NoWork.
6246 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET;
6247}
6248
6249function expirationTimeToMs(expirationTime) {
6250 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE;
6251}
6252
6253function ceiling(num, precision) {
6254 return ((num / precision | 0) + 1) * precision;
6255}
6256
6257function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6258 return ceiling(currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
6259}
6260
6261var NoContext = 0;
6262var AsyncUpdates = 1;
6263
6264var hasBadMapPolyfill = void 0;
6265
6266{
6267 hasBadMapPolyfill = false;
6268 try {
6269 var nonExtensibleObject = Object.preventExtensions({});
6270 var testMap = new Map([[nonExtensibleObject, null]]);
6271 var testSet = new Set([nonExtensibleObject]);
6272 // This is necessary for Rollup to not consider these unused.
6273 // https://github.com/rollup/rollup/issues/1771
6274 // TODO: we can remove these if Rollup fixes the bug.
6275 testMap.set(0, 0);
6276 testSet.add(0);
6277 } catch (e) {
6278 // TODO: Consider warning about bad polyfills
6279 hasBadMapPolyfill = true;
6280 }
6281}
6282
6283// A Fiber is work on a Component that needs to be done or was done. There can
6284// be more than one per component.
6285
6286
6287var debugCounter = void 0;
6288
6289{
6290 debugCounter = 1;
6291}
6292
6293function FiberNode(tag, pendingProps, key, internalContextTag) {
6294 // Instance
6295 this.tag = tag;
6296 this.key = key;
6297 this.type = null;
6298 this.stateNode = null;
6299
6300 // Fiber
6301 this['return'] = null;
6302 this.child = null;
6303 this.sibling = null;
6304 this.index = 0;
6305
6306 this.ref = null;
6307
6308 this.pendingProps = pendingProps;
6309 this.memoizedProps = null;
6310 this.updateQueue = null;
6311 this.memoizedState = null;
6312
6313 this.internalContextTag = internalContextTag;
6314
6315 // Effects
6316 this.effectTag = NoEffect;
6317 this.nextEffect = null;
6318
6319 this.firstEffect = null;
6320 this.lastEffect = null;
6321
6322 this.expirationTime = NoWork;
6323
6324 this.alternate = null;
6325
6326 {
6327 this._debugID = debugCounter++;
6328 this._debugSource = null;
6329 this._debugOwner = null;
6330 this._debugIsCurrentlyTiming = false;
6331 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
6332 Object.preventExtensions(this);
6333 }
6334 }
6335}
6336
6337// This is a constructor function, rather than a POJO constructor, still
6338// please ensure we do the following:
6339// 1) Nobody should add any instance methods on this. Instance methods can be
6340// more difficult to predict when they get optimized and they are almost
6341// never inlined properly in static compilers.
6342// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
6343// always know when it is a fiber.
6344// 3) We might want to experiment with using numeric keys since they are easier
6345// to optimize in a non-JIT environment.
6346// 4) We can easily go from a constructor to a createFiber object literal if that
6347// is faster.
6348// 5) It should be easy to port this to a C struct and keep a C implementation
6349// compatible.
6350var createFiber = function (tag, pendingProps, key, internalContextTag) {
6351 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
6352 return new FiberNode(tag, pendingProps, key, internalContextTag);
6353};
6354
6355function shouldConstruct(Component) {
6356 return !!(Component.prototype && Component.prototype.isReactComponent);
6357}
6358
6359// This is used to create an alternate fiber to do work on.
6360function createWorkInProgress(current, pendingProps, expirationTime) {
6361 var workInProgress = current.alternate;
6362 if (workInProgress === null) {
6363 // We use a double buffering pooling technique because we know that we'll
6364 // only ever need at most two versions of a tree. We pool the "other" unused
6365 // node that we're free to reuse. This is lazily created to avoid allocating
6366 // extra objects for things that are never updated. It also allow us to
6367 // reclaim the extra memory if needed.
6368 workInProgress = createFiber(current.tag, pendingProps, current.key, current.internalContextTag);
6369 workInProgress.type = current.type;
6370 workInProgress.stateNode = current.stateNode;
6371
6372 {
6373 // DEV-only fields
6374 workInProgress._debugID = current._debugID;
6375 workInProgress._debugSource = current._debugSource;
6376 workInProgress._debugOwner = current._debugOwner;
6377 }
6378
6379 workInProgress.alternate = current;
6380 current.alternate = workInProgress;
6381 } else {
6382 workInProgress.pendingProps = pendingProps;
6383
6384 // We already have an alternate.
6385 // Reset the effect tag.
6386 workInProgress.effectTag = NoEffect;
6387
6388 // The effect list is no longer valid.
6389 workInProgress.nextEffect = null;
6390 workInProgress.firstEffect = null;
6391 workInProgress.lastEffect = null;
6392 }
6393
6394 workInProgress.expirationTime = expirationTime;
6395
6396 workInProgress.child = current.child;
6397 workInProgress.memoizedProps = current.memoizedProps;
6398 workInProgress.memoizedState = current.memoizedState;
6399 workInProgress.updateQueue = current.updateQueue;
6400
6401 // These will be overridden during the parent's reconciliation
6402 workInProgress.sibling = current.sibling;
6403 workInProgress.index = current.index;
6404 workInProgress.ref = current.ref;
6405
6406 return workInProgress;
6407}
6408
6409function createHostRootFiber(isAsync) {
6410 var internalContextTag = isAsync ? AsyncUpdates : NoContext;
6411 return createFiber(HostRoot, null, null, internalContextTag);
6412}
6413
6414function createFiberFromElement(element, internalContextTag, expirationTime) {
6415 var owner = null;
6416 {
6417 owner = element._owner;
6418 }
6419
6420 var fiber = void 0;
6421 var type = element.type;
6422 var key = element.key;
6423 var pendingProps = element.props;
6424 if (typeof type === 'function') {
6425 fiber = shouldConstruct(type) ? createFiber(ClassComponent, pendingProps, key, internalContextTag) : createFiber(IndeterminateComponent, pendingProps, key, internalContextTag);
6426 fiber.type = type;
6427 } else if (typeof type === 'string') {
6428 fiber = createFiber(HostComponent, pendingProps, key, internalContextTag);
6429 fiber.type = type;
6430 } else {
6431 switch (type) {
6432 case REACT_FRAGMENT_TYPE:
6433 return createFiberFromFragment(pendingProps.children, internalContextTag, expirationTime, key);
6434 case REACT_CALL_TYPE:
6435 fiber = createFiber(CallComponent, pendingProps, key, internalContextTag);
6436 fiber.type = REACT_CALL_TYPE;
6437 break;
6438 case REACT_RETURN_TYPE:
6439 fiber = createFiber(ReturnComponent, pendingProps, key, internalContextTag);
6440 fiber.type = REACT_RETURN_TYPE;
6441 break;
6442 default:
6443 {
6444 if (typeof type === 'object' && type !== null && typeof type.tag === 'number') {
6445 // Currently assumed to be a continuation and therefore is a
6446 // fiber already.
6447 // TODO: The yield system is currently broken for updates in some
6448 // cases. The reified yield stores a fiber, but we don't know which
6449 // fiber that is; the current or a workInProgress? When the
6450 // continuation gets rendered here we don't know if we can reuse that
6451 // fiber or if we need to clone it. There is probably a clever way to
6452 // restructure this.
6453 fiber = type;
6454 fiber.pendingProps = pendingProps;
6455 } else {
6456 var info = '';
6457 {
6458 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
6459 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.';
6460 }
6461 var ownerName = owner ? getComponentName(owner) : null;
6462 if (ownerName) {
6463 info += '\n\nCheck the render method of `' + ownerName + '`.';
6464 }
6465 }
6466 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);
6467 }
6468 }
6469 }
6470 }
6471
6472 {
6473 fiber._debugSource = element._source;
6474 fiber._debugOwner = element._owner;
6475 }
6476
6477 fiber.expirationTime = expirationTime;
6478
6479 return fiber;
6480}
6481
6482function createFiberFromFragment(elements, internalContextTag, expirationTime, key) {
6483 var fiber = createFiber(Fragment, elements, key, internalContextTag);
6484 fiber.expirationTime = expirationTime;
6485 return fiber;
6486}
6487
6488function createFiberFromText(content, internalContextTag, expirationTime) {
6489 var fiber = createFiber(HostText, content, null, internalContextTag);
6490 fiber.expirationTime = expirationTime;
6491 return fiber;
6492}
6493
6494function createFiberFromHostInstanceForDeletion() {
6495 var fiber = createFiber(HostComponent, null, null, NoContext);
6496 fiber.type = 'DELETED';
6497 return fiber;
6498}
6499
6500function createFiberFromPortal(portal, internalContextTag, expirationTime) {
6501 var pendingProps = portal.children !== null ? portal.children : [];
6502 var fiber = createFiber(HostPortal, pendingProps, portal.key, internalContextTag);
6503 fiber.expirationTime = expirationTime;
6504 fiber.stateNode = {
6505 containerInfo: portal.containerInfo,
6506 pendingChildren: null, // Used by persistent updates
6507 implementation: portal.implementation
6508 };
6509 return fiber;
6510}
6511
6512// TODO: This should be lifted into the renderer.
6513
6514
6515function createFiberRoot(containerInfo, isAsync, hydrate) {
6516 // Cyclic construction. This cheats the type system right now because
6517 // stateNode is any.
6518 var uninitializedFiber = createHostRootFiber(isAsync);
6519 var root = {
6520 current: uninitializedFiber,
6521 containerInfo: containerInfo,
6522 pendingChildren: null,
6523 remainingExpirationTime: NoWork,
6524 isReadyForCommit: false,
6525 finishedWork: null,
6526 context: null,
6527 pendingContext: null,
6528 hydrate: hydrate,
6529 firstBatch: null,
6530 nextScheduledRoot: null
6531 };
6532 uninitializedFiber.stateNode = root;
6533 return root;
6534}
6535
6536var onCommitFiberRoot = null;
6537var onCommitFiberUnmount = null;
6538var hasLoggedError = false;
6539
6540function catchErrors(fn) {
6541 return function (arg) {
6542 try {
6543 return fn(arg);
6544 } catch (err) {
6545 if (true && !hasLoggedError) {
6546 hasLoggedError = true;
6547 warning_1(false, 'React DevTools encountered an error: %s', err);
6548 }
6549 }
6550 };
6551}
6552
6553function injectInternals(internals) {
6554 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
6555 // No DevTools
6556 return false;
6557 }
6558 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
6559 if (hook.isDisabled) {
6560 // This isn't a real property on the hook, but it can be set to opt out
6561 // of DevTools integration and associated warnings and logs.
6562 // https://github.com/facebook/react/issues/3877
6563 return true;
6564 }
6565 if (!hook.supportsFiber) {
6566 {
6567 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');
6568 }
6569 // DevTools exists, even though it doesn't support Fiber.
6570 return true;
6571 }
6572 try {
6573 var rendererID = hook.inject(internals);
6574 // We have successfully injected, so now it is safe to set up hooks.
6575 onCommitFiberRoot = catchErrors(function (root) {
6576 return hook.onCommitFiberRoot(rendererID, root);
6577 });
6578 onCommitFiberUnmount = catchErrors(function (fiber) {
6579 return hook.onCommitFiberUnmount(rendererID, fiber);
6580 });
6581 } catch (err) {
6582 // Catch all errors because it is unsafe to throw during initialization.
6583 {
6584 warning_1(false, 'React DevTools encountered an error: %s.', err);
6585 }
6586 }
6587 // DevTools exists
6588 return true;
6589}
6590
6591function onCommitRoot(root) {
6592 if (typeof onCommitFiberRoot === 'function') {
6593 onCommitFiberRoot(root);
6594 }
6595}
6596
6597function onCommitUnmount(fiber) {
6598 if (typeof onCommitFiberUnmount === 'function') {
6599 onCommitFiberUnmount(fiber);
6600 }
6601}
6602
6603var didWarnUpdateInsideUpdate = void 0;
6604
6605{
6606 didWarnUpdateInsideUpdate = false;
6607}
6608
6609// Callbacks are not validated until invocation
6610
6611
6612// Singly linked-list of updates. When an update is scheduled, it is added to
6613// the queue of the current fiber and the work-in-progress fiber. The two queues
6614// are separate but they share a persistent structure.
6615//
6616// During reconciliation, updates are removed from the work-in-progress fiber,
6617// but they remain on the current fiber. That ensures that if a work-in-progress
6618// is aborted, the aborted updates are recovered by cloning from current.
6619//
6620// The work-in-progress queue is always a subset of the current queue.
6621//
6622// When the tree is committed, the work-in-progress becomes the current.
6623
6624
6625function createUpdateQueue(baseState) {
6626 var queue = {
6627 baseState: baseState,
6628 expirationTime: NoWork,
6629 first: null,
6630 last: null,
6631 callbackList: null,
6632 hasForceUpdate: false,
6633 isInitialized: false
6634 };
6635 {
6636 queue.isProcessing = false;
6637 }
6638 return queue;
6639}
6640
6641function insertUpdateIntoQueue(queue, update) {
6642 // Append the update to the end of the list.
6643 if (queue.last === null) {
6644 // Queue is empty
6645 queue.first = queue.last = update;
6646 } else {
6647 queue.last.next = update;
6648 queue.last = update;
6649 }
6650 if (queue.expirationTime === NoWork || queue.expirationTime > update.expirationTime) {
6651 queue.expirationTime = update.expirationTime;
6652 }
6653}
6654
6655function insertUpdateIntoFiber(fiber, update) {
6656 // We'll have at least one and at most two distinct update queues.
6657 var alternateFiber = fiber.alternate;
6658 var queue1 = fiber.updateQueue;
6659 if (queue1 === null) {
6660 // TODO: We don't know what the base state will be until we begin work.
6661 // It depends on which fiber is the next current. Initialize with an empty
6662 // base state, then set to the memoizedState when rendering. Not super
6663 // happy with this approach.
6664 queue1 = fiber.updateQueue = createUpdateQueue(null);
6665 }
6666
6667 var queue2 = void 0;
6668 if (alternateFiber !== null) {
6669 queue2 = alternateFiber.updateQueue;
6670 if (queue2 === null) {
6671 queue2 = alternateFiber.updateQueue = createUpdateQueue(null);
6672 }
6673 } else {
6674 queue2 = null;
6675 }
6676 queue2 = queue2 !== queue1 ? queue2 : null;
6677
6678 // Warn if an update is scheduled from inside an updater function.
6679 {
6680 if ((queue1.isProcessing || queue2 !== null && queue2.isProcessing) && !didWarnUpdateInsideUpdate) {
6681 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.');
6682 didWarnUpdateInsideUpdate = true;
6683 }
6684 }
6685
6686 // If there's only one queue, add the update to that queue and exit.
6687 if (queue2 === null) {
6688 insertUpdateIntoQueue(queue1, update);
6689 return;
6690 }
6691
6692 // If either queue is empty, we need to add to both queues.
6693 if (queue1.last === null || queue2.last === null) {
6694 insertUpdateIntoQueue(queue1, update);
6695 insertUpdateIntoQueue(queue2, update);
6696 return;
6697 }
6698
6699 // If both lists are not empty, the last update is the same for both lists
6700 // because of structural sharing. So, we should only append to one of
6701 // the lists.
6702 insertUpdateIntoQueue(queue1, update);
6703 // But we still need to update the `last` pointer of queue2.
6704 queue2.last = update;
6705}
6706
6707function getUpdateExpirationTime(fiber) {
6708 if (fiber.tag !== ClassComponent && fiber.tag !== HostRoot) {
6709 return NoWork;
6710 }
6711 var updateQueue = fiber.updateQueue;
6712 if (updateQueue === null) {
6713 return NoWork;
6714 }
6715 return updateQueue.expirationTime;
6716}
6717
6718function getStateFromUpdate(update, instance, prevState, props) {
6719 var partialState = update.partialState;
6720 if (typeof partialState === 'function') {
6721 var updateFn = partialState;
6722
6723 // Invoke setState callback an extra time to help detect side-effects.
6724 if (debugRenderPhaseSideEffects) {
6725 updateFn.call(instance, prevState, props);
6726 }
6727
6728 return updateFn.call(instance, prevState, props);
6729 } else {
6730 return partialState;
6731 }
6732}
6733
6734function processUpdateQueue(current, workInProgress, queue, instance, props, renderExpirationTime) {
6735 if (current !== null && current.updateQueue === queue) {
6736 // We need to create a work-in-progress queue, by cloning the current queue.
6737 var currentQueue = queue;
6738 queue = workInProgress.updateQueue = {
6739 baseState: currentQueue.baseState,
6740 expirationTime: currentQueue.expirationTime,
6741 first: currentQueue.first,
6742 last: currentQueue.last,
6743 isInitialized: currentQueue.isInitialized,
6744 // These fields are no longer valid because they were already committed.
6745 // Reset them.
6746 callbackList: null,
6747 hasForceUpdate: false
6748 };
6749 }
6750
6751 {
6752 // Set this flag so we can warn if setState is called inside the update
6753 // function of another setState.
6754 queue.isProcessing = true;
6755 }
6756
6757 // Reset the remaining expiration time. If we skip over any updates, we'll
6758 // increase this accordingly.
6759 queue.expirationTime = NoWork;
6760
6761 // TODO: We don't know what the base state will be until we begin work.
6762 // It depends on which fiber is the next current. Initialize with an empty
6763 // base state, then set to the memoizedState when rendering. Not super
6764 // happy with this approach.
6765 var state = void 0;
6766 if (queue.isInitialized) {
6767 state = queue.baseState;
6768 } else {
6769 state = queue.baseState = workInProgress.memoizedState;
6770 queue.isInitialized = true;
6771 }
6772 var dontMutatePrevState = true;
6773 var update = queue.first;
6774 var didSkip = false;
6775 while (update !== null) {
6776 var updateExpirationTime = update.expirationTime;
6777 if (updateExpirationTime > renderExpirationTime) {
6778 // This update does not have sufficient priority. Skip it.
6779 var remainingExpirationTime = queue.expirationTime;
6780 if (remainingExpirationTime === NoWork || remainingExpirationTime > updateExpirationTime) {
6781 // Update the remaining expiration time.
6782 queue.expirationTime = updateExpirationTime;
6783 }
6784 if (!didSkip) {
6785 didSkip = true;
6786 queue.baseState = state;
6787 }
6788 // Continue to the next update.
6789 update = update.next;
6790 continue;
6791 }
6792
6793 // This update does have sufficient priority.
6794
6795 // If no previous updates were skipped, drop this update from the queue by
6796 // advancing the head of the list.
6797 if (!didSkip) {
6798 queue.first = update.next;
6799 if (queue.first === null) {
6800 queue.last = null;
6801 }
6802 }
6803
6804 // Process the update
6805 var _partialState = void 0;
6806 if (update.isReplace) {
6807 state = getStateFromUpdate(update, instance, state, props);
6808 dontMutatePrevState = true;
6809 } else {
6810 _partialState = getStateFromUpdate(update, instance, state, props);
6811 if (_partialState) {
6812 if (dontMutatePrevState) {
6813 // $FlowFixMe: Idk how to type this properly.
6814 state = _assign({}, state, _partialState);
6815 } else {
6816 state = _assign(state, _partialState);
6817 }
6818 dontMutatePrevState = false;
6819 }
6820 }
6821 if (update.isForced) {
6822 queue.hasForceUpdate = true;
6823 }
6824 if (update.callback !== null) {
6825 // Append to list of callbacks.
6826 var _callbackList = queue.callbackList;
6827 if (_callbackList === null) {
6828 _callbackList = queue.callbackList = [];
6829 }
6830 _callbackList.push(update);
6831 }
6832 update = update.next;
6833 }
6834
6835 if (queue.callbackList !== null) {
6836 workInProgress.effectTag |= Callback;
6837 } else if (queue.first === null && !queue.hasForceUpdate) {
6838 // The queue is empty. We can reset it.
6839 workInProgress.updateQueue = null;
6840 }
6841
6842 if (!didSkip) {
6843 didSkip = true;
6844 queue.baseState = state;
6845 }
6846
6847 {
6848 // No longer processing.
6849 queue.isProcessing = false;
6850 }
6851
6852 return state;
6853}
6854
6855function commitCallbacks(queue, context) {
6856 var callbackList = queue.callbackList;
6857 if (callbackList === null) {
6858 return;
6859 }
6860 // Set the list to null to make sure they don't get called more than once.
6861 queue.callbackList = null;
6862 for (var i = 0; i < callbackList.length; i++) {
6863 var update = callbackList[i];
6864 var _callback = update.callback;
6865 // This update might be processed again. Clear the callback so it's only
6866 // called once.
6867 update.callback = null;
6868 !(typeof _callback === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0;
6869 _callback.call(context);
6870 }
6871}
6872
6873var fakeInternalInstance = {};
6874var isArray = Array.isArray;
6875
6876var didWarnAboutStateAssignmentForComponent = void 0;
6877var warnOnInvalidCallback$1 = void 0;
6878
6879{
6880 var didWarnOnInvalidCallback = {};
6881 didWarnAboutStateAssignmentForComponent = {};
6882
6883 warnOnInvalidCallback$1 = function (callback, callerName) {
6884 if (callback === null || typeof callback === 'function') {
6885 return;
6886 }
6887 var key = callerName + '_' + callback;
6888 if (!didWarnOnInvalidCallback[key]) {
6889 warning_1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
6890 didWarnOnInvalidCallback[key] = true;
6891 }
6892 };
6893
6894 // This is so gross but it's at least non-critical and can be removed if
6895 // it causes problems. This is meant to give a nicer error message for
6896 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
6897 // ...)) which otherwise throws a "_processChildContext is not a function"
6898 // exception.
6899 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
6900 enumerable: false,
6901 value: function () {
6902 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).');
6903 }
6904 });
6905 Object.freeze(fakeInternalInstance);
6906}
6907
6908var ReactFiberClassComponent = function (scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState) {
6909 // Class component state updater
6910 var updater = {
6911 isMounted: isMounted,
6912 enqueueSetState: function (instance, partialState, callback) {
6913 var fiber = get(instance);
6914 callback = callback === undefined ? null : callback;
6915 {
6916 warnOnInvalidCallback$1(callback, 'setState');
6917 }
6918 var expirationTime = computeExpirationForFiber(fiber);
6919 var update = {
6920 expirationTime: expirationTime,
6921 partialState: partialState,
6922 callback: callback,
6923 isReplace: false,
6924 isForced: false,
6925 nextCallback: null,
6926 next: null
6927 };
6928 insertUpdateIntoFiber(fiber, update);
6929 scheduleWork(fiber, expirationTime);
6930 },
6931 enqueueReplaceState: function (instance, state, callback) {
6932 var fiber = get(instance);
6933 callback = callback === undefined ? null : callback;
6934 {
6935 warnOnInvalidCallback$1(callback, 'replaceState');
6936 }
6937 var expirationTime = computeExpirationForFiber(fiber);
6938 var update = {
6939 expirationTime: expirationTime,
6940 partialState: state,
6941 callback: callback,
6942 isReplace: true,
6943 isForced: false,
6944 nextCallback: null,
6945 next: null
6946 };
6947 insertUpdateIntoFiber(fiber, update);
6948 scheduleWork(fiber, expirationTime);
6949 },
6950 enqueueForceUpdate: function (instance, callback) {
6951 var fiber = get(instance);
6952 callback = callback === undefined ? null : callback;
6953 {
6954 warnOnInvalidCallback$1(callback, 'forceUpdate');
6955 }
6956 var expirationTime = computeExpirationForFiber(fiber);
6957 var update = {
6958 expirationTime: expirationTime,
6959 partialState: null,
6960 callback: callback,
6961 isReplace: false,
6962 isForced: true,
6963 nextCallback: null,
6964 next: null
6965 };
6966 insertUpdateIntoFiber(fiber, update);
6967 scheduleWork(fiber, expirationTime);
6968 }
6969 };
6970
6971 function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
6972 if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) {
6973 // If the workInProgress already has an Update effect, return true
6974 return true;
6975 }
6976
6977 var instance = workInProgress.stateNode;
6978 var type = workInProgress.type;
6979 if (typeof instance.shouldComponentUpdate === 'function') {
6980 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
6981 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext);
6982 stopPhaseTimer();
6983
6984 // Simulate an async bailout/interruption by invoking lifecycle twice.
6985 if (debugRenderPhaseSideEffects) {
6986 instance.shouldComponentUpdate(newProps, newState, newContext);
6987 }
6988
6989 {
6990 warning_1(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(workInProgress) || 'Unknown');
6991 }
6992
6993 return shouldUpdate;
6994 }
6995
6996 if (type.prototype && type.prototype.isPureReactComponent) {
6997 return !shallowEqual_1(oldProps, newProps) || !shallowEqual_1(oldState, newState);
6998 }
6999
7000 return true;
7001 }
7002
7003 function checkClassInstance(workInProgress) {
7004 var instance = workInProgress.stateNode;
7005 var type = workInProgress.type;
7006 {
7007 var name = getComponentName(workInProgress);
7008 var renderPresent = instance.render;
7009
7010 if (!renderPresent) {
7011 if (type.prototype && typeof type.prototype.render === 'function') {
7012 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
7013 } else {
7014 warning_1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
7015 }
7016 }
7017
7018 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
7019 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);
7020 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
7021 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);
7022 var noInstancePropTypes = !instance.propTypes;
7023 warning_1(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
7024 var noInstanceContextTypes = !instance.contextTypes;
7025 warning_1(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
7026 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
7027 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);
7028 if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
7029 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');
7030 }
7031 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
7032 warning_1(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
7033 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
7034 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);
7035 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
7036 warning_1(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
7037 var hasMutatedProps = instance.props !== workInProgress.pendingProps;
7038 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);
7039 var noInstanceDefaultProps = !instance.defaultProps;
7040 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);
7041 }
7042
7043 var state = instance.state;
7044 if (state && (typeof state !== 'object' || isArray(state))) {
7045 warning_1(false, '%s.state: must be set to an object or null', getComponentName(workInProgress));
7046 }
7047 if (typeof instance.getChildContext === 'function') {
7048 warning_1(typeof workInProgress.type.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', getComponentName(workInProgress));
7049 }
7050 }
7051
7052 function resetInputPointers(workInProgress, instance) {
7053 instance.props = workInProgress.memoizedProps;
7054 instance.state = workInProgress.memoizedState;
7055 }
7056
7057 function adoptClassInstance(workInProgress, instance) {
7058 instance.updater = updater;
7059 workInProgress.stateNode = instance;
7060 // The instance needs access to the fiber so that it can schedule updates
7061 set(instance, workInProgress);
7062 {
7063 instance._reactInternalInstance = fakeInternalInstance;
7064 }
7065 }
7066
7067 function constructClassInstance(workInProgress, props) {
7068 var ctor = workInProgress.type;
7069 var unmaskedContext = getUnmaskedContext(workInProgress);
7070 var needsContext = isContextConsumer(workInProgress);
7071 var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject_1;
7072 var instance = new ctor(props, context);
7073 adoptClassInstance(workInProgress, instance);
7074
7075 // Cache unmasked context so we can avoid recreating masked context unless necessary.
7076 // ReactFiberContext usually updates this cache but can't for newly-created instances.
7077 if (needsContext) {
7078 cacheContext(workInProgress, unmaskedContext, context);
7079 }
7080
7081 return instance;
7082 }
7083
7084 function callComponentWillMount(workInProgress, instance) {
7085 startPhaseTimer(workInProgress, 'componentWillMount');
7086 var oldState = instance.state;
7087 instance.componentWillMount();
7088 stopPhaseTimer();
7089
7090 if (oldState !== instance.state) {
7091 {
7092 warning_1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress));
7093 }
7094 updater.enqueueReplaceState(instance, instance.state, null);
7095 }
7096 }
7097
7098 function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) {
7099 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
7100 var oldState = instance.state;
7101 instance.componentWillReceiveProps(newProps, newContext);
7102 stopPhaseTimer();
7103
7104 // Simulate an async bailout/interruption by invoking lifecycle twice.
7105 if (debugRenderPhaseSideEffects) {
7106 instance.componentWillReceiveProps(newProps, newContext);
7107 }
7108
7109 if (instance.state !== oldState) {
7110 {
7111 var componentName = getComponentName(workInProgress) || 'Component';
7112 if (!didWarnAboutStateAssignmentForComponent[componentName]) {
7113 warning_1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
7114 didWarnAboutStateAssignmentForComponent[componentName] = true;
7115 }
7116 }
7117 updater.enqueueReplaceState(instance, instance.state, null);
7118 }
7119 }
7120
7121 // Invokes the mount life-cycles on a previously never rendered instance.
7122 function mountClassInstance(workInProgress, renderExpirationTime) {
7123 var current = workInProgress.alternate;
7124
7125 {
7126 checkClassInstance(workInProgress);
7127 }
7128
7129 var instance = workInProgress.stateNode;
7130 var state = instance.state || null;
7131 var props = workInProgress.pendingProps;
7132 var unmaskedContext = getUnmaskedContext(workInProgress);
7133
7134 instance.props = props;
7135 instance.state = workInProgress.memoizedState = state;
7136 instance.refs = emptyObject_1;
7137 instance.context = getMaskedContext(workInProgress, unmaskedContext);
7138
7139 if (enableAsyncSubtreeAPI && workInProgress.type != null && workInProgress.type.prototype != null && workInProgress.type.prototype.unstable_isAsyncReactComponent === true) {
7140 workInProgress.internalContextTag |= AsyncUpdates;
7141 }
7142
7143 if (typeof instance.componentWillMount === 'function') {
7144 callComponentWillMount(workInProgress, instance);
7145 // If we had additional state updates during this life-cycle, let's
7146 // process them now.
7147 var updateQueue = workInProgress.updateQueue;
7148 if (updateQueue !== null) {
7149 instance.state = processUpdateQueue(current, workInProgress, updateQueue, instance, props, renderExpirationTime);
7150 }
7151 }
7152 if (typeof instance.componentDidMount === 'function') {
7153 workInProgress.effectTag |= Update;
7154 }
7155 }
7156
7157 // Called on a preexisting class instance. Returns false if a resumed render
7158 // could be reused.
7159 // function resumeMountClassInstance(
7160 // workInProgress: Fiber,
7161 // priorityLevel: PriorityLevel,
7162 // ): boolean {
7163 // const instance = workInProgress.stateNode;
7164 // resetInputPointers(workInProgress, instance);
7165
7166 // let newState = workInProgress.memoizedState;
7167 // let newProps = workInProgress.pendingProps;
7168 // if (!newProps) {
7169 // // If there isn't any new props, then we'll reuse the memoized props.
7170 // // This could be from already completed work.
7171 // newProps = workInProgress.memoizedProps;
7172 // invariant(
7173 // newProps != null,
7174 // 'There should always be pending or memoized props. This error is ' +
7175 // 'likely caused by a bug in React. Please file an issue.',
7176 // );
7177 // }
7178 // const newUnmaskedContext = getUnmaskedContext(workInProgress);
7179 // const newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7180
7181 // const oldContext = instance.context;
7182 // const oldProps = workInProgress.memoizedProps;
7183
7184 // if (
7185 // typeof instance.componentWillReceiveProps === 'function' &&
7186 // (oldProps !== newProps || oldContext !== newContext)
7187 // ) {
7188 // callComponentWillReceiveProps(
7189 // workInProgress,
7190 // instance,
7191 // newProps,
7192 // newContext,
7193 // );
7194 // }
7195
7196 // // Process the update queue before calling shouldComponentUpdate
7197 // const updateQueue = workInProgress.updateQueue;
7198 // if (updateQueue !== null) {
7199 // newState = processUpdateQueue(
7200 // workInProgress,
7201 // updateQueue,
7202 // instance,
7203 // newState,
7204 // newProps,
7205 // priorityLevel,
7206 // );
7207 // }
7208
7209 // // TODO: Should we deal with a setState that happened after the last
7210 // // componentWillMount and before this componentWillMount? Probably
7211 // // unsupported anyway.
7212
7213 // if (
7214 // !checkShouldComponentUpdate(
7215 // workInProgress,
7216 // workInProgress.memoizedProps,
7217 // newProps,
7218 // workInProgress.memoizedState,
7219 // newState,
7220 // newContext,
7221 // )
7222 // ) {
7223 // // Update the existing instance's state, props, and context pointers even
7224 // // though we're bailing out.
7225 // instance.props = newProps;
7226 // instance.state = newState;
7227 // instance.context = newContext;
7228 // return false;
7229 // }
7230
7231 // // Update the input pointers now so that they are correct when we call
7232 // // componentWillMount
7233 // instance.props = newProps;
7234 // instance.state = newState;
7235 // instance.context = newContext;
7236
7237 // if (typeof instance.componentWillMount === 'function') {
7238 // callComponentWillMount(workInProgress, instance);
7239 // // componentWillMount may have called setState. Process the update queue.
7240 // const newUpdateQueue = workInProgress.updateQueue;
7241 // if (newUpdateQueue !== null) {
7242 // newState = processUpdateQueue(
7243 // workInProgress,
7244 // newUpdateQueue,
7245 // instance,
7246 // newState,
7247 // newProps,
7248 // priorityLevel,
7249 // );
7250 // }
7251 // }
7252
7253 // if (typeof instance.componentDidMount === 'function') {
7254 // workInProgress.effectTag |= Update;
7255 // }
7256
7257 // instance.state = newState;
7258
7259 // return true;
7260 // }
7261
7262 // Invokes the update life-cycles and returns false if it shouldn't rerender.
7263 function updateClassInstance(current, workInProgress, renderExpirationTime) {
7264 var instance = workInProgress.stateNode;
7265 resetInputPointers(workInProgress, instance);
7266
7267 var oldProps = workInProgress.memoizedProps;
7268 var newProps = workInProgress.pendingProps;
7269 var oldContext = instance.context;
7270 var newUnmaskedContext = getUnmaskedContext(workInProgress);
7271 var newContext = getMaskedContext(workInProgress, newUnmaskedContext);
7272
7273 // Note: During these life-cycles, instance.props/instance.state are what
7274 // ever the previously attempted to render - not the "current". However,
7275 // during componentDidUpdate we pass the "current" props.
7276
7277 if (typeof instance.componentWillReceiveProps === 'function' && (oldProps !== newProps || oldContext !== newContext)) {
7278 callComponentWillReceiveProps(workInProgress, instance, newProps, newContext);
7279 }
7280
7281 // Compute the next state using the memoized state and the update queue.
7282 var oldState = workInProgress.memoizedState;
7283 // TODO: Previous state can be null.
7284 var newState = void 0;
7285 if (workInProgress.updateQueue !== null) {
7286 newState = processUpdateQueue(current, workInProgress, workInProgress.updateQueue, instance, newProps, renderExpirationTime);
7287 } else {
7288 newState = oldState;
7289 }
7290
7291 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
7292 // If an update was already in progress, we should schedule an Update
7293 // effect even though we're bailing out, so that cWU/cDU are called.
7294 if (typeof instance.componentDidUpdate === 'function') {
7295 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7296 workInProgress.effectTag |= Update;
7297 }
7298 }
7299 return false;
7300 }
7301
7302 var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext);
7303
7304 if (shouldUpdate) {
7305 if (typeof instance.componentWillUpdate === 'function') {
7306 startPhaseTimer(workInProgress, 'componentWillUpdate');
7307 instance.componentWillUpdate(newProps, newState, newContext);
7308 stopPhaseTimer();
7309
7310 // Simulate an async bailout/interruption by invoking lifecycle twice.
7311 if (debugRenderPhaseSideEffects) {
7312 instance.componentWillUpdate(newProps, newState, newContext);
7313 }
7314 }
7315 if (typeof instance.componentDidUpdate === 'function') {
7316 workInProgress.effectTag |= Update;
7317 }
7318 } else {
7319 // If an update was already in progress, we should schedule an Update
7320 // effect even though we're bailing out, so that cWU/cDU are called.
7321 if (typeof instance.componentDidUpdate === 'function') {
7322 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
7323 workInProgress.effectTag |= Update;
7324 }
7325 }
7326
7327 // If shouldComponentUpdate returned false, we should still update the
7328 // memoized props/state to indicate that this work can be reused.
7329 memoizeProps(workInProgress, newProps);
7330 memoizeState(workInProgress, newState);
7331 }
7332
7333 // Update the existing instance's state, props, and context pointers even
7334 // if shouldComponentUpdate returns false.
7335 instance.props = newProps;
7336 instance.state = newState;
7337 instance.context = newContext;
7338
7339 return shouldUpdate;
7340 }
7341
7342 return {
7343 adoptClassInstance: adoptClassInstance,
7344 constructClassInstance: constructClassInstance,
7345 mountClassInstance: mountClassInstance,
7346 // resumeMountClassInstance,
7347 updateClassInstance: updateClassInstance
7348 };
7349};
7350
7351var getCurrentFiberStackAddendum$2 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
7352
7353
7354var didWarnAboutMaps = void 0;
7355var ownerHasKeyUseWarning = void 0;
7356var ownerHasFunctionTypeWarning = void 0;
7357var warnForMissingKey = function (child) {};
7358
7359{
7360 didWarnAboutMaps = false;
7361 /**
7362 * Warn if there's no key explicitly set on dynamic arrays of children or
7363 * object keys are not valid. This allows us to keep track of children between
7364 * updates.
7365 */
7366 ownerHasKeyUseWarning = {};
7367 ownerHasFunctionTypeWarning = {};
7368
7369 warnForMissingKey = function (child) {
7370 if (child === null || typeof child !== 'object') {
7371 return;
7372 }
7373 if (!child._store || child._store.validated || child.key != null) {
7374 return;
7375 }
7376 !(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;
7377 child._store.validated = true;
7378
7379 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() || '');
7380 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
7381 return;
7382 }
7383 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
7384
7385 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());
7386 };
7387}
7388
7389var isArray$1 = Array.isArray;
7390
7391function coerceRef(current, element) {
7392 var mixedRef = element.ref;
7393 if (mixedRef !== null && typeof mixedRef !== 'function') {
7394 if (element._owner) {
7395 var owner = element._owner;
7396 var inst = void 0;
7397 if (owner) {
7398 var ownerFiber = owner;
7399 !(ownerFiber.tag === ClassComponent) ? invariant_1(false, 'Stateless function components cannot have refs.') : void 0;
7400 inst = ownerFiber.stateNode;
7401 }
7402 !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;
7403 var stringRef = '' + mixedRef;
7404 // Check if previous string ref matches new string ref
7405 if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
7406 return current.ref;
7407 }
7408 var ref = function (value) {
7409 var refs = inst.refs === emptyObject_1 ? inst.refs = {} : inst.refs;
7410 if (value === null) {
7411 delete refs[stringRef];
7412 } else {
7413 refs[stringRef] = value;
7414 }
7415 };
7416 ref._stringRef = stringRef;
7417 return ref;
7418 } else {
7419 !(typeof mixedRef === 'string') ? invariant_1(false, 'Expected ref to be a function or a string.') : void 0;
7420 !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;
7421 }
7422 }
7423 return mixedRef;
7424}
7425
7426function throwOnInvalidObjectType(returnFiber, newChild) {
7427 if (returnFiber.type !== 'textarea') {
7428 var addendum = '';
7429 {
7430 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$2() || '');
7431 }
7432 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);
7433 }
7434}
7435
7436function warnOnFunctionType() {
7437 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() || '');
7438
7439 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
7440 return;
7441 }
7442 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
7443
7444 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() || '');
7445}
7446
7447// This wrapper function exists because I expect to clone the code in each path
7448// to be able to optimize each path individually by branching early. This needs
7449// a compiler or we can do it manually. Helpers that don't need this branching
7450// live outside of this function.
7451function ChildReconciler(shouldTrackSideEffects) {
7452 function deleteChild(returnFiber, childToDelete) {
7453 if (!shouldTrackSideEffects) {
7454 // Noop.
7455 return;
7456 }
7457 // Deletions are added in reversed order so we add it to the front.
7458 // At this point, the return fiber's effect list is empty except for
7459 // deletions, so we can just append the deletion to the list. The remaining
7460 // effects aren't added until the complete phase. Once we implement
7461 // resuming, this may not be true.
7462 var last = returnFiber.lastEffect;
7463 if (last !== null) {
7464 last.nextEffect = childToDelete;
7465 returnFiber.lastEffect = childToDelete;
7466 } else {
7467 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7468 }
7469 childToDelete.nextEffect = null;
7470 childToDelete.effectTag = Deletion;
7471 }
7472
7473 function deleteRemainingChildren(returnFiber, currentFirstChild) {
7474 if (!shouldTrackSideEffects) {
7475 // Noop.
7476 return null;
7477 }
7478
7479 // TODO: For the shouldClone case, this could be micro-optimized a bit by
7480 // assuming that after the first child we've already added everything.
7481 var childToDelete = currentFirstChild;
7482 while (childToDelete !== null) {
7483 deleteChild(returnFiber, childToDelete);
7484 childToDelete = childToDelete.sibling;
7485 }
7486 return null;
7487 }
7488
7489 function mapRemainingChildren(returnFiber, currentFirstChild) {
7490 // Add the remaining children to a temporary map so that we can find them by
7491 // keys quickly. Implicit (null) keys get added to this set with their index
7492 var existingChildren = new Map();
7493
7494 var existingChild = currentFirstChild;
7495 while (existingChild !== null) {
7496 if (existingChild.key !== null) {
7497 existingChildren.set(existingChild.key, existingChild);
7498 } else {
7499 existingChildren.set(existingChild.index, existingChild);
7500 }
7501 existingChild = existingChild.sibling;
7502 }
7503 return existingChildren;
7504 }
7505
7506 function useFiber(fiber, pendingProps, expirationTime) {
7507 // We currently set sibling to null and index to 0 here because it is easy
7508 // to forget to do before returning it. E.g. for the single child case.
7509 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
7510 clone.index = 0;
7511 clone.sibling = null;
7512 return clone;
7513 }
7514
7515 function placeChild(newFiber, lastPlacedIndex, newIndex) {
7516 newFiber.index = newIndex;
7517 if (!shouldTrackSideEffects) {
7518 // Noop.
7519 return lastPlacedIndex;
7520 }
7521 var current = newFiber.alternate;
7522 if (current !== null) {
7523 var oldIndex = current.index;
7524 if (oldIndex < lastPlacedIndex) {
7525 // This is a move.
7526 newFiber.effectTag = Placement;
7527 return lastPlacedIndex;
7528 } else {
7529 // This item can stay in place.
7530 return oldIndex;
7531 }
7532 } else {
7533 // This is an insertion.
7534 newFiber.effectTag = Placement;
7535 return lastPlacedIndex;
7536 }
7537 }
7538
7539 function placeSingleChild(newFiber) {
7540 // This is simpler for the single child case. We only need to do a
7541 // placement for inserting new children.
7542 if (shouldTrackSideEffects && newFiber.alternate === null) {
7543 newFiber.effectTag = Placement;
7544 }
7545 return newFiber;
7546 }
7547
7548 function updateTextNode(returnFiber, current, textContent, expirationTime) {
7549 if (current === null || current.tag !== HostText) {
7550 // Insert
7551 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
7552 created['return'] = returnFiber;
7553 return created;
7554 } else {
7555 // Update
7556 var existing = useFiber(current, textContent, expirationTime);
7557 existing['return'] = returnFiber;
7558 return existing;
7559 }
7560 }
7561
7562 function updateElement(returnFiber, current, element, expirationTime) {
7563 if (current !== null && current.type === element.type) {
7564 // Move based on index
7565 var existing = useFiber(current, element.props, expirationTime);
7566 existing.ref = coerceRef(current, element);
7567 existing['return'] = returnFiber;
7568 {
7569 existing._debugSource = element._source;
7570 existing._debugOwner = element._owner;
7571 }
7572 return existing;
7573 } else {
7574 // Insert
7575 var created = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
7576 created.ref = coerceRef(current, element);
7577 created['return'] = returnFiber;
7578 return created;
7579 }
7580 }
7581
7582 function updatePortal(returnFiber, current, portal, expirationTime) {
7583 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
7584 // Insert
7585 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
7586 created['return'] = returnFiber;
7587 return created;
7588 } else {
7589 // Update
7590 var existing = useFiber(current, portal.children || [], expirationTime);
7591 existing['return'] = returnFiber;
7592 return existing;
7593 }
7594 }
7595
7596 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
7597 if (current === null || current.tag !== Fragment) {
7598 // Insert
7599 var created = createFiberFromFragment(fragment, returnFiber.internalContextTag, expirationTime, key);
7600 created['return'] = returnFiber;
7601 return created;
7602 } else {
7603 // Update
7604 var existing = useFiber(current, fragment, expirationTime);
7605 existing['return'] = returnFiber;
7606 return existing;
7607 }
7608 }
7609
7610 function createChild(returnFiber, newChild, expirationTime) {
7611 if (typeof newChild === 'string' || typeof newChild === 'number') {
7612 // Text nodes don't have keys. If the previous node is implicitly keyed
7613 // we can continue to replace it without aborting even if it is not a text
7614 // node.
7615 var created = createFiberFromText('' + newChild, returnFiber.internalContextTag, expirationTime);
7616 created['return'] = returnFiber;
7617 return created;
7618 }
7619
7620 if (typeof newChild === 'object' && newChild !== null) {
7621 switch (newChild.$$typeof) {
7622 case REACT_ELEMENT_TYPE:
7623 {
7624 var _created = createFiberFromElement(newChild, returnFiber.internalContextTag, expirationTime);
7625 _created.ref = coerceRef(null, newChild);
7626 _created['return'] = returnFiber;
7627 return _created;
7628 }
7629 case REACT_PORTAL_TYPE:
7630 {
7631 var _created2 = createFiberFromPortal(newChild, returnFiber.internalContextTag, expirationTime);
7632 _created2['return'] = returnFiber;
7633 return _created2;
7634 }
7635 }
7636
7637 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7638 var _created3 = createFiberFromFragment(newChild, returnFiber.internalContextTag, expirationTime, null);
7639 _created3['return'] = returnFiber;
7640 return _created3;
7641 }
7642
7643 throwOnInvalidObjectType(returnFiber, newChild);
7644 }
7645
7646 {
7647 if (typeof newChild === 'function') {
7648 warnOnFunctionType();
7649 }
7650 }
7651
7652 return null;
7653 }
7654
7655 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
7656 // Update the fiber if the keys match, otherwise return null.
7657
7658 var key = oldFiber !== null ? oldFiber.key : null;
7659
7660 if (typeof newChild === 'string' || typeof newChild === 'number') {
7661 // Text nodes don't have keys. If the previous node is implicitly keyed
7662 // we can continue to replace it without aborting even if it is not a text
7663 // node.
7664 if (key !== null) {
7665 return null;
7666 }
7667 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
7668 }
7669
7670 if (typeof newChild === 'object' && newChild !== null) {
7671 switch (newChild.$$typeof) {
7672 case REACT_ELEMENT_TYPE:
7673 {
7674 if (newChild.key === key) {
7675 if (newChild.type === REACT_FRAGMENT_TYPE) {
7676 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
7677 }
7678 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
7679 } else {
7680 return null;
7681 }
7682 }
7683 case REACT_PORTAL_TYPE:
7684 {
7685 if (newChild.key === key) {
7686 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
7687 } else {
7688 return null;
7689 }
7690 }
7691 }
7692
7693 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7694 if (key !== null) {
7695 return null;
7696 }
7697
7698 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
7699 }
7700
7701 throwOnInvalidObjectType(returnFiber, newChild);
7702 }
7703
7704 {
7705 if (typeof newChild === 'function') {
7706 warnOnFunctionType();
7707 }
7708 }
7709
7710 return null;
7711 }
7712
7713 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
7714 if (typeof newChild === 'string' || typeof newChild === 'number') {
7715 // Text nodes don't have keys, so we neither have to check the old nor
7716 // new node for the key. If both are text nodes, they match.
7717 var matchedFiber = existingChildren.get(newIdx) || null;
7718 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
7719 }
7720
7721 if (typeof newChild === 'object' && newChild !== null) {
7722 switch (newChild.$$typeof) {
7723 case REACT_ELEMENT_TYPE:
7724 {
7725 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7726 if (newChild.type === REACT_FRAGMENT_TYPE) {
7727 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
7728 }
7729 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
7730 }
7731 case REACT_PORTAL_TYPE:
7732 {
7733 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
7734 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
7735 }
7736 }
7737
7738 if (isArray$1(newChild) || getIteratorFn(newChild)) {
7739 var _matchedFiber3 = existingChildren.get(newIdx) || null;
7740 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
7741 }
7742
7743 throwOnInvalidObjectType(returnFiber, newChild);
7744 }
7745
7746 {
7747 if (typeof newChild === 'function') {
7748 warnOnFunctionType();
7749 }
7750 }
7751
7752 return null;
7753 }
7754
7755 /**
7756 * Warns if there is a duplicate or missing key
7757 */
7758 function warnOnInvalidKey(child, knownKeys) {
7759 {
7760 if (typeof child !== 'object' || child === null) {
7761 return knownKeys;
7762 }
7763 switch (child.$$typeof) {
7764 case REACT_ELEMENT_TYPE:
7765 case REACT_PORTAL_TYPE:
7766 warnForMissingKey(child);
7767 var key = child.key;
7768 if (typeof key !== 'string') {
7769 break;
7770 }
7771 if (knownKeys === null) {
7772 knownKeys = new Set();
7773 knownKeys.add(key);
7774 break;
7775 }
7776 if (!knownKeys.has(key)) {
7777 knownKeys.add(key);
7778 break;
7779 }
7780 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());
7781 break;
7782 default:
7783 break;
7784 }
7785 }
7786 return knownKeys;
7787 }
7788
7789 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
7790 // This algorithm can't optimize by searching from boths ends since we
7791 // don't have backpointers on fibers. I'm trying to see how far we can get
7792 // with that model. If it ends up not being worth the tradeoffs, we can
7793 // add it later.
7794
7795 // Even with a two ended optimization, we'd want to optimize for the case
7796 // where there are few changes and brute force the comparison instead of
7797 // going for the Map. It'd like to explore hitting that path first in
7798 // forward-only mode and only go for the Map once we notice that we need
7799 // lots of look ahead. This doesn't handle reversal as well as two ended
7800 // search but that's unusual. Besides, for the two ended optimization to
7801 // work on Iterables, we'd need to copy the whole set.
7802
7803 // In this first iteration, we'll just live with hitting the bad case
7804 // (adding everything to a Map) in for every insert/move.
7805
7806 // If you change this code, also update reconcileChildrenIterator() which
7807 // uses the same algorithm.
7808
7809 {
7810 // First, validate keys.
7811 var knownKeys = null;
7812 for (var i = 0; i < newChildren.length; i++) {
7813 var child = newChildren[i];
7814 knownKeys = warnOnInvalidKey(child, knownKeys);
7815 }
7816 }
7817
7818 var resultingFirstChild = null;
7819 var previousNewFiber = null;
7820
7821 var oldFiber = currentFirstChild;
7822 var lastPlacedIndex = 0;
7823 var newIdx = 0;
7824 var nextOldFiber = null;
7825 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
7826 if (oldFiber.index > newIdx) {
7827 nextOldFiber = oldFiber;
7828 oldFiber = null;
7829 } else {
7830 nextOldFiber = oldFiber.sibling;
7831 }
7832 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
7833 if (newFiber === null) {
7834 // TODO: This breaks on empty slots like null children. That's
7835 // unfortunate because it triggers the slow path all the time. We need
7836 // a better way to communicate whether this was a miss or null,
7837 // boolean, undefined, etc.
7838 if (oldFiber === null) {
7839 oldFiber = nextOldFiber;
7840 }
7841 break;
7842 }
7843 if (shouldTrackSideEffects) {
7844 if (oldFiber && newFiber.alternate === null) {
7845 // We matched the slot, but we didn't reuse the existing fiber, so we
7846 // need to delete the existing child.
7847 deleteChild(returnFiber, oldFiber);
7848 }
7849 }
7850 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
7851 if (previousNewFiber === null) {
7852 // TODO: Move out of the loop. This only happens for the first run.
7853 resultingFirstChild = newFiber;
7854 } else {
7855 // TODO: Defer siblings if we're not at the right index for this slot.
7856 // I.e. if we had null values before, then we want to defer this
7857 // for each null value. However, we also don't want to call updateSlot
7858 // with the previous one.
7859 previousNewFiber.sibling = newFiber;
7860 }
7861 previousNewFiber = newFiber;
7862 oldFiber = nextOldFiber;
7863 }
7864
7865 if (newIdx === newChildren.length) {
7866 // We've reached the end of the new children. We can delete the rest.
7867 deleteRemainingChildren(returnFiber, oldFiber);
7868 return resultingFirstChild;
7869 }
7870
7871 if (oldFiber === null) {
7872 // If we don't have any more existing children we can choose a fast path
7873 // since the rest will all be insertions.
7874 for (; newIdx < newChildren.length; newIdx++) {
7875 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
7876 if (!_newFiber) {
7877 continue;
7878 }
7879 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
7880 if (previousNewFiber === null) {
7881 // TODO: Move out of the loop. This only happens for the first run.
7882 resultingFirstChild = _newFiber;
7883 } else {
7884 previousNewFiber.sibling = _newFiber;
7885 }
7886 previousNewFiber = _newFiber;
7887 }
7888 return resultingFirstChild;
7889 }
7890
7891 // Add all children to a key map for quick lookups.
7892 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
7893
7894 // Keep scanning and use the map to restore deleted items as moves.
7895 for (; newIdx < newChildren.length; newIdx++) {
7896 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
7897 if (_newFiber2) {
7898 if (shouldTrackSideEffects) {
7899 if (_newFiber2.alternate !== null) {
7900 // The new fiber is a work in progress, but if there exists a
7901 // current, that means that we reused the fiber. We need to delete
7902 // it from the child list so that we don't add it to the deletion
7903 // list.
7904 existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key);
7905 }
7906 }
7907 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
7908 if (previousNewFiber === null) {
7909 resultingFirstChild = _newFiber2;
7910 } else {
7911 previousNewFiber.sibling = _newFiber2;
7912 }
7913 previousNewFiber = _newFiber2;
7914 }
7915 }
7916
7917 if (shouldTrackSideEffects) {
7918 // Any existing children that weren't consumed above were deleted. We need
7919 // to add them to the deletion list.
7920 existingChildren.forEach(function (child) {
7921 return deleteChild(returnFiber, child);
7922 });
7923 }
7924
7925 return resultingFirstChild;
7926 }
7927
7928 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
7929 // This is the same implementation as reconcileChildrenArray(),
7930 // but using the iterator instead.
7931
7932 var iteratorFn = getIteratorFn(newChildrenIterable);
7933 !(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;
7934
7935 {
7936 // Warn about using Maps as children
7937 if (typeof newChildrenIterable.entries === 'function') {
7938 var possibleMap = newChildrenIterable;
7939 if (possibleMap.entries === iteratorFn) {
7940 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());
7941 didWarnAboutMaps = true;
7942 }
7943 }
7944
7945 // First, validate keys.
7946 // We'll get a different iterator later for the main pass.
7947 var _newChildren = iteratorFn.call(newChildrenIterable);
7948 if (_newChildren) {
7949 var knownKeys = null;
7950 var _step = _newChildren.next();
7951 for (; !_step.done; _step = _newChildren.next()) {
7952 var child = _step.value;
7953 knownKeys = warnOnInvalidKey(child, knownKeys);
7954 }
7955 }
7956 }
7957
7958 var newChildren = iteratorFn.call(newChildrenIterable);
7959 !(newChildren != null) ? invariant_1(false, 'An iterable object provided no iterator.') : void 0;
7960
7961 var resultingFirstChild = null;
7962 var previousNewFiber = null;
7963
7964 var oldFiber = currentFirstChild;
7965 var lastPlacedIndex = 0;
7966 var newIdx = 0;
7967 var nextOldFiber = null;
7968
7969 var step = newChildren.next();
7970 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
7971 if (oldFiber.index > newIdx) {
7972 nextOldFiber = oldFiber;
7973 oldFiber = null;
7974 } else {
7975 nextOldFiber = oldFiber.sibling;
7976 }
7977 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
7978 if (newFiber === null) {
7979 // TODO: This breaks on empty slots like null children. That's
7980 // unfortunate because it triggers the slow path all the time. We need
7981 // a better way to communicate whether this was a miss or null,
7982 // boolean, undefined, etc.
7983 if (!oldFiber) {
7984 oldFiber = nextOldFiber;
7985 }
7986 break;
7987 }
7988 if (shouldTrackSideEffects) {
7989 if (oldFiber && newFiber.alternate === null) {
7990 // We matched the slot, but we didn't reuse the existing fiber, so we
7991 // need to delete the existing child.
7992 deleteChild(returnFiber, oldFiber);
7993 }
7994 }
7995 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
7996 if (previousNewFiber === null) {
7997 // TODO: Move out of the loop. This only happens for the first run.
7998 resultingFirstChild = newFiber;
7999 } else {
8000 // TODO: Defer siblings if we're not at the right index for this slot.
8001 // I.e. if we had null values before, then we want to defer this
8002 // for each null value. However, we also don't want to call updateSlot
8003 // with the previous one.
8004 previousNewFiber.sibling = newFiber;
8005 }
8006 previousNewFiber = newFiber;
8007 oldFiber = nextOldFiber;
8008 }
8009
8010 if (step.done) {
8011 // We've reached the end of the new children. We can delete the rest.
8012 deleteRemainingChildren(returnFiber, oldFiber);
8013 return resultingFirstChild;
8014 }
8015
8016 if (oldFiber === null) {
8017 // If we don't have any more existing children we can choose a fast path
8018 // since the rest will all be insertions.
8019 for (; !step.done; newIdx++, step = newChildren.next()) {
8020 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
8021 if (_newFiber3 === null) {
8022 continue;
8023 }
8024 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
8025 if (previousNewFiber === null) {
8026 // TODO: Move out of the loop. This only happens for the first run.
8027 resultingFirstChild = _newFiber3;
8028 } else {
8029 previousNewFiber.sibling = _newFiber3;
8030 }
8031 previousNewFiber = _newFiber3;
8032 }
8033 return resultingFirstChild;
8034 }
8035
8036 // Add all children to a key map for quick lookups.
8037 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
8038
8039 // Keep scanning and use the map to restore deleted items as moves.
8040 for (; !step.done; newIdx++, step = newChildren.next()) {
8041 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
8042 if (_newFiber4 !== null) {
8043 if (shouldTrackSideEffects) {
8044 if (_newFiber4.alternate !== null) {
8045 // The new fiber is a work in progress, but if there exists a
8046 // current, that means that we reused the fiber. We need to delete
8047 // it from the child list so that we don't add it to the deletion
8048 // list.
8049 existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key);
8050 }
8051 }
8052 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
8053 if (previousNewFiber === null) {
8054 resultingFirstChild = _newFiber4;
8055 } else {
8056 previousNewFiber.sibling = _newFiber4;
8057 }
8058 previousNewFiber = _newFiber4;
8059 }
8060 }
8061
8062 if (shouldTrackSideEffects) {
8063 // Any existing children that weren't consumed above were deleted. We need
8064 // to add them to the deletion list.
8065 existingChildren.forEach(function (child) {
8066 return deleteChild(returnFiber, child);
8067 });
8068 }
8069
8070 return resultingFirstChild;
8071 }
8072
8073 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
8074 // There's no need to check for keys on text nodes since we don't have a
8075 // way to define them.
8076 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
8077 // We already have an existing node so let's just update it and delete
8078 // the rest.
8079 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
8080 var existing = useFiber(currentFirstChild, textContent, expirationTime);
8081 existing['return'] = returnFiber;
8082 return existing;
8083 }
8084 // The existing first child is not a text node so we need to create one
8085 // and delete the existing ones.
8086 deleteRemainingChildren(returnFiber, currentFirstChild);
8087 var created = createFiberFromText(textContent, returnFiber.internalContextTag, expirationTime);
8088 created['return'] = returnFiber;
8089 return created;
8090 }
8091
8092 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
8093 var key = element.key;
8094 var child = currentFirstChild;
8095 while (child !== null) {
8096 // TODO: If key === null and child.key === null, then this only applies to
8097 // the first item in the list.
8098 if (child.key === key) {
8099 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) {
8100 deleteRemainingChildren(returnFiber, child.sibling);
8101 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
8102 existing.ref = coerceRef(child, element);
8103 existing['return'] = returnFiber;
8104 {
8105 existing._debugSource = element._source;
8106 existing._debugOwner = element._owner;
8107 }
8108 return existing;
8109 } else {
8110 deleteRemainingChildren(returnFiber, child);
8111 break;
8112 }
8113 } else {
8114 deleteChild(returnFiber, child);
8115 }
8116 child = child.sibling;
8117 }
8118
8119 if (element.type === REACT_FRAGMENT_TYPE) {
8120 var created = createFiberFromFragment(element.props.children, returnFiber.internalContextTag, expirationTime, element.key);
8121 created['return'] = returnFiber;
8122 return created;
8123 } else {
8124 var _created4 = createFiberFromElement(element, returnFiber.internalContextTag, expirationTime);
8125 _created4.ref = coerceRef(currentFirstChild, element);
8126 _created4['return'] = returnFiber;
8127 return _created4;
8128 }
8129 }
8130
8131 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
8132 var key = portal.key;
8133 var child = currentFirstChild;
8134 while (child !== null) {
8135 // TODO: If key === null and child.key === null, then this only applies to
8136 // the first item in the list.
8137 if (child.key === key) {
8138 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
8139 deleteRemainingChildren(returnFiber, child.sibling);
8140 var existing = useFiber(child, portal.children || [], expirationTime);
8141 existing['return'] = returnFiber;
8142 return existing;
8143 } else {
8144 deleteRemainingChildren(returnFiber, child);
8145 break;
8146 }
8147 } else {
8148 deleteChild(returnFiber, child);
8149 }
8150 child = child.sibling;
8151 }
8152
8153 var created = createFiberFromPortal(portal, returnFiber.internalContextTag, expirationTime);
8154 created['return'] = returnFiber;
8155 return created;
8156 }
8157
8158 // This API will tag the children with the side-effect of the reconciliation
8159 // itself. They will be added to the side-effect list as we pass through the
8160 // children and the parent.
8161 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
8162 // This function is not recursive.
8163 // If the top level item is an array, we treat it as a set of children,
8164 // not as a fragment. Nested arrays on the other hand will be treated as
8165 // fragment nodes. Recursion happens at the normal flow.
8166
8167 // Handle top level unkeyed fragments as if they were arrays.
8168 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
8169 // We treat the ambiguous cases above the same.
8170 if (typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null) {
8171 newChild = newChild.props.children;
8172 }
8173
8174 // Handle object types
8175 var isObject = typeof newChild === 'object' && newChild !== null;
8176
8177 if (isObject) {
8178 switch (newChild.$$typeof) {
8179 case REACT_ELEMENT_TYPE:
8180 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
8181 case REACT_PORTAL_TYPE:
8182 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
8183 }
8184 }
8185
8186 if (typeof newChild === 'string' || typeof newChild === 'number') {
8187 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
8188 }
8189
8190 if (isArray$1(newChild)) {
8191 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
8192 }
8193
8194 if (getIteratorFn(newChild)) {
8195 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
8196 }
8197
8198 if (isObject) {
8199 throwOnInvalidObjectType(returnFiber, newChild);
8200 }
8201
8202 {
8203 if (typeof newChild === 'function') {
8204 warnOnFunctionType();
8205 }
8206 }
8207 if (typeof newChild === 'undefined') {
8208 // If the new child is undefined, and the return fiber is a composite
8209 // component, throw an error. If Fiber return types are disabled,
8210 // we already threw above.
8211 switch (returnFiber.tag) {
8212 case ClassComponent:
8213 {
8214 {
8215 var instance = returnFiber.stateNode;
8216 if (instance.render._isMockFunction) {
8217 // We allow auto-mocks to proceed as if they're returning null.
8218 break;
8219 }
8220 }
8221 }
8222 // Intentionally fall through to the next case, which handles both
8223 // functions and classes
8224 // eslint-disable-next-lined no-fallthrough
8225 case FunctionalComponent:
8226 {
8227 var Component = returnFiber.type;
8228 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');
8229 }
8230 }
8231 }
8232
8233 // Remaining cases are all treated as empty.
8234 return deleteRemainingChildren(returnFiber, currentFirstChild);
8235 }
8236
8237 return reconcileChildFibers;
8238}
8239
8240var reconcileChildFibers = ChildReconciler(true);
8241var mountChildFibers = ChildReconciler(false);
8242
8243function cloneChildFibers(current, workInProgress) {
8244 !(current === null || workInProgress.child === current.child) ? invariant_1(false, 'Resuming work not yet implemented.') : void 0;
8245
8246 if (workInProgress.child === null) {
8247 return;
8248 }
8249
8250 var currentChild = workInProgress.child;
8251 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8252 workInProgress.child = newChild;
8253
8254 newChild['return'] = workInProgress;
8255 while (currentChild.sibling !== null) {
8256 currentChild = currentChild.sibling;
8257 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
8258 newChild['return'] = workInProgress;
8259 }
8260 newChild.sibling = null;
8261}
8262
8263var warnedAboutStatelessRefs = void 0;
8264var didWarnAboutBadClass = void 0;
8265
8266{
8267 warnedAboutStatelessRefs = {};
8268 didWarnAboutBadClass = {};
8269}
8270
8271var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber) {
8272 var shouldSetTextContent = config.shouldSetTextContent,
8273 shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree;
8274 var pushHostContext = hostContext.pushHostContext,
8275 pushHostContainer = hostContext.pushHostContainer;
8276 var enterHydrationState = hydrationContext.enterHydrationState,
8277 resetHydrationState = hydrationContext.resetHydrationState,
8278 tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance;
8279
8280 var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleWork, computeExpirationForFiber, memoizeProps, memoizeState),
8281 adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance,
8282 constructClassInstance = _ReactFiberClassCompo.constructClassInstance,
8283 mountClassInstance = _ReactFiberClassCompo.mountClassInstance,
8284 updateClassInstance = _ReactFiberClassCompo.updateClassInstance;
8285
8286 // TODO: Remove this and use reconcileChildrenAtExpirationTime directly.
8287
8288
8289 function reconcileChildren(current, workInProgress, nextChildren) {
8290 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, workInProgress.expirationTime);
8291 }
8292
8293 function reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime) {
8294 if (current === null) {
8295 // If this is a fresh new component that hasn't been rendered yet, we
8296 // won't update its child set by applying minimal side-effects. Instead,
8297 // we will add them all to the child before it gets rendered. That means
8298 // we can optimize this reconciliation pass by not tracking side-effects.
8299 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8300 } else {
8301 // If the current child is the same as the work in progress, it means that
8302 // we haven't yet started any work on these children. Therefore, we use
8303 // the clone algorithm to create a copy of all the current children.
8304
8305 // If we had any progressed work already, that is invalid at this point so
8306 // let's throw it out.
8307 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8308 }
8309 }
8310
8311 function updateFragment(current, workInProgress) {
8312 var nextChildren = workInProgress.pendingProps;
8313 if (hasContextChanged()) {
8314 // Normally we can bail out on props equality but if context has changed
8315 // we don't do the bailout and we have to reuse existing props instead.
8316 } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) {
8317 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8318 }
8319 reconcileChildren(current, workInProgress, nextChildren);
8320 memoizeProps(workInProgress, nextChildren);
8321 return workInProgress.child;
8322 }
8323
8324 function markRef(current, workInProgress) {
8325 var ref = workInProgress.ref;
8326 if (ref !== null && (!current || current.ref !== ref)) {
8327 // Schedule a Ref effect
8328 workInProgress.effectTag |= Ref;
8329 }
8330 }
8331
8332 function updateFunctionalComponent(current, workInProgress) {
8333 var fn = workInProgress.type;
8334 var nextProps = workInProgress.pendingProps;
8335
8336 if (hasContextChanged()) {
8337 // Normally we can bail out on props equality but if context has changed
8338 // we don't do the bailout and we have to reuse existing props instead.
8339 } else {
8340 if (workInProgress.memoizedProps === nextProps) {
8341 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8342 }
8343 // TODO: consider bringing fn.shouldComponentUpdate() back.
8344 // It used to be here.
8345 }
8346
8347 var unmaskedContext = getUnmaskedContext(workInProgress);
8348 var context = getMaskedContext(workInProgress, unmaskedContext);
8349
8350 var nextChildren = void 0;
8351
8352 {
8353 ReactCurrentOwner.current = workInProgress;
8354 ReactDebugCurrentFiber.setCurrentPhase('render');
8355 nextChildren = fn(nextProps, context);
8356 ReactDebugCurrentFiber.setCurrentPhase(null);
8357 }
8358 // React DevTools reads this flag.
8359 workInProgress.effectTag |= PerformedWork;
8360 reconcileChildren(current, workInProgress, nextChildren);
8361 memoizeProps(workInProgress, nextProps);
8362 return workInProgress.child;
8363 }
8364
8365 function updateClassComponent(current, workInProgress, renderExpirationTime) {
8366 // Push context providers early to prevent context stack mismatches.
8367 // During mounting we don't know the child context yet as the instance doesn't exist.
8368 // We will invalidate the child context in finishClassComponent() right after rendering.
8369 var hasContext = pushContextProvider(workInProgress);
8370
8371 var shouldUpdate = void 0;
8372 if (current === null) {
8373 if (!workInProgress.stateNode) {
8374 // In the initial pass we might need to construct the instance.
8375 constructClassInstance(workInProgress, workInProgress.pendingProps);
8376 mountClassInstance(workInProgress, renderExpirationTime);
8377
8378 // Simulate an async bailout/interruption by invoking lifecycle twice.
8379 // We do this here rather than inside of ReactFiberClassComponent,
8380 // To more realistically simulate the interruption behavior of async,
8381 // Which would never call componentWillMount() twice on the same instance.
8382 if (debugRenderPhaseSideEffects) {
8383 constructClassInstance(workInProgress, workInProgress.pendingProps);
8384 mountClassInstance(workInProgress, renderExpirationTime);
8385 }
8386
8387 shouldUpdate = true;
8388 } else {
8389 invariant_1(false, 'Resuming work not yet implemented.');
8390 // In a resume, we'll already have an instance we can reuse.
8391 // shouldUpdate = resumeMountClassInstance(workInProgress, renderExpirationTime);
8392 }
8393 } else {
8394 shouldUpdate = updateClassInstance(current, workInProgress, renderExpirationTime);
8395 }
8396 return finishClassComponent(current, workInProgress, shouldUpdate, hasContext);
8397 }
8398
8399 function finishClassComponent(current, workInProgress, shouldUpdate, hasContext) {
8400 // Refs should update even if shouldComponentUpdate returns false
8401 markRef(current, workInProgress);
8402
8403 if (!shouldUpdate) {
8404 // Context providers should defer to sCU for rendering
8405 if (hasContext) {
8406 invalidateContextProvider(workInProgress, false);
8407 }
8408
8409 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8410 }
8411
8412 var instance = workInProgress.stateNode;
8413
8414 // Rerender
8415 ReactCurrentOwner.current = workInProgress;
8416 var nextChildren = void 0;
8417 {
8418 ReactDebugCurrentFiber.setCurrentPhase('render');
8419 nextChildren = instance.render();
8420 if (debugRenderPhaseSideEffects) {
8421 instance.render();
8422 }
8423 ReactDebugCurrentFiber.setCurrentPhase(null);
8424 }
8425 // React DevTools reads this flag.
8426 workInProgress.effectTag |= PerformedWork;
8427 reconcileChildren(current, workInProgress, nextChildren);
8428 // Memoize props and state using the values we just used to render.
8429 // TODO: Restructure so we never read values from the instance.
8430 memoizeState(workInProgress, instance.state);
8431 memoizeProps(workInProgress, instance.props);
8432
8433 // The context might have changed so we need to recalculate it.
8434 if (hasContext) {
8435 invalidateContextProvider(workInProgress, true);
8436 }
8437
8438 return workInProgress.child;
8439 }
8440
8441 function pushHostRootContext(workInProgress) {
8442 var root = workInProgress.stateNode;
8443 if (root.pendingContext) {
8444 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8445 } else if (root.context) {
8446 // Should always be set
8447 pushTopLevelContextObject(workInProgress, root.context, false);
8448 }
8449 pushHostContainer(workInProgress, root.containerInfo);
8450 }
8451
8452 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8453 pushHostRootContext(workInProgress);
8454 var updateQueue = workInProgress.updateQueue;
8455 if (updateQueue !== null) {
8456 var prevState = workInProgress.memoizedState;
8457 var state = processUpdateQueue(current, workInProgress, updateQueue, null, null, renderExpirationTime);
8458 if (prevState === state) {
8459 // If the state is the same as before, that's a bailout because we had
8460 // no work that expires at this time.
8461 resetHydrationState();
8462 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8463 }
8464 var element = state.element;
8465 var root = workInProgress.stateNode;
8466 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
8467 // If we don't have any current children this might be the first pass.
8468 // We always try to hydrate. If this isn't a hydration pass there won't
8469 // be any children to hydrate which is effectively the same thing as
8470 // not hydrating.
8471
8472 // This is a bit of a hack. We track the host root as a placement to
8473 // know that we're currently in a mounting state. That way isMounted
8474 // works as expected. We must reset this before committing.
8475 // TODO: Delete this when we delete isMounted and findDOMNode.
8476 workInProgress.effectTag |= Placement;
8477
8478 // Ensure that children mount into this root without tracking
8479 // side-effects. This ensures that we don't store Placement effects on
8480 // nodes that will be hydrated.
8481 workInProgress.child = mountChildFibers(workInProgress, null, element, renderExpirationTime);
8482 } else {
8483 // Otherwise reset hydration state in case we aborted and resumed another
8484 // root.
8485 resetHydrationState();
8486 reconcileChildren(current, workInProgress, element);
8487 }
8488 memoizeState(workInProgress, state);
8489 return workInProgress.child;
8490 }
8491 resetHydrationState();
8492 // If there is no update queue, that's a bailout because the root has no props.
8493 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8494 }
8495
8496 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8497 pushHostContext(workInProgress);
8498
8499 if (current === null) {
8500 tryToClaimNextHydratableInstance(workInProgress);
8501 }
8502
8503 var type = workInProgress.type;
8504 var memoizedProps = workInProgress.memoizedProps;
8505 var nextProps = workInProgress.pendingProps;
8506 var prevProps = current !== null ? current.memoizedProps : null;
8507
8508 if (hasContextChanged()) {
8509 // Normally we can bail out on props equality but if context has changed
8510 // we don't do the bailout and we have to reuse existing props instead.
8511 } else if (memoizedProps === nextProps) {
8512 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8513 }
8514
8515 var nextChildren = nextProps.children;
8516 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8517
8518 if (isDirectTextChild) {
8519 // We special case a direct text child of a host node. This is a common
8520 // case. We won't handle it as a reified child. We will instead handle
8521 // this in the host environment that also have access to this prop. That
8522 // avoids allocating another HostText fiber and traversing it.
8523 nextChildren = null;
8524 } else if (prevProps && shouldSetTextContent(type, prevProps)) {
8525 // If we're switching from a direct text child to a normal child, or to
8526 // empty, we need to schedule the text content to be reset.
8527 workInProgress.effectTag |= ContentReset;
8528 }
8529
8530 markRef(current, workInProgress);
8531
8532 // Check the host config to see if the children are offscreen/hidden.
8533 if (renderExpirationTime !== Never && workInProgress.internalContextTag & AsyncUpdates && shouldDeprioritizeSubtree(type, nextProps)) {
8534 // Down-prioritize the children.
8535 workInProgress.expirationTime = Never;
8536 // Bailout and come back to this fiber later.
8537 return null;
8538 }
8539
8540 reconcileChildren(current, workInProgress, nextChildren);
8541 memoizeProps(workInProgress, nextProps);
8542 return workInProgress.child;
8543 }
8544
8545 function updateHostText(current, workInProgress) {
8546 if (current === null) {
8547 tryToClaimNextHydratableInstance(workInProgress);
8548 }
8549 var nextProps = workInProgress.pendingProps;
8550 memoizeProps(workInProgress, nextProps);
8551 // Nothing to do here. This is terminal. We'll do the completion step
8552 // immediately after.
8553 return null;
8554 }
8555
8556 function mountIndeterminateComponent(current, workInProgress, renderExpirationTime) {
8557 !(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;
8558 var fn = workInProgress.type;
8559 var props = workInProgress.pendingProps;
8560 var unmaskedContext = getUnmaskedContext(workInProgress);
8561 var context = getMaskedContext(workInProgress, unmaskedContext);
8562
8563 var value = void 0;
8564
8565 {
8566 if (fn.prototype && typeof fn.prototype.render === 'function') {
8567 var componentName = getComponentName(workInProgress) || 'Unknown';
8568
8569 if (!didWarnAboutBadClass[componentName]) {
8570 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);
8571 didWarnAboutBadClass[componentName] = true;
8572 }
8573 }
8574 ReactCurrentOwner.current = workInProgress;
8575 value = fn(props, context);
8576 }
8577 // React DevTools reads this flag.
8578 workInProgress.effectTag |= PerformedWork;
8579
8580 if (typeof value === 'object' && value !== null && typeof value.render === 'function') {
8581 // Proceed under the assumption that this is a class instance
8582 workInProgress.tag = ClassComponent;
8583
8584 // Push context providers early to prevent context stack mismatches.
8585 // During mounting we don't know the child context yet as the instance doesn't exist.
8586 // We will invalidate the child context in finishClassComponent() right after rendering.
8587 var hasContext = pushContextProvider(workInProgress);
8588 adoptClassInstance(workInProgress, value);
8589 mountClassInstance(workInProgress, renderExpirationTime);
8590 return finishClassComponent(current, workInProgress, true, hasContext);
8591 } else {
8592 // Proceed under the assumption that this is a functional component
8593 workInProgress.tag = FunctionalComponent;
8594 {
8595 var Component = workInProgress.type;
8596
8597 if (Component) {
8598 warning_1(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component');
8599 }
8600 if (workInProgress.ref !== null) {
8601 var info = '';
8602 var ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
8603 if (ownerName) {
8604 info += '\n\nCheck the render method of `' + ownerName + '`.';
8605 }
8606
8607 var warningKey = ownerName || workInProgress._debugID || '';
8608 var debugSource = workInProgress._debugSource;
8609 if (debugSource) {
8610 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8611 }
8612 if (!warnedAboutStatelessRefs[warningKey]) {
8613 warnedAboutStatelessRefs[warningKey] = true;
8614 warning_1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber.getCurrentFiberStackAddendum());
8615 }
8616 }
8617 }
8618 reconcileChildren(current, workInProgress, value);
8619 memoizeProps(workInProgress, props);
8620 return workInProgress.child;
8621 }
8622 }
8623
8624 function updateCallComponent(current, workInProgress, renderExpirationTime) {
8625 var nextProps = workInProgress.pendingProps;
8626 if (hasContextChanged()) {
8627 // Normally we can bail out on props equality but if context has changed
8628 // we don't do the bailout and we have to reuse existing props instead.
8629 } else if (workInProgress.memoizedProps === nextProps) {
8630 nextProps = workInProgress.memoizedProps;
8631 // TODO: When bailing out, we might need to return the stateNode instead
8632 // of the child. To check it for work.
8633 // return bailoutOnAlreadyFinishedWork(current, workInProgress);
8634 }
8635
8636 var nextChildren = nextProps.children;
8637
8638 // The following is a fork of reconcileChildrenAtExpirationTime but using
8639 // stateNode to store the child.
8640 if (current === null) {
8641 workInProgress.stateNode = mountChildFibers(workInProgress, workInProgress.stateNode, nextChildren, renderExpirationTime);
8642 } else {
8643 workInProgress.stateNode = reconcileChildFibers(workInProgress, current.stateNode, nextChildren, renderExpirationTime);
8644 }
8645
8646 memoizeProps(workInProgress, nextProps);
8647 // This doesn't take arbitrary time so we could synchronously just begin
8648 // eagerly do the work of workInProgress.child as an optimization.
8649 return workInProgress.stateNode;
8650 }
8651
8652 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8653 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8654 var nextChildren = workInProgress.pendingProps;
8655 if (hasContextChanged()) {
8656 // Normally we can bail out on props equality but if context has changed
8657 // we don't do the bailout and we have to reuse existing props instead.
8658 } else if (workInProgress.memoizedProps === nextChildren) {
8659 return bailoutOnAlreadyFinishedWork(current, workInProgress);
8660 }
8661
8662 if (current === null) {
8663 // Portals are special because we don't append the children during mount
8664 // but at commit. Therefore we need to track insertions which the normal
8665 // flow doesn't do during mount. This doesn't happen at the root because
8666 // the root always starts with a "current" with a null child.
8667 // TODO: Consider unifying this with how the root works.
8668 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8669 memoizeProps(workInProgress, nextChildren);
8670 } else {
8671 reconcileChildren(current, workInProgress, nextChildren);
8672 memoizeProps(workInProgress, nextChildren);
8673 }
8674 return workInProgress.child;
8675 }
8676
8677 /*
8678 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) {
8679 let child = firstChild;
8680 do {
8681 // Ensure that the first and last effect of the parent corresponds
8682 // to the children's first and last effect.
8683 if (!returnFiber.firstEffect) {
8684 returnFiber.firstEffect = child.firstEffect;
8685 }
8686 if (child.lastEffect) {
8687 if (returnFiber.lastEffect) {
8688 returnFiber.lastEffect.nextEffect = child.firstEffect;
8689 }
8690 returnFiber.lastEffect = child.lastEffect;
8691 }
8692 } while (child = child.sibling);
8693 }
8694 */
8695
8696 function bailoutOnAlreadyFinishedWork(current, workInProgress) {
8697 cancelWorkTimer(workInProgress);
8698
8699 // TODO: We should ideally be able to bail out early if the children have no
8700 // more work to do. However, since we don't have a separation of this
8701 // Fiber's priority and its children yet - we don't know without doing lots
8702 // of the same work we do anyway. Once we have that separation we can just
8703 // bail out here if the children has no more work at this priority level.
8704 // if (workInProgress.priorityOfChildren <= priorityLevel) {
8705 // // If there are side-effects in these children that have not yet been
8706 // // committed we need to ensure that they get properly transferred up.
8707 // if (current && current.child !== workInProgress.child) {
8708 // reuseChildrenEffects(workInProgress, child);
8709 // }
8710 // return null;
8711 // }
8712
8713 cloneChildFibers(current, workInProgress);
8714 return workInProgress.child;
8715 }
8716
8717 function bailoutOnLowPriority(current, workInProgress) {
8718 cancelWorkTimer(workInProgress);
8719
8720 // TODO: Handle HostComponent tags here as well and call pushHostContext()?
8721 // See PR 8590 discussion for context
8722 switch (workInProgress.tag) {
8723 case HostRoot:
8724 pushHostRootContext(workInProgress);
8725 break;
8726 case ClassComponent:
8727 pushContextProvider(workInProgress);
8728 break;
8729 case HostPortal:
8730 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8731 break;
8732 }
8733 // TODO: What if this is currently in progress?
8734 // How can that happen? How is this not being cloned?
8735 return null;
8736 }
8737
8738 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead
8739 function memoizeProps(workInProgress, nextProps) {
8740 workInProgress.memoizedProps = nextProps;
8741 }
8742
8743 function memoizeState(workInProgress, nextState) {
8744 workInProgress.memoizedState = nextState;
8745 // Don't reset the updateQueue, in case there are pending updates. Resetting
8746 // is handled by processUpdateQueue.
8747 }
8748
8749 function beginWork(current, workInProgress, renderExpirationTime) {
8750 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8751 return bailoutOnLowPriority(current, workInProgress);
8752 }
8753
8754 switch (workInProgress.tag) {
8755 case IndeterminateComponent:
8756 return mountIndeterminateComponent(current, workInProgress, renderExpirationTime);
8757 case FunctionalComponent:
8758 return updateFunctionalComponent(current, workInProgress);
8759 case ClassComponent:
8760 return updateClassComponent(current, workInProgress, renderExpirationTime);
8761 case HostRoot:
8762 return updateHostRoot(current, workInProgress, renderExpirationTime);
8763 case HostComponent:
8764 return updateHostComponent(current, workInProgress, renderExpirationTime);
8765 case HostText:
8766 return updateHostText(current, workInProgress);
8767 case CallHandlerPhase:
8768 // This is a restart. Reset the tag to the initial phase.
8769 workInProgress.tag = CallComponent;
8770 // Intentionally fall through since this is now the same.
8771 case CallComponent:
8772 return updateCallComponent(current, workInProgress, renderExpirationTime);
8773 case ReturnComponent:
8774 // A return component is just a placeholder, we can just run through the
8775 // next one immediately.
8776 return null;
8777 case HostPortal:
8778 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8779 case Fragment:
8780 return updateFragment(current, workInProgress);
8781 default:
8782 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8783 }
8784 }
8785
8786 function beginFailedWork(current, workInProgress, renderExpirationTime) {
8787 // Push context providers here to avoid a push/pop context mismatch.
8788 switch (workInProgress.tag) {
8789 case ClassComponent:
8790 pushContextProvider(workInProgress);
8791 break;
8792 case HostRoot:
8793 pushHostRootContext(workInProgress);
8794 break;
8795 default:
8796 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
8797 }
8798
8799 // Add an error effect so we can handle the error during the commit phase
8800 workInProgress.effectTag |= Err;
8801
8802 // This is a weird case where we do "resume" work ? work that failed on
8803 // our first attempt. Because we no longer have a notion of "progressed
8804 // deletions," reset the child to the current child to make sure we delete
8805 // it again. TODO: Find a better way to handle this, perhaps during a more
8806 // general overhaul of error handling.
8807 if (current === null) {
8808 workInProgress.child = null;
8809 } else if (workInProgress.child !== current.child) {
8810 workInProgress.child = current.child;
8811 }
8812
8813 if (workInProgress.expirationTime === NoWork || workInProgress.expirationTime > renderExpirationTime) {
8814 return bailoutOnLowPriority(current, workInProgress);
8815 }
8816
8817 // If we don't bail out, we're going be recomputing our children so we need
8818 // to drop our effect list.
8819 workInProgress.firstEffect = null;
8820 workInProgress.lastEffect = null;
8821
8822 // Unmount the current children as if the component rendered null
8823 var nextChildren = null;
8824 reconcileChildrenAtExpirationTime(current, workInProgress, nextChildren, renderExpirationTime);
8825
8826 if (workInProgress.tag === ClassComponent) {
8827 var instance = workInProgress.stateNode;
8828 workInProgress.memoizedProps = instance.props;
8829 workInProgress.memoizedState = instance.state;
8830 }
8831
8832 return workInProgress.child;
8833 }
8834
8835 return {
8836 beginWork: beginWork,
8837 beginFailedWork: beginFailedWork
8838 };
8839};
8840
8841var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) {
8842 var createInstance = config.createInstance,
8843 createTextInstance = config.createTextInstance,
8844 appendInitialChild = config.appendInitialChild,
8845 finalizeInitialChildren = config.finalizeInitialChildren,
8846 prepareUpdate = config.prepareUpdate,
8847 mutation = config.mutation,
8848 persistence = config.persistence;
8849 var getRootHostContainer = hostContext.getRootHostContainer,
8850 popHostContext = hostContext.popHostContext,
8851 getHostContext = hostContext.getHostContext,
8852 popHostContainer = hostContext.popHostContainer;
8853 var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance,
8854 prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance,
8855 popHydrationState = hydrationContext.popHydrationState;
8856
8857
8858 function markUpdate(workInProgress) {
8859 // Tag the fiber with an update effect. This turns a Placement into
8860 // an UpdateAndPlacement.
8861 workInProgress.effectTag |= Update;
8862 }
8863
8864 function markRef(workInProgress) {
8865 workInProgress.effectTag |= Ref;
8866 }
8867
8868 function appendAllReturns(returns, workInProgress) {
8869 var node = workInProgress.stateNode;
8870 if (node) {
8871 node['return'] = workInProgress;
8872 }
8873 while (node !== null) {
8874 if (node.tag === HostComponent || node.tag === HostText || node.tag === HostPortal) {
8875 invariant_1(false, 'A call cannot have host component children.');
8876 } else if (node.tag === ReturnComponent) {
8877 returns.push(node.pendingProps.value);
8878 } else if (node.child !== null) {
8879 node.child['return'] = node;
8880 node = node.child;
8881 continue;
8882 }
8883 while (node.sibling === null) {
8884 if (node['return'] === null || node['return'] === workInProgress) {
8885 return;
8886 }
8887 node = node['return'];
8888 }
8889 node.sibling['return'] = node['return'];
8890 node = node.sibling;
8891 }
8892 }
8893
8894 function moveCallToHandlerPhase(current, workInProgress, renderExpirationTime) {
8895 var props = workInProgress.memoizedProps;
8896 !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;
8897
8898 // First step of the call has completed. Now we need to do the second.
8899 // TODO: It would be nice to have a multi stage call represented by a
8900 // single component, or at least tail call optimize nested ones. Currently
8901 // that requires additional fields that we don't want to add to the fiber.
8902 // So this requires nested handlers.
8903 // Note: This doesn't mutate the alternate node. I don't think it needs to
8904 // since this stage is reset for every pass.
8905 workInProgress.tag = CallHandlerPhase;
8906
8907 // Build up the returns.
8908 // TODO: Compare this to a generator or opaque helpers like Children.
8909 var returns = [];
8910 appendAllReturns(returns, workInProgress);
8911 var fn = props.handler;
8912 var childProps = props.props;
8913 var nextChildren = fn(childProps, returns);
8914
8915 var currentFirstChild = current !== null ? current.child : null;
8916 workInProgress.child = reconcileChildFibers(workInProgress, currentFirstChild, nextChildren, renderExpirationTime);
8917 return workInProgress.child;
8918 }
8919
8920 function appendAllChildren(parent, workInProgress) {
8921 // We only have the top Fiber that was created but we need recurse down its
8922 // children to find all the terminal nodes.
8923 var node = workInProgress.child;
8924 while (node !== null) {
8925 if (node.tag === HostComponent || node.tag === HostText) {
8926 appendInitialChild(parent, node.stateNode);
8927 } else if (node.tag === HostPortal) {
8928 // If we have a portal child, then we don't want to traverse
8929 // down its children. Instead, we'll get insertions from each child in
8930 // the portal directly.
8931 } else if (node.child !== null) {
8932 node.child['return'] = node;
8933 node = node.child;
8934 continue;
8935 }
8936 if (node === workInProgress) {
8937 return;
8938 }
8939 while (node.sibling === null) {
8940 if (node['return'] === null || node['return'] === workInProgress) {
8941 return;
8942 }
8943 node = node['return'];
8944 }
8945 node.sibling['return'] = node['return'];
8946 node = node.sibling;
8947 }
8948 }
8949
8950 var updateHostContainer = void 0;
8951 var updateHostComponent = void 0;
8952 var updateHostText = void 0;
8953 if (mutation) {
8954 if (enableMutatingReconciler) {
8955 // Mutation mode
8956 updateHostContainer = function (workInProgress) {
8957 // Noop
8958 };
8959 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
8960 // TODO: Type this specific to this type of component.
8961 workInProgress.updateQueue = updatePayload;
8962 // If the update payload indicates that there is a change or if there
8963 // is a new ref we mark this as an update. All the work is done in commitWork.
8964 if (updatePayload) {
8965 markUpdate(workInProgress);
8966 }
8967 };
8968 updateHostText = function (current, workInProgress, oldText, newText) {
8969 // If the text differs, mark it as an update. All the work in done in commitWork.
8970 if (oldText !== newText) {
8971 markUpdate(workInProgress);
8972 }
8973 };
8974 } else {
8975 invariant_1(false, 'Mutating reconciler is disabled.');
8976 }
8977 } else if (persistence) {
8978 if (enablePersistentReconciler) {
8979 // Persistent host tree mode
8980 var cloneInstance = persistence.cloneInstance,
8981 createContainerChildSet = persistence.createContainerChildSet,
8982 appendChildToContainerChildSet = persistence.appendChildToContainerChildSet,
8983 finalizeContainerChildren = persistence.finalizeContainerChildren;
8984
8985 // An unfortunate fork of appendAllChildren because we have two different parent types.
8986
8987 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) {
8988 // We only have the top Fiber that was created but we need recurse down its
8989 // children to find all the terminal nodes.
8990 var node = workInProgress.child;
8991 while (node !== null) {
8992 if (node.tag === HostComponent || node.tag === HostText) {
8993 appendChildToContainerChildSet(containerChildSet, node.stateNode);
8994 } else if (node.tag === HostPortal) {
8995 // If we have a portal child, then we don't want to traverse
8996 // down its children. Instead, we'll get insertions from each child in
8997 // the portal directly.
8998 } else if (node.child !== null) {
8999 node.child['return'] = node;
9000 node = node.child;
9001 continue;
9002 }
9003 if (node === workInProgress) {
9004 return;
9005 }
9006 while (node.sibling === null) {
9007 if (node['return'] === null || node['return'] === workInProgress) {
9008 return;
9009 }
9010 node = node['return'];
9011 }
9012 node.sibling['return'] = node['return'];
9013 node = node.sibling;
9014 }
9015 };
9016 updateHostContainer = function (workInProgress) {
9017 var portalOrRoot = workInProgress.stateNode;
9018 var childrenUnchanged = workInProgress.firstEffect === null;
9019 if (childrenUnchanged) {
9020 // No changes, just reuse the existing instance.
9021 } else {
9022 var container = portalOrRoot.containerInfo;
9023 var newChildSet = createContainerChildSet(container);
9024 if (finalizeContainerChildren(container, newChildSet)) {
9025 markUpdate(workInProgress);
9026 }
9027 portalOrRoot.pendingChildren = newChildSet;
9028 // If children might have changed, we have to add them all to the set.
9029 appendAllChildrenToContainer(newChildSet, workInProgress);
9030 // Schedule an update on the container to swap out the container.
9031 markUpdate(workInProgress);
9032 }
9033 };
9034 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9035 // If there are no effects associated with this node, then none of our children had any updates.
9036 // This guarantees that we can reuse all of them.
9037 var childrenUnchanged = workInProgress.firstEffect === null;
9038 var currentInstance = current.stateNode;
9039 if (childrenUnchanged && updatePayload === null) {
9040 // No changes, just reuse the existing instance.
9041 // Note that this might release a previous clone.
9042 workInProgress.stateNode = currentInstance;
9043 } else {
9044 var recyclableInstance = workInProgress.stateNode;
9045 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9046 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9047 markUpdate(workInProgress);
9048 }
9049 workInProgress.stateNode = newInstance;
9050 if (childrenUnchanged) {
9051 // If there are no other effects in this tree, we need to flag this node as having one.
9052 // Even though we're not going to use it for anything.
9053 // Otherwise parents won't know that there are new children to propagate upwards.
9054 markUpdate(workInProgress);
9055 } else {
9056 // If children might have changed, we have to add them all to the set.
9057 appendAllChildren(newInstance, workInProgress);
9058 }
9059 }
9060 };
9061 updateHostText = function (current, workInProgress, oldText, newText) {
9062 if (oldText !== newText) {
9063 // If the text content differs, we'll create a new text instance for it.
9064 var rootContainerInstance = getRootHostContainer();
9065 var currentHostContext = getHostContext();
9066 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9067 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9068 // This lets the parents know that at least one of their children has changed.
9069 markUpdate(workInProgress);
9070 }
9071 };
9072 } else {
9073 invariant_1(false, 'Persistent reconciler is disabled.');
9074 }
9075 } else {
9076 if (enableNoopReconciler) {
9077 // No host operations
9078 updateHostContainer = function (workInProgress) {
9079 // Noop
9080 };
9081 updateHostComponent = function (current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext) {
9082 // Noop
9083 };
9084 updateHostText = function (current, workInProgress, oldText, newText) {
9085 // Noop
9086 };
9087 } else {
9088 invariant_1(false, 'Noop reconciler is disabled.');
9089 }
9090 }
9091
9092 function completeWork(current, workInProgress, renderExpirationTime) {
9093 var newProps = workInProgress.pendingProps;
9094 switch (workInProgress.tag) {
9095 case FunctionalComponent:
9096 return null;
9097 case ClassComponent:
9098 {
9099 // We are leaving this subtree, so pop context if any.
9100 popContextProvider(workInProgress);
9101 return null;
9102 }
9103 case HostRoot:
9104 {
9105 popHostContainer(workInProgress);
9106 popTopLevelContextObject(workInProgress);
9107 var fiberRoot = workInProgress.stateNode;
9108 if (fiberRoot.pendingContext) {
9109 fiberRoot.context = fiberRoot.pendingContext;
9110 fiberRoot.pendingContext = null;
9111 }
9112
9113 if (current === null || current.child === null) {
9114 // If we hydrated, pop so that we can delete any remaining children
9115 // that weren't hydrated.
9116 popHydrationState(workInProgress);
9117 // This resets the hacky state to fix isMounted before committing.
9118 // TODO: Delete this when we delete isMounted and findDOMNode.
9119 workInProgress.effectTag &= ~Placement;
9120 }
9121 updateHostContainer(workInProgress);
9122 return null;
9123 }
9124 case HostComponent:
9125 {
9126 popHostContext(workInProgress);
9127 var rootContainerInstance = getRootHostContainer();
9128 var type = workInProgress.type;
9129 if (current !== null && workInProgress.stateNode != null) {
9130 // If we have an alternate, that means this is an update and we need to
9131 // schedule a side-effect to do the updates.
9132 var oldProps = current.memoizedProps;
9133 // If we get updated because one of our children updated, we don't
9134 // have newProps so we'll have to reuse them.
9135 // TODO: Split the update API as separate for the props vs. children.
9136 // Even better would be if children weren't special cased at all tho.
9137 var instance = workInProgress.stateNode;
9138 var currentHostContext = getHostContext();
9139 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9140
9141 updateHostComponent(current, workInProgress, updatePayload, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9142
9143 if (current.ref !== workInProgress.ref) {
9144 markRef(workInProgress);
9145 }
9146 } else {
9147 if (!newProps) {
9148 !(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;
9149 // This can happen when we abort work.
9150 return null;
9151 }
9152
9153 var _currentHostContext = getHostContext();
9154 // TODO: Move createInstance to beginWork and keep it on a context
9155 // "stack" as the parent. Then append children as we go in beginWork
9156 // or completeWork depending on we want to add then top->down or
9157 // bottom->up. Top->down is faster in IE11.
9158 var wasHydrated = popHydrationState(workInProgress);
9159 if (wasHydrated) {
9160 // TODO: Move this and createInstance step into the beginPhase
9161 // to consolidate.
9162 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) {
9163 // If changes to the hydrated node needs to be applied at the
9164 // commit-phase we mark this as such.
9165 markUpdate(workInProgress);
9166 }
9167 } else {
9168 var _instance = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress);
9169
9170 appendAllChildren(_instance, workInProgress);
9171
9172 // Certain renderers require commit-time effects for initial mount.
9173 // (eg DOM renderer supports auto-focus for certain elements).
9174 // Make sure such renderers get scheduled for later work.
9175 if (finalizeInitialChildren(_instance, type, newProps, rootContainerInstance, _currentHostContext)) {
9176 markUpdate(workInProgress);
9177 }
9178 workInProgress.stateNode = _instance;
9179 }
9180
9181 if (workInProgress.ref !== null) {
9182 // If there is a ref on a host node we need to schedule a callback
9183 markRef(workInProgress);
9184 }
9185 }
9186 return null;
9187 }
9188 case HostText:
9189 {
9190 var newText = newProps;
9191 if (current && workInProgress.stateNode != null) {
9192 var oldText = current.memoizedProps;
9193 // If we have an alternate, that means this is an update and we need
9194 // to schedule a side-effect to do the updates.
9195 updateHostText(current, workInProgress, oldText, newText);
9196 } else {
9197 if (typeof newText !== 'string') {
9198 !(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;
9199 // This can happen when we abort work.
9200 return null;
9201 }
9202 var _rootContainerInstance = getRootHostContainer();
9203 var _currentHostContext2 = getHostContext();
9204 var _wasHydrated = popHydrationState(workInProgress);
9205 if (_wasHydrated) {
9206 if (prepareToHydrateHostTextInstance(workInProgress)) {
9207 markUpdate(workInProgress);
9208 }
9209 } else {
9210 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress);
9211 }
9212 }
9213 return null;
9214 }
9215 case CallComponent:
9216 return moveCallToHandlerPhase(current, workInProgress, renderExpirationTime);
9217 case CallHandlerPhase:
9218 // Reset the tag to now be a first phase call.
9219 workInProgress.tag = CallComponent;
9220 return null;
9221 case ReturnComponent:
9222 // Does nothing.
9223 return null;
9224 case Fragment:
9225 return null;
9226 case HostPortal:
9227 popHostContainer(workInProgress);
9228 updateHostContainer(workInProgress);
9229 return null;
9230 // Error cases
9231 case IndeterminateComponent:
9232 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.');
9233 // eslint-disable-next-line no-fallthrough
9234 default:
9235 invariant_1(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9236 }
9237 }
9238
9239 return {
9240 completeWork: completeWork
9241 };
9242};
9243
9244var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback;
9245var hasCaughtError$1 = ReactErrorUtils.hasCaughtError;
9246var clearCaughtError$1 = ReactErrorUtils.clearCaughtError;
9247
9248
9249var ReactFiberCommitWork = function (config, captureError) {
9250 var getPublicInstance = config.getPublicInstance,
9251 mutation = config.mutation,
9252 persistence = config.persistence;
9253
9254
9255 var callComponentWillUnmountWithTimer = function (current, instance) {
9256 startPhaseTimer(current, 'componentWillUnmount');
9257 instance.props = current.memoizedProps;
9258 instance.state = current.memoizedState;
9259 instance.componentWillUnmount();
9260 stopPhaseTimer();
9261 };
9262
9263 // Capture errors so they don't interrupt unmounting.
9264 function safelyCallComponentWillUnmount(current, instance) {
9265 {
9266 invokeGuardedCallback$3(null, callComponentWillUnmountWithTimer, null, current, instance);
9267 if (hasCaughtError$1()) {
9268 var unmountError = clearCaughtError$1();
9269 captureError(current, unmountError);
9270 }
9271 }
9272 }
9273
9274 function safelyDetachRef(current) {
9275 var ref = current.ref;
9276 if (ref !== null) {
9277 {
9278 invokeGuardedCallback$3(null, ref, null, null);
9279 if (hasCaughtError$1()) {
9280 var refError = clearCaughtError$1();
9281 captureError(current, refError);
9282 }
9283 }
9284 }
9285 }
9286
9287 function commitLifeCycles(current, finishedWork) {
9288 switch (finishedWork.tag) {
9289 case ClassComponent:
9290 {
9291 var instance = finishedWork.stateNode;
9292 if (finishedWork.effectTag & Update) {
9293 if (current === null) {
9294 startPhaseTimer(finishedWork, 'componentDidMount');
9295 instance.props = finishedWork.memoizedProps;
9296 instance.state = finishedWork.memoizedState;
9297 instance.componentDidMount();
9298 stopPhaseTimer();
9299 } else {
9300 var prevProps = current.memoizedProps;
9301 var prevState = current.memoizedState;
9302 startPhaseTimer(finishedWork, 'componentDidUpdate');
9303 instance.props = finishedWork.memoizedProps;
9304 instance.state = finishedWork.memoizedState;
9305 instance.componentDidUpdate(prevProps, prevState);
9306 stopPhaseTimer();
9307 }
9308 }
9309 var updateQueue = finishedWork.updateQueue;
9310 if (updateQueue !== null) {
9311 commitCallbacks(updateQueue, instance);
9312 }
9313 return;
9314 }
9315 case HostRoot:
9316 {
9317 var _updateQueue = finishedWork.updateQueue;
9318 if (_updateQueue !== null) {
9319 var _instance = finishedWork.child !== null ? finishedWork.child.stateNode : null;
9320 commitCallbacks(_updateQueue, _instance);
9321 }
9322 return;
9323 }
9324 case HostComponent:
9325 {
9326 var _instance2 = finishedWork.stateNode;
9327
9328 // Renderers may schedule work to be done after host components are mounted
9329 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9330 // These effects should only be committed when components are first mounted,
9331 // aka when there is no current/alternate.
9332 if (current === null && finishedWork.effectTag & Update) {
9333 var type = finishedWork.type;
9334 var props = finishedWork.memoizedProps;
9335 commitMount(_instance2, type, props, finishedWork);
9336 }
9337
9338 return;
9339 }
9340 case HostText:
9341 {
9342 // We have no life-cycles associated with text.
9343 return;
9344 }
9345 case HostPortal:
9346 {
9347 // We have no life-cycles associated with portals.
9348 return;
9349 }
9350 default:
9351 {
9352 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.');
9353 }
9354 }
9355 }
9356
9357 function commitAttachRef(finishedWork) {
9358 var ref = finishedWork.ref;
9359 if (ref !== null) {
9360 var instance = finishedWork.stateNode;
9361 switch (finishedWork.tag) {
9362 case HostComponent:
9363 ref(getPublicInstance(instance));
9364 break;
9365 default:
9366 ref(instance);
9367 }
9368 }
9369 }
9370
9371 function commitDetachRef(current) {
9372 var currentRef = current.ref;
9373 if (currentRef !== null) {
9374 currentRef(null);
9375 }
9376 }
9377
9378 // User-originating errors (lifecycles and refs) should not interrupt
9379 // deletion, so don't let them throw. Host-originating errors should
9380 // interrupt deletion, so it's okay
9381 function commitUnmount(current) {
9382 if (typeof onCommitUnmount === 'function') {
9383 onCommitUnmount(current);
9384 }
9385
9386 switch (current.tag) {
9387 case ClassComponent:
9388 {
9389 safelyDetachRef(current);
9390 var instance = current.stateNode;
9391 if (typeof instance.componentWillUnmount === 'function') {
9392 safelyCallComponentWillUnmount(current, instance);
9393 }
9394 return;
9395 }
9396 case HostComponent:
9397 {
9398 safelyDetachRef(current);
9399 return;
9400 }
9401 case CallComponent:
9402 {
9403 commitNestedUnmounts(current.stateNode);
9404 return;
9405 }
9406 case HostPortal:
9407 {
9408 // TODO: this is recursive.
9409 // We are also not using this parent because
9410 // the portal will get pushed immediately.
9411 if (enableMutatingReconciler && mutation) {
9412 unmountHostComponents(current);
9413 } else if (enablePersistentReconciler && persistence) {
9414 emptyPortalContainer(current);
9415 }
9416 return;
9417 }
9418 }
9419 }
9420
9421 function commitNestedUnmounts(root) {
9422 // While we're inside a removed host node we don't want to call
9423 // removeChild on the inner nodes because they're removed by the top
9424 // call anyway. We also want to call componentWillUnmount on all
9425 // composites before this host node is removed from the tree. Therefore
9426 var node = root;
9427 while (true) {
9428 commitUnmount(node);
9429 // Visit children because they may contain more composite or host nodes.
9430 // Skip portals because commitUnmount() currently visits them recursively.
9431 if (node.child !== null && (
9432 // If we use mutation we drill down into portals using commitUnmount above.
9433 // If we don't use mutation we drill down into portals here instead.
9434 !mutation || node.tag !== HostPortal)) {
9435 node.child['return'] = node;
9436 node = node.child;
9437 continue;
9438 }
9439 if (node === root) {
9440 return;
9441 }
9442 while (node.sibling === null) {
9443 if (node['return'] === null || node['return'] === root) {
9444 return;
9445 }
9446 node = node['return'];
9447 }
9448 node.sibling['return'] = node['return'];
9449 node = node.sibling;
9450 }
9451 }
9452
9453 function detachFiber(current) {
9454 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9455 // should clear the child pointer of the parent alternate to let this
9456 // get GC:ed but we don't know which for sure which parent is the current
9457 // one so we'll settle for GC:ing the subtree of this child. This child
9458 // itself will be GC:ed when the parent updates the next time.
9459 current['return'] = null;
9460 current.child = null;
9461 if (current.alternate) {
9462 current.alternate.child = null;
9463 current.alternate['return'] = null;
9464 }
9465 }
9466
9467 var emptyPortalContainer = void 0;
9468
9469 if (!mutation) {
9470 var commitContainer = void 0;
9471 if (persistence) {
9472 var replaceContainerChildren = persistence.replaceContainerChildren,
9473 createContainerChildSet = persistence.createContainerChildSet;
9474
9475 emptyPortalContainer = function (current) {
9476 var portal = current.stateNode;
9477 var containerInfo = portal.containerInfo;
9478
9479 var emptyChildSet = createContainerChildSet(containerInfo);
9480 replaceContainerChildren(containerInfo, emptyChildSet);
9481 };
9482 commitContainer = function (finishedWork) {
9483 switch (finishedWork.tag) {
9484 case ClassComponent:
9485 {
9486 return;
9487 }
9488 case HostComponent:
9489 {
9490 return;
9491 }
9492 case HostText:
9493 {
9494 return;
9495 }
9496 case HostRoot:
9497 case HostPortal:
9498 {
9499 var portalOrRoot = finishedWork.stateNode;
9500 var containerInfo = portalOrRoot.containerInfo,
9501 _pendingChildren = portalOrRoot.pendingChildren;
9502
9503 replaceContainerChildren(containerInfo, _pendingChildren);
9504 return;
9505 }
9506 default:
9507 {
9508 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.');
9509 }
9510 }
9511 };
9512 } else {
9513 commitContainer = function (finishedWork) {
9514 // Noop
9515 };
9516 }
9517 if (enablePersistentReconciler || enableNoopReconciler) {
9518 return {
9519 commitResetTextContent: function (finishedWork) {},
9520 commitPlacement: function (finishedWork) {},
9521 commitDeletion: function (current) {
9522 // Detach refs and call componentWillUnmount() on the whole subtree.
9523 commitNestedUnmounts(current);
9524 detachFiber(current);
9525 },
9526 commitWork: function (current, finishedWork) {
9527 commitContainer(finishedWork);
9528 },
9529
9530 commitLifeCycles: commitLifeCycles,
9531 commitAttachRef: commitAttachRef,
9532 commitDetachRef: commitDetachRef
9533 };
9534 } else if (persistence) {
9535 invariant_1(false, 'Persistent reconciler is disabled.');
9536 } else {
9537 invariant_1(false, 'Noop reconciler is disabled.');
9538 }
9539 }
9540 var commitMount = mutation.commitMount,
9541 commitUpdate = mutation.commitUpdate,
9542 resetTextContent = mutation.resetTextContent,
9543 commitTextUpdate = mutation.commitTextUpdate,
9544 appendChild = mutation.appendChild,
9545 appendChildToContainer = mutation.appendChildToContainer,
9546 insertBefore = mutation.insertBefore,
9547 insertInContainerBefore = mutation.insertInContainerBefore,
9548 removeChild = mutation.removeChild,
9549 removeChildFromContainer = mutation.removeChildFromContainer;
9550
9551
9552 function getHostParentFiber(fiber) {
9553 var parent = fiber['return'];
9554 while (parent !== null) {
9555 if (isHostParent(parent)) {
9556 return parent;
9557 }
9558 parent = parent['return'];
9559 }
9560 invariant_1(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9561 }
9562
9563 function isHostParent(fiber) {
9564 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9565 }
9566
9567 function getHostSibling(fiber) {
9568 // We're going to search forward into the tree until we find a sibling host
9569 // node. Unfortunately, if multiple insertions are done in a row we have to
9570 // search past them. This leads to exponential search for the next sibling.
9571 var node = fiber;
9572 siblings: while (true) {
9573 // If we didn't find anything, let's try the next sibling.
9574 while (node.sibling === null) {
9575 if (node['return'] === null || isHostParent(node['return'])) {
9576 // If we pop out of the root or hit the parent the fiber we are the
9577 // last sibling.
9578 return null;
9579 }
9580 node = node['return'];
9581 }
9582 node.sibling['return'] = node['return'];
9583 node = node.sibling;
9584 while (node.tag !== HostComponent && node.tag !== HostText) {
9585 // If it is not host node and, we might have a host node inside it.
9586 // Try to search down until we find one.
9587 if (node.effectTag & Placement) {
9588 // If we don't have a child, try the siblings instead.
9589 continue siblings;
9590 }
9591 // If we don't have a child, try the siblings instead.
9592 // We also skip portals because they are not part of this host tree.
9593 if (node.child === null || node.tag === HostPortal) {
9594 continue siblings;
9595 } else {
9596 node.child['return'] = node;
9597 node = node.child;
9598 }
9599 }
9600 // Check if this host node is stable or about to be placed.
9601 if (!(node.effectTag & Placement)) {
9602 // Found it!
9603 return node.stateNode;
9604 }
9605 }
9606 }
9607
9608 function commitPlacement(finishedWork) {
9609 // Recursively insert all host nodes into the parent.
9610 var parentFiber = getHostParentFiber(finishedWork);
9611 var parent = void 0;
9612 var isContainer = void 0;
9613 switch (parentFiber.tag) {
9614 case HostComponent:
9615 parent = parentFiber.stateNode;
9616 isContainer = false;
9617 break;
9618 case HostRoot:
9619 parent = parentFiber.stateNode.containerInfo;
9620 isContainer = true;
9621 break;
9622 case HostPortal:
9623 parent = parentFiber.stateNode.containerInfo;
9624 isContainer = true;
9625 break;
9626 default:
9627 invariant_1(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9628 }
9629 if (parentFiber.effectTag & ContentReset) {
9630 // Reset the text content of the parent before doing any insertions
9631 resetTextContent(parent);
9632 // Clear ContentReset from the effect tag
9633 parentFiber.effectTag &= ~ContentReset;
9634 }
9635
9636 var before = getHostSibling(finishedWork);
9637 // We only have the top Fiber that was inserted but we need recurse down its
9638 // children to find all the terminal nodes.
9639 var node = finishedWork;
9640 while (true) {
9641 if (node.tag === HostComponent || node.tag === HostText) {
9642 if (before) {
9643 if (isContainer) {
9644 insertInContainerBefore(parent, node.stateNode, before);
9645 } else {
9646 insertBefore(parent, node.stateNode, before);
9647 }
9648 } else {
9649 if (isContainer) {
9650 appendChildToContainer(parent, node.stateNode);
9651 } else {
9652 appendChild(parent, node.stateNode);
9653 }
9654 }
9655 } else if (node.tag === HostPortal) {
9656 // If the insertion itself is a portal, then we don't want to traverse
9657 // down its children. Instead, we'll get insertions from each child in
9658 // the portal directly.
9659 } else if (node.child !== null) {
9660 node.child['return'] = node;
9661 node = node.child;
9662 continue;
9663 }
9664 if (node === finishedWork) {
9665 return;
9666 }
9667 while (node.sibling === null) {
9668 if (node['return'] === null || node['return'] === finishedWork) {
9669 return;
9670 }
9671 node = node['return'];
9672 }
9673 node.sibling['return'] = node['return'];
9674 node = node.sibling;
9675 }
9676 }
9677
9678 function unmountHostComponents(current) {
9679 // We only have the top Fiber that was inserted but we need recurse down its
9680 var node = current;
9681
9682 // Each iteration, currentParent is populated with node's host parent if not
9683 // currentParentIsValid.
9684 var currentParentIsValid = false;
9685 var currentParent = void 0;
9686 var currentParentIsContainer = void 0;
9687
9688 while (true) {
9689 if (!currentParentIsValid) {
9690 var parent = node['return'];
9691 findParent: while (true) {
9692 !(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;
9693 switch (parent.tag) {
9694 case HostComponent:
9695 currentParent = parent.stateNode;
9696 currentParentIsContainer = false;
9697 break findParent;
9698 case HostRoot:
9699 currentParent = parent.stateNode.containerInfo;
9700 currentParentIsContainer = true;
9701 break findParent;
9702 case HostPortal:
9703 currentParent = parent.stateNode.containerInfo;
9704 currentParentIsContainer = true;
9705 break findParent;
9706 }
9707 parent = parent['return'];
9708 }
9709 currentParentIsValid = true;
9710 }
9711
9712 if (node.tag === HostComponent || node.tag === HostText) {
9713 commitNestedUnmounts(node);
9714 // After all the children have unmounted, it is now safe to remove the
9715 // node from the tree.
9716 if (currentParentIsContainer) {
9717 removeChildFromContainer(currentParent, node.stateNode);
9718 } else {
9719 removeChild(currentParent, node.stateNode);
9720 }
9721 // Don't visit children because we already visited them.
9722 } else if (node.tag === HostPortal) {
9723 // When we go into a portal, it becomes the parent to remove from.
9724 // We will reassign it back when we pop the portal on the way up.
9725 currentParent = node.stateNode.containerInfo;
9726 // Visit children because portals might contain host components.
9727 if (node.child !== null) {
9728 node.child['return'] = node;
9729 node = node.child;
9730 continue;
9731 }
9732 } else {
9733 commitUnmount(node);
9734 // Visit children because we may find more host components below.
9735 if (node.child !== null) {
9736 node.child['return'] = node;
9737 node = node.child;
9738 continue;
9739 }
9740 }
9741 if (node === current) {
9742 return;
9743 }
9744 while (node.sibling === null) {
9745 if (node['return'] === null || node['return'] === current) {
9746 return;
9747 }
9748 node = node['return'];
9749 if (node.tag === HostPortal) {
9750 // When we go out of the portal, we need to restore the parent.
9751 // Since we don't keep a stack of them, we will search for it.
9752 currentParentIsValid = false;
9753 }
9754 }
9755 node.sibling['return'] = node['return'];
9756 node = node.sibling;
9757 }
9758 }
9759
9760 function commitDeletion(current) {
9761 // Recursively delete all host nodes from the parent.
9762 // Detach refs and call componentWillUnmount() on the whole subtree.
9763 unmountHostComponents(current);
9764 detachFiber(current);
9765 }
9766
9767 function commitWork(current, finishedWork) {
9768 switch (finishedWork.tag) {
9769 case ClassComponent:
9770 {
9771 return;
9772 }
9773 case HostComponent:
9774 {
9775 var instance = finishedWork.stateNode;
9776 if (instance != null) {
9777 // Commit the work prepared earlier.
9778 var newProps = finishedWork.memoizedProps;
9779 // For hydration we reuse the update path but we treat the oldProps
9780 // as the newProps. The updatePayload will contain the real change in
9781 // this case.
9782 var oldProps = current !== null ? current.memoizedProps : newProps;
9783 var type = finishedWork.type;
9784 // TODO: Type the updateQueue to be specific to host components.
9785 var updatePayload = finishedWork.updateQueue;
9786 finishedWork.updateQueue = null;
9787 if (updatePayload !== null) {
9788 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
9789 }
9790 }
9791 return;
9792 }
9793 case HostText:
9794 {
9795 !(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;
9796 var textInstance = finishedWork.stateNode;
9797 var newText = finishedWork.memoizedProps;
9798 // For hydration we reuse the update path but we treat the oldProps
9799 // as the newProps. The updatePayload will contain the real change in
9800 // this case.
9801 var oldText = current !== null ? current.memoizedProps : newText;
9802 commitTextUpdate(textInstance, oldText, newText);
9803 return;
9804 }
9805 case HostRoot:
9806 {
9807 return;
9808 }
9809 default:
9810 {
9811 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.');
9812 }
9813 }
9814 }
9815
9816 function commitResetTextContent(current) {
9817 resetTextContent(current.stateNode);
9818 }
9819
9820 if (enableMutatingReconciler) {
9821 return {
9822 commitResetTextContent: commitResetTextContent,
9823 commitPlacement: commitPlacement,
9824 commitDeletion: commitDeletion,
9825 commitWork: commitWork,
9826 commitLifeCycles: commitLifeCycles,
9827 commitAttachRef: commitAttachRef,
9828 commitDetachRef: commitDetachRef
9829 };
9830 } else {
9831 invariant_1(false, 'Mutating reconciler is disabled.');
9832 }
9833};
9834
9835var NO_CONTEXT = {};
9836
9837var ReactFiberHostContext = function (config) {
9838 var getChildHostContext = config.getChildHostContext,
9839 getRootHostContext = config.getRootHostContext;
9840
9841
9842 var contextStackCursor = createCursor(NO_CONTEXT);
9843 var contextFiberStackCursor = createCursor(NO_CONTEXT);
9844 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
9845
9846 function requiredContext(c) {
9847 !(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;
9848 return c;
9849 }
9850
9851 function getRootHostContainer() {
9852 var rootInstance = requiredContext(rootInstanceStackCursor.current);
9853 return rootInstance;
9854 }
9855
9856 function pushHostContainer(fiber, nextRootInstance) {
9857 // Push current root instance onto the stack;
9858 // This allows us to reset root when portals are popped.
9859 push(rootInstanceStackCursor, nextRootInstance, fiber);
9860
9861 var nextRootContext = getRootHostContext(nextRootInstance);
9862
9863 // Track the context and the Fiber that provided it.
9864 // This enables us to pop only Fibers that provide unique contexts.
9865 push(contextFiberStackCursor, fiber, fiber);
9866 push(contextStackCursor, nextRootContext, fiber);
9867 }
9868
9869 function popHostContainer(fiber) {
9870 pop(contextStackCursor, fiber);
9871 pop(contextFiberStackCursor, fiber);
9872 pop(rootInstanceStackCursor, fiber);
9873 }
9874
9875 function getHostContext() {
9876 var context = requiredContext(contextStackCursor.current);
9877 return context;
9878 }
9879
9880 function pushHostContext(fiber) {
9881 var rootInstance = requiredContext(rootInstanceStackCursor.current);
9882 var context = requiredContext(contextStackCursor.current);
9883 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
9884
9885 // Don't push this Fiber's context unless it's unique.
9886 if (context === nextContext) {
9887 return;
9888 }
9889
9890 // Track the context and the Fiber that provided it.
9891 // This enables us to pop only Fibers that provide unique contexts.
9892 push(contextFiberStackCursor, fiber, fiber);
9893 push(contextStackCursor, nextContext, fiber);
9894 }
9895
9896 function popHostContext(fiber) {
9897 // Do not pop unless this Fiber provided the current context.
9898 // pushHostContext() only pushes Fibers that provide unique contexts.
9899 if (contextFiberStackCursor.current !== fiber) {
9900 return;
9901 }
9902
9903 pop(contextStackCursor, fiber);
9904 pop(contextFiberStackCursor, fiber);
9905 }
9906
9907 function resetHostContainer() {
9908 contextStackCursor.current = NO_CONTEXT;
9909 rootInstanceStackCursor.current = NO_CONTEXT;
9910 }
9911
9912 return {
9913 getHostContext: getHostContext,
9914 getRootHostContainer: getRootHostContainer,
9915 popHostContainer: popHostContainer,
9916 popHostContext: popHostContext,
9917 pushHostContainer: pushHostContainer,
9918 pushHostContext: pushHostContext,
9919 resetHostContainer: resetHostContainer
9920 };
9921};
9922
9923var ReactFiberHydrationContext = function (config) {
9924 var shouldSetTextContent = config.shouldSetTextContent,
9925 hydration = config.hydration;
9926
9927 // If this doesn't have hydration mode.
9928
9929 if (!hydration) {
9930 return {
9931 enterHydrationState: function () {
9932 return false;
9933 },
9934 resetHydrationState: function () {},
9935 tryToClaimNextHydratableInstance: function () {},
9936 prepareToHydrateHostInstance: function () {
9937 invariant_1(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
9938 },
9939 prepareToHydrateHostTextInstance: function () {
9940 invariant_1(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
9941 },
9942 popHydrationState: function (fiber) {
9943 return false;
9944 }
9945 };
9946 }
9947
9948 var canHydrateInstance = hydration.canHydrateInstance,
9949 canHydrateTextInstance = hydration.canHydrateTextInstance,
9950 getNextHydratableSibling = hydration.getNextHydratableSibling,
9951 getFirstHydratableChild = hydration.getFirstHydratableChild,
9952 hydrateInstance = hydration.hydrateInstance,
9953 hydrateTextInstance = hydration.hydrateTextInstance,
9954 didNotMatchHydratedContainerTextInstance = hydration.didNotMatchHydratedContainerTextInstance,
9955 didNotMatchHydratedTextInstance = hydration.didNotMatchHydratedTextInstance,
9956 didNotHydrateContainerInstance = hydration.didNotHydrateContainerInstance,
9957 didNotHydrateInstance = hydration.didNotHydrateInstance,
9958 didNotFindHydratableContainerInstance = hydration.didNotFindHydratableContainerInstance,
9959 didNotFindHydratableContainerTextInstance = hydration.didNotFindHydratableContainerTextInstance,
9960 didNotFindHydratableInstance = hydration.didNotFindHydratableInstance,
9961 didNotFindHydratableTextInstance = hydration.didNotFindHydratableTextInstance;
9962
9963 // The deepest Fiber on the stack involved in a hydration context.
9964 // This may have been an insertion or a hydration.
9965
9966 var hydrationParentFiber = null;
9967 var nextHydratableInstance = null;
9968 var isHydrating = false;
9969
9970 function enterHydrationState(fiber) {
9971 var parentInstance = fiber.stateNode.containerInfo;
9972 nextHydratableInstance = getFirstHydratableChild(parentInstance);
9973 hydrationParentFiber = fiber;
9974 isHydrating = true;
9975 return true;
9976 }
9977
9978 function deleteHydratableInstance(returnFiber, instance) {
9979 {
9980 switch (returnFiber.tag) {
9981 case HostRoot:
9982 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
9983 break;
9984 case HostComponent:
9985 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
9986 break;
9987 }
9988 }
9989
9990 var childToDelete = createFiberFromHostInstanceForDeletion();
9991 childToDelete.stateNode = instance;
9992 childToDelete['return'] = returnFiber;
9993 childToDelete.effectTag = Deletion;
9994
9995 // This might seem like it belongs on progressedFirstDeletion. However,
9996 // these children are not part of the reconciliation list of children.
9997 // Even if we abort and rereconcile the children, that will try to hydrate
9998 // again and the nodes are still in the host tree so these will be
9999 // recreated.
10000 if (returnFiber.lastEffect !== null) {
10001 returnFiber.lastEffect.nextEffect = childToDelete;
10002 returnFiber.lastEffect = childToDelete;
10003 } else {
10004 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
10005 }
10006 }
10007
10008 function insertNonHydratedInstance(returnFiber, fiber) {
10009 fiber.effectTag |= Placement;
10010 {
10011 switch (returnFiber.tag) {
10012 case HostRoot:
10013 {
10014 var parentContainer = returnFiber.stateNode.containerInfo;
10015 switch (fiber.tag) {
10016 case HostComponent:
10017 var type = fiber.type;
10018 var props = fiber.pendingProps;
10019 didNotFindHydratableContainerInstance(parentContainer, type, props);
10020 break;
10021 case HostText:
10022 var text = fiber.pendingProps;
10023 didNotFindHydratableContainerTextInstance(parentContainer, text);
10024 break;
10025 }
10026 break;
10027 }
10028 case HostComponent:
10029 {
10030 var parentType = returnFiber.type;
10031 var parentProps = returnFiber.memoizedProps;
10032 var parentInstance = returnFiber.stateNode;
10033 switch (fiber.tag) {
10034 case HostComponent:
10035 var _type = fiber.type;
10036 var _props = fiber.pendingProps;
10037 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
10038 break;
10039 case HostText:
10040 var _text = fiber.pendingProps;
10041 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
10042 break;
10043 }
10044 break;
10045 }
10046 default:
10047 return;
10048 }
10049 }
10050 }
10051
10052 function tryHydrate(fiber, nextInstance) {
10053 switch (fiber.tag) {
10054 case HostComponent:
10055 {
10056 var type = fiber.type;
10057 var props = fiber.pendingProps;
10058 var instance = canHydrateInstance(nextInstance, type, props);
10059 if (instance !== null) {
10060 fiber.stateNode = instance;
10061 return true;
10062 }
10063 return false;
10064 }
10065 case HostText:
10066 {
10067 var text = fiber.pendingProps;
10068 var textInstance = canHydrateTextInstance(nextInstance, text);
10069 if (textInstance !== null) {
10070 fiber.stateNode = textInstance;
10071 return true;
10072 }
10073 return false;
10074 }
10075 default:
10076 return false;
10077 }
10078 }
10079
10080 function tryToClaimNextHydratableInstance(fiber) {
10081 if (!isHydrating) {
10082 return;
10083 }
10084 var nextInstance = nextHydratableInstance;
10085 if (!nextInstance) {
10086 // Nothing to hydrate. Make it an insertion.
10087 insertNonHydratedInstance(hydrationParentFiber, fiber);
10088 isHydrating = false;
10089 hydrationParentFiber = fiber;
10090 return;
10091 }
10092 if (!tryHydrate(fiber, nextInstance)) {
10093 // If we can't hydrate this instance let's try the next one.
10094 // We use this as a heuristic. It's based on intuition and not data so it
10095 // might be flawed or unnecessary.
10096 nextInstance = getNextHydratableSibling(nextInstance);
10097 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
10098 // Nothing to hydrate. Make it an insertion.
10099 insertNonHydratedInstance(hydrationParentFiber, fiber);
10100 isHydrating = false;
10101 hydrationParentFiber = fiber;
10102 return;
10103 }
10104 // We matched the next one, we'll now assume that the first one was
10105 // superfluous and we'll delete it. Since we can't eagerly delete it
10106 // we'll have to schedule a deletion. To do that, this node needs a dummy
10107 // fiber associated with it.
10108 deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance);
10109 }
10110 hydrationParentFiber = fiber;
10111 nextHydratableInstance = getFirstHydratableChild(nextInstance);
10112 }
10113
10114 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
10115 var instance = fiber.stateNode;
10116 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
10117 // TODO: Type this specific to this type of component.
10118 fiber.updateQueue = updatePayload;
10119 // If the update payload indicates that there is a change or if there
10120 // is a new ref we mark this as an update.
10121 if (updatePayload !== null) {
10122 return true;
10123 }
10124 return false;
10125 }
10126
10127 function prepareToHydrateHostTextInstance(fiber) {
10128 var textInstance = fiber.stateNode;
10129 var textContent = fiber.memoizedProps;
10130 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
10131 {
10132 if (shouldUpdate) {
10133 // We assume that prepareToHydrateHostTextInstance is called in a context where the
10134 // hydration parent is the parent host component of this host text.
10135 var returnFiber = hydrationParentFiber;
10136 if (returnFiber !== null) {
10137 switch (returnFiber.tag) {
10138 case HostRoot:
10139 {
10140 var parentContainer = returnFiber.stateNode.containerInfo;
10141 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
10142 break;
10143 }
10144 case HostComponent:
10145 {
10146 var parentType = returnFiber.type;
10147 var parentProps = returnFiber.memoizedProps;
10148 var parentInstance = returnFiber.stateNode;
10149 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
10150 break;
10151 }
10152 }
10153 }
10154 }
10155 }
10156 return shouldUpdate;
10157 }
10158
10159 function popToNextHostParent(fiber) {
10160 var parent = fiber['return'];
10161 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
10162 parent = parent['return'];
10163 }
10164 hydrationParentFiber = parent;
10165 }
10166
10167 function popHydrationState(fiber) {
10168 if (fiber !== hydrationParentFiber) {
10169 // We're deeper than the current hydration context, inside an inserted
10170 // tree.
10171 return false;
10172 }
10173 if (!isHydrating) {
10174 // If we're not currently hydrating but we're in a hydration context, then
10175 // we were an insertion and now need to pop up reenter hydration of our
10176 // siblings.
10177 popToNextHostParent(fiber);
10178 isHydrating = true;
10179 return false;
10180 }
10181
10182 var type = fiber.type;
10183
10184 // If we have any remaining hydratable nodes, we need to delete them now.
10185 // We only do this deeper than head and body since they tend to have random
10186 // other nodes in them. We also ignore components with pure text content in
10187 // side of them.
10188 // TODO: Better heuristic.
10189 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
10190 var nextInstance = nextHydratableInstance;
10191 while (nextInstance) {
10192 deleteHydratableInstance(fiber, nextInstance);
10193 nextInstance = getNextHydratableSibling(nextInstance);
10194 }
10195 }
10196
10197 popToNextHostParent(fiber);
10198 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
10199 return true;
10200 }
10201
10202 function resetHydrationState() {
10203 hydrationParentFiber = null;
10204 nextHydratableInstance = null;
10205 isHydrating = false;
10206 }
10207
10208 return {
10209 enterHydrationState: enterHydrationState,
10210 resetHydrationState: resetHydrationState,
10211 tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance,
10212 prepareToHydrateHostInstance: prepareToHydrateHostInstance,
10213 prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance,
10214 popHydrationState: popHydrationState
10215 };
10216};
10217
10218// This lets us hook into Fiber to debug what it's doing.
10219// See https://github.com/facebook/react/pull/8033.
10220// This is not part of the public API, not even for React DevTools.
10221// You may only inject a debugTool if you work on React Fiber itself.
10222var ReactFiberInstrumentation = {
10223 debugTool: null
10224};
10225
10226var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10227
10228// This module is forked in different environments.
10229// By default, return `true` to log errors to the console.
10230// Forks can return `false` if this isn't desirable.
10231function showErrorDialog(capturedError) {
10232 return true;
10233}
10234
10235function logCapturedError(capturedError) {
10236 var logError = showErrorDialog(capturedError);
10237
10238 // Allow injected showErrorDialog() to prevent default console.error logging.
10239 // This enables renderers like ReactNative to better manage redbox behavior.
10240 if (logError === false) {
10241 return;
10242 }
10243
10244 var error = capturedError.error;
10245 var suppressLogging = error && error.suppressReactErrorLogging;
10246 if (suppressLogging) {
10247 return;
10248 }
10249
10250 {
10251 var componentName = capturedError.componentName,
10252 componentStack = capturedError.componentStack,
10253 errorBoundaryName = capturedError.errorBoundaryName,
10254 errorBoundaryFound = capturedError.errorBoundaryFound,
10255 willRetry = capturedError.willRetry;
10256
10257
10258 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10259
10260 var errorBoundaryMessage = void 0;
10261 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10262 if (errorBoundaryFound && errorBoundaryName) {
10263 if (willRetry) {
10264 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10265 } else {
10266 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10267 }
10268 } else {
10269 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.';
10270 }
10271 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10272
10273 // In development, we provide our own message with just the component stack.
10274 // We don't include the original error message and JS stack because the browser
10275 // has already printed it. Even if the application swallows the error, it is still
10276 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10277 console.error(combinedMessage);
10278 }
10279}
10280
10281var invokeGuardedCallback$2 = ReactErrorUtils.invokeGuardedCallback;
10282var hasCaughtError = ReactErrorUtils.hasCaughtError;
10283var clearCaughtError = ReactErrorUtils.clearCaughtError;
10284
10285
10286var didWarnAboutStateTransition = void 0;
10287var didWarnSetStateChildContext = void 0;
10288var warnAboutUpdateOnUnmounted = void 0;
10289var warnAboutInvalidUpdates = void 0;
10290
10291{
10292 didWarnAboutStateTransition = false;
10293 didWarnSetStateChildContext = false;
10294 var didWarnStateUpdateForUnmountedComponent = {};
10295
10296 warnAboutUpdateOnUnmounted = function (fiber) {
10297 var componentName = getComponentName(fiber) || 'ReactClass';
10298 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10299 return;
10300 }
10301 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);
10302 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10303 };
10304
10305 warnAboutInvalidUpdates = function (instance) {
10306 switch (ReactDebugCurrentFiber.phase) {
10307 case 'getChildContext':
10308 if (didWarnSetStateChildContext) {
10309 return;
10310 }
10311 warning_1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10312 didWarnSetStateChildContext = true;
10313 break;
10314 case 'render':
10315 if (didWarnAboutStateTransition) {
10316 return;
10317 }
10318 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`.');
10319 didWarnAboutStateTransition = true;
10320 break;
10321 }
10322 };
10323}
10324
10325var ReactFiberScheduler = function (config) {
10326 var hostContext = ReactFiberHostContext(config);
10327 var hydrationContext = ReactFiberHydrationContext(config);
10328 var popHostContainer = hostContext.popHostContainer,
10329 popHostContext = hostContext.popHostContext,
10330 resetHostContainer = hostContext.resetHostContainer;
10331
10332 var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleWork, computeExpirationForFiber),
10333 beginWork = _ReactFiberBeginWork.beginWork,
10334 beginFailedWork = _ReactFiberBeginWork.beginFailedWork;
10335
10336 var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext),
10337 completeWork = _ReactFiberCompleteWo.completeWork;
10338
10339 var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError),
10340 commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent,
10341 commitPlacement = _ReactFiberCommitWork.commitPlacement,
10342 commitDeletion = _ReactFiberCommitWork.commitDeletion,
10343 commitWork = _ReactFiberCommitWork.commitWork,
10344 commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles,
10345 commitAttachRef = _ReactFiberCommitWork.commitAttachRef,
10346 commitDetachRef = _ReactFiberCommitWork.commitDetachRef;
10347
10348 var now = config.now,
10349 scheduleDeferredCallback = config.scheduleDeferredCallback,
10350 cancelDeferredCallback = config.cancelDeferredCallback,
10351 prepareForCommit = config.prepareForCommit,
10352 resetAfterCommit = config.resetAfterCommit;
10353
10354 // Represents the current time in ms.
10355
10356 var startTime = now();
10357 var mostRecentCurrentTime = msToExpirationTime(0);
10358
10359 // Used to ensure computeUniqueAsyncExpiration is monotonically increases.
10360 var lastUniqueAsyncExpiration = 0;
10361
10362 // Represents the expiration time that incoming updates should use. (If this
10363 // is NoWork, use the default strategy: async updates in async mode, sync
10364 // updates in sync mode.)
10365 var expirationContext = NoWork;
10366
10367 var isWorking = false;
10368
10369 // The next work in progress fiber that we're currently working on.
10370 var nextUnitOfWork = null;
10371 var nextRoot = null;
10372 // The time at which we're currently rendering work.
10373 var nextRenderExpirationTime = NoWork;
10374
10375 // The next fiber with an effect that we're currently committing.
10376 var nextEffect = null;
10377
10378 // Keep track of which fibers have captured an error that need to be handled.
10379 // Work is removed from this collection after componentDidCatch is called.
10380 var capturedErrors = null;
10381 // Keep track of which fibers have failed during the current batch of work.
10382 // This is a different set than capturedErrors, because it is not reset until
10383 // the end of the batch. This is needed to propagate errors correctly if a
10384 // subtree fails more than once.
10385 var failedBoundaries = null;
10386 // Error boundaries that captured an error during the current commit.
10387 var commitPhaseBoundaries = null;
10388 var firstUncaughtError = null;
10389 var didFatal = false;
10390
10391 var isCommitting = false;
10392 var isUnmounting = false;
10393
10394 // Used for performance tracking.
10395 var interruptedBy = null;
10396
10397 function resetContextStack() {
10398 // Reset the stack
10399 reset$1();
10400 // Reset the cursors
10401 resetContext();
10402 resetHostContainer();
10403 }
10404
10405 function commitAllHostEffects() {
10406 while (nextEffect !== null) {
10407 {
10408 ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
10409 }
10410 recordEffect();
10411
10412 var effectTag = nextEffect.effectTag;
10413 if (effectTag & ContentReset) {
10414 commitResetTextContent(nextEffect);
10415 }
10416
10417 if (effectTag & Ref) {
10418 var current = nextEffect.alternate;
10419 if (current !== null) {
10420 commitDetachRef(current);
10421 }
10422 }
10423
10424 // The following switch statement is only concerned about placement,
10425 // updates, and deletions. To avoid needing to add a case for every
10426 // possible bitmap value, we remove the secondary effects from the
10427 // effect tag and switch on that value.
10428 var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
10429 switch (primaryEffectTag) {
10430 case Placement:
10431 {
10432 commitPlacement(nextEffect);
10433 // Clear the "placement" from effect tag so that we know that this is inserted, before
10434 // any life-cycles like componentDidMount gets called.
10435 // TODO: findDOMNode doesn't rely on this any more but isMounted
10436 // does and isMounted is deprecated anyway so we should be able
10437 // to kill this.
10438 nextEffect.effectTag &= ~Placement;
10439 break;
10440 }
10441 case PlacementAndUpdate:
10442 {
10443 // Placement
10444 commitPlacement(nextEffect);
10445 // Clear the "placement" from effect tag so that we know that this is inserted, before
10446 // any life-cycles like componentDidMount gets called.
10447 nextEffect.effectTag &= ~Placement;
10448
10449 // Update
10450 var _current = nextEffect.alternate;
10451 commitWork(_current, nextEffect);
10452 break;
10453 }
10454 case Update:
10455 {
10456 var _current2 = nextEffect.alternate;
10457 commitWork(_current2, nextEffect);
10458 break;
10459 }
10460 case Deletion:
10461 {
10462 isUnmounting = true;
10463 commitDeletion(nextEffect);
10464 isUnmounting = false;
10465 break;
10466 }
10467 }
10468 nextEffect = nextEffect.nextEffect;
10469 }
10470
10471 {
10472 ReactDebugCurrentFiber.resetCurrentFiber();
10473 }
10474 }
10475
10476 function commitAllLifeCycles() {
10477 while (nextEffect !== null) {
10478 var effectTag = nextEffect.effectTag;
10479
10480 if (effectTag & (Update | Callback)) {
10481 recordEffect();
10482 var current = nextEffect.alternate;
10483 commitLifeCycles(current, nextEffect);
10484 }
10485
10486 if (effectTag & Ref) {
10487 recordEffect();
10488 commitAttachRef(nextEffect);
10489 }
10490
10491 if (effectTag & Err) {
10492 recordEffect();
10493 commitErrorHandling(nextEffect);
10494 }
10495
10496 var next = nextEffect.nextEffect;
10497 // Ensure that we clean these up so that we don't accidentally keep them.
10498 // I'm not actually sure this matters because we can't reset firstEffect
10499 // and lastEffect since they're on every node, not just the effectful
10500 // ones. So we have to clean everything as we reuse nodes anyway.
10501 nextEffect.nextEffect = null;
10502 // Ensure that we reset the effectTag here so that we can rely on effect
10503 // tags to reason about the current life-cycle.
10504 nextEffect = next;
10505 }
10506 }
10507
10508 function commitRoot(finishedWork) {
10509 // We keep track of this so that captureError can collect any boundaries
10510 // that capture an error during the commit phase. The reason these aren't
10511 // local to this function is because errors that occur during cWU are
10512 // captured elsewhere, to prevent the unmount from being interrupted.
10513 isWorking = true;
10514 isCommitting = true;
10515 startCommitTimer();
10516
10517 var root = finishedWork.stateNode;
10518 !(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;
10519 root.isReadyForCommit = false;
10520
10521 // Reset this to null before calling lifecycles
10522 ReactCurrentOwner.current = null;
10523
10524 var firstEffect = void 0;
10525 if (finishedWork.effectTag > PerformedWork) {
10526 // A fiber's effect list consists only of its children, not itself. So if
10527 // the root has an effect, we need to add it to the end of the list. The
10528 // resulting list is the set that would belong to the root's parent, if
10529 // it had one; that is, all the effects in the tree including the root.
10530 if (finishedWork.lastEffect !== null) {
10531 finishedWork.lastEffect.nextEffect = finishedWork;
10532 firstEffect = finishedWork.firstEffect;
10533 } else {
10534 firstEffect = finishedWork;
10535 }
10536 } else {
10537 // There is no effect on the root.
10538 firstEffect = finishedWork.firstEffect;
10539 }
10540
10541 prepareForCommit();
10542
10543 // Commit all the side-effects within a tree. We'll do this in two passes.
10544 // The first pass performs all the host insertions, updates, deletions and
10545 // ref unmounts.
10546 nextEffect = firstEffect;
10547 startCommitHostEffectsTimer();
10548 while (nextEffect !== null) {
10549 var didError = false;
10550 var _error = void 0;
10551 {
10552 invokeGuardedCallback$2(null, commitAllHostEffects, null);
10553 if (hasCaughtError()) {
10554 didError = true;
10555 _error = clearCaughtError();
10556 }
10557 }
10558 if (didError) {
10559 !(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;
10560 captureError(nextEffect, _error);
10561 // Clean-up
10562 if (nextEffect !== null) {
10563 nextEffect = nextEffect.nextEffect;
10564 }
10565 }
10566 }
10567 stopCommitHostEffectsTimer();
10568
10569 resetAfterCommit();
10570
10571 // The work-in-progress tree is now the current tree. This must come after
10572 // the first pass of the commit phase, so that the previous tree is still
10573 // current during componentWillUnmount, but before the second pass, so that
10574 // the finished work is current during componentDidMount/Update.
10575 root.current = finishedWork;
10576
10577 // In the second pass we'll perform all life-cycles and ref callbacks.
10578 // Life-cycles happen as a separate pass so that all placements, updates,
10579 // and deletions in the entire tree have already been invoked.
10580 // This pass also triggers any renderer-specific initial effects.
10581 nextEffect = firstEffect;
10582 startCommitLifeCyclesTimer();
10583 while (nextEffect !== null) {
10584 var _didError = false;
10585 var _error2 = void 0;
10586 {
10587 invokeGuardedCallback$2(null, commitAllLifeCycles, null);
10588 if (hasCaughtError()) {
10589 _didError = true;
10590 _error2 = clearCaughtError();
10591 }
10592 }
10593 if (_didError) {
10594 !(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;
10595 captureError(nextEffect, _error2);
10596 if (nextEffect !== null) {
10597 nextEffect = nextEffect.nextEffect;
10598 }
10599 }
10600 }
10601
10602 isCommitting = false;
10603 isWorking = false;
10604 stopCommitLifeCyclesTimer();
10605 stopCommitTimer();
10606 if (typeof onCommitRoot === 'function') {
10607 onCommitRoot(finishedWork.stateNode);
10608 }
10609 if (true && ReactFiberInstrumentation_1.debugTool) {
10610 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
10611 }
10612
10613 // If we caught any errors during this commit, schedule their boundaries
10614 // to update.
10615 if (commitPhaseBoundaries) {
10616 commitPhaseBoundaries.forEach(scheduleErrorRecovery);
10617 commitPhaseBoundaries = null;
10618 }
10619
10620 if (firstUncaughtError !== null) {
10621 var _error3 = firstUncaughtError;
10622 firstUncaughtError = null;
10623 onUncaughtError(_error3);
10624 }
10625
10626 var remainingTime = root.current.expirationTime;
10627
10628 if (remainingTime === NoWork) {
10629 capturedErrors = null;
10630 failedBoundaries = null;
10631 }
10632
10633 return remainingTime;
10634 }
10635
10636 function resetExpirationTime(workInProgress, renderTime) {
10637 if (renderTime !== Never && workInProgress.expirationTime === Never) {
10638 // The children of this component are hidden. Don't bubble their
10639 // expiration times.
10640 return;
10641 }
10642
10643 // Check for pending updates.
10644 var newExpirationTime = getUpdateExpirationTime(workInProgress);
10645
10646 // TODO: Calls need to visit stateNode
10647
10648 // Bubble up the earliest expiration time.
10649 var child = workInProgress.child;
10650 while (child !== null) {
10651 if (child.expirationTime !== NoWork && (newExpirationTime === NoWork || newExpirationTime > child.expirationTime)) {
10652 newExpirationTime = child.expirationTime;
10653 }
10654 child = child.sibling;
10655 }
10656 workInProgress.expirationTime = newExpirationTime;
10657 }
10658
10659 function completeUnitOfWork(workInProgress) {
10660 while (true) {
10661 // The current, flushed, state of this fiber is the alternate.
10662 // Ideally nothing should rely on this, but relying on it here
10663 // means that we don't need an additional field on the work in
10664 // progress.
10665 var current = workInProgress.alternate;
10666 {
10667 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10668 }
10669 var next = completeWork(current, workInProgress, nextRenderExpirationTime);
10670 {
10671 ReactDebugCurrentFiber.resetCurrentFiber();
10672 }
10673
10674 var returnFiber = workInProgress['return'];
10675 var siblingFiber = workInProgress.sibling;
10676
10677 resetExpirationTime(workInProgress, nextRenderExpirationTime);
10678
10679 if (next !== null) {
10680 stopWorkTimer(workInProgress);
10681 if (true && ReactFiberInstrumentation_1.debugTool) {
10682 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10683 }
10684 // If completing this work spawned new work, do that next. We'll come
10685 // back here again.
10686 return next;
10687 }
10688
10689 if (returnFiber !== null) {
10690 // Append all the effects of the subtree and this fiber onto the effect
10691 // list of the parent. The completion order of the children affects the
10692 // side-effect order.
10693 if (returnFiber.firstEffect === null) {
10694 returnFiber.firstEffect = workInProgress.firstEffect;
10695 }
10696 if (workInProgress.lastEffect !== null) {
10697 if (returnFiber.lastEffect !== null) {
10698 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
10699 }
10700 returnFiber.lastEffect = workInProgress.lastEffect;
10701 }
10702
10703 // If this fiber had side-effects, we append it AFTER the children's
10704 // side-effects. We can perform certain side-effects earlier if
10705 // needed, by doing multiple passes over the effect list. We don't want
10706 // to schedule our own side-effect on our own list because if end up
10707 // reusing children we'll schedule this effect onto itself since we're
10708 // at the end.
10709 var effectTag = workInProgress.effectTag;
10710 // Skip both NoWork and PerformedWork tags when creating the effect list.
10711 // PerformedWork effect is read by React DevTools but shouldn't be committed.
10712 if (effectTag > PerformedWork) {
10713 if (returnFiber.lastEffect !== null) {
10714 returnFiber.lastEffect.nextEffect = workInProgress;
10715 } else {
10716 returnFiber.firstEffect = workInProgress;
10717 }
10718 returnFiber.lastEffect = workInProgress;
10719 }
10720 }
10721
10722 stopWorkTimer(workInProgress);
10723 if (true && ReactFiberInstrumentation_1.debugTool) {
10724 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
10725 }
10726
10727 if (siblingFiber !== null) {
10728 // If there is more work to do in this returnFiber, do that next.
10729 return siblingFiber;
10730 } else if (returnFiber !== null) {
10731 // If there's no more work in this returnFiber. Complete the returnFiber.
10732 workInProgress = returnFiber;
10733 continue;
10734 } else {
10735 // We've reached the root.
10736 var root = workInProgress.stateNode;
10737 root.isReadyForCommit = true;
10738 return null;
10739 }
10740 }
10741
10742 // Without this explicit null return Flow complains of invalid return type
10743 // TODO Remove the above while(true) loop
10744 // eslint-disable-next-line no-unreachable
10745 return null;
10746 }
10747
10748 function performUnitOfWork(workInProgress) {
10749 // The current, flushed, state of this fiber is the alternate.
10750 // Ideally nothing should rely on this, but relying on it here
10751 // means that we don't need an additional field on the work in
10752 // progress.
10753 var current = workInProgress.alternate;
10754
10755 // See if beginning this work spawns more work.
10756 startWorkTimer(workInProgress);
10757 {
10758 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10759 }
10760
10761 var next = beginWork(current, workInProgress, nextRenderExpirationTime);
10762 {
10763 ReactDebugCurrentFiber.resetCurrentFiber();
10764 }
10765 if (true && ReactFiberInstrumentation_1.debugTool) {
10766 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10767 }
10768
10769 if (next === null) {
10770 // If this doesn't spawn new work, complete the current work.
10771 next = completeUnitOfWork(workInProgress);
10772 }
10773
10774 ReactCurrentOwner.current = null;
10775
10776 return next;
10777 }
10778
10779 function performFailedUnitOfWork(workInProgress) {
10780 // The current, flushed, state of this fiber is the alternate.
10781 // Ideally nothing should rely on this, but relying on it here
10782 // means that we don't need an additional field on the work in
10783 // progress.
10784 var current = workInProgress.alternate;
10785
10786 // See if beginning this work spawns more work.
10787 startWorkTimer(workInProgress);
10788 {
10789 ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
10790 }
10791 var next = beginFailedWork(current, workInProgress, nextRenderExpirationTime);
10792 {
10793 ReactDebugCurrentFiber.resetCurrentFiber();
10794 }
10795 if (true && ReactFiberInstrumentation_1.debugTool) {
10796 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
10797 }
10798
10799 if (next === null) {
10800 // If this doesn't spawn new work, complete the current work.
10801 next = completeUnitOfWork(workInProgress);
10802 }
10803
10804 ReactCurrentOwner.current = null;
10805
10806 return next;
10807 }
10808
10809 function workLoop(expirationTime) {
10810 if (capturedErrors !== null) {
10811 // If there are unhandled errors, switch to the slow work loop.
10812 // TODO: How to avoid this check in the fast path? Maybe the renderer
10813 // could keep track of which roots have unhandled errors and call a
10814 // forked version of renderRoot.
10815 slowWorkLoopThatChecksForFailedWork(expirationTime);
10816 return;
10817 }
10818 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10819 return;
10820 }
10821
10822 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10823 // Flush all expired work.
10824 while (nextUnitOfWork !== null) {
10825 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10826 }
10827 } else {
10828 // Flush asynchronous work until the deadline runs out of time.
10829 while (nextUnitOfWork !== null && !shouldYield()) {
10830 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10831 }
10832 }
10833 }
10834
10835 function slowWorkLoopThatChecksForFailedWork(expirationTime) {
10836 if (nextRenderExpirationTime === NoWork || nextRenderExpirationTime > expirationTime) {
10837 return;
10838 }
10839
10840 if (nextRenderExpirationTime <= mostRecentCurrentTime) {
10841 // Flush all expired work.
10842 while (nextUnitOfWork !== null) {
10843 if (hasCapturedError(nextUnitOfWork)) {
10844 // Use a forked version of performUnitOfWork
10845 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
10846 } else {
10847 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10848 }
10849 }
10850 } else {
10851 // Flush asynchronous work until the deadline runs out of time.
10852 while (nextUnitOfWork !== null && !shouldYield()) {
10853 if (hasCapturedError(nextUnitOfWork)) {
10854 // Use a forked version of performUnitOfWork
10855 nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork);
10856 } else {
10857 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
10858 }
10859 }
10860 }
10861 }
10862
10863 function renderRootCatchBlock(root, failedWork, boundary, expirationTime) {
10864 // We're going to restart the error boundary that captured the error.
10865 // Conceptually, we're unwinding the stack. We need to unwind the
10866 // context stack, too.
10867 unwindContexts(failedWork, boundary);
10868
10869 // Restart the error boundary using a forked version of
10870 // performUnitOfWork that deletes the boundary's children. The entire
10871 // failed subree will be unmounted. During the commit phase, a special
10872 // lifecycle method is called on the error boundary, which triggers
10873 // a re-render.
10874 nextUnitOfWork = performFailedUnitOfWork(boundary);
10875
10876 // Continue working.
10877 workLoop(expirationTime);
10878 }
10879
10880 function renderRoot(root, expirationTime) {
10881 !!isWorking ? invariant_1(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10882 isWorking = true;
10883
10884 // We're about to mutate the work-in-progress tree. If the root was pending
10885 // commit, it no longer is: we'll need to complete it again.
10886 root.isReadyForCommit = false;
10887
10888 // Check if we're starting from a fresh stack, or if we're resuming from
10889 // previously yielded work.
10890 if (root !== nextRoot || expirationTime !== nextRenderExpirationTime || nextUnitOfWork === null) {
10891 // Reset the stack and start working from the root.
10892 resetContextStack();
10893 nextRoot = root;
10894 nextRenderExpirationTime = expirationTime;
10895 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, expirationTime);
10896 }
10897
10898 startWorkLoopTimer(nextUnitOfWork);
10899
10900 var didError = false;
10901 var error = null;
10902 {
10903 invokeGuardedCallback$2(null, workLoop, null, expirationTime);
10904 if (hasCaughtError()) {
10905 didError = true;
10906 error = clearCaughtError();
10907 }
10908 }
10909
10910 // An error was thrown during the render phase.
10911 while (didError) {
10912 if (didFatal) {
10913 // This was a fatal error. Don't attempt to recover from it.
10914 firstUncaughtError = error;
10915 break;
10916 }
10917
10918 var failedWork = nextUnitOfWork;
10919 if (failedWork === null) {
10920 // An error was thrown but there's no current unit of work. This can
10921 // happen during the commit phase if there's a bug in the renderer.
10922 didFatal = true;
10923 continue;
10924 }
10925
10926 // "Capture" the error by finding the nearest boundary. If there is no
10927 // error boundary, we use the root.
10928 var boundary = captureError(failedWork, error);
10929 !(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;
10930
10931 if (didFatal) {
10932 // The error we just captured was a fatal error. This happens
10933 // when the error propagates to the root more than once.
10934 continue;
10935 }
10936
10937 didError = false;
10938 error = null;
10939 {
10940 invokeGuardedCallback$2(null, renderRootCatchBlock, null, root, failedWork, boundary, expirationTime);
10941 if (hasCaughtError()) {
10942 didError = true;
10943 error = clearCaughtError();
10944 continue;
10945 }
10946 }
10947 // We're finished working. Exit the error loop.
10948 break;
10949 }
10950
10951 var uncaughtError = firstUncaughtError;
10952
10953 // We're done performing work. Time to clean up.
10954 stopWorkLoopTimer(interruptedBy);
10955 interruptedBy = null;
10956 isWorking = false;
10957 didFatal = false;
10958 firstUncaughtError = null;
10959
10960 if (uncaughtError !== null) {
10961 onUncaughtError(uncaughtError);
10962 }
10963
10964 return root.isReadyForCommit ? root.current.alternate : null;
10965 }
10966
10967 // Returns the boundary that captured the error, or null if the error is ignored
10968 function captureError(failedWork, error) {
10969 // It is no longer valid because we exited the user code.
10970 ReactCurrentOwner.current = null;
10971 {
10972 ReactDebugCurrentFiber.resetCurrentFiber();
10973 }
10974
10975 // Search for the nearest error boundary.
10976 var boundary = null;
10977
10978 // Passed to logCapturedError()
10979 var errorBoundaryFound = false;
10980 var willRetry = false;
10981 var errorBoundaryName = null;
10982
10983 // Host containers are a special case. If the failed work itself is a host
10984 // container, then it acts as its own boundary. In all other cases, we
10985 // ignore the work itself and only search through the parents.
10986 if (failedWork.tag === HostRoot) {
10987 boundary = failedWork;
10988
10989 if (isFailedBoundary(failedWork)) {
10990 // If this root already failed, there must have been an error when
10991 // attempting to unmount it. This is a worst-case scenario and
10992 // should only be possible if there's a bug in the renderer.
10993 didFatal = true;
10994 }
10995 } else {
10996 var node = failedWork['return'];
10997 while (node !== null && boundary === null) {
10998 if (node.tag === ClassComponent) {
10999 var instance = node.stateNode;
11000 if (typeof instance.componentDidCatch === 'function') {
11001 errorBoundaryFound = true;
11002 errorBoundaryName = getComponentName(node);
11003
11004 // Found an error boundary!
11005 boundary = node;
11006 willRetry = true;
11007 }
11008 } else if (node.tag === HostRoot) {
11009 // Treat the root like a no-op error boundary
11010 boundary = node;
11011 }
11012
11013 if (isFailedBoundary(node)) {
11014 // This boundary is already in a failed state.
11015
11016 // If we're currently unmounting, that means this error was
11017 // thrown while unmounting a failed subtree. We should ignore
11018 // the error.
11019 if (isUnmounting) {
11020 return null;
11021 }
11022
11023 // If we're in the commit phase, we should check to see if
11024 // this boundary already captured an error during this commit.
11025 // This case exists because multiple errors can be thrown during
11026 // a single commit without interruption.
11027 if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) {
11028 // If so, we should ignore this error.
11029 return null;
11030 }
11031
11032 // The error should propagate to the next boundary -? we keep looking.
11033 boundary = null;
11034 willRetry = false;
11035 }
11036
11037 node = node['return'];
11038 }
11039 }
11040
11041 if (boundary !== null) {
11042 // Add to the collection of failed boundaries. This lets us know that
11043 // subsequent errors in this subtree should propagate to the next boundary.
11044 if (failedBoundaries === null) {
11045 failedBoundaries = new Set();
11046 }
11047 failedBoundaries.add(boundary);
11048
11049 // This method is unsafe outside of the begin and complete phases.
11050 // We might be in the commit phase when an error is captured.
11051 // The risk is that the return path from this Fiber may not be accurate.
11052 // That risk is acceptable given the benefit of providing users more context.
11053 var _componentStack = getStackAddendumByWorkInProgressFiber(failedWork);
11054 var _componentName = getComponentName(failedWork);
11055
11056 // Add to the collection of captured errors. This is stored as a global
11057 // map of errors and their component stack location keyed by the boundaries
11058 // that capture them. We mostly use this Map as a Set; it's a Map only to
11059 // avoid adding a field to Fiber to store the error.
11060 if (capturedErrors === null) {
11061 capturedErrors = new Map();
11062 }
11063
11064 var capturedError = {
11065 componentName: _componentName,
11066 componentStack: _componentStack,
11067 error: error,
11068 errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
11069 errorBoundaryFound: errorBoundaryFound,
11070 errorBoundaryName: errorBoundaryName,
11071 willRetry: willRetry
11072 };
11073
11074 capturedErrors.set(boundary, capturedError);
11075
11076 try {
11077 logCapturedError(capturedError);
11078 } catch (e) {
11079 // Prevent cycle if logCapturedError() throws.
11080 // A cycle may still occur if logCapturedError renders a component that throws.
11081 var suppressLogging = e && e.suppressReactErrorLogging;
11082 if (!suppressLogging) {
11083 console.error(e);
11084 }
11085 }
11086
11087 // If we're in the commit phase, defer scheduling an update on the
11088 // boundary until after the commit is complete
11089 if (isCommitting) {
11090 if (commitPhaseBoundaries === null) {
11091 commitPhaseBoundaries = new Set();
11092 }
11093 commitPhaseBoundaries.add(boundary);
11094 } else {
11095 // Otherwise, schedule an update now.
11096 // TODO: Is this actually necessary during the render phase? Is it
11097 // possible to unwind and continue rendering at the same priority,
11098 // without corrupting internal state?
11099 scheduleErrorRecovery(boundary);
11100 }
11101 return boundary;
11102 } else if (firstUncaughtError === null) {
11103 // If no boundary is found, we'll need to throw the error
11104 firstUncaughtError = error;
11105 }
11106 return null;
11107 }
11108
11109 function hasCapturedError(fiber) {
11110 // TODO: capturedErrors should store the boundary instance, to avoid needing
11111 // to check the alternate.
11112 return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate));
11113 }
11114
11115 function isFailedBoundary(fiber) {
11116 // TODO: failedBoundaries should store the boundary instance, to avoid
11117 // needing to check the alternate.
11118 return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate));
11119 }
11120
11121 function commitErrorHandling(effectfulFiber) {
11122 var capturedError = void 0;
11123 if (capturedErrors !== null) {
11124 capturedError = capturedErrors.get(effectfulFiber);
11125 capturedErrors['delete'](effectfulFiber);
11126 if (capturedError == null) {
11127 if (effectfulFiber.alternate !== null) {
11128 effectfulFiber = effectfulFiber.alternate;
11129 capturedError = capturedErrors.get(effectfulFiber);
11130 capturedErrors['delete'](effectfulFiber);
11131 }
11132 }
11133 }
11134
11135 !(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;
11136
11137 switch (effectfulFiber.tag) {
11138 case ClassComponent:
11139 var instance = effectfulFiber.stateNode;
11140
11141 var info = {
11142 componentStack: capturedError.componentStack
11143 };
11144
11145 // Allow the boundary to handle the error, usually by scheduling
11146 // an update to itself
11147 instance.componentDidCatch(capturedError.error, info);
11148 return;
11149 case HostRoot:
11150 if (firstUncaughtError === null) {
11151 firstUncaughtError = capturedError.error;
11152 }
11153 return;
11154 default:
11155 invariant_1(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.');
11156 }
11157 }
11158
11159 function unwindContexts(from, to) {
11160 var node = from;
11161 while (node !== null) {
11162 switch (node.tag) {
11163 case ClassComponent:
11164 popContextProvider(node);
11165 break;
11166 case HostComponent:
11167 popHostContext(node);
11168 break;
11169 case HostRoot:
11170 popHostContainer(node);
11171 break;
11172 case HostPortal:
11173 popHostContainer(node);
11174 break;
11175 }
11176 if (node === to || node.alternate === to) {
11177 stopFailedWorkTimer(node);
11178 break;
11179 } else {
11180 stopWorkTimer(node);
11181 }
11182 node = node['return'];
11183 }
11184 }
11185
11186 function computeAsyncExpiration() {
11187 // Given the current clock time, returns an expiration time. We use rounding
11188 // to batch like updates together.
11189 // Should complete within ~1000ms. 1200ms max.
11190 var currentTime = recalculateCurrentTime();
11191 var expirationMs = 1000;
11192 var bucketSizeMs = 200;
11193 return computeExpirationBucket(currentTime, expirationMs, bucketSizeMs);
11194 }
11195
11196 // Creates a unique async expiration time.
11197 function computeUniqueAsyncExpiration() {
11198 var result = computeAsyncExpiration();
11199 if (result <= lastUniqueAsyncExpiration) {
11200 // Since we assume the current time monotonically increases, we only hit
11201 // this branch when computeUniqueAsyncExpiration is fired multiple times
11202 // within a 200ms window (or whatever the async bucket size is).
11203 result = lastUniqueAsyncExpiration + 1;
11204 }
11205 lastUniqueAsyncExpiration = result;
11206 return lastUniqueAsyncExpiration;
11207 }
11208
11209 function computeExpirationForFiber(fiber) {
11210 var expirationTime = void 0;
11211 if (expirationContext !== NoWork) {
11212 // An explicit expiration context was set;
11213 expirationTime = expirationContext;
11214 } else if (isWorking) {
11215 if (isCommitting) {
11216 // Updates that occur during the commit phase should have sync priority
11217 // by default.
11218 expirationTime = Sync;
11219 } else {
11220 // Updates during the render phase should expire at the same time as
11221 // the work that is being rendered.
11222 expirationTime = nextRenderExpirationTime;
11223 }
11224 } else {
11225 // No explicit expiration context was set, and we're not currently
11226 // performing work. Calculate a new expiration time.
11227 if (fiber.internalContextTag & AsyncUpdates) {
11228 // This is an async update
11229 expirationTime = computeAsyncExpiration();
11230 } else {
11231 // This is a sync update
11232 expirationTime = Sync;
11233 }
11234 }
11235 return expirationTime;
11236 }
11237
11238 function scheduleWork(fiber, expirationTime) {
11239 return scheduleWorkImpl(fiber, expirationTime, false);
11240 }
11241
11242 function checkRootNeedsClearing(root, fiber, expirationTime) {
11243 if (!isWorking && root === nextRoot && expirationTime < nextRenderExpirationTime) {
11244 // Restart the root from the top.
11245 if (nextUnitOfWork !== null) {
11246 // This is an interruption. (Used for performance tracking.)
11247 interruptedBy = fiber;
11248 }
11249 nextRoot = null;
11250 nextUnitOfWork = null;
11251 nextRenderExpirationTime = NoWork;
11252 }
11253 }
11254
11255 function scheduleWorkImpl(fiber, expirationTime, isErrorRecovery) {
11256 recordScheduleUpdate();
11257
11258 {
11259 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11260 var instance = fiber.stateNode;
11261 warnAboutInvalidUpdates(instance);
11262 }
11263 }
11264
11265 var node = fiber;
11266 while (node !== null) {
11267 // Walk the parent path to the root and update each node's
11268 // expiration time.
11269 if (node.expirationTime === NoWork || node.expirationTime > expirationTime) {
11270 node.expirationTime = expirationTime;
11271 }
11272 if (node.alternate !== null) {
11273 if (node.alternate.expirationTime === NoWork || node.alternate.expirationTime > expirationTime) {
11274 node.alternate.expirationTime = expirationTime;
11275 }
11276 }
11277 if (node['return'] === null) {
11278 if (node.tag === HostRoot) {
11279 var root = node.stateNode;
11280
11281 checkRootNeedsClearing(root, fiber, expirationTime);
11282 requestWork(root, expirationTime);
11283 checkRootNeedsClearing(root, fiber, expirationTime);
11284 } else {
11285 {
11286 if (!isErrorRecovery && fiber.tag === ClassComponent) {
11287 warnAboutUpdateOnUnmounted(fiber);
11288 }
11289 }
11290 return;
11291 }
11292 }
11293 node = node['return'];
11294 }
11295 }
11296
11297 function scheduleErrorRecovery(fiber) {
11298 scheduleWorkImpl(fiber, Sync, true);
11299 }
11300
11301 function recalculateCurrentTime() {
11302 // Subtract initial time so it fits inside 32bits
11303 var ms = now() - startTime;
11304 mostRecentCurrentTime = msToExpirationTime(ms);
11305 return mostRecentCurrentTime;
11306 }
11307
11308 function deferredUpdates(fn) {
11309 var previousExpirationContext = expirationContext;
11310 expirationContext = computeAsyncExpiration();
11311 try {
11312 return fn();
11313 } finally {
11314 expirationContext = previousExpirationContext;
11315 }
11316 }
11317
11318 function syncUpdates(fn) {
11319 var previousExpirationContext = expirationContext;
11320 expirationContext = Sync;
11321 try {
11322 return fn();
11323 } finally {
11324 expirationContext = previousExpirationContext;
11325 }
11326 }
11327
11328 // TODO: Everything below this is written as if it has been lifted to the
11329 // renderers. I'll do this in a follow-up.
11330
11331 // Linked-list of roots
11332 var firstScheduledRoot = null;
11333 var lastScheduledRoot = null;
11334
11335 var callbackExpirationTime = NoWork;
11336 var callbackID = -1;
11337 var isRendering = false;
11338 var nextFlushedRoot = null;
11339 var nextFlushedExpirationTime = NoWork;
11340 var deadlineDidExpire = false;
11341 var hasUnhandledError = false;
11342 var unhandledError = null;
11343 var deadline = null;
11344
11345 var isBatchingUpdates = false;
11346 var isUnbatchingUpdates = false;
11347
11348 var completedBatches = null;
11349
11350 // Use these to prevent an infinite loop of nested updates
11351 var NESTED_UPDATE_LIMIT = 1000;
11352 var nestedUpdateCount = 0;
11353
11354 var timeHeuristicForUnitOfWork = 1;
11355
11356 function scheduleCallbackWithExpiration(expirationTime) {
11357 if (callbackExpirationTime !== NoWork) {
11358 // A callback is already scheduled. Check its expiration time (timeout).
11359 if (expirationTime > callbackExpirationTime) {
11360 // Existing callback has sufficient timeout. Exit.
11361 return;
11362 } else {
11363 // Existing callback has insufficient timeout. Cancel and schedule a
11364 // new one.
11365 cancelDeferredCallback(callbackID);
11366 }
11367 // The request callback timer is already running. Don't start a new one.
11368 } else {
11369 startRequestCallbackTimer();
11370 }
11371
11372 // Compute a timeout for the given expiration time.
11373 var currentMs = now() - startTime;
11374 var expirationMs = expirationTimeToMs(expirationTime);
11375 var timeout = expirationMs - currentMs;
11376
11377 callbackExpirationTime = expirationTime;
11378 callbackID = scheduleDeferredCallback(performAsyncWork, { timeout: timeout });
11379 }
11380
11381 // requestWork is called by the scheduler whenever a root receives an update.
11382 // It's up to the renderer to call renderRoot at some point in the future.
11383 function requestWork(root, expirationTime) {
11384 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
11385 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.');
11386 }
11387
11388 // Add the root to the schedule.
11389 // Check if this root is already part of the schedule.
11390 if (root.nextScheduledRoot === null) {
11391 // This root is not already scheduled. Add it.
11392 root.remainingExpirationTime = expirationTime;
11393 if (lastScheduledRoot === null) {
11394 firstScheduledRoot = lastScheduledRoot = root;
11395 root.nextScheduledRoot = root;
11396 } else {
11397 lastScheduledRoot.nextScheduledRoot = root;
11398 lastScheduledRoot = root;
11399 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11400 }
11401 } else {
11402 // This root is already scheduled, but its priority may have increased.
11403 var remainingExpirationTime = root.remainingExpirationTime;
11404 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) {
11405 // Update the priority.
11406 root.remainingExpirationTime = expirationTime;
11407 }
11408 }
11409
11410 if (isRendering) {
11411 // Prevent reentrancy. Remaining work will be scheduled at the end of
11412 // the currently rendering batch.
11413 return;
11414 }
11415
11416 if (isBatchingUpdates) {
11417 // Flush work at the end of the batch.
11418 if (isUnbatchingUpdates) {
11419 // ...unless we're inside unbatchedUpdates, in which case we should
11420 // flush it now.
11421 nextFlushedRoot = root;
11422 nextFlushedExpirationTime = Sync;
11423 performWorkOnRoot(root, Sync, recalculateCurrentTime());
11424 }
11425 return;
11426 }
11427
11428 // TODO: Get rid of Sync and use current time?
11429 if (expirationTime === Sync) {
11430 performWork(Sync, null);
11431 } else {
11432 scheduleCallbackWithExpiration(expirationTime);
11433 }
11434 }
11435
11436 function findHighestPriorityRoot() {
11437 var highestPriorityWork = NoWork;
11438 var highestPriorityRoot = null;
11439
11440 if (lastScheduledRoot !== null) {
11441 var previousScheduledRoot = lastScheduledRoot;
11442 var root = firstScheduledRoot;
11443 while (root !== null) {
11444 var remainingExpirationTime = root.remainingExpirationTime;
11445 if (remainingExpirationTime === NoWork) {
11446 // This root no longer has work. Remove it from the scheduler.
11447
11448 // TODO: This check is redudant, but Flow is confused by the branch
11449 // below where we set lastScheduledRoot to null, even though we break
11450 // from the loop right after.
11451 !(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;
11452 if (root === root.nextScheduledRoot) {
11453 // This is the only root in the list.
11454 root.nextScheduledRoot = null;
11455 firstScheduledRoot = lastScheduledRoot = null;
11456 break;
11457 } else if (root === firstScheduledRoot) {
11458 // This is the first root in the list.
11459 var next = root.nextScheduledRoot;
11460 firstScheduledRoot = next;
11461 lastScheduledRoot.nextScheduledRoot = next;
11462 root.nextScheduledRoot = null;
11463 } else if (root === lastScheduledRoot) {
11464 // This is the last root in the list.
11465 lastScheduledRoot = previousScheduledRoot;
11466 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
11467 root.nextScheduledRoot = null;
11468 break;
11469 } else {
11470 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
11471 root.nextScheduledRoot = null;
11472 }
11473 root = previousScheduledRoot.nextScheduledRoot;
11474 } else {
11475 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) {
11476 // Update the priority, if it's higher
11477 highestPriorityWork = remainingExpirationTime;
11478 highestPriorityRoot = root;
11479 }
11480 if (root === lastScheduledRoot) {
11481 break;
11482 }
11483 previousScheduledRoot = root;
11484 root = root.nextScheduledRoot;
11485 }
11486 }
11487 }
11488
11489 // If the next root is the same as the previous root, this is a nested
11490 // update. To prevent an infinite loop, increment the nested update count.
11491 var previousFlushedRoot = nextFlushedRoot;
11492 if (previousFlushedRoot !== null && previousFlushedRoot === highestPriorityRoot) {
11493 nestedUpdateCount++;
11494 } else {
11495 // Reset whenever we switch roots.
11496 nestedUpdateCount = 0;
11497 }
11498 nextFlushedRoot = highestPriorityRoot;
11499 nextFlushedExpirationTime = highestPriorityWork;
11500 }
11501
11502 function performAsyncWork(dl) {
11503 performWork(NoWork, dl);
11504 }
11505
11506 function performWork(minExpirationTime, dl) {
11507 deadline = dl;
11508
11509 // Keep working on roots until there's no more work, or until the we reach
11510 // the deadline.
11511 findHighestPriorityRoot();
11512
11513 if (enableUserTimingAPI && deadline !== null) {
11514 var didExpire = nextFlushedExpirationTime < recalculateCurrentTime();
11515 stopRequestCallbackTimer(didExpire);
11516 }
11517
11518 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || nextFlushedExpirationTime <= minExpirationTime) && !deadlineDidExpire) {
11519 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, recalculateCurrentTime());
11520 // Find the next highest priority work.
11521 findHighestPriorityRoot();
11522 }
11523
11524 // We're done flushing work. Either we ran out of time in this callback,
11525 // or there's no more work left with sufficient priority.
11526
11527 // If we're inside a callback, set this to false since we just completed it.
11528 if (deadline !== null) {
11529 callbackExpirationTime = NoWork;
11530 callbackID = -1;
11531 }
11532 // If there's work left over, schedule a new callback.
11533 if (nextFlushedExpirationTime !== NoWork) {
11534 scheduleCallbackWithExpiration(nextFlushedExpirationTime);
11535 }
11536
11537 // Clean-up.
11538 deadline = null;
11539 deadlineDidExpire = false;
11540 nestedUpdateCount = 0;
11541
11542 finishRendering();
11543 }
11544
11545 function flushRoot(root, expirationTime) {
11546 !!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;
11547 // Perform work on root as if the given expiration time is the current time.
11548 // This has the effect of synchronously flushing all work up to and
11549 // including the given time.
11550 performWorkOnRoot(root, expirationTime, expirationTime);
11551 finishRendering();
11552 }
11553
11554 function finishRendering() {
11555 if (completedBatches !== null) {
11556 var batches = completedBatches;
11557 completedBatches = null;
11558 for (var i = 0; i < batches.length; i++) {
11559 var batch = batches[i];
11560 try {
11561 batch._onComplete();
11562 } catch (error) {
11563 if (!hasUnhandledError) {
11564 hasUnhandledError = true;
11565 unhandledError = error;
11566 }
11567 }
11568 }
11569 }
11570
11571 if (hasUnhandledError) {
11572 var _error4 = unhandledError;
11573 unhandledError = null;
11574 hasUnhandledError = false;
11575 throw _error4;
11576 }
11577 }
11578
11579 function performWorkOnRoot(root, expirationTime, currentTime) {
11580 !!isRendering ? invariant_1(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11581
11582 isRendering = true;
11583
11584 // Check if this is async work or sync/expired work.
11585 if (expirationTime <= currentTime) {
11586 // Flush sync work.
11587 var finishedWork = root.finishedWork;
11588 if (finishedWork !== null) {
11589 // This root is already complete. We can commit it.
11590 completeRoot(root, finishedWork, expirationTime);
11591 } else {
11592 root.finishedWork = null;
11593 finishedWork = renderRoot(root, expirationTime);
11594 if (finishedWork !== null) {
11595 // We've completed the root. Commit it.
11596 completeRoot(root, finishedWork, expirationTime);
11597 }
11598 }
11599 } else {
11600 // Flush async work.
11601 var _finishedWork = root.finishedWork;
11602 if (_finishedWork !== null) {
11603 // This root is already complete. We can commit it.
11604 completeRoot(root, _finishedWork, expirationTime);
11605 } else {
11606 root.finishedWork = null;
11607 _finishedWork = renderRoot(root, expirationTime);
11608 if (_finishedWork !== null) {
11609 // We've completed the root. Check the deadline one more time
11610 // before committing.
11611 if (!shouldYield()) {
11612 // Still time left. Commit the root.
11613 completeRoot(root, _finishedWork, expirationTime);
11614 } else {
11615 // There's no time left. Mark this root as complete. We'll come
11616 // back and commit it later.
11617 root.finishedWork = _finishedWork;
11618 }
11619 }
11620 }
11621 }
11622
11623 isRendering = false;
11624 }
11625
11626 function completeRoot(root, finishedWork, expirationTime) {
11627 // Check if there's a batch that matches this expiration time.
11628 var firstBatch = root.firstBatch;
11629 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) {
11630 if (completedBatches === null) {
11631 completedBatches = [firstBatch];
11632 } else {
11633 completedBatches.push(firstBatch);
11634 }
11635 if (firstBatch._defer) {
11636 // This root is blocked from committing by a batch. Unschedule it until
11637 // we receive another update.
11638 root.finishedWork = finishedWork;
11639 root.remainingExpirationTime = NoWork;
11640 return;
11641 }
11642 }
11643
11644 // Commit the root.
11645 root.finishedWork = null;
11646 root.remainingExpirationTime = commitRoot(finishedWork);
11647 }
11648
11649 // When working on async work, the reconciler asks the renderer if it should
11650 // yield execution. For DOM, we implement this with requestIdleCallback.
11651 function shouldYield() {
11652 if (deadline === null) {
11653 return false;
11654 }
11655 if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
11656 // Disregard deadline.didTimeout. Only expired work should be flushed
11657 // during a timeout. This path is only hit for non-expired work.
11658 return false;
11659 }
11660 deadlineDidExpire = true;
11661 return true;
11662 }
11663
11664 // TODO: Not happy about this hook. Conceptually, renderRoot should return a
11665 // tuple of (isReadyForCommit, didError, error)
11666 function onUncaughtError(error) {
11667 !(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;
11668 // Unschedule this root so we don't work on it again until there's
11669 // another update.
11670 nextFlushedRoot.remainingExpirationTime = NoWork;
11671 if (!hasUnhandledError) {
11672 hasUnhandledError = true;
11673 unhandledError = error;
11674 }
11675 }
11676
11677 // TODO: Batching should be implemented at the renderer level, not inside
11678 // the reconciler.
11679 function batchedUpdates(fn, a) {
11680 var previousIsBatchingUpdates = isBatchingUpdates;
11681 isBatchingUpdates = true;
11682 try {
11683 return fn(a);
11684 } finally {
11685 isBatchingUpdates = previousIsBatchingUpdates;
11686 if (!isBatchingUpdates && !isRendering) {
11687 performWork(Sync, null);
11688 }
11689 }
11690 }
11691
11692 // TODO: Batching should be implemented at the renderer level, not inside
11693 // the reconciler.
11694 function unbatchedUpdates(fn) {
11695 if (isBatchingUpdates && !isUnbatchingUpdates) {
11696 isUnbatchingUpdates = true;
11697 try {
11698 return fn();
11699 } finally {
11700 isUnbatchingUpdates = false;
11701 }
11702 }
11703 return fn();
11704 }
11705
11706 // TODO: Batching should be implemented at the renderer level, not within
11707 // the reconciler.
11708 function flushSync(fn) {
11709 var previousIsBatchingUpdates = isBatchingUpdates;
11710 isBatchingUpdates = true;
11711 try {
11712 return syncUpdates(fn);
11713 } finally {
11714 isBatchingUpdates = previousIsBatchingUpdates;
11715 !!isRendering ? invariant_1(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
11716 performWork(Sync, null);
11717 }
11718 }
11719
11720 return {
11721 computeExpirationForFiber: computeExpirationForFiber,
11722 scheduleWork: scheduleWork,
11723 requestWork: requestWork,
11724 flushRoot: flushRoot,
11725 batchedUpdates: batchedUpdates,
11726 unbatchedUpdates: unbatchedUpdates,
11727 flushSync: flushSync,
11728 deferredUpdates: deferredUpdates,
11729 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration
11730 };
11731};
11732
11733var didWarnAboutNestedUpdates = void 0;
11734
11735{
11736 didWarnAboutNestedUpdates = false;
11737}
11738
11739// 0 is PROD, 1 is DEV.
11740// Might add PROFILE later.
11741
11742
11743function getContextForSubtree(parentComponent) {
11744 if (!parentComponent) {
11745 return emptyObject_1;
11746 }
11747
11748 var fiber = get(parentComponent);
11749 var parentContext = findCurrentUnmaskedContext(fiber);
11750 return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext;
11751}
11752
11753var ReactFiberReconciler$1 = function (config) {
11754 var getPublicInstance = config.getPublicInstance;
11755
11756 var _ReactFiberScheduler = ReactFiberScheduler(config),
11757 computeUniqueAsyncExpiration = _ReactFiberScheduler.computeUniqueAsyncExpiration,
11758 computeExpirationForFiber = _ReactFiberScheduler.computeExpirationForFiber,
11759 scheduleWork = _ReactFiberScheduler.scheduleWork,
11760 requestWork = _ReactFiberScheduler.requestWork,
11761 flushRoot = _ReactFiberScheduler.flushRoot,
11762 batchedUpdates = _ReactFiberScheduler.batchedUpdates,
11763 unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates,
11764 flushSync = _ReactFiberScheduler.flushSync,
11765 deferredUpdates = _ReactFiberScheduler.deferredUpdates;
11766
11767 function scheduleRootUpdate(current, element, expirationTime, callback) {
11768 {
11769 if (ReactDebugCurrentFiber.phase === 'render' && ReactDebugCurrentFiber.current !== null && !didWarnAboutNestedUpdates) {
11770 didWarnAboutNestedUpdates = true;
11771 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');
11772 }
11773 }
11774
11775 callback = callback === undefined ? null : callback;
11776 {
11777 warning_1(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
11778 }
11779
11780 var update = {
11781 expirationTime: expirationTime,
11782 partialState: { element: element },
11783 callback: callback,
11784 isReplace: false,
11785 isForced: false,
11786 next: null
11787 };
11788 insertUpdateIntoFiber(current, update);
11789 scheduleWork(current, expirationTime);
11790
11791 return expirationTime;
11792 }
11793
11794 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
11795 // TODO: If this is a nested container, this won't be the root.
11796 var current = container.current;
11797
11798 {
11799 if (ReactFiberInstrumentation_1.debugTool) {
11800 if (current.alternate === null) {
11801 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
11802 } else if (element === null) {
11803 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
11804 } else {
11805 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
11806 }
11807 }
11808 }
11809
11810 var context = getContextForSubtree(parentComponent);
11811 if (container.context === null) {
11812 container.context = context;
11813 } else {
11814 container.pendingContext = context;
11815 }
11816
11817 return scheduleRootUpdate(current, element, expirationTime, callback);
11818 }
11819
11820 function findHostInstance(fiber) {
11821 var hostFiber = findCurrentHostFiber(fiber);
11822 if (hostFiber === null) {
11823 return null;
11824 }
11825 return hostFiber.stateNode;
11826 }
11827
11828 return {
11829 createContainer: function (containerInfo, isAsync, hydrate) {
11830 return createFiberRoot(containerInfo, isAsync, hydrate);
11831 },
11832 updateContainer: function (element, container, parentComponent, callback) {
11833 var current = container.current;
11834 var expirationTime = computeExpirationForFiber(current);
11835 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
11836 },
11837
11838
11839 updateContainerAtExpirationTime: updateContainerAtExpirationTime,
11840
11841 flushRoot: flushRoot,
11842
11843 requestWork: requestWork,
11844
11845 computeUniqueAsyncExpiration: computeUniqueAsyncExpiration,
11846
11847 batchedUpdates: batchedUpdates,
11848
11849 unbatchedUpdates: unbatchedUpdates,
11850
11851 deferredUpdates: deferredUpdates,
11852
11853 flushSync: flushSync,
11854
11855 getPublicRootInstance: function (container) {
11856 var containerFiber = container.current;
11857 if (!containerFiber.child) {
11858 return null;
11859 }
11860 switch (containerFiber.child.tag) {
11861 case HostComponent:
11862 return getPublicInstance(containerFiber.child.stateNode);
11863 default:
11864 return containerFiber.child.stateNode;
11865 }
11866 },
11867
11868
11869 findHostInstance: findHostInstance,
11870
11871 findHostInstanceWithNoPortals: function (fiber) {
11872 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
11873 if (hostFiber === null) {
11874 return null;
11875 }
11876 return hostFiber.stateNode;
11877 },
11878 injectIntoDevTools: function (devToolsConfig) {
11879 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
11880
11881 return injectInternals(_assign({}, devToolsConfig, {
11882 findHostInstanceByFiber: function (fiber) {
11883 return findHostInstance(fiber);
11884 },
11885 findFiberByHostInstance: function (instance) {
11886 if (!findFiberByHostInstance) {
11887 // Might not be implemented by the renderer.
11888 return null;
11889 }
11890 return findFiberByHostInstance(instance);
11891 }
11892 }));
11893 }
11894 };
11895};
11896
11897var ReactFiberReconciler$2 = Object.freeze({
11898 default: ReactFiberReconciler$1
11899});
11900
11901var ReactFiberReconciler$3 = ( ReactFiberReconciler$2 && ReactFiberReconciler$1 ) || ReactFiberReconciler$2;
11902
11903// TODO: bundle Flow types with the package.
11904
11905
11906
11907// TODO: decide on the top-level export form.
11908// This is hacky but makes it work with both Rollup and Jest.
11909var reactReconciler = ReactFiberReconciler$3['default'] ? ReactFiberReconciler$3['default'] : ReactFiberReconciler$3;
11910
11911function createPortal$1(children, containerInfo,
11912// TODO: figure out the API for cross-renderer implementation.
11913implementation) {
11914 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
11915
11916 return {
11917 // This tag allow us to uniquely identify this as a React Portal
11918 $$typeof: REACT_PORTAL_TYPE,
11919 key: key == null ? null : '' + key,
11920 children: children,
11921 containerInfo: containerInfo,
11922 implementation: implementation
11923 };
11924}
11925
11926// TODO: this is special because it gets imported during build.
11927
11928var ReactVersion = '16.2.0';
11929
11930// a requestAnimationFrame, storing the time for the start of the frame, then
11931// scheduling a postMessage which gets scheduled after paint. Within the
11932// postMessage handler do as much work as possible until time + frame rate.
11933// By separating the idle call into a separate event tick we ensure that
11934// layout, paint and other browser work is counted against the available time.
11935// The frame rate is dynamically adjusted.
11936
11937{
11938 if (ExecutionEnvironment_1.canUseDOM && typeof requestAnimationFrame !== 'function') {
11939 warning_1(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
11940 }
11941}
11942
11943var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
11944
11945var now = void 0;
11946if (hasNativePerformanceNow) {
11947 now = function () {
11948 return performance.now();
11949 };
11950} else {
11951 now = function () {
11952 return Date.now();
11953 };
11954}
11955
11956// TODO: There's no way to cancel, because Fiber doesn't atm.
11957var rIC = void 0;
11958var cIC = void 0;
11959
11960if (!ExecutionEnvironment_1.canUseDOM) {
11961 rIC = function (frameCallback) {
11962 return setTimeout(function () {
11963 frameCallback({
11964 timeRemaining: function () {
11965 return Infinity;
11966 }
11967 });
11968 });
11969 };
11970 cIC = function (timeoutID) {
11971 clearTimeout(timeoutID);
11972 };
11973} else if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
11974 // Polyfill requestIdleCallback and cancelIdleCallback
11975
11976 var scheduledRICCallback = null;
11977 var isIdleScheduled = false;
11978 var timeoutTime = -1;
11979
11980 var isAnimationFrameScheduled = false;
11981
11982 var frameDeadline = 0;
11983 // We start out assuming that we run at 30fps but then the heuristic tracking
11984 // will adjust this value to a faster fps if we get more frequent animation
11985 // frames.
11986 var previousFrameTime = 33;
11987 var activeFrameTime = 33;
11988
11989 var frameDeadlineObject = void 0;
11990 if (hasNativePerformanceNow) {
11991 frameDeadlineObject = {
11992 didTimeout: false,
11993 timeRemaining: function () {
11994 // We assume that if we have a performance timer that the rAF callback
11995 // gets a performance timer value. Not sure if this is always true.
11996 var remaining = frameDeadline - performance.now();
11997 return remaining > 0 ? remaining : 0;
11998 }
11999 };
12000 } else {
12001 frameDeadlineObject = {
12002 didTimeout: false,
12003 timeRemaining: function () {
12004 // Fallback to Date.now()
12005 var remaining = frameDeadline - Date.now();
12006 return remaining > 0 ? remaining : 0;
12007 }
12008 };
12009 }
12010
12011 // We use the postMessage trick to defer idle work until after the repaint.
12012 var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
12013 var idleTick = function (event) {
12014 if (event.source !== window || event.data !== messageKey) {
12015 return;
12016 }
12017
12018 isIdleScheduled = false;
12019
12020 var currentTime = now();
12021 if (frameDeadline - currentTime <= 0) {
12022 // There's no time left in this idle period. Check if the callback has
12023 // a timeout and whether it's been exceeded.
12024 if (timeoutTime !== -1 && timeoutTime <= currentTime) {
12025 // Exceeded the timeout. Invoke the callback even though there's no
12026 // time left.
12027 frameDeadlineObject.didTimeout = true;
12028 } else {
12029 // No timeout.
12030 if (!isAnimationFrameScheduled) {
12031 // Schedule another animation callback so we retry later.
12032 isAnimationFrameScheduled = true;
12033 requestAnimationFrame(animationTick);
12034 }
12035 // Exit without invoking the callback.
12036 return;
12037 }
12038 } else {
12039 // There's still time left in this idle period.
12040 frameDeadlineObject.didTimeout = false;
12041 }
12042
12043 timeoutTime = -1;
12044 var callback = scheduledRICCallback;
12045 scheduledRICCallback = null;
12046 if (callback !== null) {
12047 callback(frameDeadlineObject);
12048 }
12049 };
12050 // Assumes that we have addEventListener in this environment. Might need
12051 // something better for old IE.
12052 window.addEventListener('message', idleTick, false);
12053
12054 var animationTick = function (rafTime) {
12055 isAnimationFrameScheduled = false;
12056 var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
12057 if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
12058 if (nextFrameTime < 8) {
12059 // Defensive coding. We don't support higher frame rates than 120hz.
12060 // If we get lower than that, it is probably a bug.
12061 nextFrameTime = 8;
12062 }
12063 // If one frame goes long, then the next one can be short to catch up.
12064 // If two frames are short in a row, then that's an indication that we
12065 // actually have a higher frame rate than what we're currently optimizing.
12066 // We adjust our heuristic dynamically accordingly. For example, if we're
12067 // running on 120hz display or 90hz VR display.
12068 // Take the max of the two in case one of them was an anomaly due to
12069 // missed frame deadlines.
12070 activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
12071 } else {
12072 previousFrameTime = nextFrameTime;
12073 }
12074 frameDeadline = rafTime + activeFrameTime;
12075 if (!isIdleScheduled) {
12076 isIdleScheduled = true;
12077 window.postMessage(messageKey, '*');
12078 }
12079 };
12080
12081 rIC = function (callback, options) {
12082 // This assumes that we only schedule one callback at a time because that's
12083 // how Fiber uses it.
12084 scheduledRICCallback = callback;
12085 if (options != null && typeof options.timeout === 'number') {
12086 timeoutTime = now() + options.timeout;
12087 }
12088 if (!isAnimationFrameScheduled) {
12089 // If rAF didn't already schedule one, we need to schedule a frame.
12090 // TODO: If this rAF doesn't materialize because the browser throttles, we
12091 // might want to still have setTimeout trigger rIC as a backup to ensure
12092 // that we keep performing work.
12093 isAnimationFrameScheduled = true;
12094 requestAnimationFrame(animationTick);
12095 }
12096 return 0;
12097 };
12098
12099 cIC = function () {
12100 scheduledRICCallback = null;
12101 isIdleScheduled = false;
12102 timeoutTime = -1;
12103 };
12104} else {
12105 rIC = window.requestIdleCallback;
12106 cIC = window.cancelIdleCallback;
12107}
12108
12109var didWarnSelectedSetOnOption = false;
12110
12111function flattenChildren(children) {
12112 var content = '';
12113
12114 // Flatten children and warn if they aren't strings or numbers;
12115 // invalid types are ignored.
12116 // We can silently skip them because invalid DOM nesting warning
12117 // catches these cases in Fiber.
12118 React.Children.forEach(children, function (child) {
12119 if (child == null) {
12120 return;
12121 }
12122 if (typeof child === 'string' || typeof child === 'number') {
12123 content += child;
12124 }
12125 });
12126
12127 return content;
12128}
12129
12130/**
12131 * Implements an <option> host component that warns when `selected` is set.
12132 */
12133
12134function validateProps(element, props) {
12135 // TODO (yungsters): Remove support for `selected` in <option>.
12136 {
12137 if (props.selected != null && !didWarnSelectedSetOnOption) {
12138 warning_1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
12139 didWarnSelectedSetOnOption = true;
12140 }
12141 }
12142}
12143
12144function postMountWrapper$1(element, props) {
12145 // value="" should make a value attribute (#6219)
12146 if (props.value != null) {
12147 element.setAttribute('value', props.value);
12148 }
12149}
12150
12151function getHostProps$1(element, props) {
12152 var hostProps = _assign({ children: undefined }, props);
12153 var content = flattenChildren(props.children);
12154
12155 if (content) {
12156 hostProps.children = content;
12157 }
12158
12159 return hostProps;
12160}
12161
12162// TODO: direct imports like some-package/src/* are bad. Fix me.
12163var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
12164var getCurrentFiberStackAddendum$4 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12165
12166
12167var didWarnValueDefaultValue$1 = void 0;
12168
12169{
12170 didWarnValueDefaultValue$1 = false;
12171}
12172
12173function getDeclarationErrorAddendum() {
12174 var ownerName = getCurrentFiberOwnerName$3();
12175 if (ownerName) {
12176 return '\n\nCheck the render method of `' + ownerName + '`.';
12177 }
12178 return '';
12179}
12180
12181var valuePropNames = ['value', 'defaultValue'];
12182
12183/**
12184 * Validation function for `value` and `defaultValue`.
12185 */
12186function checkSelectPropTypes(props) {
12187 ReactControlledValuePropTypes.checkPropTypes('select', props, getCurrentFiberStackAddendum$4);
12188
12189 for (var i = 0; i < valuePropNames.length; i++) {
12190 var propName = valuePropNames[i];
12191 if (props[propName] == null) {
12192 continue;
12193 }
12194 var isArray = Array.isArray(props[propName]);
12195 if (props.multiple && !isArray) {
12196 warning_1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
12197 } else if (!props.multiple && isArray) {
12198 warning_1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
12199 }
12200 }
12201}
12202
12203function updateOptions(node, multiple, propValue, setDefaultSelected) {
12204 var options = node.options;
12205
12206 if (multiple) {
12207 var selectedValues = propValue;
12208 var selectedValue = {};
12209 for (var i = 0; i < selectedValues.length; i++) {
12210 // Prefix to avoid chaos with special keys.
12211 selectedValue['$' + selectedValues[i]] = true;
12212 }
12213 for (var _i = 0; _i < options.length; _i++) {
12214 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
12215 if (options[_i].selected !== selected) {
12216 options[_i].selected = selected;
12217 }
12218 if (selected && setDefaultSelected) {
12219 options[_i].defaultSelected = true;
12220 }
12221 }
12222 } else {
12223 // Do not set `select.value` as exact behavior isn't consistent across all
12224 // browsers for all cases.
12225 var _selectedValue = '' + propValue;
12226 var defaultSelected = null;
12227 for (var _i2 = 0; _i2 < options.length; _i2++) {
12228 if (options[_i2].value === _selectedValue) {
12229 options[_i2].selected = true;
12230 if (setDefaultSelected) {
12231 options[_i2].defaultSelected = true;
12232 }
12233 return;
12234 }
12235 if (defaultSelected === null && !options[_i2].disabled) {
12236 defaultSelected = options[_i2];
12237 }
12238 }
12239 if (defaultSelected !== null) {
12240 defaultSelected.selected = true;
12241 }
12242 }
12243}
12244
12245/**
12246 * Implements a <select> host component that allows optionally setting the
12247 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
12248 * stringable. If `multiple` is true, the prop must be an array of stringables.
12249 *
12250 * If `value` is not supplied (or null/undefined), user actions that change the
12251 * selected option will trigger updates to the rendered options.
12252 *
12253 * If it is supplied (and not null/undefined), the rendered options will not
12254 * update in response to user actions. Instead, the `value` prop must change in
12255 * order for the rendered options to update.
12256 *
12257 * If `defaultValue` is provided, any options with the supplied values will be
12258 * selected.
12259 */
12260
12261function getHostProps$2(element, props) {
12262 return _assign({}, props, {
12263 value: undefined
12264 });
12265}
12266
12267function initWrapperState$1(element, props) {
12268 var node = element;
12269 {
12270 checkSelectPropTypes(props);
12271 }
12272
12273 var value = props.value;
12274 node._wrapperState = {
12275 initialValue: value != null ? value : props.defaultValue,
12276 wasMultiple: !!props.multiple
12277 };
12278
12279 {
12280 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
12281 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');
12282 didWarnValueDefaultValue$1 = true;
12283 }
12284 }
12285}
12286
12287function postMountWrapper$2(element, props) {
12288 var node = element;
12289 node.multiple = !!props.multiple;
12290 var value = props.value;
12291 if (value != null) {
12292 updateOptions(node, !!props.multiple, value, false);
12293 } else if (props.defaultValue != null) {
12294 updateOptions(node, !!props.multiple, props.defaultValue, true);
12295 }
12296}
12297
12298function postUpdateWrapper(element, props) {
12299 var node = element;
12300 // After the initial mount, we control selected-ness manually so don't pass
12301 // this value down
12302 node._wrapperState.initialValue = undefined;
12303
12304 var wasMultiple = node._wrapperState.wasMultiple;
12305 node._wrapperState.wasMultiple = !!props.multiple;
12306
12307 var value = props.value;
12308 if (value != null) {
12309 updateOptions(node, !!props.multiple, value, false);
12310 } else if (wasMultiple !== !!props.multiple) {
12311 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
12312 if (props.defaultValue != null) {
12313 updateOptions(node, !!props.multiple, props.defaultValue, true);
12314 } else {
12315 // Revert the select back to its default unselected state.
12316 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
12317 }
12318 }
12319}
12320
12321function restoreControlledState$2(element, props) {
12322 var node = element;
12323 var value = props.value;
12324
12325 if (value != null) {
12326 updateOptions(node, !!props.multiple, value, false);
12327 }
12328}
12329
12330// TODO: direct imports like some-package/src/* are bad. Fix me.
12331var getCurrentFiberStackAddendum$5 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
12332
12333var didWarnValDefaultVal = false;
12334
12335/**
12336 * Implements a <textarea> host component that allows setting `value`, and
12337 * `defaultValue`. This differs from the traditional DOM API because value is
12338 * usually set as PCDATA children.
12339 *
12340 * If `value` is not supplied (or null/undefined), user actions that affect the
12341 * value will trigger updates to the element.
12342 *
12343 * If `value` is supplied (and not null/undefined), the rendered element will
12344 * not trigger updates to the element. Instead, the `value` prop must change in
12345 * order for the rendered element to be updated.
12346 *
12347 * The rendered element will be initialized with an empty value, the prop
12348 * `defaultValue` if specified, or the children content (deprecated).
12349 */
12350
12351function getHostProps$3(element, props) {
12352 var node = element;
12353 !(props.dangerouslySetInnerHTML == null) ? invariant_1(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
12354
12355 // Always set children to the same thing. In IE9, the selection range will
12356 // get reset if `textContent` is mutated. We could add a check in setTextContent
12357 // to only set the value if/when the value differs from the node value (which would
12358 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
12359 // solution. The value can be a boolean or object so that's why it's forced
12360 // to be a string.
12361 var hostProps = _assign({}, props, {
12362 value: undefined,
12363 defaultValue: undefined,
12364 children: '' + node._wrapperState.initialValue
12365 });
12366
12367 return hostProps;
12368}
12369
12370function initWrapperState$2(element, props) {
12371 var node = element;
12372 {
12373 ReactControlledValuePropTypes.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$5);
12374 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
12375 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');
12376 didWarnValDefaultVal = true;
12377 }
12378 }
12379
12380 var initialValue = props.value;
12381
12382 // Only bother fetching default value if we're going to use it
12383 if (initialValue == null) {
12384 var defaultValue = props.defaultValue;
12385 // TODO (yungsters): Remove support for children content in <textarea>.
12386 var children = props.children;
12387 if (children != null) {
12388 {
12389 warning_1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
12390 }
12391 !(defaultValue == null) ? invariant_1(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
12392 if (Array.isArray(children)) {
12393 !(children.length <= 1) ? invariant_1(false, '<textarea> can only have at most one child.') : void 0;
12394 children = children[0];
12395 }
12396
12397 defaultValue = '' + children;
12398 }
12399 if (defaultValue == null) {
12400 defaultValue = '';
12401 }
12402 initialValue = defaultValue;
12403 }
12404
12405 node._wrapperState = {
12406 initialValue: '' + initialValue
12407 };
12408}
12409
12410function updateWrapper$1(element, props) {
12411 var node = element;
12412 var value = props.value;
12413 if (value != null) {
12414 // Cast `value` to a string to ensure the value is set correctly. While
12415 // browsers typically do this as necessary, jsdom doesn't.
12416 var newValue = '' + value;
12417
12418 // To avoid side effects (such as losing text selection), only set value if changed
12419 if (newValue !== node.value) {
12420 node.value = newValue;
12421 }
12422 if (props.defaultValue == null) {
12423 node.defaultValue = newValue;
12424 }
12425 }
12426 if (props.defaultValue != null) {
12427 node.defaultValue = props.defaultValue;
12428 }
12429}
12430
12431function postMountWrapper$3(element, props) {
12432 var node = element;
12433 // This is in postMount because we need access to the DOM node, which is not
12434 // available until after the component has mounted.
12435 var textContent = node.textContent;
12436
12437 // Only set node.value if textContent is equal to the expected
12438 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
12439 // will populate textContent as well.
12440 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
12441 if (textContent === node._wrapperState.initialValue) {
12442 node.value = textContent;
12443 }
12444}
12445
12446function restoreControlledState$3(element, props) {
12447 // DOM component is still mounted; update
12448 updateWrapper$1(element, props);
12449}
12450
12451var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
12452var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
12453var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
12454
12455var Namespaces = {
12456 html: HTML_NAMESPACE$1,
12457 mathml: MATH_NAMESPACE,
12458 svg: SVG_NAMESPACE
12459};
12460
12461// Assumes there is no parent namespace.
12462function getIntrinsicNamespace(type) {
12463 switch (type) {
12464 case 'svg':
12465 return SVG_NAMESPACE;
12466 case 'math':
12467 return MATH_NAMESPACE;
12468 default:
12469 return HTML_NAMESPACE$1;
12470 }
12471}
12472
12473function getChildNamespace(parentNamespace, type) {
12474 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
12475 // No (or default) parent namespace: potential entry point.
12476 return getIntrinsicNamespace(type);
12477 }
12478 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
12479 // We're leaving SVG.
12480 return HTML_NAMESPACE$1;
12481 }
12482 // By default, pass namespace below.
12483 return parentNamespace;
12484}
12485
12486/* globals MSApp */
12487
12488/**
12489 * Create a function which has 'unsafe' privileges (required by windows8 apps)
12490 */
12491var createMicrosoftUnsafeLocalFunction = function (func) {
12492 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
12493 return function (arg0, arg1, arg2, arg3) {
12494 MSApp.execUnsafeLocalFunction(function () {
12495 return func(arg0, arg1, arg2, arg3);
12496 });
12497 };
12498 } else {
12499 return func;
12500 }
12501};
12502
12503// SVG temp container for IE lacking innerHTML
12504var reusableSVGContainer = void 0;
12505
12506/**
12507 * Set the innerHTML property of a node
12508 *
12509 * @param {DOMElement} node
12510 * @param {string} html
12511 * @internal
12512 */
12513var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
12514 // IE does not have innerHTML for SVG nodes, so instead we inject the
12515 // new markup in a temp node and then move the child nodes across into
12516 // the target node
12517
12518 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
12519 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
12520 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
12521 var svgNode = reusableSVGContainer.firstChild;
12522 while (node.firstChild) {
12523 node.removeChild(node.firstChild);
12524 }
12525 while (svgNode.firstChild) {
12526 node.appendChild(svgNode.firstChild);
12527 }
12528 } else {
12529 node.innerHTML = html;
12530 }
12531});
12532
12533/**
12534 * Set the textContent property of a node. For text updates, it's faster
12535 * to set the `nodeValue` of the Text node directly instead of using
12536 * `.textContent` which will remove the existing node and create a new one.
12537 *
12538 * @param {DOMElement} node
12539 * @param {string} text
12540 * @internal
12541 */
12542var setTextContent = function (node, text) {
12543 if (text) {
12544 var firstChild = node.firstChild;
12545
12546 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
12547 firstChild.nodeValue = text;
12548 return;
12549 }
12550 }
12551 node.textContent = text;
12552};
12553
12554/**
12555 * CSS properties which accept numbers but are not in units of "px".
12556 */
12557var isUnitlessNumber = {
12558 animationIterationCount: true,
12559 borderImageOutset: true,
12560 borderImageSlice: true,
12561 borderImageWidth: true,
12562 boxFlex: true,
12563 boxFlexGroup: true,
12564 boxOrdinalGroup: true,
12565 columnCount: true,
12566 columns: true,
12567 flex: true,
12568 flexGrow: true,
12569 flexPositive: true,
12570 flexShrink: true,
12571 flexNegative: true,
12572 flexOrder: true,
12573 gridRow: true,
12574 gridRowEnd: true,
12575 gridRowSpan: true,
12576 gridRowStart: true,
12577 gridColumn: true,
12578 gridColumnEnd: true,
12579 gridColumnSpan: true,
12580 gridColumnStart: true,
12581 fontWeight: true,
12582 lineClamp: true,
12583 lineHeight: true,
12584 opacity: true,
12585 order: true,
12586 orphans: true,
12587 tabSize: true,
12588 widows: true,
12589 zIndex: true,
12590 zoom: true,
12591
12592 // SVG-related properties
12593 fillOpacity: true,
12594 floodOpacity: true,
12595 stopOpacity: true,
12596 strokeDasharray: true,
12597 strokeDashoffset: true,
12598 strokeMiterlimit: true,
12599 strokeOpacity: true,
12600 strokeWidth: true
12601};
12602
12603/**
12604 * @param {string} prefix vendor-specific prefix, eg: Webkit
12605 * @param {string} key style name, eg: transitionDuration
12606 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
12607 * WebkitTransitionDuration
12608 */
12609function prefixKey(prefix, key) {
12610 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
12611}
12612
12613/**
12614 * Support style names that may come passed in prefixed by adding permutations
12615 * of vendor prefixes.
12616 */
12617var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
12618
12619// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
12620// infinite loop, because it iterates over the newly added props too.
12621Object.keys(isUnitlessNumber).forEach(function (prop) {
12622 prefixes.forEach(function (prefix) {
12623 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
12624 });
12625});
12626
12627/**
12628 * Convert a value into the proper css writable value. The style name `name`
12629 * should be logical (no hyphens), as specified
12630 * in `CSSProperty.isUnitlessNumber`.
12631 *
12632 * @param {string} name CSS property name such as `topMargin`.
12633 * @param {*} value CSS property value such as `10px`.
12634 * @return {string} Normalized style value with dimensions applied.
12635 */
12636function dangerousStyleValue(name, value, isCustomProperty) {
12637 // Note that we've removed escapeTextForBrowser() calls here since the
12638 // whole string will be escaped when the attribute is injected into
12639 // the markup. If you provide unsafe user data here they can inject
12640 // arbitrary CSS which may be problematic (I couldn't repro this):
12641 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
12642 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
12643 // This is not an XSS hole but instead a potential CSS injection issue
12644 // which has lead to a greater discussion about how we're going to
12645 // trust URLs moving forward. See #2115901
12646
12647 var isEmpty = value == null || typeof value === 'boolean' || value === '';
12648 if (isEmpty) {
12649 return '';
12650 }
12651
12652 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
12653 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
12654 }
12655
12656 return ('' + value).trim();
12657}
12658
12659/**
12660 * Copyright (c) 2013-present, Facebook, Inc.
12661 *
12662 * This source code is licensed under the MIT license found in the
12663 * LICENSE file in the root directory of this source tree.
12664 *
12665 * @typechecks
12666 */
12667
12668var _uppercasePattern = /([A-Z])/g;
12669
12670/**
12671 * Hyphenates a camelcased string, for example:
12672 *
12673 * > hyphenate('backgroundColor')
12674 * < "background-color"
12675 *
12676 * For CSS style names, use `hyphenateStyleName` instead which works properly
12677 * with all vendor prefixes, including `ms`.
12678 *
12679 * @param {string} string
12680 * @return {string}
12681 */
12682function hyphenate(string) {
12683 return string.replace(_uppercasePattern, '-$1').toLowerCase();
12684}
12685
12686var hyphenate_1 = hyphenate;
12687
12688/**
12689 * Copyright (c) 2013-present, Facebook, Inc.
12690 *
12691 * This source code is licensed under the MIT license found in the
12692 * LICENSE file in the root directory of this source tree.
12693 *
12694 * @typechecks
12695 */
12696
12697
12698
12699
12700
12701var msPattern = /^ms-/;
12702
12703/**
12704 * Hyphenates a camelcased CSS property name, for example:
12705 *
12706 * > hyphenateStyleName('backgroundColor')
12707 * < "background-color"
12708 * > hyphenateStyleName('MozTransition')
12709 * < "-moz-transition"
12710 * > hyphenateStyleName('msTransition')
12711 * < "-ms-transition"
12712 *
12713 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
12714 * is converted to `-ms-`.
12715 *
12716 * @param {string} string
12717 * @return {string}
12718 */
12719function hyphenateStyleName(string) {
12720 return hyphenate_1(string).replace(msPattern, '-ms-');
12721}
12722
12723var hyphenateStyleName_1 = hyphenateStyleName;
12724
12725/**
12726 * Copyright (c) 2013-present, Facebook, Inc.
12727 *
12728 * This source code is licensed under the MIT license found in the
12729 * LICENSE file in the root directory of this source tree.
12730 *
12731 * @typechecks
12732 */
12733
12734var _hyphenPattern = /-(.)/g;
12735
12736/**
12737 * Camelcases a hyphenated string, for example:
12738 *
12739 * > camelize('background-color')
12740 * < "backgroundColor"
12741 *
12742 * @param {string} string
12743 * @return {string}
12744 */
12745function camelize(string) {
12746 return string.replace(_hyphenPattern, function (_, character) {
12747 return character.toUpperCase();
12748 });
12749}
12750
12751var camelize_1 = camelize;
12752
12753/**
12754 * Copyright (c) 2013-present, Facebook, Inc.
12755 *
12756 * This source code is licensed under the MIT license found in the
12757 * LICENSE file in the root directory of this source tree.
12758 *
12759 * @typechecks
12760 */
12761
12762
12763
12764
12765
12766var msPattern$1 = /^-ms-/;
12767
12768/**
12769 * Camelcases a hyphenated CSS property name, for example:
12770 *
12771 * > camelizeStyleName('background-color')
12772 * < "backgroundColor"
12773 * > camelizeStyleName('-moz-transition')
12774 * < "MozTransition"
12775 * > camelizeStyleName('-ms-transition')
12776 * < "msTransition"
12777 *
12778 * As Andi Smith suggests
12779 * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
12780 * is converted to lowercase `ms`.
12781 *
12782 * @param {string} string
12783 * @return {string}
12784 */
12785function camelizeStyleName(string) {
12786 return camelize_1(string.replace(msPattern$1, 'ms-'));
12787}
12788
12789var camelizeStyleName_1 = camelizeStyleName;
12790
12791var warnValidStyle = emptyFunction_1;
12792
12793{
12794 // 'msTransform' is correct, but the other prefixes should be capitalized
12795 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
12796
12797 // style values shouldn't contain a semicolon
12798 var badStyleValueWithSemicolonPattern = /;\s*$/;
12799
12800 var warnedStyleNames = {};
12801 var warnedStyleValues = {};
12802 var warnedForNaNValue = false;
12803 var warnedForInfinityValue = false;
12804
12805 var warnHyphenatedStyleName = function (name, getStack) {
12806 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12807 return;
12808 }
12809
12810 warnedStyleNames[name] = true;
12811 warning_1(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName_1(name), getStack());
12812 };
12813
12814 var warnBadVendoredStyleName = function (name, getStack) {
12815 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
12816 return;
12817 }
12818
12819 warnedStyleNames[name] = true;
12820 warning_1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack());
12821 };
12822
12823 var warnStyleValueWithSemicolon = function (name, value, getStack) {
12824 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
12825 return;
12826 }
12827
12828 warnedStyleValues[value] = true;
12829 warning_1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack());
12830 };
12831
12832 var warnStyleValueIsNaN = function (name, value, getStack) {
12833 if (warnedForNaNValue) {
12834 return;
12835 }
12836
12837 warnedForNaNValue = true;
12838 warning_1(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack());
12839 };
12840
12841 var warnStyleValueIsInfinity = function (name, value, getStack) {
12842 if (warnedForInfinityValue) {
12843 return;
12844 }
12845
12846 warnedForInfinityValue = true;
12847 warning_1(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack());
12848 };
12849
12850 warnValidStyle = function (name, value, getStack) {
12851 if (name.indexOf('-') > -1) {
12852 warnHyphenatedStyleName(name, getStack);
12853 } else if (badVendoredStyleNamePattern.test(name)) {
12854 warnBadVendoredStyleName(name, getStack);
12855 } else if (badStyleValueWithSemicolonPattern.test(value)) {
12856 warnStyleValueWithSemicolon(name, value, getStack);
12857 }
12858
12859 if (typeof value === 'number') {
12860 if (isNaN(value)) {
12861 warnStyleValueIsNaN(name, value, getStack);
12862 } else if (!isFinite(value)) {
12863 warnStyleValueIsInfinity(name, value, getStack);
12864 }
12865 }
12866 };
12867}
12868
12869var warnValidStyle$1 = warnValidStyle;
12870
12871/**
12872 * Operations for dealing with CSS properties.
12873 */
12874
12875/**
12876 * This creates a string that is expected to be equivalent to the style
12877 * attribute generated by server-side rendering. It by-passes warnings and
12878 * security checks so it's not safe to use this value for anything other than
12879 * comparison. It is only used in DEV for SSR validation.
12880 */
12881function createDangerousStringForStyles(styles) {
12882 {
12883 var serialized = '';
12884 var delimiter = '';
12885 for (var styleName in styles) {
12886 if (!styles.hasOwnProperty(styleName)) {
12887 continue;
12888 }
12889 var styleValue = styles[styleName];
12890 if (styleValue != null) {
12891 var isCustomProperty = styleName.indexOf('--') === 0;
12892 serialized += delimiter + hyphenateStyleName_1(styleName) + ':';
12893 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
12894
12895 delimiter = ';';
12896 }
12897 }
12898 return serialized || null;
12899 }
12900}
12901
12902/**
12903 * Sets the value for multiple styles on a node. If a value is specified as
12904 * '' (empty string), the corresponding style property will be unset.
12905 *
12906 * @param {DOMElement} node
12907 * @param {object} styles
12908 */
12909function setValueForStyles(node, styles, getStack) {
12910 var style = node.style;
12911 for (var styleName in styles) {
12912 if (!styles.hasOwnProperty(styleName)) {
12913 continue;
12914 }
12915 var isCustomProperty = styleName.indexOf('--') === 0;
12916 {
12917 if (!isCustomProperty) {
12918 warnValidStyle$1(styleName, styles[styleName], getStack);
12919 }
12920 }
12921 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
12922 if (styleName === 'float') {
12923 styleName = 'cssFloat';
12924 }
12925 if (isCustomProperty) {
12926 style.setProperty(styleName, styleValue);
12927 } else {
12928 style[styleName] = styleValue;
12929 }
12930 }
12931}
12932
12933// For HTML, certain tags should omit their close tag. We keep a whitelist for
12934// those special-case tags.
12935
12936var omittedCloseTags = {
12937 area: true,
12938 base: true,
12939 br: true,
12940 col: true,
12941 embed: true,
12942 hr: true,
12943 img: true,
12944 input: true,
12945 keygen: true,
12946 link: true,
12947 meta: true,
12948 param: true,
12949 source: true,
12950 track: true,
12951 wbr: true
12952};
12953
12954// For HTML, certain tags cannot have children. This has the same purpose as
12955// `omittedCloseTags` except that `menuitem` should still have its closing tag.
12956
12957var voidElementTags = _assign({
12958 menuitem: true
12959}, omittedCloseTags);
12960
12961var HTML$1 = '__html';
12962
12963function assertValidProps(tag, props, getStack) {
12964 if (!props) {
12965 return;
12966 }
12967 // Note the use of `==` which checks for null or undefined.
12968 if (voidElementTags[tag]) {
12969 !(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;
12970 }
12971 if (props.dangerouslySetInnerHTML != null) {
12972 !(props.children == null) ? invariant_1(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
12973 !(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;
12974 }
12975 {
12976 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());
12977 }
12978 !(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;
12979}
12980
12981function isCustomComponent(tagName, props) {
12982 if (tagName.indexOf('-') === -1) {
12983 return typeof props.is === 'string';
12984 }
12985 switch (tagName) {
12986 // These are reserved SVG and MathML elements.
12987 // We don't mind this whitelist too much because we expect it to never grow.
12988 // The alternative is to track the namespace in a few places which is convoluted.
12989 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
12990 case 'annotation-xml':
12991 case 'color-profile':
12992 case 'font-face':
12993 case 'font-face-src':
12994 case 'font-face-uri':
12995 case 'font-face-format':
12996 case 'font-face-name':
12997 case 'missing-glyph':
12998 return false;
12999 default:
13000 return true;
13001 }
13002}
13003
13004// When adding attributes to the HTML or SVG whitelist, be sure to
13005// also add them to this module to ensure casing and incorrect name
13006// warnings.
13007var possibleStandardNames = {
13008 // HTML
13009 accept: 'accept',
13010 acceptcharset: 'acceptCharset',
13011 'accept-charset': 'acceptCharset',
13012 accesskey: 'accessKey',
13013 action: 'action',
13014 allowfullscreen: 'allowFullScreen',
13015 alt: 'alt',
13016 as: 'as',
13017 async: 'async',
13018 autocapitalize: 'autoCapitalize',
13019 autocomplete: 'autoComplete',
13020 autocorrect: 'autoCorrect',
13021 autofocus: 'autoFocus',
13022 autoplay: 'autoPlay',
13023 autosave: 'autoSave',
13024 capture: 'capture',
13025 cellpadding: 'cellPadding',
13026 cellspacing: 'cellSpacing',
13027 challenge: 'challenge',
13028 charset: 'charSet',
13029 checked: 'checked',
13030 children: 'children',
13031 cite: 'cite',
13032 'class': 'className',
13033 classid: 'classID',
13034 classname: 'className',
13035 cols: 'cols',
13036 colspan: 'colSpan',
13037 content: 'content',
13038 contenteditable: 'contentEditable',
13039 contextmenu: 'contextMenu',
13040 controls: 'controls',
13041 controlslist: 'controlsList',
13042 coords: 'coords',
13043 crossorigin: 'crossOrigin',
13044 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
13045 data: 'data',
13046 datetime: 'dateTime',
13047 'default': 'default',
13048 defaultchecked: 'defaultChecked',
13049 defaultvalue: 'defaultValue',
13050 defer: 'defer',
13051 dir: 'dir',
13052 disabled: 'disabled',
13053 download: 'download',
13054 draggable: 'draggable',
13055 enctype: 'encType',
13056 'for': 'htmlFor',
13057 form: 'form',
13058 formmethod: 'formMethod',
13059 formaction: 'formAction',
13060 formenctype: 'formEncType',
13061 formnovalidate: 'formNoValidate',
13062 formtarget: 'formTarget',
13063 frameborder: 'frameBorder',
13064 headers: 'headers',
13065 height: 'height',
13066 hidden: 'hidden',
13067 high: 'high',
13068 href: 'href',
13069 hreflang: 'hrefLang',
13070 htmlfor: 'htmlFor',
13071 httpequiv: 'httpEquiv',
13072 'http-equiv': 'httpEquiv',
13073 icon: 'icon',
13074 id: 'id',
13075 innerhtml: 'innerHTML',
13076 inputmode: 'inputMode',
13077 integrity: 'integrity',
13078 is: 'is',
13079 itemid: 'itemID',
13080 itemprop: 'itemProp',
13081 itemref: 'itemRef',
13082 itemscope: 'itemScope',
13083 itemtype: 'itemType',
13084 keyparams: 'keyParams',
13085 keytype: 'keyType',
13086 kind: 'kind',
13087 label: 'label',
13088 lang: 'lang',
13089 list: 'list',
13090 loop: 'loop',
13091 low: 'low',
13092 manifest: 'manifest',
13093 marginwidth: 'marginWidth',
13094 marginheight: 'marginHeight',
13095 max: 'max',
13096 maxlength: 'maxLength',
13097 media: 'media',
13098 mediagroup: 'mediaGroup',
13099 method: 'method',
13100 min: 'min',
13101 minlength: 'minLength',
13102 multiple: 'multiple',
13103 muted: 'muted',
13104 name: 'name',
13105 nomodule: 'noModule',
13106 nonce: 'nonce',
13107 novalidate: 'noValidate',
13108 open: 'open',
13109 optimum: 'optimum',
13110 pattern: 'pattern',
13111 placeholder: 'placeholder',
13112 playsinline: 'playsInline',
13113 poster: 'poster',
13114 preload: 'preload',
13115 profile: 'profile',
13116 radiogroup: 'radioGroup',
13117 readonly: 'readOnly',
13118 referrerpolicy: 'referrerPolicy',
13119 rel: 'rel',
13120 required: 'required',
13121 reversed: 'reversed',
13122 role: 'role',
13123 rows: 'rows',
13124 rowspan: 'rowSpan',
13125 sandbox: 'sandbox',
13126 scope: 'scope',
13127 scoped: 'scoped',
13128 scrolling: 'scrolling',
13129 seamless: 'seamless',
13130 selected: 'selected',
13131 shape: 'shape',
13132 size: 'size',
13133 sizes: 'sizes',
13134 span: 'span',
13135 spellcheck: 'spellCheck',
13136 src: 'src',
13137 srcdoc: 'srcDoc',
13138 srclang: 'srcLang',
13139 srcset: 'srcSet',
13140 start: 'start',
13141 step: 'step',
13142 style: 'style',
13143 summary: 'summary',
13144 tabindex: 'tabIndex',
13145 target: 'target',
13146 title: 'title',
13147 type: 'type',
13148 usemap: 'useMap',
13149 value: 'value',
13150 width: 'width',
13151 wmode: 'wmode',
13152 wrap: 'wrap',
13153
13154 // SVG
13155 about: 'about',
13156 accentheight: 'accentHeight',
13157 'accent-height': 'accentHeight',
13158 accumulate: 'accumulate',
13159 additive: 'additive',
13160 alignmentbaseline: 'alignmentBaseline',
13161 'alignment-baseline': 'alignmentBaseline',
13162 allowreorder: 'allowReorder',
13163 alphabetic: 'alphabetic',
13164 amplitude: 'amplitude',
13165 arabicform: 'arabicForm',
13166 'arabic-form': 'arabicForm',
13167 ascent: 'ascent',
13168 attributename: 'attributeName',
13169 attributetype: 'attributeType',
13170 autoreverse: 'autoReverse',
13171 azimuth: 'azimuth',
13172 basefrequency: 'baseFrequency',
13173 baselineshift: 'baselineShift',
13174 'baseline-shift': 'baselineShift',
13175 baseprofile: 'baseProfile',
13176 bbox: 'bbox',
13177 begin: 'begin',
13178 bias: 'bias',
13179 by: 'by',
13180 calcmode: 'calcMode',
13181 capheight: 'capHeight',
13182 'cap-height': 'capHeight',
13183 clip: 'clip',
13184 clippath: 'clipPath',
13185 'clip-path': 'clipPath',
13186 clippathunits: 'clipPathUnits',
13187 cliprule: 'clipRule',
13188 'clip-rule': 'clipRule',
13189 color: 'color',
13190 colorinterpolation: 'colorInterpolation',
13191 'color-interpolation': 'colorInterpolation',
13192 colorinterpolationfilters: 'colorInterpolationFilters',
13193 'color-interpolation-filters': 'colorInterpolationFilters',
13194 colorprofile: 'colorProfile',
13195 'color-profile': 'colorProfile',
13196 colorrendering: 'colorRendering',
13197 'color-rendering': 'colorRendering',
13198 contentscripttype: 'contentScriptType',
13199 contentstyletype: 'contentStyleType',
13200 cursor: 'cursor',
13201 cx: 'cx',
13202 cy: 'cy',
13203 d: 'd',
13204 datatype: 'datatype',
13205 decelerate: 'decelerate',
13206 descent: 'descent',
13207 diffuseconstant: 'diffuseConstant',
13208 direction: 'direction',
13209 display: 'display',
13210 divisor: 'divisor',
13211 dominantbaseline: 'dominantBaseline',
13212 'dominant-baseline': 'dominantBaseline',
13213 dur: 'dur',
13214 dx: 'dx',
13215 dy: 'dy',
13216 edgemode: 'edgeMode',
13217 elevation: 'elevation',
13218 enablebackground: 'enableBackground',
13219 'enable-background': 'enableBackground',
13220 end: 'end',
13221 exponent: 'exponent',
13222 externalresourcesrequired: 'externalResourcesRequired',
13223 fill: 'fill',
13224 fillopacity: 'fillOpacity',
13225 'fill-opacity': 'fillOpacity',
13226 fillrule: 'fillRule',
13227 'fill-rule': 'fillRule',
13228 filter: 'filter',
13229 filterres: 'filterRes',
13230 filterunits: 'filterUnits',
13231 floodopacity: 'floodOpacity',
13232 'flood-opacity': 'floodOpacity',
13233 floodcolor: 'floodColor',
13234 'flood-color': 'floodColor',
13235 focusable: 'focusable',
13236 fontfamily: 'fontFamily',
13237 'font-family': 'fontFamily',
13238 fontsize: 'fontSize',
13239 'font-size': 'fontSize',
13240 fontsizeadjust: 'fontSizeAdjust',
13241 'font-size-adjust': 'fontSizeAdjust',
13242 fontstretch: 'fontStretch',
13243 'font-stretch': 'fontStretch',
13244 fontstyle: 'fontStyle',
13245 'font-style': 'fontStyle',
13246 fontvariant: 'fontVariant',
13247 'font-variant': 'fontVariant',
13248 fontweight: 'fontWeight',
13249 'font-weight': 'fontWeight',
13250 format: 'format',
13251 from: 'from',
13252 fx: 'fx',
13253 fy: 'fy',
13254 g1: 'g1',
13255 g2: 'g2',
13256 glyphname: 'glyphName',
13257 'glyph-name': 'glyphName',
13258 glyphorientationhorizontal: 'glyphOrientationHorizontal',
13259 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
13260 glyphorientationvertical: 'glyphOrientationVertical',
13261 'glyph-orientation-vertical': 'glyphOrientationVertical',
13262 glyphref: 'glyphRef',
13263 gradienttransform: 'gradientTransform',
13264 gradientunits: 'gradientUnits',
13265 hanging: 'hanging',
13266 horizadvx: 'horizAdvX',
13267 'horiz-adv-x': 'horizAdvX',
13268 horizoriginx: 'horizOriginX',
13269 'horiz-origin-x': 'horizOriginX',
13270 ideographic: 'ideographic',
13271 imagerendering: 'imageRendering',
13272 'image-rendering': 'imageRendering',
13273 in2: 'in2',
13274 'in': 'in',
13275 inlist: 'inlist',
13276 intercept: 'intercept',
13277 k1: 'k1',
13278 k2: 'k2',
13279 k3: 'k3',
13280 k4: 'k4',
13281 k: 'k',
13282 kernelmatrix: 'kernelMatrix',
13283 kernelunitlength: 'kernelUnitLength',
13284 kerning: 'kerning',
13285 keypoints: 'keyPoints',
13286 keysplines: 'keySplines',
13287 keytimes: 'keyTimes',
13288 lengthadjust: 'lengthAdjust',
13289 letterspacing: 'letterSpacing',
13290 'letter-spacing': 'letterSpacing',
13291 lightingcolor: 'lightingColor',
13292 'lighting-color': 'lightingColor',
13293 limitingconeangle: 'limitingConeAngle',
13294 local: 'local',
13295 markerend: 'markerEnd',
13296 'marker-end': 'markerEnd',
13297 markerheight: 'markerHeight',
13298 markermid: 'markerMid',
13299 'marker-mid': 'markerMid',
13300 markerstart: 'markerStart',
13301 'marker-start': 'markerStart',
13302 markerunits: 'markerUnits',
13303 markerwidth: 'markerWidth',
13304 mask: 'mask',
13305 maskcontentunits: 'maskContentUnits',
13306 maskunits: 'maskUnits',
13307 mathematical: 'mathematical',
13308 mode: 'mode',
13309 numoctaves: 'numOctaves',
13310 offset: 'offset',
13311 opacity: 'opacity',
13312 operator: 'operator',
13313 order: 'order',
13314 orient: 'orient',
13315 orientation: 'orientation',
13316 origin: 'origin',
13317 overflow: 'overflow',
13318 overlineposition: 'overlinePosition',
13319 'overline-position': 'overlinePosition',
13320 overlinethickness: 'overlineThickness',
13321 'overline-thickness': 'overlineThickness',
13322 paintorder: 'paintOrder',
13323 'paint-order': 'paintOrder',
13324 panose1: 'panose1',
13325 'panose-1': 'panose1',
13326 pathlength: 'pathLength',
13327 patterncontentunits: 'patternContentUnits',
13328 patterntransform: 'patternTransform',
13329 patternunits: 'patternUnits',
13330 pointerevents: 'pointerEvents',
13331 'pointer-events': 'pointerEvents',
13332 points: 'points',
13333 pointsatx: 'pointsAtX',
13334 pointsaty: 'pointsAtY',
13335 pointsatz: 'pointsAtZ',
13336 prefix: 'prefix',
13337 preservealpha: 'preserveAlpha',
13338 preserveaspectratio: 'preserveAspectRatio',
13339 primitiveunits: 'primitiveUnits',
13340 property: 'property',
13341 r: 'r',
13342 radius: 'radius',
13343 refx: 'refX',
13344 refy: 'refY',
13345 renderingintent: 'renderingIntent',
13346 'rendering-intent': 'renderingIntent',
13347 repeatcount: 'repeatCount',
13348 repeatdur: 'repeatDur',
13349 requiredextensions: 'requiredExtensions',
13350 requiredfeatures: 'requiredFeatures',
13351 resource: 'resource',
13352 restart: 'restart',
13353 result: 'result',
13354 results: 'results',
13355 rotate: 'rotate',
13356 rx: 'rx',
13357 ry: 'ry',
13358 scale: 'scale',
13359 security: 'security',
13360 seed: 'seed',
13361 shaperendering: 'shapeRendering',
13362 'shape-rendering': 'shapeRendering',
13363 slope: 'slope',
13364 spacing: 'spacing',
13365 specularconstant: 'specularConstant',
13366 specularexponent: 'specularExponent',
13367 speed: 'speed',
13368 spreadmethod: 'spreadMethod',
13369 startoffset: 'startOffset',
13370 stddeviation: 'stdDeviation',
13371 stemh: 'stemh',
13372 stemv: 'stemv',
13373 stitchtiles: 'stitchTiles',
13374 stopcolor: 'stopColor',
13375 'stop-color': 'stopColor',
13376 stopopacity: 'stopOpacity',
13377 'stop-opacity': 'stopOpacity',
13378 strikethroughposition: 'strikethroughPosition',
13379 'strikethrough-position': 'strikethroughPosition',
13380 strikethroughthickness: 'strikethroughThickness',
13381 'strikethrough-thickness': 'strikethroughThickness',
13382 string: 'string',
13383 stroke: 'stroke',
13384 strokedasharray: 'strokeDasharray',
13385 'stroke-dasharray': 'strokeDasharray',
13386 strokedashoffset: 'strokeDashoffset',
13387 'stroke-dashoffset': 'strokeDashoffset',
13388 strokelinecap: 'strokeLinecap',
13389 'stroke-linecap': 'strokeLinecap',
13390 strokelinejoin: 'strokeLinejoin',
13391 'stroke-linejoin': 'strokeLinejoin',
13392 strokemiterlimit: 'strokeMiterlimit',
13393 'stroke-miterlimit': 'strokeMiterlimit',
13394 strokewidth: 'strokeWidth',
13395 'stroke-width': 'strokeWidth',
13396 strokeopacity: 'strokeOpacity',
13397 'stroke-opacity': 'strokeOpacity',
13398 suppresscontenteditablewarning: 'suppressContentEditableWarning',
13399 suppresshydrationwarning: 'suppressHydrationWarning',
13400 surfacescale: 'surfaceScale',
13401 systemlanguage: 'systemLanguage',
13402 tablevalues: 'tableValues',
13403 targetx: 'targetX',
13404 targety: 'targetY',
13405 textanchor: 'textAnchor',
13406 'text-anchor': 'textAnchor',
13407 textdecoration: 'textDecoration',
13408 'text-decoration': 'textDecoration',
13409 textlength: 'textLength',
13410 textrendering: 'textRendering',
13411 'text-rendering': 'textRendering',
13412 to: 'to',
13413 transform: 'transform',
13414 'typeof': 'typeof',
13415 u1: 'u1',
13416 u2: 'u2',
13417 underlineposition: 'underlinePosition',
13418 'underline-position': 'underlinePosition',
13419 underlinethickness: 'underlineThickness',
13420 'underline-thickness': 'underlineThickness',
13421 unicode: 'unicode',
13422 unicodebidi: 'unicodeBidi',
13423 'unicode-bidi': 'unicodeBidi',
13424 unicoderange: 'unicodeRange',
13425 'unicode-range': 'unicodeRange',
13426 unitsperem: 'unitsPerEm',
13427 'units-per-em': 'unitsPerEm',
13428 unselectable: 'unselectable',
13429 valphabetic: 'vAlphabetic',
13430 'v-alphabetic': 'vAlphabetic',
13431 values: 'values',
13432 vectoreffect: 'vectorEffect',
13433 'vector-effect': 'vectorEffect',
13434 version: 'version',
13435 vertadvy: 'vertAdvY',
13436 'vert-adv-y': 'vertAdvY',
13437 vertoriginx: 'vertOriginX',
13438 'vert-origin-x': 'vertOriginX',
13439 vertoriginy: 'vertOriginY',
13440 'vert-origin-y': 'vertOriginY',
13441 vhanging: 'vHanging',
13442 'v-hanging': 'vHanging',
13443 videographic: 'vIdeographic',
13444 'v-ideographic': 'vIdeographic',
13445 viewbox: 'viewBox',
13446 viewtarget: 'viewTarget',
13447 visibility: 'visibility',
13448 vmathematical: 'vMathematical',
13449 'v-mathematical': 'vMathematical',
13450 vocab: 'vocab',
13451 widths: 'widths',
13452 wordspacing: 'wordSpacing',
13453 'word-spacing': 'wordSpacing',
13454 writingmode: 'writingMode',
13455 'writing-mode': 'writingMode',
13456 x1: 'x1',
13457 x2: 'x2',
13458 x: 'x',
13459 xchannelselector: 'xChannelSelector',
13460 xheight: 'xHeight',
13461 'x-height': 'xHeight',
13462 xlinkactuate: 'xlinkActuate',
13463 'xlink:actuate': 'xlinkActuate',
13464 xlinkarcrole: 'xlinkArcrole',
13465 'xlink:arcrole': 'xlinkArcrole',
13466 xlinkhref: 'xlinkHref',
13467 'xlink:href': 'xlinkHref',
13468 xlinkrole: 'xlinkRole',
13469 'xlink:role': 'xlinkRole',
13470 xlinkshow: 'xlinkShow',
13471 'xlink:show': 'xlinkShow',
13472 xlinktitle: 'xlinkTitle',
13473 'xlink:title': 'xlinkTitle',
13474 xlinktype: 'xlinkType',
13475 'xlink:type': 'xlinkType',
13476 xmlbase: 'xmlBase',
13477 'xml:base': 'xmlBase',
13478 xmllang: 'xmlLang',
13479 'xml:lang': 'xmlLang',
13480 xmlns: 'xmlns',
13481 'xml:space': 'xmlSpace',
13482 xmlnsxlink: 'xmlnsXlink',
13483 'xmlns:xlink': 'xmlnsXlink',
13484 xmlspace: 'xmlSpace',
13485 y1: 'y1',
13486 y2: 'y2',
13487 y: 'y',
13488 ychannelselector: 'yChannelSelector',
13489 z: 'z',
13490 zoomandpan: 'zoomAndPan'
13491};
13492
13493var ariaProperties = {
13494 'aria-current': 0, // state
13495 'aria-details': 0,
13496 'aria-disabled': 0, // state
13497 'aria-hidden': 0, // state
13498 'aria-invalid': 0, // state
13499 'aria-keyshortcuts': 0,
13500 'aria-label': 0,
13501 'aria-roledescription': 0,
13502 // Widget Attributes
13503 'aria-autocomplete': 0,
13504 'aria-checked': 0,
13505 'aria-expanded': 0,
13506 'aria-haspopup': 0,
13507 'aria-level': 0,
13508 'aria-modal': 0,
13509 'aria-multiline': 0,
13510 'aria-multiselectable': 0,
13511 'aria-orientation': 0,
13512 'aria-placeholder': 0,
13513 'aria-pressed': 0,
13514 'aria-readonly': 0,
13515 'aria-required': 0,
13516 'aria-selected': 0,
13517 'aria-sort': 0,
13518 'aria-valuemax': 0,
13519 'aria-valuemin': 0,
13520 'aria-valuenow': 0,
13521 'aria-valuetext': 0,
13522 // Live Region Attributes
13523 'aria-atomic': 0,
13524 'aria-busy': 0,
13525 'aria-live': 0,
13526 'aria-relevant': 0,
13527 // Drag-and-Drop Attributes
13528 'aria-dropeffect': 0,
13529 'aria-grabbed': 0,
13530 // Relationship Attributes
13531 'aria-activedescendant': 0,
13532 'aria-colcount': 0,
13533 'aria-colindex': 0,
13534 'aria-colspan': 0,
13535 'aria-controls': 0,
13536 'aria-describedby': 0,
13537 'aria-errormessage': 0,
13538 'aria-flowto': 0,
13539 'aria-labelledby': 0,
13540 'aria-owns': 0,
13541 'aria-posinset': 0,
13542 'aria-rowcount': 0,
13543 'aria-rowindex': 0,
13544 'aria-rowspan': 0,
13545 'aria-setsize': 0
13546};
13547
13548var warnedProperties = {};
13549var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13550var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13551
13552var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
13553
13554function getStackAddendum() {
13555 var stack = ReactDebugCurrentFrame.getStackAddendum();
13556 return stack != null ? stack : '';
13557}
13558
13559function validateProperty(tagName, name) {
13560 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
13561 return true;
13562 }
13563
13564 if (rARIACamel.test(name)) {
13565 var ariaName = 'aria-' + name.slice(4).toLowerCase();
13566 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
13567
13568 // If this is an aria-* attribute, but is not listed in the known DOM
13569 // DOM properties, then it is an invalid aria-* attribute.
13570 if (correctName == null) {
13571 warning_1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum());
13572 warnedProperties[name] = true;
13573 return true;
13574 }
13575 // aria-* attributes should be lowercase; suggest the lowercase version.
13576 if (name !== correctName) {
13577 warning_1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum());
13578 warnedProperties[name] = true;
13579 return true;
13580 }
13581 }
13582
13583 if (rARIA.test(name)) {
13584 var lowerCasedName = name.toLowerCase();
13585 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
13586
13587 // If this is an aria-* attribute, but is not listed in the known DOM
13588 // DOM properties, then it is an invalid aria-* attribute.
13589 if (standardName == null) {
13590 warnedProperties[name] = true;
13591 return false;
13592 }
13593 // aria-* attributes should be lowercase; suggest the lowercase version.
13594 if (name !== standardName) {
13595 warning_1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum());
13596 warnedProperties[name] = true;
13597 return true;
13598 }
13599 }
13600
13601 return true;
13602}
13603
13604function warnInvalidARIAProps(type, props) {
13605 var invalidProps = [];
13606
13607 for (var key in props) {
13608 var isValid = validateProperty(type, key);
13609 if (!isValid) {
13610 invalidProps.push(key);
13611 }
13612 }
13613
13614 var unknownPropString = invalidProps.map(function (prop) {
13615 return '`' + prop + '`';
13616 }).join(', ');
13617
13618 if (invalidProps.length === 1) {
13619 warning_1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13620 } else if (invalidProps.length > 1) {
13621 warning_1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum());
13622 }
13623}
13624
13625function validateProperties(type, props) {
13626 if (isCustomComponent(type, props)) {
13627 return;
13628 }
13629 warnInvalidARIAProps(type, props);
13630}
13631
13632var didWarnValueNull = false;
13633
13634function getStackAddendum$1() {
13635 var stack = ReactDebugCurrentFrame.getStackAddendum();
13636 return stack != null ? stack : '';
13637}
13638
13639function validateProperties$1(type, props) {
13640 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
13641 return;
13642 }
13643
13644 if (props != null && props.value === null && !didWarnValueNull) {
13645 didWarnValueNull = true;
13646 if (type === 'select' && props.multiple) {
13647 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());
13648 } else {
13649 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());
13650 }
13651 }
13652}
13653
13654function getStackAddendum$2() {
13655 var stack = ReactDebugCurrentFrame.getStackAddendum();
13656 return stack != null ? stack : '';
13657}
13658
13659var validateProperty$1 = function () {};
13660
13661{
13662 var warnedProperties$1 = {};
13663 var _hasOwnProperty = Object.prototype.hasOwnProperty;
13664 var EVENT_NAME_REGEX = /^on./;
13665 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
13666 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
13667 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
13668
13669 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
13670 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
13671 return true;
13672 }
13673
13674 var lowerCasedName = name.toLowerCase();
13675 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
13676 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.');
13677 warnedProperties$1[name] = true;
13678 return true;
13679 }
13680
13681 // We can't rely on the event system being injected on the server.
13682 if (canUseEventSystem) {
13683 if (registrationNameModules.hasOwnProperty(name)) {
13684 return true;
13685 }
13686 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
13687 if (registrationName != null) {
13688 warning_1(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2());
13689 warnedProperties$1[name] = true;
13690 return true;
13691 }
13692 if (EVENT_NAME_REGEX.test(name)) {
13693 warning_1(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2());
13694 warnedProperties$1[name] = true;
13695 return true;
13696 }
13697 } else if (EVENT_NAME_REGEX.test(name)) {
13698 // If no event plugins have been injected, we are in a server environment.
13699 // So we can't tell if the event name is correct for sure, but we can filter
13700 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
13701 if (INVALID_EVENT_NAME_REGEX.test(name)) {
13702 warning_1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$2());
13703 }
13704 warnedProperties$1[name] = true;
13705 return true;
13706 }
13707
13708 // Let the ARIA attribute hook validate ARIA attributes
13709 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
13710 return true;
13711 }
13712
13713 if (lowerCasedName === 'innerhtml') {
13714 warning_1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
13715 warnedProperties$1[name] = true;
13716 return true;
13717 }
13718
13719 if (lowerCasedName === 'aria') {
13720 warning_1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
13721 warnedProperties$1[name] = true;
13722 return true;
13723 }
13724
13725 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
13726 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());
13727 warnedProperties$1[name] = true;
13728 return true;
13729 }
13730
13731 if (typeof value === 'number' && isNaN(value)) {
13732 warning_1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2());
13733 warnedProperties$1[name] = true;
13734 return true;
13735 }
13736
13737 var propertyInfo = getPropertyInfo(name);
13738 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
13739
13740 // Known attributes should match the casing specified in the property config.
13741 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
13742 var standardName = possibleStandardNames[lowerCasedName];
13743 if (standardName !== name) {
13744 warning_1(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2());
13745 warnedProperties$1[name] = true;
13746 return true;
13747 }
13748 } else if (!isReserved && name !== lowerCasedName) {
13749 // Unknown attributes should have lowercase casing since that's how they
13750 // will be cased anyway with server rendering.
13751 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());
13752 warnedProperties$1[name] = true;
13753 return true;
13754 }
13755
13756 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13757 if (value) {
13758 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());
13759 } else {
13760 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());
13761 }
13762 warnedProperties$1[name] = true;
13763 return true;
13764 }
13765
13766 // Now that we've validated casing, do not validate
13767 // data types for reserved props
13768 if (isReserved) {
13769 return true;
13770 }
13771
13772 // Warn when a known attribute is a bad type
13773 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
13774 warnedProperties$1[name] = true;
13775 return false;
13776 }
13777
13778 return true;
13779 };
13780}
13781
13782var warnUnknownProperties = function (type, props, canUseEventSystem) {
13783 var unknownProps = [];
13784 for (var key in props) {
13785 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
13786 if (!isValid) {
13787 unknownProps.push(key);
13788 }
13789 }
13790
13791 var unknownPropString = unknownProps.map(function (prop) {
13792 return '`' + prop + '`';
13793 }).join(', ');
13794 if (unknownProps.length === 1) {
13795 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());
13796 } else if (unknownProps.length > 1) {
13797 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());
13798 }
13799};
13800
13801function validateProperties$2(type, props, canUseEventSystem) {
13802 if (isCustomComponent(type, props)) {
13803 return;
13804 }
13805 warnUnknownProperties(type, props, canUseEventSystem);
13806}
13807
13808// TODO: direct imports like some-package/src/* are bad. Fix me.
13809var getCurrentFiberOwnerName$2 = ReactDebugCurrentFiber.getCurrentFiberOwnerName;
13810var getCurrentFiberStackAddendum$3 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
13811
13812var didWarnInvalidHydration = false;
13813var didWarnShadyDOM = false;
13814
13815var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
13816var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
13817var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
13818var AUTOFOCUS = 'autoFocus';
13819var CHILDREN = 'children';
13820var STYLE = 'style';
13821var HTML = '__html';
13822
13823var HTML_NAMESPACE = Namespaces.html;
13824
13825
13826var getStack = emptyFunction_1.thatReturns('');
13827
13828var warnedUnknownTags = void 0;
13829var suppressHydrationWarning = void 0;
13830
13831var validatePropertiesInDevelopment = void 0;
13832var warnForTextDifference = void 0;
13833var warnForPropDifference = void 0;
13834var warnForExtraAttributes = void 0;
13835var warnForInvalidEventListener = void 0;
13836
13837var normalizeMarkupForTextOrAttribute = void 0;
13838var normalizeHTML = void 0;
13839
13840{
13841 getStack = getCurrentFiberStackAddendum$3;
13842
13843 warnedUnknownTags = {
13844 // Chrome is the only major browser not shipping <time>. But as of July
13845 // 2017 it intends to ship it due to widespread usage. We intentionally
13846 // *don't* warn for <time> even if it's unrecognized by Chrome because
13847 // it soon will be, and many apps have been using it anyway.
13848 time: true,
13849 // There are working polyfills for <dialog>. Let people use it.
13850 dialog: true
13851 };
13852
13853 validatePropertiesInDevelopment = function (type, props) {
13854 validateProperties(type, props);
13855 validateProperties$1(type, props);
13856 validateProperties$2(type, props, /* canUseEventSystem */true);
13857 };
13858
13859 // HTML parsing normalizes CR and CRLF to LF.
13860 // It also can turn \u0000 into \uFFFD inside attributes.
13861 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
13862 // If we have a mismatch, it might be caused by that.
13863 // We will still patch up in this case but not fire the warning.
13864 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
13865 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
13866
13867 normalizeMarkupForTextOrAttribute = function (markup) {
13868 var markupString = typeof markup === 'string' ? markup : '' + markup;
13869 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
13870 };
13871
13872 warnForTextDifference = function (serverText, clientText) {
13873 if (didWarnInvalidHydration) {
13874 return;
13875 }
13876 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
13877 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
13878 if (normalizedServerText === normalizedClientText) {
13879 return;
13880 }
13881 didWarnInvalidHydration = true;
13882 warning_1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
13883 };
13884
13885 warnForPropDifference = function (propName, serverValue, clientValue) {
13886 if (didWarnInvalidHydration) {
13887 return;
13888 }
13889 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
13890 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
13891 if (normalizedServerValue === normalizedClientValue) {
13892 return;
13893 }
13894 didWarnInvalidHydration = true;
13895 warning_1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
13896 };
13897
13898 warnForExtraAttributes = function (attributeNames) {
13899 if (didWarnInvalidHydration) {
13900 return;
13901 }
13902 didWarnInvalidHydration = true;
13903 var names = [];
13904 attributeNames.forEach(function (name) {
13905 names.push(name);
13906 });
13907 warning_1(false, 'Extra attributes from the server: %s', names);
13908 };
13909
13910 warnForInvalidEventListener = function (registrationName, listener) {
13911 if (listener === false) {
13912 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());
13913 } else {
13914 warning_1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum$3());
13915 }
13916 };
13917
13918 // Parse the HTML and read it back to normalize the HTML string so that it
13919 // can be used for comparison.
13920 normalizeHTML = function (parent, html) {
13921 // We could have created a separate document here to avoid
13922 // re-initializing custom elements if they exist. But this breaks
13923 // how <noscript> is being handled. So we use the same document.
13924 // See the discussion in https://github.com/facebook/react/pull/11157.
13925 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
13926 testElement.innerHTML = html;
13927 return testElement.innerHTML;
13928 };
13929}
13930
13931function ensureListeningTo(rootContainerElement, registrationName) {
13932 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
13933 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
13934 listenTo(registrationName, doc);
13935}
13936
13937function getOwnerDocumentFromRootContainer(rootContainerElement) {
13938 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
13939}
13940
13941// There are so many media events, it makes sense to just
13942// maintain a list rather than create a `trapBubbledEvent` for each
13943var mediaEvents = {
13944 topAbort: 'abort',
13945 topCanPlay: 'canplay',
13946 topCanPlayThrough: 'canplaythrough',
13947 topDurationChange: 'durationchange',
13948 topEmptied: 'emptied',
13949 topEncrypted: 'encrypted',
13950 topEnded: 'ended',
13951 topError: 'error',
13952 topLoadedData: 'loadeddata',
13953 topLoadedMetadata: 'loadedmetadata',
13954 topLoadStart: 'loadstart',
13955 topPause: 'pause',
13956 topPlay: 'play',
13957 topPlaying: 'playing',
13958 topProgress: 'progress',
13959 topRateChange: 'ratechange',
13960 topSeeked: 'seeked',
13961 topSeeking: 'seeking',
13962 topStalled: 'stalled',
13963 topSuspend: 'suspend',
13964 topTimeUpdate: 'timeupdate',
13965 topVolumeChange: 'volumechange',
13966 topWaiting: 'waiting'
13967};
13968
13969function trapClickOnNonInteractiveElement(node) {
13970 // Mobile Safari does not fire properly bubble click events on
13971 // non-interactive elements, which means delegated click listeners do not
13972 // fire. The workaround for this bug involves attaching an empty click
13973 // listener on the target node.
13974 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
13975 // Just set it using the onclick property so that we don't have to manage any
13976 // bookkeeping for it. Not sure if we need to clear it when the listener is
13977 // removed.
13978 // TODO: Only do this for the relevant Safaris maybe?
13979 node.onclick = emptyFunction_1;
13980}
13981
13982function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
13983 for (var propKey in nextProps) {
13984 if (!nextProps.hasOwnProperty(propKey)) {
13985 continue;
13986 }
13987 var nextProp = nextProps[propKey];
13988 if (propKey === STYLE) {
13989 {
13990 if (nextProp) {
13991 // Freeze the next style object so that we can assume it won't be
13992 // mutated. We have already warned for this in the past.
13993 Object.freeze(nextProp);
13994 }
13995 }
13996 // Relies on `updateStylesByID` not mutating `styleUpdates`.
13997 setValueForStyles(domElement, nextProp, getStack);
13998 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
13999 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14000 if (nextHtml != null) {
14001 setInnerHTML(domElement, nextHtml);
14002 }
14003 } else if (propKey === CHILDREN) {
14004 if (typeof nextProp === 'string') {
14005 // Avoid setting initial textContent when the text is empty. In IE11 setting
14006 // textContent on a <textarea> will cause the placeholder to not
14007 // show within the <textarea> until it has been focused and blurred again.
14008 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
14009 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
14010 if (canSetTextContent) {
14011 setTextContent(domElement, nextProp);
14012 }
14013 } else if (typeof nextProp === 'number') {
14014 setTextContent(domElement, '' + nextProp);
14015 }
14016 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14017 // Noop
14018 } else if (propKey === AUTOFOCUS) {
14019 // We polyfill it separately on the client during commit.
14020 // We blacklist it here rather than in the property list because we emit it in SSR.
14021 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14022 if (nextProp != null) {
14023 if (true && typeof nextProp !== 'function') {
14024 warnForInvalidEventListener(propKey, nextProp);
14025 }
14026 ensureListeningTo(rootContainerElement, propKey);
14027 }
14028 } else if (nextProp != null) {
14029 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
14030 }
14031 }
14032}
14033
14034function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
14035 // TODO: Handle wasCustomComponentTag
14036 for (var i = 0; i < updatePayload.length; i += 2) {
14037 var propKey = updatePayload[i];
14038 var propValue = updatePayload[i + 1];
14039 if (propKey === STYLE) {
14040 setValueForStyles(domElement, propValue, getStack);
14041 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14042 setInnerHTML(domElement, propValue);
14043 } else if (propKey === CHILDREN) {
14044 setTextContent(domElement, propValue);
14045 } else {
14046 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
14047 }
14048 }
14049}
14050
14051function createElement$1(type, props, rootContainerElement, parentNamespace) {
14052 var isCustomComponentTag = void 0;
14053
14054 // We create tags in the namespace of their parent container, except HTML
14055 // tags get no namespace.
14056 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
14057 var domElement = void 0;
14058 var namespaceURI = parentNamespace;
14059 if (namespaceURI === HTML_NAMESPACE) {
14060 namespaceURI = getIntrinsicNamespace(type);
14061 }
14062 if (namespaceURI === HTML_NAMESPACE) {
14063 {
14064 isCustomComponentTag = isCustomComponent(type, props);
14065 // Should this check be gated by parent namespace? Not sure we want to
14066 // allow <SVG> or <mATH>.
14067 warning_1(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type);
14068 }
14069
14070 if (type === 'script') {
14071 // Create the script via .innerHTML so its "parser-inserted" flag is
14072 // set to true and it does not execute
14073 var div = ownerDocument.createElement('div');
14074 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
14075 // This is guaranteed to yield a script element.
14076 var firstChild = div.firstChild;
14077 domElement = div.removeChild(firstChild);
14078 } else if (typeof props.is === 'string') {
14079 // $FlowIssue `createElement` should be updated for Web Components
14080 domElement = ownerDocument.createElement(type, { is: props.is });
14081 } else {
14082 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
14083 // See discussion in https://github.com/facebook/react/pull/6896
14084 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
14085 domElement = ownerDocument.createElement(type);
14086 }
14087 } else {
14088 domElement = ownerDocument.createElementNS(namespaceURI, type);
14089 }
14090
14091 {
14092 if (namespaceURI === HTML_NAMESPACE) {
14093 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
14094 warnedUnknownTags[type] = true;
14095 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);
14096 }
14097 }
14098 }
14099
14100 return domElement;
14101}
14102
14103function createTextNode$1(text, rootContainerElement) {
14104 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
14105}
14106
14107function setInitialProperties$1(domElement, tag, rawProps, rootContainerElement) {
14108 var isCustomComponentTag = isCustomComponent(tag, rawProps);
14109 {
14110 validatePropertiesInDevelopment(tag, rawProps);
14111 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14112 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14113 didWarnShadyDOM = true;
14114 }
14115 }
14116
14117 // TODO: Make sure that we check isMounted before firing any of these events.
14118 var props = void 0;
14119 switch (tag) {
14120 case 'iframe':
14121 case 'object':
14122 trapBubbledEvent('topLoad', 'load', domElement);
14123 props = rawProps;
14124 break;
14125 case 'video':
14126 case 'audio':
14127 // Create listener for each media event
14128 for (var event in mediaEvents) {
14129 if (mediaEvents.hasOwnProperty(event)) {
14130 trapBubbledEvent(event, mediaEvents[event], domElement);
14131 }
14132 }
14133 props = rawProps;
14134 break;
14135 case 'source':
14136 trapBubbledEvent('topError', 'error', domElement);
14137 props = rawProps;
14138 break;
14139 case 'img':
14140 case 'image':
14141 case 'link':
14142 trapBubbledEvent('topError', 'error', domElement);
14143 trapBubbledEvent('topLoad', 'load', domElement);
14144 props = rawProps;
14145 break;
14146 case 'form':
14147 trapBubbledEvent('topReset', 'reset', domElement);
14148 trapBubbledEvent('topSubmit', 'submit', domElement);
14149 props = rawProps;
14150 break;
14151 case 'details':
14152 trapBubbledEvent('topToggle', 'toggle', domElement);
14153 props = rawProps;
14154 break;
14155 case 'input':
14156 initWrapperState(domElement, rawProps);
14157 props = getHostProps(domElement, rawProps);
14158 trapBubbledEvent('topInvalid', 'invalid', domElement);
14159 // For controlled components we always need to ensure we're listening
14160 // to onChange. Even if there is no listener.
14161 ensureListeningTo(rootContainerElement, 'onChange');
14162 break;
14163 case 'option':
14164 validateProps(domElement, rawProps);
14165 props = getHostProps$1(domElement, rawProps);
14166 break;
14167 case 'select':
14168 initWrapperState$1(domElement, rawProps);
14169 props = getHostProps$2(domElement, rawProps);
14170 trapBubbledEvent('topInvalid', 'invalid', domElement);
14171 // For controlled components we always need to ensure we're listening
14172 // to onChange. Even if there is no listener.
14173 ensureListeningTo(rootContainerElement, 'onChange');
14174 break;
14175 case 'textarea':
14176 initWrapperState$2(domElement, rawProps);
14177 props = getHostProps$3(domElement, rawProps);
14178 trapBubbledEvent('topInvalid', 'invalid', domElement);
14179 // For controlled components we always need to ensure we're listening
14180 // to onChange. Even if there is no listener.
14181 ensureListeningTo(rootContainerElement, 'onChange');
14182 break;
14183 default:
14184 props = rawProps;
14185 }
14186
14187 assertValidProps(tag, props, getStack);
14188
14189 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
14190
14191 switch (tag) {
14192 case 'input':
14193 // TODO: Make sure we check if this is still unmounted or do any clean
14194 // up necessary since we never stop tracking anymore.
14195 track(domElement);
14196 postMountWrapper(domElement, rawProps);
14197 break;
14198 case 'textarea':
14199 // TODO: Make sure we check if this is still unmounted or do any clean
14200 // up necessary since we never stop tracking anymore.
14201 track(domElement);
14202 postMountWrapper$3(domElement, rawProps);
14203 break;
14204 case 'option':
14205 postMountWrapper$1(domElement, rawProps);
14206 break;
14207 case 'select':
14208 postMountWrapper$2(domElement, rawProps);
14209 break;
14210 default:
14211 if (typeof props.onClick === 'function') {
14212 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14213 trapClickOnNonInteractiveElement(domElement);
14214 }
14215 break;
14216 }
14217}
14218
14219// Calculate the diff between the two objects.
14220function diffProperties$1(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
14221 {
14222 validatePropertiesInDevelopment(tag, nextRawProps);
14223 }
14224
14225 var updatePayload = null;
14226
14227 var lastProps = void 0;
14228 var nextProps = void 0;
14229 switch (tag) {
14230 case 'input':
14231 lastProps = getHostProps(domElement, lastRawProps);
14232 nextProps = getHostProps(domElement, nextRawProps);
14233 updatePayload = [];
14234 break;
14235 case 'option':
14236 lastProps = getHostProps$1(domElement, lastRawProps);
14237 nextProps = getHostProps$1(domElement, nextRawProps);
14238 updatePayload = [];
14239 break;
14240 case 'select':
14241 lastProps = getHostProps$2(domElement, lastRawProps);
14242 nextProps = getHostProps$2(domElement, nextRawProps);
14243 updatePayload = [];
14244 break;
14245 case 'textarea':
14246 lastProps = getHostProps$3(domElement, lastRawProps);
14247 nextProps = getHostProps$3(domElement, nextRawProps);
14248 updatePayload = [];
14249 break;
14250 default:
14251 lastProps = lastRawProps;
14252 nextProps = nextRawProps;
14253 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
14254 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14255 trapClickOnNonInteractiveElement(domElement);
14256 }
14257 break;
14258 }
14259
14260 assertValidProps(tag, nextProps, getStack);
14261
14262 var propKey = void 0;
14263 var styleName = void 0;
14264 var styleUpdates = null;
14265 for (propKey in lastProps) {
14266 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
14267 continue;
14268 }
14269 if (propKey === STYLE) {
14270 var lastStyle = lastProps[propKey];
14271 for (styleName in lastStyle) {
14272 if (lastStyle.hasOwnProperty(styleName)) {
14273 if (!styleUpdates) {
14274 styleUpdates = {};
14275 }
14276 styleUpdates[styleName] = '';
14277 }
14278 }
14279 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
14280 // Noop. This is handled by the clear text mechanism.
14281 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14282 // Noop
14283 } else if (propKey === AUTOFOCUS) {
14284 // Noop. It doesn't work on updates anyway.
14285 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14286 // This is a special case. If any listener updates we need to ensure
14287 // that the "current" fiber pointer gets updated so we need a commit
14288 // to update this element.
14289 if (!updatePayload) {
14290 updatePayload = [];
14291 }
14292 } else {
14293 // For all other deleted properties we add it to the queue. We use
14294 // the whitelist in the commit phase instead.
14295 (updatePayload = updatePayload || []).push(propKey, null);
14296 }
14297 }
14298 for (propKey in nextProps) {
14299 var nextProp = nextProps[propKey];
14300 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
14301 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
14302 continue;
14303 }
14304 if (propKey === STYLE) {
14305 {
14306 if (nextProp) {
14307 // Freeze the next style object so that we can assume it won't be
14308 // mutated. We have already warned for this in the past.
14309 Object.freeze(nextProp);
14310 }
14311 }
14312 if (lastProp) {
14313 // Unset styles on `lastProp` but not on `nextProp`.
14314 for (styleName in lastProp) {
14315 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
14316 if (!styleUpdates) {
14317 styleUpdates = {};
14318 }
14319 styleUpdates[styleName] = '';
14320 }
14321 }
14322 // Update styles that changed since `lastProp`.
14323 for (styleName in nextProp) {
14324 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
14325 if (!styleUpdates) {
14326 styleUpdates = {};
14327 }
14328 styleUpdates[styleName] = nextProp[styleName];
14329 }
14330 }
14331 } else {
14332 // Relies on `updateStylesByID` not mutating `styleUpdates`.
14333 if (!styleUpdates) {
14334 if (!updatePayload) {
14335 updatePayload = [];
14336 }
14337 updatePayload.push(propKey, styleUpdates);
14338 }
14339 styleUpdates = nextProp;
14340 }
14341 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14342 var nextHtml = nextProp ? nextProp[HTML] : undefined;
14343 var lastHtml = lastProp ? lastProp[HTML] : undefined;
14344 if (nextHtml != null) {
14345 if (lastHtml !== nextHtml) {
14346 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
14347 }
14348 } else {
14349 // TODO: It might be too late to clear this if we have children
14350 // inserted already.
14351 }
14352 } else if (propKey === CHILDREN) {
14353 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
14354 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
14355 }
14356 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
14357 // Noop
14358 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14359 if (nextProp != null) {
14360 // We eagerly listen to this even though we haven't committed yet.
14361 if (true && typeof nextProp !== 'function') {
14362 warnForInvalidEventListener(propKey, nextProp);
14363 }
14364 ensureListeningTo(rootContainerElement, propKey);
14365 }
14366 if (!updatePayload && lastProp !== nextProp) {
14367 // This is a special case. If any listener updates we need to ensure
14368 // that the "current" props pointer gets updated so we need a commit
14369 // to update this element.
14370 updatePayload = [];
14371 }
14372 } else {
14373 // For any other property we always add it to the queue and then we
14374 // filter it out using the whitelist during the commit.
14375 (updatePayload = updatePayload || []).push(propKey, nextProp);
14376 }
14377 }
14378 if (styleUpdates) {
14379 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
14380 }
14381 return updatePayload;
14382}
14383
14384// Apply the diff.
14385function updateProperties$1(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
14386 // Update checked *before* name.
14387 // In the middle of an update, it is possible to have multiple checked.
14388 // When a checked radio tries to change name, browser makes another radio's checked false.
14389 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
14390 updateChecked(domElement, nextRawProps);
14391 }
14392
14393 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
14394 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
14395 // Apply the diff.
14396 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
14397
14398 // TODO: Ensure that an update gets scheduled if any of the special props
14399 // changed.
14400 switch (tag) {
14401 case 'input':
14402 // Update the wrapper around inputs *after* updating props. This has to
14403 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
14404 // raise warnings and prevent the new value from being assigned.
14405 updateWrapper(domElement, nextRawProps);
14406 break;
14407 case 'textarea':
14408 updateWrapper$1(domElement, nextRawProps);
14409 break;
14410 case 'select':
14411 // <select> value update needs to occur after <option> children
14412 // reconciliation
14413 postUpdateWrapper(domElement, nextRawProps);
14414 break;
14415 }
14416}
14417
14418function getPossibleStandardName(propName) {
14419 {
14420 var lowerCasedName = propName.toLowerCase();
14421 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
14422 return null;
14423 }
14424 return possibleStandardNames[lowerCasedName] || null;
14425 }
14426 return null;
14427}
14428
14429function diffHydratedProperties$1(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
14430 var isCustomComponentTag = void 0;
14431 var extraAttributeNames = void 0;
14432
14433 {
14434 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
14435 isCustomComponentTag = isCustomComponent(tag, rawProps);
14436 validatePropertiesInDevelopment(tag, rawProps);
14437 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
14438 warning_1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName$2() || 'A component');
14439 didWarnShadyDOM = true;
14440 }
14441 }
14442
14443 // TODO: Make sure that we check isMounted before firing any of these events.
14444 switch (tag) {
14445 case 'iframe':
14446 case 'object':
14447 trapBubbledEvent('topLoad', 'load', domElement);
14448 break;
14449 case 'video':
14450 case 'audio':
14451 // Create listener for each media event
14452 for (var event in mediaEvents) {
14453 if (mediaEvents.hasOwnProperty(event)) {
14454 trapBubbledEvent(event, mediaEvents[event], domElement);
14455 }
14456 }
14457 break;
14458 case 'source':
14459 trapBubbledEvent('topError', 'error', domElement);
14460 break;
14461 case 'img':
14462 case 'image':
14463 case 'link':
14464 trapBubbledEvent('topError', 'error', domElement);
14465 trapBubbledEvent('topLoad', 'load', domElement);
14466 break;
14467 case 'form':
14468 trapBubbledEvent('topReset', 'reset', domElement);
14469 trapBubbledEvent('topSubmit', 'submit', domElement);
14470 break;
14471 case 'details':
14472 trapBubbledEvent('topToggle', 'toggle', domElement);
14473 break;
14474 case 'input':
14475 initWrapperState(domElement, rawProps);
14476 trapBubbledEvent('topInvalid', 'invalid', domElement);
14477 // For controlled components we always need to ensure we're listening
14478 // to onChange. Even if there is no listener.
14479 ensureListeningTo(rootContainerElement, 'onChange');
14480 break;
14481 case 'option':
14482 validateProps(domElement, rawProps);
14483 break;
14484 case 'select':
14485 initWrapperState$1(domElement, rawProps);
14486 trapBubbledEvent('topInvalid', 'invalid', domElement);
14487 // For controlled components we always need to ensure we're listening
14488 // to onChange. Even if there is no listener.
14489 ensureListeningTo(rootContainerElement, 'onChange');
14490 break;
14491 case 'textarea':
14492 initWrapperState$2(domElement, rawProps);
14493 trapBubbledEvent('topInvalid', 'invalid', domElement);
14494 // For controlled components we always need to ensure we're listening
14495 // to onChange. Even if there is no listener.
14496 ensureListeningTo(rootContainerElement, 'onChange');
14497 break;
14498 }
14499
14500 assertValidProps(tag, rawProps, getStack);
14501
14502 {
14503 extraAttributeNames = new Set();
14504 var attributes = domElement.attributes;
14505 for (var i = 0; i < attributes.length; i++) {
14506 var name = attributes[i].name.toLowerCase();
14507 switch (name) {
14508 // Built-in SSR attribute is whitelisted
14509 case 'data-reactroot':
14510 break;
14511 // Controlled attributes are not validated
14512 // TODO: Only ignore them on controlled tags.
14513 case 'value':
14514 break;
14515 case 'checked':
14516 break;
14517 case 'selected':
14518 break;
14519 default:
14520 // Intentionally use the original name.
14521 // See discussion in https://github.com/facebook/react/pull/10676.
14522 extraAttributeNames.add(attributes[i].name);
14523 }
14524 }
14525 }
14526
14527 var updatePayload = null;
14528 for (var propKey in rawProps) {
14529 if (!rawProps.hasOwnProperty(propKey)) {
14530 continue;
14531 }
14532 var nextProp = rawProps[propKey];
14533 if (propKey === CHILDREN) {
14534 // For text content children we compare against textContent. This
14535 // might match additional HTML that is hidden when we read it using
14536 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
14537 // satisfies our requirement. Our requirement is not to produce perfect
14538 // HTML and attributes. Ideally we should preserve structure but it's
14539 // ok not to if the visible content is still enough to indicate what
14540 // even listeners these nodes might be wired up to.
14541 // TODO: Warn if there is more than a single textNode as a child.
14542 // TODO: Should we use domElement.firstChild.nodeValue to compare?
14543 if (typeof nextProp === 'string') {
14544 if (domElement.textContent !== nextProp) {
14545 if (true && !suppressHydrationWarning) {
14546 warnForTextDifference(domElement.textContent, nextProp);
14547 }
14548 updatePayload = [CHILDREN, nextProp];
14549 }
14550 } else if (typeof nextProp === 'number') {
14551 if (domElement.textContent !== '' + nextProp) {
14552 if (true && !suppressHydrationWarning) {
14553 warnForTextDifference(domElement.textContent, nextProp);
14554 }
14555 updatePayload = [CHILDREN, '' + nextProp];
14556 }
14557 }
14558 } else if (registrationNameModules.hasOwnProperty(propKey)) {
14559 if (nextProp != null) {
14560 if (true && typeof nextProp !== 'function') {
14561 warnForInvalidEventListener(propKey, nextProp);
14562 }
14563 ensureListeningTo(rootContainerElement, propKey);
14564 }
14565 } else if (true &&
14566 // Convince Flow we've calculated it (it's DEV-only in this method.)
14567 typeof isCustomComponentTag === 'boolean') {
14568 // Validate that the properties correspond to their expected values.
14569 var serverValue = void 0;
14570 var propertyInfo = getPropertyInfo(propKey);
14571 if (suppressHydrationWarning) {
14572 // Don't bother comparing. We're ignoring all these warnings.
14573 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
14574 // Controlled attributes are not validated
14575 // TODO: Only ignore them on controlled tags.
14576 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
14577 // Noop
14578 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
14579 var rawHtml = nextProp ? nextProp[HTML] || '' : '';
14580 var serverHTML = domElement.innerHTML;
14581 var expectedHTML = normalizeHTML(domElement, rawHtml);
14582 if (expectedHTML !== serverHTML) {
14583 warnForPropDifference(propKey, serverHTML, expectedHTML);
14584 }
14585 } else if (propKey === STYLE) {
14586 // $FlowFixMe - Should be inferred as not undefined.
14587 extraAttributeNames['delete'](propKey);
14588 var expectedStyle = createDangerousStringForStyles(nextProp);
14589 serverValue = domElement.getAttribute('style');
14590 if (expectedStyle !== serverValue) {
14591 warnForPropDifference(propKey, serverValue, expectedStyle);
14592 }
14593 } else if (isCustomComponentTag) {
14594 // $FlowFixMe - Should be inferred as not undefined.
14595 extraAttributeNames['delete'](propKey.toLowerCase());
14596 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14597
14598 if (nextProp !== serverValue) {
14599 warnForPropDifference(propKey, serverValue, nextProp);
14600 }
14601 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
14602 var isMismatchDueToBadCasing = false;
14603 if (propertyInfo !== null) {
14604 // $FlowFixMe - Should be inferred as not undefined.
14605 extraAttributeNames['delete'](propertyInfo.attributeName);
14606 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
14607 } else {
14608 var ownNamespace = parentNamespace;
14609 if (ownNamespace === HTML_NAMESPACE) {
14610 ownNamespace = getIntrinsicNamespace(tag);
14611 }
14612 if (ownNamespace === HTML_NAMESPACE) {
14613 // $FlowFixMe - Should be inferred as not undefined.
14614 extraAttributeNames['delete'](propKey.toLowerCase());
14615 } else {
14616 var standardName = getPossibleStandardName(propKey);
14617 if (standardName !== null && standardName !== propKey) {
14618 // If an SVG prop is supplied with bad casing, it will
14619 // be successfully parsed from HTML, but will produce a mismatch
14620 // (and would be incorrectly rendered on the client).
14621 // However, we already warn about bad casing elsewhere.
14622 // So we'll skip the misleading extra mismatch warning in this case.
14623 isMismatchDueToBadCasing = true;
14624 // $FlowFixMe - Should be inferred as not undefined.
14625 extraAttributeNames['delete'](standardName);
14626 }
14627 // $FlowFixMe - Should be inferred as not undefined.
14628 extraAttributeNames['delete'](propKey);
14629 }
14630 serverValue = getValueForAttribute(domElement, propKey, nextProp);
14631 }
14632
14633 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
14634 warnForPropDifference(propKey, serverValue, nextProp);
14635 }
14636 }
14637 }
14638 }
14639
14640 {
14641 // $FlowFixMe - Should be inferred as not undefined.
14642 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
14643 // $FlowFixMe - Should be inferred as not undefined.
14644 warnForExtraAttributes(extraAttributeNames);
14645 }
14646 }
14647
14648 switch (tag) {
14649 case 'input':
14650 // TODO: Make sure we check if this is still unmounted or do any clean
14651 // up necessary since we never stop tracking anymore.
14652 track(domElement);
14653 postMountWrapper(domElement, rawProps);
14654 break;
14655 case 'textarea':
14656 // TODO: Make sure we check if this is still unmounted or do any clean
14657 // up necessary since we never stop tracking anymore.
14658 track(domElement);
14659 postMountWrapper$3(domElement, rawProps);
14660 break;
14661 case 'select':
14662 case 'option':
14663 // For input and textarea we current always set the value property at
14664 // post mount to force it to diverge from attributes. However, for
14665 // option and select we don't quite do the same thing and select
14666 // is not resilient to the DOM state changing so we don't do that here.
14667 // TODO: Consider not doing this for input and textarea.
14668 break;
14669 default:
14670 if (typeof rawProps.onClick === 'function') {
14671 // TODO: This cast may not be sound for SVG, MathML or custom elements.
14672 trapClickOnNonInteractiveElement(domElement);
14673 }
14674 break;
14675 }
14676
14677 return updatePayload;
14678}
14679
14680function diffHydratedText$1(textNode, text) {
14681 var isDifferent = textNode.nodeValue !== text;
14682 return isDifferent;
14683}
14684
14685function warnForUnmatchedText$1(textNode, text) {
14686 {
14687 warnForTextDifference(textNode.nodeValue, text);
14688 }
14689}
14690
14691function warnForDeletedHydratableElement$1(parentNode, child) {
14692 {
14693 if (didWarnInvalidHydration) {
14694 return;
14695 }
14696 didWarnInvalidHydration = true;
14697 warning_1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
14698 }
14699}
14700
14701function warnForDeletedHydratableText$1(parentNode, child) {
14702 {
14703 if (didWarnInvalidHydration) {
14704 return;
14705 }
14706 didWarnInvalidHydration = true;
14707 warning_1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
14708 }
14709}
14710
14711function warnForInsertedHydratedElement$1(parentNode, tag, props) {
14712 {
14713 if (didWarnInvalidHydration) {
14714 return;
14715 }
14716 didWarnInvalidHydration = true;
14717 warning_1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
14718 }
14719}
14720
14721function warnForInsertedHydratedText$1(parentNode, text) {
14722 {
14723 if (text === '') {
14724 // We expect to insert empty text nodes since they're not represented in
14725 // the HTML.
14726 // TODO: Remove this special case if we can just avoid inserting empty
14727 // text nodes.
14728 return;
14729 }
14730 if (didWarnInvalidHydration) {
14731 return;
14732 }
14733 didWarnInvalidHydration = true;
14734 warning_1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
14735 }
14736}
14737
14738function restoreControlledState$1(domElement, tag, props) {
14739 switch (tag) {
14740 case 'input':
14741 restoreControlledState(domElement, props);
14742 return;
14743 case 'textarea':
14744 restoreControlledState$3(domElement, props);
14745 return;
14746 case 'select':
14747 restoreControlledState$2(domElement, props);
14748 return;
14749 }
14750}
14751
14752var ReactDOMFiberComponent = Object.freeze({
14753 createElement: createElement$1,
14754 createTextNode: createTextNode$1,
14755 setInitialProperties: setInitialProperties$1,
14756 diffProperties: diffProperties$1,
14757 updateProperties: updateProperties$1,
14758 diffHydratedProperties: diffHydratedProperties$1,
14759 diffHydratedText: diffHydratedText$1,
14760 warnForUnmatchedText: warnForUnmatchedText$1,
14761 warnForDeletedHydratableElement: warnForDeletedHydratableElement$1,
14762 warnForDeletedHydratableText: warnForDeletedHydratableText$1,
14763 warnForInsertedHydratedElement: warnForInsertedHydratedElement$1,
14764 warnForInsertedHydratedText: warnForInsertedHydratedText$1,
14765 restoreControlledState: restoreControlledState$1
14766});
14767
14768// TODO: direct imports like some-package/src/* are bad. Fix me.
14769var getCurrentFiberStackAddendum$6 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum;
14770
14771var validateDOMNesting = emptyFunction_1;
14772
14773{
14774 // This validation code was written based on the HTML5 parsing spec:
14775 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14776 //
14777 // Note: this does not catch all invalid nesting, nor does it try to (as it's
14778 // not clear what practical benefit doing so provides); instead, we warn only
14779 // for cases where the parser will give a parse tree differing from what React
14780 // intended. For example, <b><div></div></b> is invalid but we don't warn
14781 // because it still parses correctly; we do warn for other cases like nested
14782 // <p> tags where the beginning of the second element implicitly closes the
14783 // first, causing a confusing mess.
14784
14785 // https://html.spec.whatwg.org/multipage/syntax.html#special
14786 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'];
14787
14788 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
14789 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
14790
14791 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
14792 // TODO: Distinguish by namespace here -- for <title>, including it here
14793 // errs on the side of fewer warnings
14794 'foreignObject', 'desc', 'title'];
14795
14796 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
14797 var buttonScopeTags = inScopeTags.concat(['button']);
14798
14799 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
14800 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
14801
14802 var emptyAncestorInfo = {
14803 current: null,
14804
14805 formTag: null,
14806 aTagInScope: null,
14807 buttonTagInScope: null,
14808 nobrTagInScope: null,
14809 pTagInButtonScope: null,
14810
14811 listItemTagAutoclosing: null,
14812 dlItemTagAutoclosing: null
14813 };
14814
14815 var updatedAncestorInfo$1 = function (oldInfo, tag, instance) {
14816 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
14817 var info = { tag: tag, instance: instance };
14818
14819 if (inScopeTags.indexOf(tag) !== -1) {
14820 ancestorInfo.aTagInScope = null;
14821 ancestorInfo.buttonTagInScope = null;
14822 ancestorInfo.nobrTagInScope = null;
14823 }
14824 if (buttonScopeTags.indexOf(tag) !== -1) {
14825 ancestorInfo.pTagInButtonScope = null;
14826 }
14827
14828 // See rules for 'li', 'dd', 'dt' start tags in
14829 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14830 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
14831 ancestorInfo.listItemTagAutoclosing = null;
14832 ancestorInfo.dlItemTagAutoclosing = null;
14833 }
14834
14835 ancestorInfo.current = info;
14836
14837 if (tag === 'form') {
14838 ancestorInfo.formTag = info;
14839 }
14840 if (tag === 'a') {
14841 ancestorInfo.aTagInScope = info;
14842 }
14843 if (tag === 'button') {
14844 ancestorInfo.buttonTagInScope = info;
14845 }
14846 if (tag === 'nobr') {
14847 ancestorInfo.nobrTagInScope = info;
14848 }
14849 if (tag === 'p') {
14850 ancestorInfo.pTagInButtonScope = info;
14851 }
14852 if (tag === 'li') {
14853 ancestorInfo.listItemTagAutoclosing = info;
14854 }
14855 if (tag === 'dd' || tag === 'dt') {
14856 ancestorInfo.dlItemTagAutoclosing = info;
14857 }
14858
14859 return ancestorInfo;
14860 };
14861
14862 /**
14863 * Returns whether
14864 */
14865 var isTagValidWithParent = function (tag, parentTag) {
14866 // First, let's check if we're in an unusual parsing mode...
14867 switch (parentTag) {
14868 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
14869 case 'select':
14870 return tag === 'option' || tag === 'optgroup' || tag === '#text';
14871 case 'optgroup':
14872 return tag === 'option' || tag === '#text';
14873 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
14874 // but
14875 case 'option':
14876 return tag === '#text';
14877 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
14878 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
14879 // No special behavior since these rules fall back to "in body" mode for
14880 // all except special table nodes which cause bad parsing behavior anyway.
14881
14882 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
14883 case 'tr':
14884 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
14885 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
14886 case 'tbody':
14887 case 'thead':
14888 case 'tfoot':
14889 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
14890 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
14891 case 'colgroup':
14892 return tag === 'col' || tag === 'template';
14893 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
14894 case 'table':
14895 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
14896 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
14897 case 'head':
14898 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
14899 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
14900 case 'html':
14901 return tag === 'head' || tag === 'body';
14902 case '#document':
14903 return tag === 'html';
14904 }
14905
14906 // Probably in the "in body" parsing mode, so we outlaw only tag combos
14907 // where the parsing rules cause implicit opens or closes to be added.
14908 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
14909 switch (tag) {
14910 case 'h1':
14911 case 'h2':
14912 case 'h3':
14913 case 'h4':
14914 case 'h5':
14915 case 'h6':
14916 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
14917
14918 case 'rp':
14919 case 'rt':
14920 return impliedEndTags.indexOf(parentTag) === -1;
14921
14922 case 'body':
14923 case 'caption':
14924 case 'col':
14925 case 'colgroup':
14926 case 'frame':
14927 case 'head':
14928 case 'html':
14929 case 'tbody':
14930 case 'td':
14931 case 'tfoot':
14932 case 'th':
14933 case 'thead':
14934 case 'tr':
14935 // These tags are only valid with a few parents that have special child
14936 // parsing rules -- if we're down here, then none of those matched and
14937 // so we allow it only if we don't know what the parent is, as all other
14938 // cases are invalid.
14939 return parentTag == null;
14940 }
14941
14942 return true;
14943 };
14944
14945 /**
14946 * Returns whether
14947 */
14948 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
14949 switch (tag) {
14950 case 'address':
14951 case 'article':
14952 case 'aside':
14953 case 'blockquote':
14954 case 'center':
14955 case 'details':
14956 case 'dialog':
14957 case 'dir':
14958 case 'div':
14959 case 'dl':
14960 case 'fieldset':
14961 case 'figcaption':
14962 case 'figure':
14963 case 'footer':
14964 case 'header':
14965 case 'hgroup':
14966 case 'main':
14967 case 'menu':
14968 case 'nav':
14969 case 'ol':
14970 case 'p':
14971 case 'section':
14972 case 'summary':
14973 case 'ul':
14974 case 'pre':
14975 case 'listing':
14976 case 'table':
14977 case 'hr':
14978 case 'xmp':
14979 case 'h1':
14980 case 'h2':
14981 case 'h3':
14982 case 'h4':
14983 case 'h5':
14984 case 'h6':
14985 return ancestorInfo.pTagInButtonScope;
14986
14987 case 'form':
14988 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
14989
14990 case 'li':
14991 return ancestorInfo.listItemTagAutoclosing;
14992
14993 case 'dd':
14994 case 'dt':
14995 return ancestorInfo.dlItemTagAutoclosing;
14996
14997 case 'button':
14998 return ancestorInfo.buttonTagInScope;
14999
15000 case 'a':
15001 // Spec says something about storing a list of markers, but it sounds
15002 // equivalent to this check.
15003 return ancestorInfo.aTagInScope;
15004
15005 case 'nobr':
15006 return ancestorInfo.nobrTagInScope;
15007 }
15008
15009 return null;
15010 };
15011
15012 var didWarn = {};
15013
15014 validateDOMNesting = function (childTag, childText, ancestorInfo) {
15015 ancestorInfo = ancestorInfo || emptyAncestorInfo;
15016 var parentInfo = ancestorInfo.current;
15017 var parentTag = parentInfo && parentInfo.tag;
15018
15019 if (childText != null) {
15020 warning_1(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null');
15021 childTag = '#text';
15022 }
15023
15024 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
15025 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
15026 var invalidParentOrAncestor = invalidParent || invalidAncestor;
15027 if (!invalidParentOrAncestor) {
15028 return;
15029 }
15030
15031 var ancestorTag = invalidParentOrAncestor.tag;
15032 var addendum = getCurrentFiberStackAddendum$6();
15033
15034 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
15035 if (didWarn[warnKey]) {
15036 return;
15037 }
15038 didWarn[warnKey] = true;
15039
15040 var tagDisplayName = childTag;
15041 var whitespaceInfo = '';
15042 if (childTag === '#text') {
15043 if (/\S/.test(childText)) {
15044 tagDisplayName = 'Text nodes';
15045 } else {
15046 tagDisplayName = 'Whitespace text nodes';
15047 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
15048 }
15049 } else {
15050 tagDisplayName = '<' + childTag + '>';
15051 }
15052
15053 if (invalidParent) {
15054 var info = '';
15055 if (ancestorTag === 'table' && childTag === 'tr') {
15056 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
15057 }
15058 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
15059 } else {
15060 warning_1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
15061 }
15062 };
15063
15064 // TODO: turn this into a named export
15065 validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo$1;
15066}
15067
15068var validateDOMNesting$1 = validateDOMNesting;
15069
15070// TODO: This type is shared between the reconciler and ReactDOM, but will
15071// eventually be lifted out to the renderer.
15072
15073// TODO: direct imports like some-package/src/* are bad. Fix me.
15074var createElement = createElement$1;
15075var createTextNode = createTextNode$1;
15076var setInitialProperties = setInitialProperties$1;
15077var diffProperties = diffProperties$1;
15078var updateProperties = updateProperties$1;
15079var diffHydratedProperties = diffHydratedProperties$1;
15080var diffHydratedText = diffHydratedText$1;
15081var warnForUnmatchedText = warnForUnmatchedText$1;
15082var warnForDeletedHydratableElement = warnForDeletedHydratableElement$1;
15083var warnForDeletedHydratableText = warnForDeletedHydratableText$1;
15084var warnForInsertedHydratedElement = warnForInsertedHydratedElement$1;
15085var warnForInsertedHydratedText = warnForInsertedHydratedText$1;
15086var updatedAncestorInfo = validateDOMNesting$1.updatedAncestorInfo;
15087var precacheFiberNode = precacheFiberNode$1;
15088var updateFiberProps = updateFiberProps$1;
15089
15090
15091var SUPPRESS_HYDRATION_WARNING = void 0;
15092var topLevelUpdateWarnings = void 0;
15093var warnOnInvalidCallback = void 0;
15094var didWarnAboutUnstableCreatePortal = false;
15095
15096{
15097 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
15098 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') {
15099 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');
15100 }
15101
15102 topLevelUpdateWarnings = function (container) {
15103 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
15104 var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
15105 if (hostInstance) {
15106 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.');
15107 }
15108 }
15109
15110 var isRootRenderedBySomeReact = !!container._reactRootContainer;
15111 var rootEl = getReactRootElementInContainer(container);
15112 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
15113
15114 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.');
15115
15116 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.');
15117 };
15118
15119 warnOnInvalidCallback = function (callback, callerName) {
15120 warning_1(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
15121 };
15122}
15123
15124injection$2.injectFiberControlledHostComponent(ReactDOMFiberComponent);
15125
15126var eventsEnabled = null;
15127var selectionInformation = null;
15128
15129function ReactBatch(root) {
15130 var expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
15131 this._expirationTime = expirationTime;
15132 this._root = root;
15133 this._next = null;
15134 this._callbacks = null;
15135 this._didComplete = false;
15136 this._hasChildren = false;
15137 this._children = null;
15138 this._defer = true;
15139}
15140ReactBatch.prototype.render = function (children) {
15141 !this._defer ? invariant_1(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
15142 this._hasChildren = true;
15143 this._children = children;
15144 var internalRoot = this._root._internalRoot;
15145 var expirationTime = this._expirationTime;
15146 var work = new ReactWork();
15147 DOMRenderer.updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
15148 return work;
15149};
15150ReactBatch.prototype.then = function (onComplete) {
15151 if (this._didComplete) {
15152 onComplete();
15153 return;
15154 }
15155 var callbacks = this._callbacks;
15156 if (callbacks === null) {
15157 callbacks = this._callbacks = [];
15158 }
15159 callbacks.push(onComplete);
15160};
15161ReactBatch.prototype.commit = function () {
15162 var internalRoot = this._root._internalRoot;
15163 var firstBatch = internalRoot.firstBatch;
15164 !(this._defer && firstBatch !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15165
15166 if (!this._hasChildren) {
15167 // This batch is empty. Return.
15168 this._next = null;
15169 this._defer = false;
15170 return;
15171 }
15172
15173 var expirationTime = this._expirationTime;
15174
15175 // Ensure this is the first batch in the list.
15176 if (firstBatch !== this) {
15177 // This batch is not the earliest batch. We need to move it to the front.
15178 // Update its expiration time to be the expiration time of the earliest
15179 // batch, so that we can flush it without flushing the other batches.
15180 if (this._hasChildren) {
15181 expirationTime = this._expirationTime = firstBatch._expirationTime;
15182 // Rendering this batch again ensures its children will be the final state
15183 // when we flush (updates are processed in insertion order: last
15184 // update wins).
15185 // TODO: This forces a restart. Should we print a warning?
15186 this.render(this._children);
15187 }
15188
15189 // Remove the batch from the list.
15190 var previous = null;
15191 var batch = firstBatch;
15192 while (batch !== this) {
15193 previous = batch;
15194 batch = batch._next;
15195 }
15196 !(previous !== null) ? invariant_1(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
15197 previous._next = batch._next;
15198
15199 // Add it to the front.
15200 this._next = firstBatch;
15201 firstBatch = internalRoot.firstBatch = this;
15202 }
15203
15204 // Synchronously flush all the work up to this batch's expiration time.
15205 this._defer = false;
15206 DOMRenderer.flushRoot(internalRoot, expirationTime);
15207
15208 // Pop the batch from the list.
15209 var next = this._next;
15210 this._next = null;
15211 firstBatch = internalRoot.firstBatch = next;
15212
15213 // Append the next earliest batch's children to the update queue.
15214 if (firstBatch !== null && firstBatch._hasChildren) {
15215 firstBatch.render(firstBatch._children);
15216 }
15217};
15218ReactBatch.prototype._onComplete = function () {
15219 if (this._didComplete) {
15220 return;
15221 }
15222 this._didComplete = true;
15223 var callbacks = this._callbacks;
15224 if (callbacks === null) {
15225 return;
15226 }
15227 // TODO: Error handling.
15228 for (var i = 0; i < callbacks.length; i++) {
15229 var _callback = callbacks[i];
15230 _callback();
15231 }
15232};
15233
15234function ReactWork() {
15235 this._callbacks = null;
15236 this._didCommit = false;
15237 // TODO: Avoid need to bind by replacing callbacks in the update queue with
15238 // list of Work objects.
15239 this._onCommit = this._onCommit.bind(this);
15240}
15241ReactWork.prototype.then = function (onCommit) {
15242 if (this._didCommit) {
15243 onCommit();
15244 return;
15245 }
15246 var callbacks = this._callbacks;
15247 if (callbacks === null) {
15248 callbacks = this._callbacks = [];
15249 }
15250 callbacks.push(onCommit);
15251};
15252ReactWork.prototype._onCommit = function () {
15253 if (this._didCommit) {
15254 return;
15255 }
15256 this._didCommit = true;
15257 var callbacks = this._callbacks;
15258 if (callbacks === null) {
15259 return;
15260 }
15261 // TODO: Error handling.
15262 for (var i = 0; i < callbacks.length; i++) {
15263 var _callback2 = callbacks[i];
15264 !(typeof _callback2 === 'function') ? invariant_1(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
15265 _callback2();
15266 }
15267};
15268
15269function ReactRoot(container, isAsync, hydrate) {
15270 var root = DOMRenderer.createContainer(container, isAsync, hydrate);
15271 this._internalRoot = root;
15272}
15273ReactRoot.prototype.render = function (children, callback) {
15274 var root = this._internalRoot;
15275 var work = new ReactWork();
15276 callback = callback === undefined ? null : callback;
15277 {
15278 warnOnInvalidCallback(callback, 'render');
15279 }
15280 if (callback !== null) {
15281 work.then(callback);
15282 }
15283 DOMRenderer.updateContainer(children, root, null, work._onCommit);
15284 return work;
15285};
15286ReactRoot.prototype.unmount = function (callback) {
15287 var root = this._internalRoot;
15288 var work = new ReactWork();
15289 callback = callback === undefined ? null : callback;
15290 {
15291 warnOnInvalidCallback(callback, 'render');
15292 }
15293 if (callback !== null) {
15294 work.then(callback);
15295 }
15296 DOMRenderer.updateContainer(null, root, null, work._onCommit);
15297 return work;
15298};
15299ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
15300 var root = this._internalRoot;
15301 var work = new ReactWork();
15302 callback = callback === undefined ? null : callback;
15303 {
15304 warnOnInvalidCallback(callback, 'render');
15305 }
15306 if (callback !== null) {
15307 work.then(callback);
15308 }
15309 DOMRenderer.updateContainer(children, root, parentComponent, work._onCommit);
15310 return work;
15311};
15312ReactRoot.prototype.createBatch = function () {
15313 var batch = new ReactBatch(this);
15314 var expirationTime = batch._expirationTime;
15315
15316 var internalRoot = this._internalRoot;
15317 var firstBatch = internalRoot.firstBatch;
15318 if (firstBatch === null) {
15319 internalRoot.firstBatch = batch;
15320 batch._next = null;
15321 } else {
15322 // Insert sorted by expiration time then insertion order
15323 var insertAfter = null;
15324 var insertBefore = firstBatch;
15325 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) {
15326 insertAfter = insertBefore;
15327 insertBefore = insertBefore._next;
15328 }
15329 batch._next = insertBefore;
15330 if (insertAfter !== null) {
15331 insertAfter._next = batch;
15332 }
15333 }
15334
15335 return batch;
15336};
15337
15338/**
15339 * True if the supplied DOM node is a valid node element.
15340 *
15341 * @param {?DOMElement} node The candidate DOM node.
15342 * @return {boolean} True if the DOM is a valid DOM node.
15343 * @internal
15344 */
15345function isValidContainer(node) {
15346 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 '));
15347}
15348
15349function getReactRootElementInContainer(container) {
15350 if (!container) {
15351 return null;
15352 }
15353
15354 if (container.nodeType === DOCUMENT_NODE) {
15355 return container.documentElement;
15356 } else {
15357 return container.firstChild;
15358 }
15359}
15360
15361function shouldHydrateDueToLegacyHeuristic(container) {
15362 var rootElement = getReactRootElementInContainer(container);
15363 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
15364}
15365
15366function shouldAutoFocusHostComponent(type, props) {
15367 switch (type) {
15368 case 'button':
15369 case 'input':
15370 case 'select':
15371 case 'textarea':
15372 return !!props.autoFocus;
15373 }
15374 return false;
15375}
15376
15377var DOMRenderer = reactReconciler({
15378 getRootHostContext: function (rootContainerInstance) {
15379 var type = void 0;
15380 var namespace = void 0;
15381 var nodeType = rootContainerInstance.nodeType;
15382 switch (nodeType) {
15383 case DOCUMENT_NODE:
15384 case DOCUMENT_FRAGMENT_NODE:
15385 {
15386 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
15387 var root = rootContainerInstance.documentElement;
15388 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
15389 break;
15390 }
15391 default:
15392 {
15393 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
15394 var ownNamespace = container.namespaceURI || null;
15395 type = container.tagName;
15396 namespace = getChildNamespace(ownNamespace, type);
15397 break;
15398 }
15399 }
15400 {
15401 var validatedTag = type.toLowerCase();
15402 var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null);
15403 return { namespace: namespace, ancestorInfo: _ancestorInfo };
15404 }
15405 return namespace;
15406 },
15407 getChildHostContext: function (parentHostContext, type) {
15408 {
15409 var parentHostContextDev = parentHostContext;
15410 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
15411 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null);
15412 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
15413 }
15414 var parentNamespace = parentHostContext;
15415 return getChildNamespace(parentNamespace, type);
15416 },
15417 getPublicInstance: function (instance) {
15418 return instance;
15419 },
15420 prepareForCommit: function () {
15421 eventsEnabled = isEnabled();
15422 selectionInformation = getSelectionInformation();
15423 setEnabled(false);
15424 },
15425 resetAfterCommit: function () {
15426 restoreSelection(selectionInformation);
15427 selectionInformation = null;
15428 setEnabled(eventsEnabled);
15429 eventsEnabled = null;
15430 },
15431 createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15432 var parentNamespace = void 0;
15433 {
15434 // TODO: take namespace into account when validating.
15435 var hostContextDev = hostContext;
15436 validateDOMNesting$1(type, null, hostContextDev.ancestorInfo);
15437 if (typeof props.children === 'string' || typeof props.children === 'number') {
15438 var string = '' + props.children;
15439 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15440 validateDOMNesting$1(null, string, ownAncestorInfo);
15441 }
15442 parentNamespace = hostContextDev.namespace;
15443 }
15444 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
15445 precacheFiberNode(internalInstanceHandle, domElement);
15446 updateFiberProps(domElement, props);
15447 return domElement;
15448 },
15449 appendInitialChild: function (parentInstance, child) {
15450 parentInstance.appendChild(child);
15451 },
15452 finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) {
15453 setInitialProperties(domElement, type, props, rootContainerInstance);
15454 return shouldAutoFocusHostComponent(type, props);
15455 },
15456 prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
15457 {
15458 var hostContextDev = hostContext;
15459 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
15460 var string = '' + newProps.children;
15461 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null);
15462 validateDOMNesting$1(null, string, ownAncestorInfo);
15463 }
15464 }
15465 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
15466 },
15467 shouldSetTextContent: function (type, props) {
15468 return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string';
15469 },
15470 shouldDeprioritizeSubtree: function (type, props) {
15471 return !!props.hidden;
15472 },
15473 createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) {
15474 {
15475 var hostContextDev = hostContext;
15476 validateDOMNesting$1(null, text, hostContextDev.ancestorInfo);
15477 }
15478 var textNode = createTextNode(text, rootContainerInstance);
15479 precacheFiberNode(internalInstanceHandle, textNode);
15480 return textNode;
15481 },
15482
15483
15484 now: now,
15485
15486 mutation: {
15487 commitMount: function (domElement, type, newProps, internalInstanceHandle) {
15488 // Despite the naming that might imply otherwise, this method only
15489 // fires if there is an `Update` effect scheduled during mounting.
15490 // This happens if `finalizeInitialChildren` returns `true` (which it
15491 // does to implement the `autoFocus` attribute on the client). But
15492 // there are also other cases when this might happen (such as patching
15493 // up text content during hydration mismatch). So we'll check this again.
15494 if (shouldAutoFocusHostComponent(type, newProps)) {
15495 domElement.focus();
15496 }
15497 },
15498 commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
15499 // Update the props handle so that we know which props are the ones with
15500 // with current event handlers.
15501 updateFiberProps(domElement, newProps);
15502 // Apply the diff to the DOM node.
15503 updateProperties(domElement, updatePayload, type, oldProps, newProps);
15504 },
15505 resetTextContent: function (domElement) {
15506 setTextContent(domElement, '');
15507 },
15508 commitTextUpdate: function (textInstance, oldText, newText) {
15509 textInstance.nodeValue = newText;
15510 },
15511 appendChild: function (parentInstance, child) {
15512 parentInstance.appendChild(child);
15513 },
15514 appendChildToContainer: function (container, child) {
15515 if (container.nodeType === COMMENT_NODE) {
15516 container.parentNode.insertBefore(child, container);
15517 } else {
15518 container.appendChild(child);
15519 }
15520 },
15521 insertBefore: function (parentInstance, child, beforeChild) {
15522 parentInstance.insertBefore(child, beforeChild);
15523 },
15524 insertInContainerBefore: function (container, child, beforeChild) {
15525 if (container.nodeType === COMMENT_NODE) {
15526 container.parentNode.insertBefore(child, beforeChild);
15527 } else {
15528 container.insertBefore(child, beforeChild);
15529 }
15530 },
15531 removeChild: function (parentInstance, child) {
15532 parentInstance.removeChild(child);
15533 },
15534 removeChildFromContainer: function (container, child) {
15535 if (container.nodeType === COMMENT_NODE) {
15536 container.parentNode.removeChild(child);
15537 } else {
15538 container.removeChild(child);
15539 }
15540 }
15541 },
15542
15543 hydration: {
15544 canHydrateInstance: function (instance, type, props) {
15545 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
15546 return null;
15547 }
15548 // This has now been refined to an element node.
15549 return instance;
15550 },
15551 canHydrateTextInstance: function (instance, text) {
15552 if (text === '' || instance.nodeType !== TEXT_NODE) {
15553 // Empty strings are not parsed by HTML so there won't be a correct match here.
15554 return null;
15555 }
15556 // This has now been refined to a text node.
15557 return instance;
15558 },
15559 getNextHydratableSibling: function (instance) {
15560 var node = instance.nextSibling;
15561 // Skip non-hydratable nodes.
15562 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
15563 node = node.nextSibling;
15564 }
15565 return node;
15566 },
15567 getFirstHydratableChild: function (parentInstance) {
15568 var next = parentInstance.firstChild;
15569 // Skip non-hydratable nodes.
15570 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
15571 next = next.nextSibling;
15572 }
15573 return next;
15574 },
15575 hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
15576 precacheFiberNode(internalInstanceHandle, instance);
15577 // TODO: Possibly defer this until the commit phase where all the events
15578 // get attached.
15579 updateFiberProps(instance, props);
15580 var parentNamespace = void 0;
15581 {
15582 var hostContextDev = hostContext;
15583 parentNamespace = hostContextDev.namespace;
15584 }
15585 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
15586 },
15587 hydrateTextInstance: function (textInstance, text, internalInstanceHandle) {
15588 precacheFiberNode(internalInstanceHandle, textInstance);
15589 return diffHydratedText(textInstance, text);
15590 },
15591 didNotMatchHydratedContainerTextInstance: function (parentContainer, textInstance, text) {
15592 {
15593 warnForUnmatchedText(textInstance, text);
15594 }
15595 },
15596 didNotMatchHydratedTextInstance: function (parentType, parentProps, parentInstance, textInstance, text) {
15597 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15598 warnForUnmatchedText(textInstance, text);
15599 }
15600 },
15601 didNotHydrateContainerInstance: function (parentContainer, instance) {
15602 {
15603 if (instance.nodeType === 1) {
15604 warnForDeletedHydratableElement(parentContainer, instance);
15605 } else {
15606 warnForDeletedHydratableText(parentContainer, instance);
15607 }
15608 }
15609 },
15610 didNotHydrateInstance: function (parentType, parentProps, parentInstance, instance) {
15611 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15612 if (instance.nodeType === 1) {
15613 warnForDeletedHydratableElement(parentInstance, instance);
15614 } else {
15615 warnForDeletedHydratableText(parentInstance, instance);
15616 }
15617 }
15618 },
15619 didNotFindHydratableContainerInstance: function (parentContainer, type, props) {
15620 {
15621 warnForInsertedHydratedElement(parentContainer, type, props);
15622 }
15623 },
15624 didNotFindHydratableContainerTextInstance: function (parentContainer, text) {
15625 {
15626 warnForInsertedHydratedText(parentContainer, text);
15627 }
15628 },
15629 didNotFindHydratableInstance: function (parentType, parentProps, parentInstance, type, props) {
15630 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15631 warnForInsertedHydratedElement(parentInstance, type, props);
15632 }
15633 },
15634 didNotFindHydratableTextInstance: function (parentType, parentProps, parentInstance, text) {
15635 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
15636 warnForInsertedHydratedText(parentInstance, text);
15637 }
15638 }
15639 },
15640
15641 scheduleDeferredCallback: rIC,
15642 cancelDeferredCallback: cIC
15643});
15644
15645injection$3.injectFiberBatchedUpdates(DOMRenderer.batchedUpdates);
15646
15647var warnedAboutHydrateAPI = false;
15648
15649function legacyCreateRootFromDOMContainer(container, forceHydrate) {
15650 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
15651 // First clear any existing content.
15652 if (!shouldHydrate) {
15653 var warned = false;
15654 var rootSibling = void 0;
15655 while (rootSibling = container.lastChild) {
15656 {
15657 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
15658 warned = true;
15659 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.');
15660 }
15661 }
15662 container.removeChild(rootSibling);
15663 }
15664 }
15665 {
15666 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
15667 warnedAboutHydrateAPI = true;
15668 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.');
15669 }
15670 }
15671 // Legacy roots are not async by default.
15672 var isAsync = false;
15673 return new ReactRoot(container, isAsync, shouldHydrate);
15674}
15675
15676function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
15677 // TODO: Ensure all entry points contain this check
15678 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15679
15680 {
15681 topLevelUpdateWarnings(container);
15682 }
15683
15684 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
15685 // member of intersection type." Whyyyyyy.
15686 var root = container._reactRootContainer;
15687 if (!root) {
15688 // Initial mount
15689 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
15690 if (typeof callback === 'function') {
15691 var originalCallback = callback;
15692 callback = function () {
15693 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15694 originalCallback.call(instance);
15695 };
15696 }
15697 // Initial mount should not be batched.
15698 DOMRenderer.unbatchedUpdates(function () {
15699 if (parentComponent != null) {
15700 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15701 } else {
15702 root.render(children, callback);
15703 }
15704 });
15705 } else {
15706 if (typeof callback === 'function') {
15707 var _originalCallback = callback;
15708 callback = function () {
15709 var instance = DOMRenderer.getPublicRootInstance(root._internalRoot);
15710 _originalCallback.call(instance);
15711 };
15712 }
15713 // Update
15714 if (parentComponent != null) {
15715 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
15716 } else {
15717 root.render(children, callback);
15718 }
15719 }
15720 return DOMRenderer.getPublicRootInstance(root._internalRoot);
15721}
15722
15723function createPortal(children, container) {
15724 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15725
15726 !isValidContainer(container) ? invariant_1(false, 'Target container is not a DOM element.') : void 0;
15727 // TODO: pass ReactDOM portal implementation as third argument
15728 return createPortal$1(children, container, null, key);
15729}
15730
15731var ReactDOM = {
15732 createPortal: createPortal,
15733
15734 findDOMNode: function (componentOrElement) {
15735 {
15736 var owner = ReactCurrentOwner.current;
15737 if (owner !== null) {
15738 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
15739 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');
15740 owner.stateNode._warnedAboutRefsInRender = true;
15741 }
15742 }
15743 if (componentOrElement == null) {
15744 return null;
15745 }
15746 if (componentOrElement.nodeType === ELEMENT_NODE) {
15747 return componentOrElement;
15748 }
15749
15750 var inst = get(componentOrElement);
15751 if (inst) {
15752 return DOMRenderer.findHostInstance(inst);
15753 }
15754
15755 if (typeof componentOrElement.render === 'function') {
15756 invariant_1(false, 'Unable to find node on an unmounted component.');
15757 } else {
15758 invariant_1(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement));
15759 }
15760 },
15761 hydrate: function (element, container, callback) {
15762 // TODO: throw or warn if we couldn't hydrate?
15763 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
15764 },
15765 render: function (element, container, callback) {
15766 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
15767 },
15768 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
15769 !(parentComponent != null && has(parentComponent)) ? invariant_1(false, 'parentComponent must be a valid React Component') : void 0;
15770 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
15771 },
15772 unmountComponentAtNode: function (container) {
15773 !isValidContainer(container) ? invariant_1(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
15774
15775 if (container._reactRootContainer) {
15776 {
15777 var rootEl = getReactRootElementInContainer(container);
15778 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
15779 warning_1(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
15780 }
15781
15782 // Unmount should not be batched.
15783 DOMRenderer.unbatchedUpdates(function () {
15784 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
15785 container._reactRootContainer = null;
15786 });
15787 });
15788 // If you call unmountComponentAtNode twice in quick succession, you'll
15789 // get `true` twice. That's probably fine?
15790 return true;
15791 } else {
15792 {
15793 var _rootEl = getReactRootElementInContainer(container);
15794 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
15795
15796 // Check if the container itself is a React root node.
15797 var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
15798
15799 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.');
15800 }
15801
15802 return false;
15803 }
15804 },
15805
15806
15807 // Temporary alias since we already shipped React 16 RC with it.
15808 // TODO: remove in React 17.
15809 unstable_createPortal: function () {
15810 if (!didWarnAboutUnstableCreatePortal) {
15811 didWarnAboutUnstableCreatePortal = true;
15812 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.');
15813 }
15814 return createPortal.apply(undefined, arguments);
15815 },
15816
15817
15818 unstable_batchedUpdates: batchedUpdates,
15819
15820 unstable_deferredUpdates: DOMRenderer.deferredUpdates,
15821
15822 flushSync: DOMRenderer.flushSync,
15823
15824 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
15825 // For TapEventPlugin which is popular in open source
15826 EventPluginHub: EventPluginHub,
15827 // Used by test-utils
15828 EventPluginRegistry: EventPluginRegistry,
15829 EventPropagators: EventPropagators,
15830 ReactControlledComponent: ReactControlledComponent,
15831 ReactDOMComponentTree: ReactDOMComponentTree,
15832 ReactDOMEventListener: ReactDOMEventListener
15833 }
15834};
15835
15836{
15837 // Show deprecation warnings as we don't want to support injection forever.
15838 // We do it now to let the internal injection happen without warnings.
15839 // https://github.com/facebook/react/issues/11689
15840 enableWarningOnInjection();
15841}
15842
15843if (enableCreateRoot) {
15844 ReactDOM.createRoot = function createRoot(container, options) {
15845 var hydrate = options != null && options.hydrate === true;
15846 return new ReactRoot(container, true, hydrate);
15847 };
15848}
15849
15850var foundDevTools = DOMRenderer.injectIntoDevTools({
15851 findFiberByHostInstance: getClosestInstanceFromNode,
15852 bundleType: 1,
15853 version: ReactVersion,
15854 rendererPackageName: 'react-dom'
15855});
15856
15857{
15858 if (!foundDevTools && ExecutionEnvironment_1.canUseDOM && window.top === window.self) {
15859 // If we're in Chrome or Firefox, provide a download link if not installed.
15860 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
15861 var protocol = window.location.protocol;
15862 // Don't warn in exotic cases like chrome-extension://.
15863 if (/^(https?|file):$/.test(protocol)) {
15864 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');
15865 }
15866 }
15867 }
15868}
15869
15870
15871
15872var ReactDOM$2 = Object.freeze({
15873 default: ReactDOM
15874});
15875
15876var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
15877
15878// TODO: decide on the top-level export form.
15879// This is hacky but makes it work with both Rollup and Jest.
15880var reactDom = ReactDOM$3['default'] ? ReactDOM$3['default'] : ReactDOM$3;
15881
15882return reactDom;
15883
15884})));