From e23ccdad747ec9bd14e8031b8068a127e0962d04 Mon Sep 17 00:00:00 2001 From: jayshah123 Date: Sun, 15 Dec 2019 12:30:16 +0530 Subject: [PATCH 0001/1126] last item removal scroll position restore --- .../scroll/ReactHorizontalScrollView.java | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index e41ae5caa2d568..cff0dd58dd18ae 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -18,6 +18,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.widget.HorizontalScrollView; import android.widget.OverScroller; import androidx.annotation.Nullable; @@ -39,7 +40,8 @@ /** Similar to {@link ReactScrollView} but only supports horizontal scrolling. */ public class ReactHorizontalScrollView extends HorizontalScrollView - implements ReactClippingViewGroup { + implements ReactClippingViewGroup, ViewGroup.OnHierarchyChangeListener, + View.OnLayoutChangeListener { private static @Nullable Field sScrollerField; private static boolean sTriedToGetScrollerField = false; @@ -68,6 +70,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView private @Nullable List mSnapOffsets; private boolean mSnapToStart = true; private boolean mSnapToEnd = true; + private View mContentView; private ReactViewBackgroundManager mReactBackgroundManager; private boolean mPagedArrowScrolling = false; @@ -83,6 +86,7 @@ public ReactHorizontalScrollView(Context context, @Nullable FpsListener fpsListe mFpsListener = fpsListener; mScroller = getOverScrollerFromParent(); + setOnHierarchyChangeListener(this); } @Nullable @@ -537,6 +541,51 @@ protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolea super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); } + private int getMaxScrollX() { + int contentWidth = mContentView.getWidth(); + int viewportWidth = getWidth() - getPaddingLeft() - getPaddingRight(); + return Math.max(0, contentWidth - viewportWidth); + } + + @Override + public void onChildViewAdded(View parent, View child) { + mContentView = child; + mContentView.addOnLayoutChangeListener(this); + } + + @Override + public void onChildViewRemoved(View parent, View child) { + mContentView.removeOnLayoutChangeListener(this); + mContentView = null; + } + + /** + * Called when a mContentView's layout has changed. Fixes the scroll position if it's too large + * after the content resizes. Without this, the user would see a blank ScrollView when the scroll + * position is larger than the ScrollView's max scroll position after the content shrinks. + */ + @Override + public void onLayoutChange( + View v, + int left, + int top, + int right, + int bottom, + int oldLeft, + int oldTop, + int oldRight, + int oldBottom) { + if (mContentView == null) { + return; + } + + int currentScrollX = getScrollX(); + int maxScrollX = getMaxScrollX(); + if (currentScrollX > maxScrollX) { + scrollTo(maxScrollX, getScrollY()); + } + } + private void enableFpsListener() { if (isScrollPerfLoggingEnabled()) { Assertions.assertNotNull(mFpsListener); From 159624d901c8143999e1ce59b852080019b528f3 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 9 Jan 2020 11:15:50 -0800 Subject: [PATCH 0002/1126] React Native sync for revisions 6cff70a...19f6fe1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This sync includes the following changes: - **[19f6fe170](https://github.com/facebook/react/commit/19f6fe170 )**: Revert "Revert "Dispatch commands to both UIManagers from both renderers (#17211)" (#17232)" (#17799) //// - **[6250462be](https://github.com/facebook/react/commit/6250462be )**: Renamed "ReactDOM-fb" imports to "ReactDOM" in www shims (#17797) //// - **[59f21f1b2](https://github.com/facebook/react/commit/59f21f1b2 )**: HostText needs to copy over from current if it is unchanged in persistent mode (#17538) //// - **[ccc6100d7](https://github.com/facebook/react/commit/ccc6100d7 )**: Fix comments typos (#17550) //// - **[1b9328cd9](https://github.com/facebook/react/commit/1b9328cd9 )**: Null stateNode after unmount (#17666) //// - **[897976600](https://github.com/facebook/react/commit/897976600 )**: [ESLint] Allow partial matches for custom Effect Hooks (#17663) //// - **[72592310a](https://github.com/facebook/react/commit/72592310a )**: Create packages/dom-event-testing-library (#17660) //// - **[a5e951d4c](https://github.com/facebook/react/commit/a5e951d4c )**: [react-interactions] Event testing library improvements (#17614) //// - **[7dc974542](https://github.com/facebook/react/commit/7dc974542 )**: [Flight] Chunks API (#17398) //// - **[9354dd275](https://github.com/facebook/react/commit/9354dd275 )**: Make HostComponent inexact (#17412) //// - **[4c270375e](https://github.com/facebook/react/commit/4c270375e )**: Favor fallthrough switch instead of case statements for work tags (#17648) //// - **[6fef7c47a](https://github.com/facebook/react/commit/6fef7c47a )**: Add a regression test for switching from Fragment to a component (#17647) //// - **[9fe103124](https://github.com/facebook/react/commit/9fe103124 )**: [react-interactions] Rename Flare APIs to deprecated and remove from RN (#17644) //// - **[4b0cdf29a](https://github.com/facebook/react/commit/4b0cdf29a )**: Build FB RN targets only in experimental mode (#17641) //// - **[7309c5f93](https://github.com/facebook/react/commit/7309c5f93 )**: Use zero-fill right shift instead of Math.floor (#17616) //<伊撒尔>// - **[3c54df091](https://github.com/facebook/react/commit/3c54df091 )**: Fix missing stacks in WWW warnings (#17638) //// - **[b66e86d95](https://github.com/facebook/react/commit/b66e86d95 )**: react-refresh@0.7.1 //// - **[c2d1561c6](https://github.com/facebook/react/commit/c2d1561c6 )**: [Fast Refresh] Support injecting runtime after renderer executes (#17633) //// - **[f42431abe](https://github.com/facebook/react/commit/f42431abe )**: Revert "Remove renderPhaseUpdates Map (#17484)" (#17623) //// - **[0b5a26a48](https://github.com/facebook/react/commit/0b5a26a48 )**: Rename toWarnDev -> toErrorDev, toLowPriorityWarnDev -> toWarnDev (#17605) //// - **[0cf22a56a](https://github.com/facebook/react/commit/0cf22a56a )**: Use console directly instead of warning() modules (#17599) //// - **[b6c423daa](https://github.com/facebook/react/commit/b6c423daa )**: Use matching test command for equivalence tests (#17604) //// - **[8a347ed02](https://github.com/facebook/react/commit/8a347ed02 )**: Remove renderPhaseUpdates Map (#17484) //// - **[be603f5a5](https://github.com/facebook/react/commit/be603f5a5 )**: [react-events] Remove lastNativeEvent in favor of SystemFlags (#17585) //// - **[b15bf3675](https://github.com/facebook/react/commit/b15bf3675 )**: Add component stacks to (almost) all warnings (#17586) //// - **[2afeebdcc](https://github.com/facebook/react/commit/2afeebdcc )**: [react-interactions] Remove responder root event types + revert commit phase change (#17577) //// - **[9ac42dd07](https://github.com/facebook/react/commit/9ac42dd07 )**: Remove the condition argument from warning() (#17568) //// - **[7bf40e1cf](https://github.com/facebook/react/commit/7bf40e1cf )**: Initialize update queue object on mount (#17560) //// - **[e039e690b](https://github.com/facebook/react/commit/e039e690b )**: Revert Update Queue Refactor //// - **[b617db3d9](https://github.com/facebook/react/commit/b617db3d9 )**: Refactor Update Queues to Fix Rebasing Bug //// - **[b43eec7ea](https://github.com/facebook/react/commit/b43eec7ea )**: Replace `wrap-warning-with-env-check` with an eslint plugin (#17540) //// - **[acfe4b21b](https://github.com/facebook/react/commit/acfe4b21b )**: [react-interactions] Upgrade passive event listeners to active listeners (#17513) //// - **[5064c7f6a](https://github.com/facebook/react/commit/5064c7f6a )**: Revert Rerender Error Check (#17519) //// - **[6d105ad3f](https://github.com/facebook/react/commit/6d105ad3f )**: [react-interactions] Move Flare event registration to commit phase (#17518) //// - **[dc18b8b8d](https://github.com/facebook/react/commit/dc18b8b8d )**: Don't group Idle/Offscreen work with other work (#17456) //// - **[f523b2e0d](https://github.com/facebook/react/commit/f523b2e0d )**: Use fewer global variables in Hooks (#17480) //// - **[d75323f65](https://github.com/facebook/react/commit/d75323f65 )**: Remove case that only exists for createBatch (#17506) //// - **[79572e34d](https://github.com/facebook/react/commit/79572e34d )**: Adjust SuspenseList CPU bound heuristic (#17455) //// - **[969f4b5bb](https://github.com/facebook/react/commit/969f4b5bb )**: Change DevTools hook warning message (#17478) //// - **[6470e0f16](https://github.com/facebook/react/commit/6470e0f16 )**: [Fresh] Make all errors recoverable (#17438) //// Changelog: [General][Changed] - React sync for revisions 6cff70a...19f6fe1 Reviewed By: TheSavior Differential Revision: D19318286 fbshipit-source-id: acaa5224f7162a274c395a62e54da82199001005 --- Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 4391 +++++++---------- .../implementations/ReactFabric-dev.js | 4391 +++++++---------- .../implementations/ReactFabric-prod.fb.js | 2184 ++++---- .../implementations/ReactFabric-prod.js | 2184 ++++---- .../ReactFabric-profiling.fb.js | 1586 +++--- .../implementations/ReactFabric-profiling.js | 1586 +++--- .../ReactNativeRenderer-dev.fb.js | 3677 +++++++------- .../ReactNativeRenderer-dev.js | 3677 +++++++------- .../ReactNativeRenderer-prod.fb.js | 2079 ++++---- .../ReactNativeRenderer-prod.js | 2079 ++++---- .../ReactNativeRenderer-profiling.fb.js | 1493 +++--- .../ReactNativeRenderer-profiling.js | 1493 +++--- Libraries/Renderer/shims/ReactNativeTypes.js | 48 - package.json | 8 +- template/package.json | 4 +- yarn.lock | 26 +- 17 files changed, 14606 insertions(+), 16302 deletions(-) diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index d45d99aeb1adb8..9be2711e1c8310 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -6cff70a740d1e6ad10070ebf88514bd3a49d0f0d +19f6fe170ce920d7183a5620f4e218334c8bac62 \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index aafcdcead33c33..1b3fd6c211d332 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -15,13 +15,110 @@ if (__DEV__) { (function() { "use strict"; +var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); -var React = require("react"); -var Scheduler = require("scheduler"); var checkPropTypes = require("prop-types/checkPropTypes"); +var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// by calls to these methods by a Babel plugin. +// +// In PROD (or in packages without access to React internals), +// they are left as they are instead. + +function warn(format) { + { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); + } +} +function error(format) { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } +} + +function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === "string" && + args[args.length - 1].indexOf("\n in") === 0; + + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } + } + + var argsWithFormat = args.map(function(item) { + return "" + item; + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + } +} + /** * Use invariant() to assert state which your program assumes to be true. * @@ -559,71 +656,6 @@ function clearCaughtError() { } } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var warningWithoutStack = function() {}; - -{ - warningWithoutStack = function(condition, format) { - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - if (format === undefined) { - throw new Error( - "`warningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (args.length > 8) { - // Check before the condition to catch violations early. - throw new Error( - "warningWithoutStack() currently supports at most 8 arguments." - ); - } - - if (condition) { - return; - } - - if (typeof console !== "undefined") { - var argsWithFormat = args.map(function(item) { - return "" + item; - }); - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - - Function.prototype.apply.call(console.error, console, argsWithFormat); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} - }; -} - -var warningWithoutStack$1 = warningWithoutStack; - var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -637,13 +669,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -664,9 +695,10 @@ var validateEventDispatches; : dispatchInstances ? 1 : 0; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -1093,6 +1125,7 @@ var DehydratedFragment = 18; var SuspenseListComponent = 19; var FundamentalComponent = 20; var ScopeComponent = 21; +var Chunk = 22; function getParent(inst) { do { @@ -1230,9 +1263,9 @@ function listenerAtPhase(inst, event, propagationPhase) { function accumulateDirectionalDispatches(inst, phase, event) { { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; + if (!inst) { + error("Dispatching inst must not be null"); + } } var listener = listenerAtPhase(inst, event, phase); @@ -1577,7 +1610,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function set(val) { var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); + warn$$1(action, "This is effectively a no-op"); return val; } @@ -1586,24 +1619,22 @@ function getPooledWarningPropertyDefinition(propName, getVal) { var result = isFunction ? "This is a no-op function" : "This is set to null"; - warn(action, result); + warn$$1(action, result); return getVal; } - function warn(action, result) { - var warningCondition = false; - !warningCondition - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + function warn$$1(action, result) { + { + error( + "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 + ); + } } } @@ -1748,15 +1779,14 @@ function getTouchIdentifier(_ref) { } { - !(identifier <= MAX_TOUCH_BANK) - ? warningWithoutStack$1( - false, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ) - : void 0; + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } } return identifier; @@ -1788,12 +1818,15 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1810,12 +1843,15 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1866,9 +1902,10 @@ var ResponderTouchHistoryStore = { { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } } } } @@ -2397,9 +2434,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2575,11 +2615,13 @@ var enableProfilerTimer = true; var enableSchedulerTracing = true; var enableSuspenseServerRenderer = false; +var enableChunksAPI = false; + var debugRenderPhaseSideEffectsForStrictMode = true; var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; var warnAboutDeprecatedLifecycles = true; -var enableFlareAPI = false; +var enableDeprecatedFlareAPI = false; var enableFundamentalAPI = false; var enableScopeAPI = false; @@ -2590,6 +2632,7 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +var enableTrainModelFix = false; // Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -2670,23 +2713,6 @@ function set(key, value) { key._reactInternalFiber = value; } -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} - // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -2713,6 +2739,7 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; +var REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 0xead9; var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 0xead5; @@ -2736,43 +2763,6 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; - -{ - warning = function(condition, format) { - if (condition) { - return; - } - - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args - - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} - -var warning$1 = warning; - var Uninitialized = -1; var Pending = 0; var Resolved = 1; @@ -2793,8 +2783,7 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + "Instead received: %s\n\nYour code should look like: \n " + "const MyComponent = lazy(() => import('./MyComponent'))", @@ -2807,10 +2796,10 @@ function initializeLazyComponentType(lazyComponent) { lazyComponent._result = defaultExport; } }, - function(error) { + function(error$$1) { if (lazyComponent._status === Pending) { lazyComponent._status = Rejected; - lazyComponent._result = error; + lazyComponent._result = error$$1; } } ); @@ -2833,8 +2822,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2883,6 +2871,9 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); + case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3006,17 +2997,18 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !instance._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%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.type) || "A component" - ) - : void 0; + + if (!instance._warnedAboutRefsInRender) { + error( + "%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.type) || "A component" + ); + } + instance._warnedAboutRefsInRender = true; } } @@ -3284,17 +3276,19 @@ function throwOnStylesProp(component, props) { } } function warnForStyleProps(props, validAttributes) { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - console.error( - "You are setting the style `{ " + - key + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { " + - key + - ": ... } }`" - ); + { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + error( + "You are setting the style `{ %s" + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { %s" + + ": ... } }`", + key, + key + ); + } } } } @@ -3778,8 +3772,13 @@ function restoreStateOfTarget(target) { ); } - var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - restoreImpl(internalInstance.stateNode, internalInstance.type, props); + var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. + + if (stateNode) { + var _props = getFiberCurrentPropsFromNode(stateNode); + + restoreImpl(internalInstance.stateNode, internalInstance.type, _props); + } } function needsStateRestore() { @@ -3813,16 +3812,9 @@ var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var discreteUpdatesImpl = function(fn, a, b, c) { - return fn(a, b, c); -}; - var flushDiscreteUpdatesImpl = function() {}; -var batchedEventUpdatesImpl = batchedUpdatesImpl; var isInsideEventHandler = false; -var isBatchingEventUpdates = false; - function finishEventHandler() { // Here we wait until all updates have propagated, which is important // when using controlled components within layers: @@ -3855,72 +3847,8 @@ function batchedUpdates(fn, bookkeeping) { finishEventHandler(); } } -function batchedEventUpdates(fn, a, b) { - if (isBatchingEventUpdates) { - // If we are currently inside another batch, we need to wait until it - // fully completes before restoring state. - return fn(a, b); - } - - isBatchingEventUpdates = true; - - try { - return batchedEventUpdatesImpl(fn, a, b); - } finally { - isBatchingEventUpdates = false; - finishEventHandler(); - } -} // This is for the React Flare event system - -function executeUserEventHandler(fn, value) { - var previouslyInEventHandler = isInsideEventHandler; - - try { - isInsideEventHandler = true; - var type = typeof value === "object" && value !== null ? value.type : ""; - invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value); - } finally { - isInsideEventHandler = previouslyInEventHandler; - } -} -function discreteUpdates(fn, a, b, c) { - var prevIsInsideEventHandler = isInsideEventHandler; - isInsideEventHandler = true; +// This is for the React Flare event system - try { - return discreteUpdatesImpl(fn, a, b, c); - } finally { - isInsideEventHandler = prevIsInsideEventHandler; - - if (!isInsideEventHandler) { - finishEventHandler(); - } - } -} -var lastFlushedEventTimeStamp = 0; -function flushDiscreteUpdatesIfNeeded(timeStamp) { - // event.timeStamp isn't overly reliable due to inconsistencies in - // how different browsers have historically provided the time stamp. - // Some browsers provide high-resolution time stamps for all events, - // some provide low-resolution time stamps for all events. FF < 52 - // even mixes both time stamps together. Some browsers even report - // negative time stamps or time stamps that are 0 (iOS9) in some cases. - // Given we are only comparing two time stamps with equality (!==), - // we are safe from the resolution differences. If the time stamp is 0 - // we bail-out of preventing the flush, which can affect semantics, - // such as if an earlier flush removes or adds event listeners that - // are fired in the subsequent flush. However, this is the same - // behaviour as we had before this change, so the risks are low. - if ( - !isInsideEventHandler && - (!enableFlareAPI || - timeStamp === 0 || - lastFlushedEventTimeStamp !== timeStamp) - ) { - lastFlushedEventTimeStamp = timeStamp; - flushDiscreteUpdatesImpl(); - } -} function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -3928,501 +3856,43 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - discreteUpdatesImpl = _discreteUpdatesImpl; flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; - batchedEventUpdatesImpl = _batchedEventUpdatesImpl; -} - -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; } -/** - * Class only exists for its Flow type. - */ -var ReactNativeComponent = - /*#__PURE__*/ - (function(_React$Component) { - _inheritsLoose(ReactNativeComponent, _React$Component); +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + var eventTarget = null; - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; + if (enableNativeTargetAsInstance) { + if (targetFiber != null) { + eventTarget = targetFiber.stateNode.canonical; } + } else { + eventTarget = nativeEvent.target; + } - var _proto = ReactNativeComponent.prototype; - - _proto.blur = function blur() {}; - - _proto.focus = function focus() {}; + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + eventTarget, + PLUGIN_EVENT_SYSTEM + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. +} - _proto.measure = function measure(callback) {}; +// can re-export everything from this module. - _proto.measureInWindow = function measureInWindow(callback) {}; - - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) {}; - - _proto.setNativeProps = function setNativeProps(nativeProps) {}; - - return ReactNativeComponent; - })(React.Component); // This type is only used for FlowTests. It shouldn't be imported directly - -var DiscreteEvent = 0; -var UserBlockingEvent = 1; -var ContinuousEvent = 2; - -// CommonJS interop named imports. - -var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; -var runWithPriority = Scheduler.unstable_runWithPriority; -var _nativeFabricUIManage$2 = nativeFabricUIManager; -var measureInWindow = _nativeFabricUIManage$2.measureInWindow; -var rootEventTypesToEventResponderInstances = new Map(); -var currentTimeStamp = 0; -var currentInstance = null; -var eventResponderContext = { - dispatchEvent: function(eventValue, eventListener, eventPriority) { - validateResponderContext(); - validateEventValue(eventValue); - - switch (eventPriority) { - case DiscreteEvent: { - flushDiscreteUpdatesIfNeeded(currentTimeStamp); - discreteUpdates(function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } - - case UserBlockingEvent: { - runWithPriority(UserBlockingPriority, function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } - - case ContinuousEvent: { - executeUserEventHandler(eventListener, eventValue); - break; - } - } - }, - isTargetWithinNode: function(childTarget, parentTarget) { - validateResponderContext(); - var childFiber = getFiberFromTarget(childTarget); - var parentFiber = getFiberFromTarget(parentTarget); - var node = childFiber; - - while (node !== null) { - if (node === parentFiber) { - return true; - } - - node = node.return; - } - - return false; - }, - getTargetBoundingRect: function(target, callback) { - measureInWindow(target.node, function(x, y, width, height) { - callback({ - left: x, - right: x + width, - top: y, - bottom: y + height - }); - }); - }, - addRootEventTypes: function(rootEventTypes) { - validateResponderContext(); - - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var eventResponderInstance = currentInstance; - registerRootEventType(rootEventType, eventResponderInstance); - } - }, - removeRootEventTypes: function(rootEventTypes) { - validateResponderContext(); - - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var rootEventResponders = rootEventTypesToEventResponderInstances.get( - rootEventType - ); - var rootEventTypesSet = currentInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - rootEventTypesSet.delete(rootEventType); - } - - if (rootEventResponders !== undefined) { - rootEventResponders.delete(currentInstance); - } - } - }, - getTimeStamp: function() { - validateResponderContext(); - return currentTimeStamp; - }, - getResponderNode: function() { - validateResponderContext(); - var responderFiber = currentInstance.fiber; - - if (responderFiber.tag === ScopeComponent) { - return null; - } - - return responderFiber.stateNode; - } -}; - -function validateEventValue(eventValue) { - if (typeof eventValue === "object" && eventValue !== null) { - var target = eventValue.target, - type = eventValue.type, - timeStamp = eventValue.timeStamp; - - if (target == null || type == null || timeStamp == null) { - throw new Error( - 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' - ); - } - - var showWarning = function(name) { - { - warning$1( - false, - "%s is not available on event objects created from event responder modules (React Flare). " + - 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', - name, - name - ); - } - }; - - eventValue.preventDefault = function() { - { - showWarning("preventDefault()"); - } - }; - - eventValue.stopPropagation = function() { - { - showWarning("stopPropagation()"); - } - }; - - eventValue.isDefaultPrevented = function() { - { - showWarning("isDefaultPrevented()"); - } - }; - - eventValue.isPropagationStopped = function() { - { - showWarning("isPropagationStopped()"); - } - }; // $FlowFixMe: we don't need value, Flow thinks we do - - Object.defineProperty(eventValue, "nativeEvent", { - get: function() { - { - showWarning("nativeEvent"); - } - } - }); - } -} - -function getFiberFromTarget(target) { - if (target === null) { - return null; - } - - return target.canonical._internalInstanceHandle || null; -} - -function createFabricResponderEvent(topLevelType, nativeEvent, target) { - return { - nativeEvent: nativeEvent, - target: target, - type: topLevelType - }; -} - -function validateResponderContext() { - if (!currentInstance) { - throw Error( - "An event responder context was used outside of an event cycle." - ); - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function responderEventTypesContainType(eventTypes, type) { - for (var i = 0, len = eventTypes.length; i < len; i++) { - if (eventTypes[i] === type) { - return true; - } - } - - return false; -} - -function validateResponderTargetEventTypes(eventType, responder) { - var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder - - if (targetEventTypes !== null) { - return responderEventTypesContainType(targetEventTypes, eventType); - } - - return false; -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function traverseAndHandleEventResponderInstances( - eventType, - targetFiber, - nativeEvent -) { - // Trigger event responders in this order: - // - Bubble target responder phase - // - Root responder phase - var responderEvent = createFabricResponderEvent( - eventType, - nativeEvent, - targetFiber !== null ? targetFiber.stateNode : null - ); - var visitedResponders = new Set(); - var node = targetFiber; - - while (node !== null) { - var _node = node, - dependencies = _node.dependencies, - tag = _node.tag; - - if ( - (tag === HostComponent || tag === ScopeComponent) && - dependencies !== null - ) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for (var i = 0, length = responderInstances.length; i < length; i++) { - var responderInstance = responderInstances[i]; - var props = responderInstance.props, - responder = responderInstance.responder, - state = responderInstance.state; - - if ( - !visitedResponders.has(responder) && - validateResponderTargetEventTypes(eventType, responder) - ) { - var onEvent = responder.onEvent; - visitedResponders.add(responder); - - if (onEvent !== null) { - currentInstance = responderInstance; - onEvent(responderEvent, eventResponderContext, props, state); - } - } - } - } - } - - node = node.return; - } // Root phase - - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - eventType - ); - - if (rootEventResponderInstances !== undefined) { - var _responderInstances = Array.from(rootEventResponderInstances); - - for (var _i = 0; _i < _responderInstances.length; _i++) { - var _responderInstance = _responderInstances[_i]; - var props = _responderInstance.props, - responder = _responderInstance.responder, - state = _responderInstance.state; - var onRootEvent = responder.onRootEvent; - - if (onRootEvent !== null) { - currentInstance = _responderInstance; - onRootEvent(responderEvent, eventResponderContext, props, state); - } - } - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function dispatchEventForResponderEventSystem( - topLevelType, - targetFiber, - nativeEvent -) { - var previousInstance = currentInstance; - var previousTimeStamp = currentTimeStamp; // We might want to control timeStamp another way here - - currentTimeStamp = Date.now(); - - try { - batchedEventUpdates(function() { - traverseAndHandleEventResponderInstances( - topLevelType, - targetFiber, - nativeEvent - ); - }); - } finally { - currentInstance = previousInstance; - currentTimeStamp = previousTimeStamp; - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function mountEventResponder(responder, responderInstance, props, state) { - var onMount = responder.onMount; - - if (onMount !== null) { - currentInstance = responderInstance; - - try { - batchedEventUpdates(function() { - onMount(eventResponderContext, props, state); - }); - } finally { - currentInstance = null; - } - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function unmountEventResponder(responderInstance) { - var responder = responderInstance.responder; - var onUnmount = responder.onUnmount; - - if (onUnmount !== null) { - var props = responderInstance.props, - state = responderInstance.state; - currentInstance = responderInstance; - - try { - batchedEventUpdates(function() { - onUnmount(eventResponderContext, props, state); - }); - } finally { - currentInstance = null; - } - } - - var rootEventTypesSet = responderInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - var rootEventTypes = Array.from(rootEventTypesSet); - - for (var i = 0; i < rootEventTypes.length; i++) { - var topLevelEventType = rootEventTypes[i]; - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - topLevelEventType - ); - - if (rootEventResponderInstances !== undefined) { - rootEventResponderInstances.delete(responderInstance); - } - } - } -} - -function registerRootEventType(rootEventType, responderInstance) { - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - rootEventType - ); - - if (rootEventResponderInstances === undefined) { - rootEventResponderInstances = new Set(); - rootEventTypesToEventResponderInstances.set( - rootEventType, - rootEventResponderInstances - ); - } - - var rootEventTypesSet = responderInstance.rootEventTypes; - - if (rootEventTypesSet === null) { - rootEventTypesSet = responderInstance.rootEventTypes = new Set(); - } - - if (!!rootEventTypesSet.has(rootEventType)) { - throw Error( - 'addRootEventTypes() found a duplicate root event type of "' + - rootEventType + - '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' - ); - } - - rootEventTypesSet.add(rootEventType); - rootEventResponderInstances.add(responderInstance); -} - -function addRootEventTypesForResponderInstance( - responderInstance, - rootEventTypes -) { - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - registerRootEventType(rootEventType, responderInstance); - } -} - -function dispatchEvent(target, topLevelType, nativeEvent) { - var targetFiber = target; - - if (enableFlareAPI) { - // React Flare event system - dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); - } - - var eventTarget = null; - - if (enableNativeTargetAsInstance) { - if (targetFiber != null) { - eventTarget = targetFiber.stateNode.canonical; - } - } else { - eventTarget = nativeEvent.target; - } - - batchedUpdates(function() { - // Heritage plugin event system - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - eventTarget, - PLUGIN_EVENT_SYSTEM - ); - }); // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. -} - -// can re-export everything from this module. - -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Mutation (when unsupported) +function shim() { + { + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Mutation (when unsupported) var supportsMutation = false; var appendChild = shim; @@ -4478,21 +3948,21 @@ var didNotFindHydratableInstance = shim$1; var didNotFindHydratableTextInstance = shim$1; var didNotFindHydratableSuspenseInstance = shim$1; -var _nativeFabricUIManage$1 = nativeFabricUIManager; -var createNode = _nativeFabricUIManage$1.createNode; -var cloneNode = _nativeFabricUIManage$1.cloneNode; -var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var _nativeFabricUIManage = nativeFabricUIManager; +var createNode = _nativeFabricUIManage.createNode; +var cloneNode = _nativeFabricUIManage.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren; var cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; -var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; -var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; -var appendChildNode = _nativeFabricUIManage$1.appendChild; -var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; -var completeRoot = _nativeFabricUIManage$1.completeRoot; -var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; -var fabricMeasure = _nativeFabricUIManage$1.measure; -var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; -var fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout; + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage.createChildSet; +var appendChildNode = _nativeFabricUIManage.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet; +var completeRoot = _nativeFabricUIManage.completeRoot; +var registerEventHandler = _nativeFabricUIManage.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage.measure; +var fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage.measureLayout; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. // % 10 === 1 means it is a rootTag. @@ -4563,10 +4033,12 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } + return; } @@ -4579,10 +4051,10 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; }; @@ -4797,28 +4269,17 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -function mountResponderInstance( +function DEPRECATED_mountResponderInstance( responder, responderInstance, props, state, instance ) { - if (enableFlareAPI) { - var rootEventTypes = responder.rootEventTypes; - - if (rootEventTypes !== null) { - addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); - } - - mountEventResponder(responder, responderInstance, props, state); - } + throw new Error("Not yet implemented."); } -function unmountResponderInstance(responderInstance) { - if (enableFlareAPI) { - // TODO stop listening to targetEventTypes - unmountEventResponder(responderInstance); - } +function DEPRECATED_unmountResponderInstance(responderInstance) { + throw new Error("Not yet implemented."); } function getFundamentalComponentInstance(fundamentalInstance) { throw new Error("Not yet implemented."); @@ -4841,6 +4302,9 @@ function cloneFundamentalInstance(fundamentalInstance) { function getInstanceFromNode$1(node) { throw new Error("Not yet implemented."); } +function beforeRemoveInstance(instance) { + // noop +} var BEFORE_SLASH_RE = /^(.*)[\\\/]/; var describeComponentFrame = function(name, source, ownerName) { @@ -5424,7 +4888,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5432,7 +4896,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5619,8 +5083,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%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.", @@ -5819,7 +5283,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority$1 = 98; +var UserBlockingPriority = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -5851,7 +5315,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + return UserBlockingPriority; case Scheduler_NormalPriority: return NormalPriority; @@ -5873,7 +5337,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority$1: + case UserBlockingPriority: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -5891,7 +5355,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -5941,7 +5405,7 @@ function flushSyncCallbackQueueImpl() { try { var _isSync = true; var queue = syncQueue; - runWithPriority$1(ImmediatePriority, function() { + runWithPriority(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; @@ -6076,7 +5540,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority$1; + return UserBlockingPriority; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -6139,78 +5603,6 @@ function shallowEqual(objA, objB) { return true; } -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var lowPriorityWarningWithoutStack = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - - if (typeof console !== "undefined") { - console.warn(message); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (!condition) { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(void 0, [format].concat(args)); - } - }; -} - -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; - var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, flushPendingUnsafeLifecycleWarnings: function() {}, @@ -6381,8 +5773,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6396,8 +5788,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6415,8 +5806,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6429,8 +5819,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6448,8 +5837,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6468,8 +5856,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6494,11 +5881,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6531,8 +5918,8 @@ var ReactStrictModeWarnings = { }); var sortedNames = setToSortedString(uniqueNames); var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -7065,17 +6452,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue = nextValue; { - !( - context._currentRenderer === undefined || - context._currentRenderer === null || - context._currentRenderer === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer = rendererSigil; } } else { @@ -7083,17 +6470,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue2 = nextValue; { - !( - context._currentRenderer2 === undefined || - context._currentRenderer2 === null || - context._currentRenderer2 === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -7120,14 +6507,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) - ? warning$1( - false, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ) - : void 0; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7323,15 +6709,14 @@ function readContext(context, observedBits) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. - !!isDisallowedContextReadInDEV - ? warning$1( - false, - "Context can only be read while React is rendering. " + - "In classes, you can read it in the render method or getDerivedStateFromProps. " + - "In function components, you can read it directly in the function body, but not " + - "inside Hooks like useReducer() or useMemo()." - ) - : void 0; + if (isDisallowedContextReadInDEV) { + error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } } if (lastContextWithAllBitsObserved === context) { @@ -7472,38 +6857,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { - var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { +function initializeUpdateQueue(fiber) { var queue = { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + fiber.updateQueue = queue; +} +function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + baseQueue: currentQueue.baseQueue, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7511,9 +6890,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7521,136 +6900,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -function appendUpdateToQueue(queue, update) { - // Append the update to the end of the list. - if (queue.lastUpdate === null) { - // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; - } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -function enqueueUpdate(fiber, update) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1; - var queue2; + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } + update.next = pending.next; + pending.next = update; } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update); - appendUpdateToQueue(queue2, update); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - - queue2.lastUpdate = update; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "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." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } // Append the update to the end of the list. + if (current !== null) { + // Ensure the work-in-progress queue is a clone + cloneUpdateQueue(current, workInProgress); + } // Captured updates go only on the work-in-progress queue. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7742,163 +7047,171 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, - queue, props, instance, renderExpirationTime ) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; hasForceUpdate = false; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. + + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - if (updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; // Since this is the first update that was skipped, the current result - // is the new base state. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } else { - // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. - - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var callback = update.callback; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + do { + var updateExpirationTime = update.expirationTime; + + if (updateExpirationTime < renderExpirationTime) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + if (updateExpirationTime > newExpirationTime) { + newExpirationTime = updateExpirationTime; + } + } else { + // This update does have sufficient priority. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + + markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ); // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; - if (_updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is - // the new base state. + if (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // Since this update will remain in the list, update the remaining - // expiration time. - if (newExpirationTime < _updateExpirationTime) { - newExpirationTime = _updateExpirationTime; - } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; + update = update.next; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - update.nextEffect = null; - - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + update = baseQueue.next = pendingQueue.next; + pendingQueue.next = first; + queue.baseQueue = baseQueue = pendingQueue; + queue.shared.pending = null; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. - // This should be fine because the only two other things that contribute to - // expiration time are props and context. We're already in the middle of the - // begin phase by the time we start processing the queue, so we've already - // dealt with the props. Context in components that specify - // shouldComponentUpdate is tricky; but we'll have to account for - // that regardless. - - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - { currentlyProcessingQueue = null; } @@ -7927,36 +7240,20 @@ function commitUpdateQueue( instance, renderExpirationTime ) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } // Clear the list of captured updates. - - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; - } // Commit the effects - - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} - -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - effect = effect.nextEffect; + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } + } } } @@ -8001,8 +7298,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -8017,8 +7314,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -8075,9 +7372,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -8176,14 +7473,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(shouldUpdate !== undefined) - ? warningWithoutStack$1( - false, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ) - : void 0; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -8207,15 +7503,13 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -8223,54 +7517,50 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noGetInitialStateOnES6 = - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state; - !noGetInitialStateOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noGetDefaultPropsOnES6 = - !instance.getDefaultProps || - instance.getDefaultProps.isReactClassApproved; - !noGetDefaultPropsOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noInstancePropTypes = !instance.propTypes; - !noInstancePropTypes - ? warningWithoutStack$1( - false, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ) - : void 0; - var noInstanceContextType = !instance.contextType; - !noInstanceContextType - ? warningWithoutStack$1( - false, - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name - ) - : void 0; + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "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 + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "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 + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } if (disableLegacyContext) { if (ctor.childContextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy childContextTypes API which is no longer supported. " + "Use React.createContext() instead.", name @@ -8278,23 +7568,20 @@ function checkClassInstance(workInProgress, ctor, newProps) { } if (ctor.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with static contextType instead.", name ); } } else { - var noInstanceContextTypes = !instance.contextTypes; - !noInstanceContextTypes - ? warningWithoutStack$1( - false, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ) - : void 0; + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ); + } if ( ctor.contextType && @@ -8302,8 +7589,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8311,26 +7598,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noComponentShouldUpdate = - typeof instance.componentShouldUpdate !== "function"; - !noComponentShouldUpdate - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; + if (typeof instance.componentShouldUpdate === "function") { + error( + "%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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8338,70 +7621,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - var noComponentDidUnmount = - typeof instance.componentDidUnmount !== "function"; - !noComponentDidUnmount - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ) - : void 0; - var noComponentDidReceiveProps = - typeof instance.componentDidReceiveProps !== "function"; - !noComponentDidReceiveProps - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; - var noComponentWillRecieveProps = - typeof instance.componentWillRecieveProps !== "function"; - !noComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ) - : void 0; - var noUnsafeComponentWillRecieveProps = - typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - !noUnsafeComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ) - : void 0; + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%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 + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + var hasMutatedProps = instance.props !== newProps; - !(instance.props === undefined || !hasMutatedProps) - ? warningWithoutStack$1( - false, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ) - : void 0; - var noInstanceDefaultProps = !instance.defaultProps; - !noInstanceDefaultProps - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ); + } + + if (instance.defaultProps) { + error( + "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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8409,63 +7683,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - var noInstanceGetDerivedStateFromProps = - typeof instance.getDerivedStateFromProps !== "function"; - !noInstanceGetDerivedStateFromProps - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noInstanceGetDerivedStateFromCatch = - typeof instance.getDerivedStateFromError !== "function"; - !noInstanceGetDerivedStateFromCatch - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noStaticGetSnapshotBeforeUpdate = - typeof ctor.getSnapshotBeforeUpdate !== "function"; - !noStaticGetSnapshotBeforeUpdate - ? warningWithoutStack$1( - false, - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ) - : void 0; - var _state = instance.state; + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } - if (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", name ); } - if (typeof instance.getChildContext === "function") { - !(typeof ctor.childContextTypes === "object") - ? warningWithoutStack$1( - false, - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ) - : void 0; + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ); + } + + var _state = instance.state; + + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); } } } @@ -8524,8 +7788,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8569,8 +7832,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -8635,8 +7898,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -8678,8 +7941,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8716,8 +7978,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8744,6 +8006,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { @@ -8761,8 +8024,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -8786,19 +8049,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8821,18 +8073,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8891,18 +8138,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8992,6 +8229,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -9035,18 +8273,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -9208,8 +8436,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -9235,8 +8463,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!didWarnAboutStringRefs[componentName]) { if (warnAboutStringRefs) { - warningWithoutStack$1( - false, + error( 'Component "%s" contains the string ref "%s". Support for string refs ' + "will be removed in a future major release. We recommend using " + "useRef() or createRef() instead. " + @@ -9247,8 +8474,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } else { - warningWithoutStack$1( - false, + error( 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -9361,23 +8587,25 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); + { + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; + } - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - warning$1( - false, - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + + error( + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + ); + } } // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching @@ -9506,44 +8734,62 @@ function ChildReconciler(shouldTrackSideEffects) { ); created.return = returnFiber; return created; - } else { - // Update - var existing = useFiber(current$$1, textContent, expirationTime); - existing.return = returnFiber; - return existing; - } - } - - function updateElement(returnFiber, current$$1, element, expirationTime) { - if ( - current$$1 !== null && - (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current$$1, element)) - ) { - // Move based on index - var existing = useFiber(current$$1, element.props, expirationTime); - existing.ref = coerceRef(returnFiber, current$$1, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; + } else { + // Update + var existing = useFiber(current$$1, textContent, expirationTime); + existing.return = returnFiber; + return existing; } } + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (current$$1 !== null) { + if ( + current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } else if ( + enableChunksAPI && + current$$1.tag === Chunk && + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === current$$1.type.render + ) { + // Same as above but also update the .type field. + var _existing = useFiber(current$$1, element.props, expirationTime); + + _existing.return = returnFiber; + _existing.type = element.type; + + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; + } + } // Insert + + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( current$$1 === null || @@ -9859,8 +9105,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9868,6 +9113,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; default: @@ -10073,28 +9319,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !didWarnAboutGenerators - ? warning$1( - false, - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ) - : void 0; + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !didWarnAboutMaps - ? warning$1( - false, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ) - : void 0; + if (!didWarnAboutMaps) { + error( + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ); + } + didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10302,33 +9548,79 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - if ( - child.tag === Fragment - ? element.type === REACT_FRAGMENT_TYPE - : child.elementType === element.type || // Keep this check inline so it only runs on the false path: + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.props.children, + expirationTime + ); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } + + break; + } + + case Chunk: + if (enableChunksAPI) { + if ( + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === child.type.render + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing2 = useFiber(child, element.props, expirationTime); + + _existing2.type = element.type; + _existing2.return = returnFiber; + + { + _existing2._debugSource = element._source; + _existing2._debugOwner = element._owner; + } + + return _existing2; + } + } + + // We intentionally fallthrough here if enableChunksAPI is not on. + // eslint-disable-next-lined no-fallthrough + + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber( - child, - element.type === REACT_FRAGMENT_TYPE - ? element.props.children - : element.props, - expirationTime - ); - existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + var _existing3 = useFiber(child, element.props, expirationTime); + + _existing3.ref = coerceRef(returnFiber, child, element); + _existing3.return = returnFiber; + + { + _existing3._debugSource = element._source; + _existing3._debugOwner = element._owner; + } + + return _existing3; + } + + break; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10784,7 +10076,7 @@ function createResponderInstance( }; } -function mountEventResponder$1( +function mountEventResponder( responder, responderProps, fiber, @@ -10823,7 +10115,7 @@ function mountEventResponder$1( } } - mountResponderInstance( + DEPRECATED_mountResponderInstance( responder, responderInstance, responderProps, @@ -10859,8 +10151,7 @@ function updateEventListener( if (visistedResponders.has(responder)) { // show warning { - warning$1( - false, + error( 'Duplicate event responder "%s" found in event listeners. ' + "Event listeners passed to elements cannot use the same event responder more than once.", responder.displayName @@ -10875,7 +10166,7 @@ function updateEventListener( if (responderInstance === undefined) { // Mount (happens in either complete or commit phase) - mountEventResponder$1( + mountEventResponder( responder, listenerProps, fiber, @@ -10889,7 +10180,11 @@ function updateEventListener( } } -function updateEventListeners(listeners, fiber, rootContainerInstance) { +function updateDeprecatedEventListeners( + listeners, + fiber, + rootContainerInstance +) { var visistedResponders = new Set(); var dependencies = fiber.dependencies; @@ -10905,7 +10200,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { var respondersMap = dependencies.responders; if (respondersMap === null) { - respondersMap = new Map(); + dependencies.responders = respondersMap = new Map(); } if (isArray$2(listeners)) { @@ -10943,7 +10238,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { if (!visistedResponders.has(mountedResponder)) { var responderInstance = _respondersMap.get(mountedResponder); - unmountResponderInstance(responderInstance); + DEPRECATED_unmountResponderInstance(responderInstance); _respondersMap.delete(mountedResponder); } @@ -10951,7 +10246,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { } } } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10963,6 +10258,24 @@ function createResponderListener(responder, props) { return eventResponderListener; } +function unmountDeprecatedResponderListeners(fiber) { + var dependencies = fiber.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + DEPRECATED_unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } +} var NoEffect$1 = /* */ @@ -11007,13 +10320,7 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var nextCurrentHook = null; -var firstWorkInProgressHook = null; -var workInProgressHook = null; -var nextWorkInProgressHook = null; -var remainingExpirationTime = NoWork; -var componentUpdateQueue = null; -var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the // end of the current pass. We can't store these updates on the normal queue, // because if the work is aborted, they should be discarded. Because this is // a relatively rare case, we also don't want to add an additional field to @@ -11071,8 +10378,7 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -11108,8 +10414,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -11143,8 +10448,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -11159,8 +10463,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -11188,12 +10491,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -11201,24 +10503,25 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // The following should have already been reset // currentHook = null; // workInProgressHook = null; - // remainingExpirationTime = NoWork; - // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; - // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { + if (current !== null && current.memoizedState !== null) { ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, @@ -11232,7 +10535,7 @@ function renderWithHooks( } } - var children = Component(props, refOrContext); + var children = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do { @@ -11245,11 +10548,9 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. @@ -11257,7 +10558,7 @@ function renderWithHooks( } ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); + children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; @@ -11266,14 +10567,9 @@ function renderWithHooks( // at the beginning of the render phase and there's no re-entrancy. ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. @@ -11281,20 +10577,13 @@ function renderWithHooks( renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } - - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above + } // These were reset above // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; @@ -11325,10 +10614,7 @@ function resetHooks() { renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11336,9 +10622,6 @@ function resetHooks() { currentHookNameInDev = null; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -11348,14 +10631,14 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11370,12 +10653,33 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; - nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -11386,20 +10690,18 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11427,13 +10729,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11485,7 +10787,7 @@ function updateReducer(reducer, initialArg, init) { // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. - if (hook.baseUpdate === queue.last) { + if (hook.baseQueue === null) { hook.baseState = newState; } @@ -11495,35 +10797,37 @@ function updateReducer(reducer, initialArg, init) { } return [hook.memoizedState, _dispatch]; - } // The last update in the entire queue + } - var last = queue.last; // The last update that is part of the base state. + var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - var first; + var pendingQueue = queue.pending; - if (baseUpdate !== null) { - if (last !== null) { - // For the first update, the queue is a circular linked list where - // `queue.last.next = queue.first`. Once the first update commits, and - // the `baseUpdate` is no longer empty, we can unravel the list. - last.next = null; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var _newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; var _update = first; - var didSkip = false; do { var updateExpirationTime = _update.expirationTime; @@ -11532,24 +10836,46 @@ function updateReducer(reducer, initialArg, init) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; newBaseState = _newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig @@ -11565,13 +10891,13 @@ function updateReducer(reducer, initialArg, init) { } } - prevUpdate = _update; _update = _update.next; } while (_update !== null && _update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; + if (newBaseQueueLast === null) { newBaseState = _newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. @@ -11580,8 +10906,8 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = _newState; } @@ -11598,13 +10924,13 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11624,9 +10950,11 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -11666,7 +10994,7 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } @@ -11689,7 +11017,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } @@ -11747,14 +11075,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !refObject.hasOwnProperty("current") - ? warning$1( - false, - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ) - : void 0; + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } } var _inst2 = create(); @@ -11768,14 +11095,13 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11790,14 +11116,13 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11880,17 +11205,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -11904,47 +11226,54 @@ function updateDeferredValue(value, config) { updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); return prevValue; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority( + priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, + function() { + setPending(true); + } + ); + runWithPriority( + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + } + ); +} + function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var startTransition = mountCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { @@ -11952,25 +11281,11 @@ function updateTransition(config) { isPending = _updateState2[0], setPending = _updateState2[1]; - var startTransition = updateCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { @@ -11981,14 +11296,13 @@ function dispatchAction(fiber, queue, action) { } { - !(typeof arguments[3] !== "function") - ? warning$1( - false, - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ) - : void 0; + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } } var alternate = fiber.alternate; @@ -12053,23 +11367,17 @@ function dispatchAction(fiber, queue, action) { _update2.priority = getCurrentPriorityLevel(); } // Append the update to the end of the list. - var last = queue.last; + var pending = queue.pending; - if (last === null) { + if (pending === null) { // This is the first update. Create a circular list. _update2.next = _update2; } else { - var first = last.next; - - if (first !== null) { - // Still circular. - _update2.next = first; - } - - last.next = _update2; + _update2.next = pending.next; + pending.next = _update2; } - queue.last = _update2; + queue.pending = _update2; if ( fiber.expirationTime === NoWork && @@ -12105,7 +11413,7 @@ function dispatchAction(fiber, queue, action) { // time the reducer has changed. return; } - } catch (error) { + } catch (error$$1) { // Suppress the error. It will throw again in the render phase. } finally { { @@ -12151,8 +11459,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; { var warnInvalidContextAccess = function() { - warning$1( - false, + error( "Context can only be read while React is rendering. " + "In classes, you can read it in the render method or getDerivedStateFromProps. " + "In function components, you can read it directly in the function body, but not " + @@ -12161,8 +11468,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -12253,7 +11559,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12344,7 +11650,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12435,7 +11741,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12538,7 +11844,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12643,7 +11949,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12723,12 +12029,11 @@ var isHydrating = false; function warnIfHydrating() { { - !!isHydrating - ? warning$1( - false, - "We should not be hydrating here. This is a bug in React. Please file a bug." - ) - : void 0; + if (isHydrating) { + error( + "We should not be hydrating here. This is a bug in React. Please file a bug." + ); + } } } @@ -13255,8 +12560,8 @@ function forceUnmountCurrentAndReconcile( renderExpirationTime ); // In the second pass, we mount the new children. The trick here is that we // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13516,7 +12821,7 @@ function updateSimpleMemoComponent( if ( shallowEqual(prevProps, nextProps) && - current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current$$1.type ) { didReceiveUpdate = false; @@ -13676,6 +12981,73 @@ function updateFunctionComponent( return workInProgress.child; } +function updateChunk( + current$$1, + workInProgress, + chunk, + nextProps, + renderExpirationTime +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + var render = chunk.render; + var data = chunk.query(); // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + function updateClassComponent( current$$1, workInProgress, @@ -13718,9 +13090,9 @@ function updateClassComponent( if (instance === null) { if (current$$1 !== null) { - // An class component without an instance only mounts if it suspended - // inside a non- concurrent tree, in an inconsistent state. We want to - // tree it like a new mount, even though an empty version of it already + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect @@ -13772,14 +13144,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (inst.props !== nextProps) { - !didWarnAboutReassigningProps - ? warning$1( - false, - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" - ) - : void 0; + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); + } + didWarnAboutReassigningProps = true; } } @@ -13821,7 +13193,7 @@ function finishClassComponent( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. @@ -13900,7 +13272,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + if (!(current$$1 !== null && updateQueue !== null)) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); @@ -13909,13 +13281,8 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current$$1, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". @@ -13989,7 +13356,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { if (isDirectTextChild) { // We special case a direct text child of a host node. This is a common // case. We won't handle it as a reified child. We will instead handle - // this in the host environment that also have access to this prop. That + // this in the host environment that also has access to this prop. That // avoids allocating another HostText fiber and traversing it. nextChildren = null; } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { @@ -14039,7 +13406,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. // Disconnect the alternate pointers. @@ -14077,7 +13444,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -14094,7 +13461,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -14111,7 +13478,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -14139,36 +13506,48 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } - default: { - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + case Chunk: { + if (enableChunksAPI) { + // TODO: Resolve for Hot Reloading. + child = updateChunk( + null, + workInProgress, + Component, + props, + renderExpirationTime ); + return child; } + + break; } } - return child; + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } function mountIncompleteClassComponent( @@ -14262,13 +13641,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "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 ); + didWarnAboutBadClass[componentName] = true; } } @@ -14300,8 +13679,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to be a function component that returns a class instance. " + "Change %s to a class that extends React.Component instead. " + "If you can't use a class try assigning the prototype on the function as a workaround. " + @@ -14311,6 +13689,7 @@ function mountIndeterminateComponent( _componentName, _componentName ); + didWarnAboutModulePatternComponent[_componentName] = true; } } // Proceed under the assumption that this is a class instance @@ -14332,6 +13711,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14359,8 +13739,7 @@ function mountIndeterminateComponent( { if (disableLegacyContext && Component.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with React.useContext() instead.", getComponentName(Component) || "Unknown" @@ -14396,86 +13775,87 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; - warning$1( - false, - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - } - if ( - warnAboutDefaultPropsOnFunctionComponents && - Component.defaultProps !== undefined - ) { - var componentName = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { - warningWithoutStack$1( - false, - "%s: Support for defaultProps will be removed from function components " + - "in a future major release. Use JavaScript default parameters instead.", - componentName - ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } } - } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - warningWithoutStack$1( - false, - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14547,8 +13927,8 @@ function updateSuspenseComponent( if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { didWarnAboutMaxDuration = true; - warning$1( - false, + + error( "maxDuration has been removed from React. " + "Remove the maxDuration prop." ); @@ -14920,7 +14300,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -14966,8 +14346,7 @@ function mountDehydratedSuspenseComponent( // Instead, we'll leave the content in place and try to hydrate it later. if ((workInProgress.mode & BlockingMode) === NoMode) { { - warning$1( - false, + error( "Cannot hydrate Suspense in legacy mode. Switch from " + "ReactDOM.hydrate(element, container) to " + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + @@ -15227,40 +14606,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15275,16 +14653,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15302,8 +14680,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15313,6 +14691,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15353,8 +14732,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + error( 'A single row was passed to a . ' + "This is not useful since it needs multiple rows. " + "Did you mean to pass multiple children or an array?", @@ -15380,6 +14758,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15390,6 +14769,7 @@ function initSuspenseListRenderState( // We can reuse the existing object from previous renders. renderState.isBackwards = isBackwards; renderState.rendering = null; + renderState.renderingStartTime = 0; renderState.last = lastContentRow; renderState.tail = tail; renderState.tailExpiration = 0; @@ -15662,8 +15042,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15678,15 +15058,14 @@ function updateContextConsumer( var render = newProps.children; { - !(typeof render === "function") - ? warningWithoutStack$1( - false, - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ) - : void 0; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -16294,6 +15673,22 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; } + + case Chunk: { + if (enableChunksAPI) { + var chunk = workInProgress.type; + var props = workInProgress.pendingProps; + return updateChunk( + current$$1, + workInProgress, + chunk, + props, + renderExpirationTime + ); + } + + break; + } } { @@ -16978,6 +16373,8 @@ if (supportsMutation) { // This lets the parents know that at least one of their children has changed. markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; } }; } else { @@ -17076,14 +16473,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -17092,7 +16491,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -17118,7 +16517,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -17135,9 +16534,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = current.memoizedProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { markUpdate(workInProgress); @@ -17155,12 +16554,12 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return null; } var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on we want to add then top->down or + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. var _wasHydrated = popHydrationState(workInProgress); @@ -17175,16 +16574,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { currentHostContext ) ) { - // If changes to the hydrated node needs to be applied at the + // If changes to the hydrated node need to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } - if (enableFlareAPI) { - var listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var listeners = newProps.DEPRECATED_flareListeners; if (listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( listeners, workInProgress, rootContainerInstance @@ -17203,11 +16602,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = instance; - if (enableFlareAPI) { - var _listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners = newProps.DEPRECATED_flareListeners; if (_listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( _listeners, workInProgress, rootContainerInstance @@ -17236,7 +16635,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17276,12 +16675,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - case ForwardRef: - break; - case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; @@ -17307,15 +16703,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { // We should never have been in a hydration state if we didn't have a current. // However, in some of those paths, we might have reentered a hydration state - // and then we might be inside a hydration state. In that case, we'll need to - // exit out of it. + // and then we might be inside a hydration state. In that case, we'll need to exit out of it. resetHydrationState(); if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated and unsuspended. workInProgress.memoizedState = null; } // If nothing suspended, we need to schedule an effect to mark this boundary - // as having hydrated so events know that they're free be invoked. + // as having hydrated so events know that they're free to be invoked. // It's also a signal to replay events and the suspense callback. // If something suspended, schedule an effect to attach retry listeners. // So we might as well always mark this. @@ -17408,7 +16803,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if not prevDidTimeout. if (nextDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. workInProgress.effectTag |= Update; } @@ -17418,9 +16813,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if these values are non equal, i.e. it changed. if (nextDidTimeout || prevDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } @@ -17435,33 +16830,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17472,7 +16852,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17480,9 +16860,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var renderState = workInProgress.memoizedState; if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17598,7 +16978,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // The time it took to render last row is greater than time until + // the expiration. + now() * 2 - renderState.renderingStartTime > + renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -17648,13 +17031,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this + // is a per component value. It should really be since the start + // of the total render or last commit. Consider using something like + // globalMostRecentFallbackTime. That doesn't account for being + // suspended for part of the time or when it's a new render. + // It should probably use a global start time value instead. } // Pop a row. var next = renderState.tail; renderState.rendering = next; renderState.tail = next.sibling; renderState.lastEffect = workInProgress.lastEffect; + renderState.renderingStartTime = now(); next.sibling = null; // Restore the context. // TODO: We can probably just avoid popping it instead and only // setting it the first time we go from not suspended to suspended. @@ -17675,7 +17064,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; + return null; } case FundamentalComponent: { @@ -17730,6 +17119,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } + + return null; } break; @@ -17746,13 +17137,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = scopeInstance; scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners2 = newProps.DEPRECATED_flareListeners; if (_listeners2 != null) { var _rootContainerInstance2 = getRootHostContainer(); - updateEventListeners( + updateDeprecatedEventListeners( _listeners2, workInProgress, _rootContainerInstance2 @@ -17765,9 +17156,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - if (enableFlareAPI) { - var _prevListeners = current.memoizedProps.listeners; - var _nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _prevListeners = + current.memoizedProps.DEPRECATED_flareListeners; + var _nextListeners = newProps.DEPRECATED_flareListeners; if ( _prevListeners !== _nextListeners || @@ -17785,21 +17177,28 @@ function completeWork(current, workInProgress, renderExpirationTime) { markRef$1(workInProgress); } } + + return null; } break; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + case Chunk: + if (enableChunksAPI) { + return null; + } + + break; } - return null; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } function unwindWork(workInProgress, renderExpirationTime) { @@ -17992,7 +17391,8 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console.error(error); // For a more detailed description of this block, see: + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -18029,7 +17429,7 @@ function logCapturedError(capturedError) { // has already printed it. Even if the application swallows the error, it is still // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - console.error(combinedMessage); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -18127,8 +17527,8 @@ function safelyCallDestroy(current$$1, destroy) { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(current$$1, error$$1); } } } @@ -18137,7 +17537,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } @@ -18157,28 +17558,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18194,8 +17594,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -18218,14 +17618,12 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18281,8 +17679,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { addendum = " You returned: " + _destroy; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18302,7 +17699,8 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; @@ -18323,9 +17721,10 @@ function commitLifeCycles( switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + return; } case ClassComponent: { @@ -18342,28 +17741,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18387,28 +17785,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18429,28 +17826,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -18562,14 +17958,12 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18656,8 +18050,7 @@ function commitAttachRef(finishedWork) { } else { { if (!ref.hasOwnProperty("current")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18692,7 +18085,8 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { @@ -18716,7 +18110,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel; - runWithPriority$1(priorityLevel, function() { + runWithPriority(priorityLevel, function() { var effect = firstEffect; do { @@ -18732,7 +18126,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } } - break; + return; } case ClassComponent: { @@ -18747,27 +18141,9 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ - ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); - } - - dependencies.responders = null; - } - } + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + beforeRemoveInstance(current$$1.stateNode); } safelyDetachRef(current$$1); @@ -18817,9 +18193,15 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case ScopeComponent: { + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + } + if (enableScopeAPI) { safelyDetachRef(current$$1); } + + return; } } } @@ -18880,6 +18262,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; if (alternate !== null) { detachFiber(alternate); @@ -18916,14 +18299,12 @@ function commitContainer(finishedWork) { pendingChildren = portalOrRoot.pendingChildren; return; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19259,7 +18640,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19304,7 +18686,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19342,12 +18725,12 @@ function commitWork(current$$1, finishedWork) { ); } - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = oldProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + updateDeprecatedEventListeners(nextListeners, finishedWork, null); } } } @@ -19409,9 +18792,10 @@ function commitWork(current$$1, finishedWork) { if (enableFundamentalAPI) { var fundamentalInstance = finishedWork.stateNode; updateFundamentalComponent(fundamentalInstance); + return; } - return; + break; } case ScopeComponent: { @@ -19419,31 +18803,31 @@ function commitWork(current$$1, finishedWork) { var scopeInstance = finishedWork.stateNode; scopeInstance.fiber = finishedWork; - if (enableFlareAPI) { + if (enableDeprecatedFlareAPI) { var _newProps = finishedWork.memoizedProps; var _oldProps = current$$1 !== null ? current$$1.memoizedProps : _newProps; - var _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + var _prevListeners = _oldProps.DEPRECATED_flareListeners; + var _nextListeners = _newProps.DEPRECATED_flareListeners; - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); + if (_prevListeners !== _nextListeners || current$$1 === null) { + updateDeprecatedEventListeners(_nextListeners, finishedWork, null); } } + + return; } - return; + break; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19475,7 +18859,7 @@ function commitSuspenseComponent(finishedWork) { } } else { if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + error("Unexpected type for suspenseCallback."); } } } @@ -19568,10 +18952,10 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { update.payload = { element: null }; - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.callback = function() { - onUncaughtError(error); + onUncaughtError(error$$1); logError(fiber, errorInfo); }; @@ -19584,11 +18968,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$$1); }; } @@ -19611,9 +18995,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$$1, { componentStack: stack !== null ? stack : "" }); @@ -19622,14 +19006,13 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(fiber.expirationTime === Sync) - ? warningWithoutStack$1( - false, - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ) - : void 0; + if (fiber.expirationTime !== Sync) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } } } }; @@ -19694,6 +19077,20 @@ function throwException( ) { // This is a thenable. var thenable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.expirationTime = currentSource.expirationTime; + } else { + sourceFiber.memoizedState = null; + } + } + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, @@ -20018,7 +19415,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { expirationTime = Sync; break; - case UserBlockingPriority$1: + case UserBlockingPriority: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; @@ -20100,7 +19497,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || + (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -20219,9 +19616,21 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; + var nextLevel = + lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; + + if ( + enableTrainModelFix && + nextLevel <= Idle && + firstPendingTime !== nextLevel + ) { + // Don't work on Idle/Never priority unless everything else is committed. + return NoWork; + } + + return nextLevel; } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the // expiration time of the existing task is the same as the expiration time of @@ -20669,80 +20078,70 @@ function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; - if (root.finishedExpirationTime === expirationTime) { - // There's already a pending commit at this expiration time. - // TODO: This is poorly factored. This case only exists for the - // batch.commit() API. - commitRoot(root); - } else { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } // If we have a work-in-progress fiber, it means there's still work to do - // in this root. + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); } + } while (true); - if (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } else { - // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. - stopFinishedWorkLoopTimer(); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - finishSyncRender(root, workInProgressRootExitStatus, expirationTime); - } // Before exiting, make sure there's a callback scheduled for the next - // pending level. + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); ensureRootIsScheduled(root); + throw fatalError; } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } return null; @@ -20770,12 +20169,13 @@ function flushDiscreteUpdates() { (executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext ) { - if (true && (executionContext & RenderContext) !== NoContext) { - warning$1( - false, - "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + - "already rendering." - ); + { + if ((executionContext & RenderContext) !== NoContext) { + error( + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } } // We're already rendering, so we can't synchronously flush pending work. // This is probably a nested event dispatch triggered by a lifecycle/effect, // like `el.focus()`. Exit. @@ -20790,7 +20190,7 @@ function flushDiscreteUpdates() { } function syncUpdates(fn, a, b, c) { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c)); + return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } function flushPendingDiscreteUpdates() { @@ -20844,7 +20244,7 @@ function discreteUpdates$1(fn, a, b, c) { try { // Should this - return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); } finally { executionContext = prevExecutionContext; @@ -20868,7 +20268,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } finally { executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -21353,7 +20753,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1( + runWithPriority( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -21361,7 +20761,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21455,8 +20864,8 @@ function commitRootImpl(root, renderPriorityLevel) { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(nextEffect, error$$1); nextEffect = nextEffect.nextEffect; } } @@ -21792,7 +21201,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } @@ -21828,8 +21237,8 @@ function flushPassiveEffectsImpl() { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(effect, error$$1); } resetCurrentFiber(); @@ -21869,17 +21278,17 @@ function markLegacyErrorBoundaryAsFailed(instance) { } } -function prepareToThrowUncaughtError(error) { +function prepareToThrowUncaughtError(error$$1) { if (!hasUncaughtError) { hasUncaughtError = true; - firstUncaughtError = error; + firstUncaughtError = error$$1; } } var onUncaughtError = prepareToThrowUncaughtError; -function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - var errorInfo = createCapturedValue(error, sourceFiber); +function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error$$1) { + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createRootErrorUpdate(rootFiber, errorInfo, Sync); enqueueUpdate(rootFiber, update); var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync); @@ -21890,11 +21299,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, error$$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$$1); return; } @@ -21902,7 +21311,7 @@ function captureCommitPhaseError(sourceFiber, error) { while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -21913,7 +21322,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createClassErrorUpdate( fiber, errorInfo, // TODO: This is always sync @@ -21987,7 +21396,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { root.lastPingedTime = suspendedTime; - if (root.finishedExpirationTime === suspendedTime) { + if (!enableTrainModelFix && root.finishedExpirationTime === suspendedTime) { // If there's a pending fallback waiting to commit, throw it away. root.finishedExpirationTime = NoWork; root.finishedWork = null; @@ -22141,8 +21550,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -22197,7 +21606,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Chunk ) { // Only warn for user-defined components, not internal ones like Suspense. return; @@ -22216,8 +21626,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -22308,10 +21717,10 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "setState(...): Cannot call setState() inside getChildContext()" ); + didWarnAboutUpdateInGetChildContext = true; break; @@ -22320,12 +21729,12 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "Cannot update during an existing state transition (such as " + "within `render`). Render methods should be a pure function of " + "props and state." ); + didWarnAboutUpdateInRender = true; break; } @@ -22343,8 +21752,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "It looks like you're using the wrong act() around your test interactions.\n" + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + "// for react-dom:\n" + @@ -22370,8 +21778,7 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22398,8 +21805,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22433,8 +21839,8 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22443,8 +21849,8 @@ function warnIfUnmockedScheduler(fiber) { ); } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'Starting from React v17, the "scheduler" module will need to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22462,7 +21868,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { if ( (sourceFiber.mode & ConcurrentMode) !== NoEffect && - (currentPriorityLevel === UserBlockingPriority$1 || + (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority) ) { var workInProgressNode = sourceFiber; @@ -22481,13 +21887,13 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { - var update = updateQueue.firstUpdate; + var update = updateQueue.baseQueue; while (update !== null) { var priorityLevel = update.priority; if ( - priorityLevel === UserBlockingPriority$1 || + priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority ) { if (componentsThatTriggeredHighPriSuspend === null) { @@ -22512,18 +21918,18 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { case FunctionComponent: case ForwardRef: case SimpleMemoComponent: - if ( - workInProgressNode.memoizedState !== null && - workInProgressNode.memoizedState.baseUpdate !== null - ) { - var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + case Chunk: { + var firstHook = current$$1.memoizedState; // TODO: This just checks the first Hook. Isn't it suppose to check all Hooks? + + if (firstHook !== null && firstHook.baseQueue !== null) { + var _update = firstHook.baseQueue; // Loop through the functional component's memoized state to see whether // the component has triggered any high pri updates while (_update !== null) { var priority = _update.priority; if ( - priority === UserBlockingPriority$1 || + priority === UserBlockingPriority || priority === ImmediatePriority ) { if (componentsThatTriggeredHighPriSuspend === null) { @@ -22539,9 +21945,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { break; } - if ( - _update.next === workInProgressNode.memoizedState.baseUpdate - ) { + if (_update.next === firstHook.baseQueue) { break; } @@ -22550,6 +21954,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { } break; + } default: break; @@ -22572,8 +21977,7 @@ function flushSuspensePriorityWarningInDEV() { componentsThatTriggeredHighPriSuspend = null; if (componentNames.length > 0) { - warningWithoutStack$1( - false, + error( "%s triggered a user-blocking update that suspended." + "\n\n" + "The fix is to split the update into multiple parts: a user-blocking " + @@ -22686,10 +22090,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { try { subscriber.onWorkStarted(interactions, threadID); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22711,10 +22115,10 @@ function finishPendingInteractions(root, committedExpirationTime) { var threadID = computeThreadID(root, committedExpirationTime); subscriber.onWorkStopped(root.memoizedInteractions, threadID); } - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } finally { // Clear completed interactions from the pending Map. @@ -22736,10 +22140,10 @@ function finishPendingInteractions(root, committedExpirationTime) { if (subscriber !== null && interaction.__count === 0) { try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22749,6 +22153,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22770,8 +22175,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "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" @@ -22784,6 +22188,23 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + { + // Only used by Fast Refresh + if (typeof hook.onScheduleFiberRoot === "function") { + onScheduleFiberRoot = function(root, children) { + try { + hook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + }; + } + } + onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -22799,13 +22220,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22814,29 +22234,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation encountered an error: %s.", err); } } // DevTools exists return true; } +function onScheduleRoot(root, children) { + if (typeof onScheduleFiberRoot === "function") { + onScheduleFiberRoot(root, children); + } +} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -22984,6 +22404,12 @@ function resolveLazyComponentTag(Component) { if ($$typeof === REACT_MEMO_TYPE) { return MemoComponent; } + + if (enableChunksAPI) { + if ($$typeof === REACT_CHUNK_TYPE) { + return Chunk; + } + } } return IndeterminateComponent; @@ -23264,6 +22690,10 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; + case REACT_CHUNK_TYPE: + fiberTag = Chunk; + break getTag; + case REACT_FUNDAMENTAL_TYPE: if (enableFundamentalAPI) { return createFiberFromFundamental( @@ -23389,8 +22819,7 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { typeof pendingProps.id !== "string" || typeof pendingProps.onRender !== "function" ) { - warningWithoutStack$1( - false, + error( 'Profiler must specify an "id" string and "onRender" function as props' ); } @@ -23552,6 +22981,7 @@ function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -23645,15 +23075,6 @@ function markRootExpiredAtTime(root, expirationTime) { } } -// This lets us hook into Fiber to debug what it's doing. -// See https://github.com/facebook/react/pull/8033. -// This is not part of the public API, not even for React DevTools. -// You may only inject a debugTool if you work on React Fiber itself. -var ReactFiberInstrumentation = { - debugTool: null -}; -var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; - var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -23740,8 +23161,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23753,8 +23173,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23779,6 +23198,10 @@ function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); @@ -23796,19 +23219,6 @@ function updateContainer(element, container, parentComponent, callback) { current$$1, suspenseConfig ); - - { - if (ReactFiberInstrumentation_1.debugTool) { - if (current$$1.alternate === null) { - ReactFiberInstrumentation_1.debugTool.onMountContainer(container); - } else if (element === null) { - ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); - } else { - ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); - } - } - } - var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -23820,8 +23230,8 @@ function updateContainer(element, container, parentComponent, callback) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23840,14 +23250,16 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ) - : void 0; + ); + } + } + update.callback = callback; } @@ -24005,7 +23417,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.11.0"; +var ReactVersion = "16.12.0-experimental-19f6fe170"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -24049,7 +23461,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24095,7 +23507,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24139,7 +23551,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24147,12 +23559,14 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24165,10 +23579,12 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24200,7 +23616,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24208,10 +23624,10 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; } @@ -24302,7 +23718,13 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { return NativeMethodsMixin; }; -var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} + +var ReactNativeComponent = function(findNodeHandle, findHostInstance) { /** * Superclass that provides methods to access the underlying native component. * This can be useful when you want to focus a view or measure its dimensions. @@ -24371,7 +23793,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24415,7 +23837,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24456,7 +23878,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24464,12 +23886,14 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24482,10 +23906,12 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24517,7 +23943,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24525,10 +23951,12 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error( + "Warning: setNativeProps is not currently supported in Fabric" + ); + } + return; } @@ -24672,8 +24100,6 @@ var getInspectorDataForViewTag; }; } -var _nativeFabricUIManage = nativeFabricUIManager; -var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { @@ -24681,17 +24107,17 @@ function findHostInstance_DEPRECATED(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24734,17 +24160,17 @@ function findNodeHandle(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24796,31 +24222,36 @@ setBatchingImplementation( ); var roots = new Map(); var ReactFabric = { - NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), + NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), // This is needed for implementation details of TouchableNativeFeedback // Remove this once TouchableNativeFeedback doesn't use cloneElement findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { - var invalid = - handle._nativeTag == null || handle._internalInstanceHandle == null; - - if (invalid) { - !!invalid - ? warningWithoutStack$1( - false, - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ) - : void 0; + if (handle._nativeTag == null) { + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + return; } - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index 1d431cb1a3de42..398cab778a59af 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -16,13 +16,110 @@ if (__DEV__) { (function() { "use strict"; +var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); -var React = require("react"); -var Scheduler = require("scheduler"); var checkPropTypes = require("prop-types/checkPropTypes"); +var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// by calls to these methods by a Babel plugin. +// +// In PROD (or in packages without access to React internals), +// they are left as they are instead. + +function warn(format) { + { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); + } +} +function error(format) { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } +} + +function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === "string" && + args[args.length - 1].indexOf("\n in") === 0; + + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } + } + + var argsWithFormat = args.map(function(item) { + return "" + item; + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + } +} + /** * Use invariant() to assert state which your program assumes to be true. * @@ -560,71 +657,6 @@ function clearCaughtError() { } } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var warningWithoutStack = function() {}; - -{ - warningWithoutStack = function(condition, format) { - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - if (format === undefined) { - throw new Error( - "`warningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (args.length > 8) { - // Check before the condition to catch violations early. - throw new Error( - "warningWithoutStack() currently supports at most 8 arguments." - ); - } - - if (condition) { - return; - } - - if (typeof console !== "undefined") { - var argsWithFormat = args.map(function(item) { - return "" + item; - }); - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - - Function.prototype.apply.call(console.error, console, argsWithFormat); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} - }; -} - -var warningWithoutStack$1 = warningWithoutStack; - var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -638,13 +670,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -665,9 +696,10 @@ var validateEventDispatches; : dispatchInstances ? 1 : 0; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -1094,6 +1126,7 @@ var DehydratedFragment = 18; var SuspenseListComponent = 19; var FundamentalComponent = 20; var ScopeComponent = 21; +var Chunk = 22; function getParent(inst) { do { @@ -1231,9 +1264,9 @@ function listenerAtPhase(inst, event, propagationPhase) { function accumulateDirectionalDispatches(inst, phase, event) { { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; + if (!inst) { + error("Dispatching inst must not be null"); + } } var listener = listenerAtPhase(inst, event, phase); @@ -1578,7 +1611,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function set(val) { var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); + warn$$1(action, "This is effectively a no-op"); return val; } @@ -1587,24 +1620,22 @@ function getPooledWarningPropertyDefinition(propName, getVal) { var result = isFunction ? "This is a no-op function" : "This is set to null"; - warn(action, result); + warn$$1(action, result); return getVal; } - function warn(action, result) { - var warningCondition = false; - !warningCondition - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + function warn$$1(action, result) { + { + error( + "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 + ); + } } } @@ -1749,15 +1780,14 @@ function getTouchIdentifier(_ref) { } { - !(identifier <= MAX_TOUCH_BANK) - ? warningWithoutStack$1( - false, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ) - : void 0; + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } } return identifier; @@ -1789,12 +1819,15 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1811,12 +1844,15 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1867,9 +1903,10 @@ var ResponderTouchHistoryStore = { { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } } } } @@ -2398,9 +2435,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2575,7 +2615,9 @@ var enableProfilerTimer = true; var enableSchedulerTracing = true; var enableSuspenseServerRenderer = false; -var enableFlareAPI = false; +var enableChunksAPI = false; + +var enableDeprecatedFlareAPI = false; var enableFundamentalAPI = false; var enableScopeAPI = false; @@ -2586,6 +2628,7 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +var enableTrainModelFix = false; var enableNativeTargetAsInstance = false; // Only used in www builds. @@ -2667,23 +2710,6 @@ function set(key, value) { key._reactInternalFiber = value; } -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} - // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -2710,6 +2736,7 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; +var REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 0xead9; var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 0xead5; @@ -2733,43 +2760,6 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; - -{ - warning = function(condition, format) { - if (condition) { - return; - } - - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args - - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} - -var warning$1 = warning; - var Uninitialized = -1; var Pending = 0; var Resolved = 1; @@ -2790,8 +2780,7 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + "Instead received: %s\n\nYour code should look like: \n " + "const MyComponent = lazy(() => import('./MyComponent'))", @@ -2804,10 +2793,10 @@ function initializeLazyComponentType(lazyComponent) { lazyComponent._result = defaultExport; } }, - function(error) { + function(error$$1) { if (lazyComponent._status === Pending) { lazyComponent._status = Rejected; - lazyComponent._result = error; + lazyComponent._result = error$$1; } } ); @@ -2830,8 +2819,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2880,6 +2868,9 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); + case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3003,17 +2994,18 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !instance._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%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.type) || "A component" - ) - : void 0; + + if (!instance._warnedAboutRefsInRender) { + error( + "%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.type) || "A component" + ); + } + instance._warnedAboutRefsInRender = true; } } @@ -3281,17 +3273,19 @@ function throwOnStylesProp(component, props) { } } function warnForStyleProps(props, validAttributes) { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - console.error( - "You are setting the style `{ " + - key + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { " + - key + - ": ... } }`" - ); + { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + error( + "You are setting the style `{ %s" + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { %s" + + ": ... } }`", + key, + key + ); + } } } } @@ -3775,8 +3769,13 @@ function restoreStateOfTarget(target) { ); } - var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - restoreImpl(internalInstance.stateNode, internalInstance.type, props); + var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. + + if (stateNode) { + var _props = getFiberCurrentPropsFromNode(stateNode); + + restoreImpl(internalInstance.stateNode, internalInstance.type, _props); + } } function needsStateRestore() { @@ -3810,16 +3809,9 @@ var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var discreteUpdatesImpl = function(fn, a, b, c) { - return fn(a, b, c); -}; - var flushDiscreteUpdatesImpl = function() {}; -var batchedEventUpdatesImpl = batchedUpdatesImpl; var isInsideEventHandler = false; -var isBatchingEventUpdates = false; - function finishEventHandler() { // Here we wait until all updates have propagated, which is important // when using controlled components within layers: @@ -3852,72 +3844,8 @@ function batchedUpdates(fn, bookkeeping) { finishEventHandler(); } } -function batchedEventUpdates(fn, a, b) { - if (isBatchingEventUpdates) { - // If we are currently inside another batch, we need to wait until it - // fully completes before restoring state. - return fn(a, b); - } - - isBatchingEventUpdates = true; - - try { - return batchedEventUpdatesImpl(fn, a, b); - } finally { - isBatchingEventUpdates = false; - finishEventHandler(); - } -} // This is for the React Flare event system - -function executeUserEventHandler(fn, value) { - var previouslyInEventHandler = isInsideEventHandler; - - try { - isInsideEventHandler = true; - var type = typeof value === "object" && value !== null ? value.type : ""; - invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value); - } finally { - isInsideEventHandler = previouslyInEventHandler; - } -} -function discreteUpdates(fn, a, b, c) { - var prevIsInsideEventHandler = isInsideEventHandler; - isInsideEventHandler = true; +// This is for the React Flare event system - try { - return discreteUpdatesImpl(fn, a, b, c); - } finally { - isInsideEventHandler = prevIsInsideEventHandler; - - if (!isInsideEventHandler) { - finishEventHandler(); - } - } -} -var lastFlushedEventTimeStamp = 0; -function flushDiscreteUpdatesIfNeeded(timeStamp) { - // event.timeStamp isn't overly reliable due to inconsistencies in - // how different browsers have historically provided the time stamp. - // Some browsers provide high-resolution time stamps for all events, - // some provide low-resolution time stamps for all events. FF < 52 - // even mixes both time stamps together. Some browsers even report - // negative time stamps or time stamps that are 0 (iOS9) in some cases. - // Given we are only comparing two time stamps with equality (!==), - // we are safe from the resolution differences. If the time stamp is 0 - // we bail-out of preventing the flush, which can affect semantics, - // such as if an earlier flush removes or adds event listeners that - // are fired in the subsequent flush. However, this is the same - // behaviour as we had before this change, so the risks are low. - if ( - !isInsideEventHandler && - (!enableFlareAPI || - timeStamp === 0 || - lastFlushedEventTimeStamp !== timeStamp) - ) { - lastFlushedEventTimeStamp = timeStamp; - flushDiscreteUpdatesImpl(); - } -} function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -3925,501 +3853,43 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - discreteUpdatesImpl = _discreteUpdatesImpl; flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; - batchedEventUpdatesImpl = _batchedEventUpdatesImpl; -} - -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; } -/** - * Class only exists for its Flow type. - */ -var ReactNativeComponent = - /*#__PURE__*/ - (function(_React$Component) { - _inheritsLoose(ReactNativeComponent, _React$Component); +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + var eventTarget = null; - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; + if (enableNativeTargetAsInstance) { + if (targetFiber != null) { + eventTarget = targetFiber.stateNode.canonical; } + } else { + eventTarget = nativeEvent.target; + } - var _proto = ReactNativeComponent.prototype; - - _proto.blur = function blur() {}; - - _proto.focus = function focus() {}; + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + eventTarget, + PLUGIN_EVENT_SYSTEM + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. +} - _proto.measure = function measure(callback) {}; +// can re-export everything from this module. - _proto.measureInWindow = function measureInWindow(callback) {}; - - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) {}; - - _proto.setNativeProps = function setNativeProps(nativeProps) {}; - - return ReactNativeComponent; - })(React.Component); // This type is only used for FlowTests. It shouldn't be imported directly - -var DiscreteEvent = 0; -var UserBlockingEvent = 1; -var ContinuousEvent = 2; - -// CommonJS interop named imports. - -var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; -var runWithPriority = Scheduler.unstable_runWithPriority; -var _nativeFabricUIManage$2 = nativeFabricUIManager; -var measureInWindow = _nativeFabricUIManage$2.measureInWindow; -var rootEventTypesToEventResponderInstances = new Map(); -var currentTimeStamp = 0; -var currentInstance = null; -var eventResponderContext = { - dispatchEvent: function(eventValue, eventListener, eventPriority) { - validateResponderContext(); - validateEventValue(eventValue); - - switch (eventPriority) { - case DiscreteEvent: { - flushDiscreteUpdatesIfNeeded(currentTimeStamp); - discreteUpdates(function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } - - case UserBlockingEvent: { - runWithPriority(UserBlockingPriority, function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } - - case ContinuousEvent: { - executeUserEventHandler(eventListener, eventValue); - break; - } - } - }, - isTargetWithinNode: function(childTarget, parentTarget) { - validateResponderContext(); - var childFiber = getFiberFromTarget(childTarget); - var parentFiber = getFiberFromTarget(parentTarget); - var node = childFiber; - - while (node !== null) { - if (node === parentFiber) { - return true; - } - - node = node.return; - } - - return false; - }, - getTargetBoundingRect: function(target, callback) { - measureInWindow(target.node, function(x, y, width, height) { - callback({ - left: x, - right: x + width, - top: y, - bottom: y + height - }); - }); - }, - addRootEventTypes: function(rootEventTypes) { - validateResponderContext(); - - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var eventResponderInstance = currentInstance; - registerRootEventType(rootEventType, eventResponderInstance); - } - }, - removeRootEventTypes: function(rootEventTypes) { - validateResponderContext(); - - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var rootEventResponders = rootEventTypesToEventResponderInstances.get( - rootEventType - ); - var rootEventTypesSet = currentInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - rootEventTypesSet.delete(rootEventType); - } - - if (rootEventResponders !== undefined) { - rootEventResponders.delete(currentInstance); - } - } - }, - getTimeStamp: function() { - validateResponderContext(); - return currentTimeStamp; - }, - getResponderNode: function() { - validateResponderContext(); - var responderFiber = currentInstance.fiber; - - if (responderFiber.tag === ScopeComponent) { - return null; - } - - return responderFiber.stateNode; - } -}; - -function validateEventValue(eventValue) { - if (typeof eventValue === "object" && eventValue !== null) { - var target = eventValue.target, - type = eventValue.type, - timeStamp = eventValue.timeStamp; - - if (target == null || type == null || timeStamp == null) { - throw new Error( - 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' - ); - } - - var showWarning = function(name) { - { - warning$1( - false, - "%s is not available on event objects created from event responder modules (React Flare). " + - 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', - name, - name - ); - } - }; - - eventValue.preventDefault = function() { - { - showWarning("preventDefault()"); - } - }; - - eventValue.stopPropagation = function() { - { - showWarning("stopPropagation()"); - } - }; - - eventValue.isDefaultPrevented = function() { - { - showWarning("isDefaultPrevented()"); - } - }; - - eventValue.isPropagationStopped = function() { - { - showWarning("isPropagationStopped()"); - } - }; // $FlowFixMe: we don't need value, Flow thinks we do - - Object.defineProperty(eventValue, "nativeEvent", { - get: function() { - { - showWarning("nativeEvent"); - } - } - }); - } -} - -function getFiberFromTarget(target) { - if (target === null) { - return null; - } - - return target.canonical._internalInstanceHandle || null; -} - -function createFabricResponderEvent(topLevelType, nativeEvent, target) { - return { - nativeEvent: nativeEvent, - target: target, - type: topLevelType - }; -} - -function validateResponderContext() { - if (!currentInstance) { - throw Error( - "An event responder context was used outside of an event cycle." - ); - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function responderEventTypesContainType(eventTypes, type) { - for (var i = 0, len = eventTypes.length; i < len; i++) { - if (eventTypes[i] === type) { - return true; - } - } - - return false; -} - -function validateResponderTargetEventTypes(eventType, responder) { - var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder - - if (targetEventTypes !== null) { - return responderEventTypesContainType(targetEventTypes, eventType); - } - - return false; -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function traverseAndHandleEventResponderInstances( - eventType, - targetFiber, - nativeEvent -) { - // Trigger event responders in this order: - // - Bubble target responder phase - // - Root responder phase - var responderEvent = createFabricResponderEvent( - eventType, - nativeEvent, - targetFiber !== null ? targetFiber.stateNode : null - ); - var visitedResponders = new Set(); - var node = targetFiber; - - while (node !== null) { - var _node = node, - dependencies = _node.dependencies, - tag = _node.tag; - - if ( - (tag === HostComponent || tag === ScopeComponent) && - dependencies !== null - ) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for (var i = 0, length = responderInstances.length; i < length; i++) { - var responderInstance = responderInstances[i]; - var props = responderInstance.props, - responder = responderInstance.responder, - state = responderInstance.state; - - if ( - !visitedResponders.has(responder) && - validateResponderTargetEventTypes(eventType, responder) - ) { - var onEvent = responder.onEvent; - visitedResponders.add(responder); - - if (onEvent !== null) { - currentInstance = responderInstance; - onEvent(responderEvent, eventResponderContext, props, state); - } - } - } - } - } - - node = node.return; - } // Root phase - - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - eventType - ); - - if (rootEventResponderInstances !== undefined) { - var _responderInstances = Array.from(rootEventResponderInstances); - - for (var _i = 0; _i < _responderInstances.length; _i++) { - var _responderInstance = _responderInstances[_i]; - var props = _responderInstance.props, - responder = _responderInstance.responder, - state = _responderInstance.state; - var onRootEvent = responder.onRootEvent; - - if (onRootEvent !== null) { - currentInstance = _responderInstance; - onRootEvent(responderEvent, eventResponderContext, props, state); - } - } - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function dispatchEventForResponderEventSystem( - topLevelType, - targetFiber, - nativeEvent -) { - var previousInstance = currentInstance; - var previousTimeStamp = currentTimeStamp; // We might want to control timeStamp another way here - - currentTimeStamp = Date.now(); - - try { - batchedEventUpdates(function() { - traverseAndHandleEventResponderInstances( - topLevelType, - targetFiber, - nativeEvent - ); - }); - } finally { - currentInstance = previousInstance; - currentTimeStamp = previousTimeStamp; - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function mountEventResponder(responder, responderInstance, props, state) { - var onMount = responder.onMount; - - if (onMount !== null) { - currentInstance = responderInstance; - - try { - batchedEventUpdates(function() { - onMount(eventResponderContext, props, state); - }); - } finally { - currentInstance = null; - } - } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic - -function unmountEventResponder(responderInstance) { - var responder = responderInstance.responder; - var onUnmount = responder.onUnmount; - - if (onUnmount !== null) { - var props = responderInstance.props, - state = responderInstance.state; - currentInstance = responderInstance; - - try { - batchedEventUpdates(function() { - onUnmount(eventResponderContext, props, state); - }); - } finally { - currentInstance = null; - } - } - - var rootEventTypesSet = responderInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - var rootEventTypes = Array.from(rootEventTypesSet); - - for (var i = 0; i < rootEventTypes.length; i++) { - var topLevelEventType = rootEventTypes[i]; - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - topLevelEventType - ); - - if (rootEventResponderInstances !== undefined) { - rootEventResponderInstances.delete(responderInstance); - } - } - } -} - -function registerRootEventType(rootEventType, responderInstance) { - var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( - rootEventType - ); - - if (rootEventResponderInstances === undefined) { - rootEventResponderInstances = new Set(); - rootEventTypesToEventResponderInstances.set( - rootEventType, - rootEventResponderInstances - ); - } - - var rootEventTypesSet = responderInstance.rootEventTypes; - - if (rootEventTypesSet === null) { - rootEventTypesSet = responderInstance.rootEventTypes = new Set(); - } - - if (!!rootEventTypesSet.has(rootEventType)) { - throw Error( - 'addRootEventTypes() found a duplicate root event type of "' + - rootEventType + - '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' - ); - } - - rootEventTypesSet.add(rootEventType); - rootEventResponderInstances.add(responderInstance); -} - -function addRootEventTypesForResponderInstance( - responderInstance, - rootEventTypes -) { - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - registerRootEventType(rootEventType, responderInstance); - } -} - -function dispatchEvent(target, topLevelType, nativeEvent) { - var targetFiber = target; - - if (enableFlareAPI) { - // React Flare event system - dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); - } - - var eventTarget = null; - - if (enableNativeTargetAsInstance) { - if (targetFiber != null) { - eventTarget = targetFiber.stateNode.canonical; - } - } else { - eventTarget = nativeEvent.target; - } - - batchedUpdates(function() { - // Heritage plugin event system - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - eventTarget, - PLUGIN_EVENT_SYSTEM - ); - }); // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. -} - -// can re-export everything from this module. - -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Mutation (when unsupported) +function shim() { + { + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Mutation (when unsupported) var supportsMutation = false; var appendChild = shim; @@ -4475,21 +3945,21 @@ var didNotFindHydratableInstance = shim$1; var didNotFindHydratableTextInstance = shim$1; var didNotFindHydratableSuspenseInstance = shim$1; -var _nativeFabricUIManage$1 = nativeFabricUIManager; -var createNode = _nativeFabricUIManage$1.createNode; -var cloneNode = _nativeFabricUIManage$1.cloneNode; -var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var _nativeFabricUIManage = nativeFabricUIManager; +var createNode = _nativeFabricUIManage.createNode; +var cloneNode = _nativeFabricUIManage.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren; var cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; -var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; -var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; -var appendChildNode = _nativeFabricUIManage$1.appendChild; -var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; -var completeRoot = _nativeFabricUIManage$1.completeRoot; -var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; -var fabricMeasure = _nativeFabricUIManage$1.measure; -var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; -var fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout; + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage.createChildSet; +var appendChildNode = _nativeFabricUIManage.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet; +var completeRoot = _nativeFabricUIManage.completeRoot; +var registerEventHandler = _nativeFabricUIManage.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage.measure; +var fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage.measureLayout; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. // % 10 === 1 means it is a rootTag. @@ -4560,10 +4030,12 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } + return; } @@ -4576,10 +4048,10 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; }; @@ -4794,28 +4266,17 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -function mountResponderInstance( +function DEPRECATED_mountResponderInstance( responder, responderInstance, props, state, instance ) { - if (enableFlareAPI) { - var rootEventTypes = responder.rootEventTypes; - - if (rootEventTypes !== null) { - addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); - } - - mountEventResponder(responder, responderInstance, props, state); - } + throw new Error("Not yet implemented."); } -function unmountResponderInstance(responderInstance) { - if (enableFlareAPI) { - // TODO stop listening to targetEventTypes - unmountEventResponder(responderInstance); - } +function DEPRECATED_unmountResponderInstance(responderInstance) { + throw new Error("Not yet implemented."); } function getFundamentalComponentInstance(fundamentalInstance) { throw new Error("Not yet implemented."); @@ -4838,6 +4299,9 @@ function cloneFundamentalInstance(fundamentalInstance) { function getInstanceFromNode$1(node) { throw new Error("Not yet implemented."); } +function beforeRemoveInstance(instance) { + // noop +} var BEFORE_SLASH_RE = /^(.*)[\\\/]/; var describeComponentFrame = function(name, source, ownerName) { @@ -5421,7 +4885,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5429,7 +4893,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5616,8 +5080,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%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.", @@ -5816,7 +5280,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority$1 = 98; +var UserBlockingPriority = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -5848,7 +5312,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + return UserBlockingPriority; case Scheduler_NormalPriority: return NormalPriority; @@ -5870,7 +5334,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority$1: + case UserBlockingPriority: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -5888,7 +5352,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -5938,7 +5402,7 @@ function flushSyncCallbackQueueImpl() { try { var _isSync = true; var queue = syncQueue; - runWithPriority$1(ImmediatePriority, function() { + runWithPriority(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; @@ -6073,7 +5537,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority$1; + return UserBlockingPriority; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -6136,78 +5600,6 @@ function shallowEqual(objA, objB) { return true; } -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var lowPriorityWarningWithoutStack = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - - if (typeof console !== "undefined") { - console.warn(message); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (!condition) { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(void 0, [format].concat(args)); - } - }; -} - -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; - var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, flushPendingUnsafeLifecycleWarnings: function() {}, @@ -6378,8 +5770,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6393,8 +5785,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6412,8 +5803,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6426,8 +5816,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6445,8 +5834,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6465,8 +5853,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6491,11 +5878,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6528,8 +5915,8 @@ var ReactStrictModeWarnings = { }); var sortedNames = setToSortedString(uniqueNames); var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -7062,17 +6449,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue = nextValue; { - !( - context._currentRenderer === undefined || - context._currentRenderer === null || - context._currentRenderer === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer = rendererSigil; } } else { @@ -7080,17 +6467,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue2 = nextValue; { - !( - context._currentRenderer2 === undefined || - context._currentRenderer2 === null || - context._currentRenderer2 === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -7117,14 +6504,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) - ? warning$1( - false, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ) - : void 0; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7320,15 +6706,14 @@ function readContext(context, observedBits) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. - !!isDisallowedContextReadInDEV - ? warning$1( - false, - "Context can only be read while React is rendering. " + - "In classes, you can read it in the render method or getDerivedStateFromProps. " + - "In function components, you can read it directly in the function body, but not " + - "inside Hooks like useReducer() or useMemo()." - ) - : void 0; + if (isDisallowedContextReadInDEV) { + error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } } if (lastContextWithAllBitsObserved === context) { @@ -7469,38 +6854,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { - var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { +function initializeUpdateQueue(fiber) { var queue = { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + fiber.updateQueue = queue; +} +function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + baseQueue: currentQueue.baseQueue, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7508,9 +6887,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7518,136 +6897,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -function appendUpdateToQueue(queue, update) { - // Append the update to the end of the list. - if (queue.lastUpdate === null) { - // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; - } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -function enqueueUpdate(fiber, update) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1; - var queue2; + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } + update.next = pending.next; + pending.next = update; } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update); - appendUpdateToQueue(queue2, update); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - - queue2.lastUpdate = update; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "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." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } // Append the update to the end of the list. + if (current !== null) { + // Ensure the work-in-progress queue is a clone + cloneUpdateQueue(current, workInProgress); + } // Captured updates go only on the work-in-progress queue. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7739,163 +7044,171 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, - queue, props, instance, renderExpirationTime ) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; hasForceUpdate = false; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. + + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - if (updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; // Since this is the first update that was skipped, the current result - // is the new base state. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } else { - // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. - - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var callback = update.callback; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + do { + var updateExpirationTime = update.expirationTime; + + if (updateExpirationTime < renderExpirationTime) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + if (updateExpirationTime > newExpirationTime) { + newExpirationTime = updateExpirationTime; + } + } else { + // This update does have sufficient priority. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + + markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ); // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; - if (_updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is - // the new base state. + if (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // Since this update will remain in the list, update the remaining - // expiration time. - if (newExpirationTime < _updateExpirationTime) { - newExpirationTime = _updateExpirationTime; - } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; + update = update.next; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - update.nextEffect = null; - - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + update = baseQueue.next = pendingQueue.next; + pendingQueue.next = first; + queue.baseQueue = baseQueue = pendingQueue; + queue.shared.pending = null; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. - // This should be fine because the only two other things that contribute to - // expiration time are props and context. We're already in the middle of the - // begin phase by the time we start processing the queue, so we've already - // dealt with the props. Context in components that specify - // shouldComponentUpdate is tricky; but we'll have to account for - // that regardless. - - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - { currentlyProcessingQueue = null; } @@ -7924,36 +7237,20 @@ function commitUpdateQueue( instance, renderExpirationTime ) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } // Clear the list of captured updates. - - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; - } // Commit the effects - - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} - -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - effect = effect.nextEffect; + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } + } } } @@ -7998,8 +7295,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -8014,8 +7311,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -8072,9 +7369,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -8173,14 +7470,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(shouldUpdate !== undefined) - ? warningWithoutStack$1( - false, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ) - : void 0; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -8204,15 +7500,13 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -8220,54 +7514,50 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noGetInitialStateOnES6 = - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state; - !noGetInitialStateOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noGetDefaultPropsOnES6 = - !instance.getDefaultProps || - instance.getDefaultProps.isReactClassApproved; - !noGetDefaultPropsOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noInstancePropTypes = !instance.propTypes; - !noInstancePropTypes - ? warningWithoutStack$1( - false, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ) - : void 0; - var noInstanceContextType = !instance.contextType; - !noInstanceContextType - ? warningWithoutStack$1( - false, - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name - ) - : void 0; + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "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 + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "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 + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } if (disableLegacyContext) { if (ctor.childContextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy childContextTypes API which is no longer supported. " + "Use React.createContext() instead.", name @@ -8275,23 +7565,20 @@ function checkClassInstance(workInProgress, ctor, newProps) { } if (ctor.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with static contextType instead.", name ); } } else { - var noInstanceContextTypes = !instance.contextTypes; - !noInstanceContextTypes - ? warningWithoutStack$1( - false, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ) - : void 0; + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ); + } if ( ctor.contextType && @@ -8299,8 +7586,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8308,26 +7595,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noComponentShouldUpdate = - typeof instance.componentShouldUpdate !== "function"; - !noComponentShouldUpdate - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; + if (typeof instance.componentShouldUpdate === "function") { + error( + "%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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8335,70 +7618,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - var noComponentDidUnmount = - typeof instance.componentDidUnmount !== "function"; - !noComponentDidUnmount - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ) - : void 0; - var noComponentDidReceiveProps = - typeof instance.componentDidReceiveProps !== "function"; - !noComponentDidReceiveProps - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; - var noComponentWillRecieveProps = - typeof instance.componentWillRecieveProps !== "function"; - !noComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ) - : void 0; - var noUnsafeComponentWillRecieveProps = - typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - !noUnsafeComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ) - : void 0; + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%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 + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + var hasMutatedProps = instance.props !== newProps; - !(instance.props === undefined || !hasMutatedProps) - ? warningWithoutStack$1( - false, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ) - : void 0; - var noInstanceDefaultProps = !instance.defaultProps; - !noInstanceDefaultProps - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ); + } + + if (instance.defaultProps) { + error( + "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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8406,63 +7680,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - var noInstanceGetDerivedStateFromProps = - typeof instance.getDerivedStateFromProps !== "function"; - !noInstanceGetDerivedStateFromProps - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noInstanceGetDerivedStateFromCatch = - typeof instance.getDerivedStateFromError !== "function"; - !noInstanceGetDerivedStateFromCatch - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noStaticGetSnapshotBeforeUpdate = - typeof ctor.getSnapshotBeforeUpdate !== "function"; - !noStaticGetSnapshotBeforeUpdate - ? warningWithoutStack$1( - false, - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ) - : void 0; - var _state = instance.state; + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } - if (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", name ); } - if (typeof instance.getChildContext === "function") { - !(typeof ctor.childContextTypes === "object") - ? warningWithoutStack$1( - false, - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ) - : void 0; + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ); + } + + var _state = instance.state; + + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); } } } @@ -8521,8 +7785,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8566,8 +7829,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -8632,8 +7895,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -8675,8 +7938,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8713,8 +7975,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8741,6 +8003,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { @@ -8758,8 +8021,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -8783,19 +8046,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8818,18 +8070,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8888,18 +8135,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8989,6 +8226,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -9032,18 +8270,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -9205,8 +8433,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -9232,8 +8460,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!didWarnAboutStringRefs[componentName]) { if (warnAboutStringRefs) { - warningWithoutStack$1( - false, + error( 'Component "%s" contains the string ref "%s". Support for string refs ' + "will be removed in a future major release. We recommend using " + "useRef() or createRef() instead. " + @@ -9244,8 +8471,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } else { - warningWithoutStack$1( - false, + error( 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -9358,23 +8584,25 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); + { + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; + } - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - warning$1( - false, - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + + error( + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + ); + } } // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching @@ -9503,44 +8731,62 @@ function ChildReconciler(shouldTrackSideEffects) { ); created.return = returnFiber; return created; - } else { - // Update - var existing = useFiber(current$$1, textContent, expirationTime); - existing.return = returnFiber; - return existing; - } - } - - function updateElement(returnFiber, current$$1, element, expirationTime) { - if ( - current$$1 !== null && - (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current$$1, element)) - ) { - // Move based on index - var existing = useFiber(current$$1, element.props, expirationTime); - existing.ref = coerceRef(returnFiber, current$$1, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; + } else { + // Update + var existing = useFiber(current$$1, textContent, expirationTime); + existing.return = returnFiber; + return existing; } } + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (current$$1 !== null) { + if ( + current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } else if ( + enableChunksAPI && + current$$1.tag === Chunk && + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === current$$1.type.render + ) { + // Same as above but also update the .type field. + var _existing = useFiber(current$$1, element.props, expirationTime); + + _existing.return = returnFiber; + _existing.type = element.type; + + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; + } + } // Insert + + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( current$$1 === null || @@ -9856,8 +9102,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9865,6 +9110,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; default: @@ -10070,28 +9316,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !didWarnAboutGenerators - ? warning$1( - false, - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ) - : void 0; + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !didWarnAboutMaps - ? warning$1( - false, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ) - : void 0; + if (!didWarnAboutMaps) { + error( + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ); + } + didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10299,33 +9545,79 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - if ( - child.tag === Fragment - ? element.type === REACT_FRAGMENT_TYPE - : child.elementType === element.type || // Keep this check inline so it only runs on the false path: + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.props.children, + expirationTime + ); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } + + break; + } + + case Chunk: + if (enableChunksAPI) { + if ( + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === child.type.render + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing2 = useFiber(child, element.props, expirationTime); + + _existing2.type = element.type; + _existing2.return = returnFiber; + + { + _existing2._debugSource = element._source; + _existing2._debugOwner = element._owner; + } + + return _existing2; + } + } + + // We intentionally fallthrough here if enableChunksAPI is not on. + // eslint-disable-next-lined no-fallthrough + + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber( - child, - element.type === REACT_FRAGMENT_TYPE - ? element.props.children - : element.props, - expirationTime - ); - existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + var _existing3 = useFiber(child, element.props, expirationTime); + + _existing3.ref = coerceRef(returnFiber, child, element); + _existing3.return = returnFiber; + + { + _existing3._debugSource = element._source; + _existing3._debugOwner = element._owner; + } + + return _existing3; + } + + break; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10781,7 +10073,7 @@ function createResponderInstance( }; } -function mountEventResponder$1( +function mountEventResponder( responder, responderProps, fiber, @@ -10820,7 +10112,7 @@ function mountEventResponder$1( } } - mountResponderInstance( + DEPRECATED_mountResponderInstance( responder, responderInstance, responderProps, @@ -10856,8 +10148,7 @@ function updateEventListener( if (visistedResponders.has(responder)) { // show warning { - warning$1( - false, + error( 'Duplicate event responder "%s" found in event listeners. ' + "Event listeners passed to elements cannot use the same event responder more than once.", responder.displayName @@ -10872,7 +10163,7 @@ function updateEventListener( if (responderInstance === undefined) { // Mount (happens in either complete or commit phase) - mountEventResponder$1( + mountEventResponder( responder, listenerProps, fiber, @@ -10886,7 +10177,11 @@ function updateEventListener( } } -function updateEventListeners(listeners, fiber, rootContainerInstance) { +function updateDeprecatedEventListeners( + listeners, + fiber, + rootContainerInstance +) { var visistedResponders = new Set(); var dependencies = fiber.dependencies; @@ -10902,7 +10197,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { var respondersMap = dependencies.responders; if (respondersMap === null) { - respondersMap = new Map(); + dependencies.responders = respondersMap = new Map(); } if (isArray$2(listeners)) { @@ -10940,7 +10235,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { if (!visistedResponders.has(mountedResponder)) { var responderInstance = _respondersMap.get(mountedResponder); - unmountResponderInstance(responderInstance); + DEPRECATED_unmountResponderInstance(responderInstance); _respondersMap.delete(mountedResponder); } @@ -10948,7 +10243,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { } } } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10960,6 +10255,24 @@ function createResponderListener(responder, props) { return eventResponderListener; } +function unmountDeprecatedResponderListeners(fiber) { + var dependencies = fiber.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + DEPRECATED_unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } +} var NoEffect$1 = /* */ @@ -11004,13 +10317,7 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var nextCurrentHook = null; -var firstWorkInProgressHook = null; -var workInProgressHook = null; -var nextWorkInProgressHook = null; -var remainingExpirationTime = NoWork; -var componentUpdateQueue = null; -var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the // end of the current pass. We can't store these updates on the normal queue, // because if the work is aborted, they should be discarded. Because this is // a relatively rare case, we also don't want to add an additional field to @@ -11068,8 +10375,7 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -11105,8 +10411,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -11140,8 +10445,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -11156,8 +10460,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -11185,12 +10488,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -11198,24 +10500,25 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // The following should have already been reset // currentHook = null; // workInProgressHook = null; - // remainingExpirationTime = NoWork; - // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; - // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { + if (current !== null && current.memoizedState !== null) { ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, @@ -11229,7 +10532,7 @@ function renderWithHooks( } } - var children = Component(props, refOrContext); + var children = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do { @@ -11242,11 +10545,9 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. @@ -11254,7 +10555,7 @@ function renderWithHooks( } ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); + children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; @@ -11263,14 +10564,9 @@ function renderWithHooks( // at the beginning of the render phase and there's no re-entrancy. ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. @@ -11278,20 +10574,13 @@ function renderWithHooks( renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } - - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above + } // These were reset above // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; @@ -11322,10 +10611,7 @@ function resetHooks() { renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11333,9 +10619,6 @@ function resetHooks() { currentHookNameInDev = null; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -11345,14 +10628,14 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11367,12 +10650,33 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; - nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -11383,20 +10687,18 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11424,13 +10726,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11482,7 +10784,7 @@ function updateReducer(reducer, initialArg, init) { // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. - if (hook.baseUpdate === queue.last) { + if (hook.baseQueue === null) { hook.baseState = newState; } @@ -11492,35 +10794,37 @@ function updateReducer(reducer, initialArg, init) { } return [hook.memoizedState, _dispatch]; - } // The last update in the entire queue + } - var last = queue.last; // The last update that is part of the base state. + var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - var first; + var pendingQueue = queue.pending; - if (baseUpdate !== null) { - if (last !== null) { - // For the first update, the queue is a circular linked list where - // `queue.last.next = queue.first`. Once the first update commits, and - // the `baseUpdate` is no longer empty, we can unravel the list. - last.next = null; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var _newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; var _update = first; - var didSkip = false; do { var updateExpirationTime = _update.expirationTime; @@ -11529,24 +10833,46 @@ function updateReducer(reducer, initialArg, init) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; newBaseState = _newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig @@ -11562,13 +10888,13 @@ function updateReducer(reducer, initialArg, init) { } } - prevUpdate = _update; _update = _update.next; } while (_update !== null && _update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; + if (newBaseQueueLast === null) { newBaseState = _newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. @@ -11577,8 +10903,8 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = _newState; } @@ -11595,13 +10921,13 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11621,9 +10947,11 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -11663,7 +10991,7 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } @@ -11686,7 +11014,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } @@ -11744,14 +11072,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !refObject.hasOwnProperty("current") - ? warning$1( - false, - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ) - : void 0; + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } } var _inst2 = create(); @@ -11765,14 +11092,13 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11787,14 +11113,13 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11877,17 +11202,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -11901,47 +11223,54 @@ function updateDeferredValue(value, config) { updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); return prevValue; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority( + priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, + function() { + setPending(true); + } + ); + runWithPriority( + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + } + ); +} + function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var startTransition = mountCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { @@ -11949,25 +11278,11 @@ function updateTransition(config) { isPending = _updateState2[0], setPending = _updateState2[1]; - var startTransition = updateCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { @@ -11978,14 +11293,13 @@ function dispatchAction(fiber, queue, action) { } { - !(typeof arguments[3] !== "function") - ? warning$1( - false, - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ) - : void 0; + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } } var alternate = fiber.alternate; @@ -12050,23 +11364,17 @@ function dispatchAction(fiber, queue, action) { _update2.priority = getCurrentPriorityLevel(); } // Append the update to the end of the list. - var last = queue.last; + var pending = queue.pending; - if (last === null) { + if (pending === null) { // This is the first update. Create a circular list. _update2.next = _update2; } else { - var first = last.next; - - if (first !== null) { - // Still circular. - _update2.next = first; - } - - last.next = _update2; + _update2.next = pending.next; + pending.next = _update2; } - queue.last = _update2; + queue.pending = _update2; if ( fiber.expirationTime === NoWork && @@ -12102,7 +11410,7 @@ function dispatchAction(fiber, queue, action) { // time the reducer has changed. return; } - } catch (error) { + } catch (error$$1) { // Suppress the error. It will throw again in the render phase. } finally { { @@ -12148,8 +11456,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; { var warnInvalidContextAccess = function() { - warning$1( - false, + error( "Context can only be read while React is rendering. " + "In classes, you can read it in the render method or getDerivedStateFromProps. " + "In function components, you can read it directly in the function body, but not " + @@ -12158,8 +11465,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -12250,7 +11556,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12341,7 +11647,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12432,7 +11738,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12535,7 +11841,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12640,7 +11946,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12720,12 +12026,11 @@ var isHydrating = false; function warnIfHydrating() { { - !!isHydrating - ? warning$1( - false, - "We should not be hydrating here. This is a bug in React. Please file a bug." - ) - : void 0; + if (isHydrating) { + error( + "We should not be hydrating here. This is a bug in React. Please file a bug." + ); + } } } @@ -13252,8 +12557,8 @@ function forceUnmountCurrentAndReconcile( renderExpirationTime ); // In the second pass, we mount the new children. The trick here is that we // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13513,7 +12818,7 @@ function updateSimpleMemoComponent( if ( shallowEqual(prevProps, nextProps) && - current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current$$1.type ) { didReceiveUpdate = false; @@ -13673,6 +12978,73 @@ function updateFunctionComponent( return workInProgress.child; } +function updateChunk( + current$$1, + workInProgress, + chunk, + nextProps, + renderExpirationTime +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + var render = chunk.render; + var data = chunk.query(); // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + function updateClassComponent( current$$1, workInProgress, @@ -13715,9 +13087,9 @@ function updateClassComponent( if (instance === null) { if (current$$1 !== null) { - // An class component without an instance only mounts if it suspended - // inside a non- concurrent tree, in an inconsistent state. We want to - // tree it like a new mount, even though an empty version of it already + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect @@ -13769,14 +13141,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (inst.props !== nextProps) { - !didWarnAboutReassigningProps - ? warning$1( - false, - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" - ) - : void 0; + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); + } + didWarnAboutReassigningProps = true; } } @@ -13818,7 +13190,7 @@ function finishClassComponent( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. @@ -13897,7 +13269,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + if (!(current$$1 !== null && updateQueue !== null)) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); @@ -13906,13 +13278,8 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current$$1, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". @@ -13986,7 +13353,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { if (isDirectTextChild) { // We special case a direct text child of a host node. This is a common // case. We won't handle it as a reified child. We will instead handle - // this in the host environment that also have access to this prop. That + // this in the host environment that also has access to this prop. That // avoids allocating another HostText fiber and traversing it. nextChildren = null; } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { @@ -14036,7 +13403,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. // Disconnect the alternate pointers. @@ -14074,7 +13441,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -14091,7 +13458,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -14108,7 +13475,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -14136,36 +13503,48 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } - default: { - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + case Chunk: { + if (enableChunksAPI) { + // TODO: Resolve for Hot Reloading. + child = updateChunk( + null, + workInProgress, + Component, + props, + renderExpirationTime ); + return child; } + + break; } } - return child; + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } function mountIncompleteClassComponent( @@ -14259,13 +13638,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "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 ); + didWarnAboutBadClass[componentName] = true; } } @@ -14297,8 +13676,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to be a function component that returns a class instance. " + "Change %s to a class that extends React.Component instead. " + "If you can't use a class try assigning the prototype on the function as a workaround. " + @@ -14308,6 +13686,7 @@ function mountIndeterminateComponent( _componentName, _componentName ); + didWarnAboutModulePatternComponent[_componentName] = true; } } // Proceed under the assumption that this is a class instance @@ -14329,6 +13708,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14356,8 +13736,7 @@ function mountIndeterminateComponent( { if (disableLegacyContext && Component.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with React.useContext() instead.", getComponentName(Component) || "Unknown" @@ -14393,86 +13772,87 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; - warning$1( - false, - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - } - if ( - warnAboutDefaultPropsOnFunctionComponents && - Component.defaultProps !== undefined - ) { - var componentName = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { - warningWithoutStack$1( - false, - "%s: Support for defaultProps will be removed from function components " + - "in a future major release. Use JavaScript default parameters instead.", - componentName - ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } } - } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - warningWithoutStack$1( - false, - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14544,8 +13924,8 @@ function updateSuspenseComponent( if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { didWarnAboutMaxDuration = true; - warning$1( - false, + + error( "maxDuration has been removed from React. " + "Remove the maxDuration prop." ); @@ -14917,7 +14297,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -14963,8 +14343,7 @@ function mountDehydratedSuspenseComponent( // Instead, we'll leave the content in place and try to hydrate it later. if ((workInProgress.mode & BlockingMode) === NoMode) { { - warning$1( - false, + error( "Cannot hydrate Suspense in legacy mode. Switch from " + "ReactDOM.hydrate(element, container) to " + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + @@ -15224,40 +14603,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15272,16 +14650,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15299,8 +14677,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15310,6 +14688,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15350,8 +14729,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + error( 'A single row was passed to a . ' + "This is not useful since it needs multiple rows. " + "Did you mean to pass multiple children or an array?", @@ -15377,6 +14755,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15387,6 +14766,7 @@ function initSuspenseListRenderState( // We can reuse the existing object from previous renders. renderState.isBackwards = isBackwards; renderState.rendering = null; + renderState.renderingStartTime = 0; renderState.last = lastContentRow; renderState.tail = tail; renderState.tailExpiration = 0; @@ -15659,8 +15039,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15675,15 +15055,14 @@ function updateContextConsumer( var render = newProps.children; { - !(typeof render === "function") - ? warningWithoutStack$1( - false, - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ) - : void 0; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -16291,6 +15670,22 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; } + + case Chunk: { + if (enableChunksAPI) { + var chunk = workInProgress.type; + var props = workInProgress.pendingProps; + return updateChunk( + current$$1, + workInProgress, + chunk, + props, + renderExpirationTime + ); + } + + break; + } } { @@ -16975,6 +16370,8 @@ if (supportsMutation) { // This lets the parents know that at least one of their children has changed. markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; } }; } else { @@ -17073,14 +16470,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -17089,7 +16488,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -17115,7 +16514,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -17132,9 +16531,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = current.memoizedProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { markUpdate(workInProgress); @@ -17152,12 +16551,12 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return null; } var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on we want to add then top->down or + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. var _wasHydrated = popHydrationState(workInProgress); @@ -17172,16 +16571,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { currentHostContext ) ) { - // If changes to the hydrated node needs to be applied at the + // If changes to the hydrated node need to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } - if (enableFlareAPI) { - var listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var listeners = newProps.DEPRECATED_flareListeners; if (listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( listeners, workInProgress, rootContainerInstance @@ -17200,11 +16599,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = instance; - if (enableFlareAPI) { - var _listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners = newProps.DEPRECATED_flareListeners; if (_listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( _listeners, workInProgress, rootContainerInstance @@ -17233,7 +16632,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17273,12 +16672,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - case ForwardRef: - break; - case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; @@ -17304,15 +16700,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { // We should never have been in a hydration state if we didn't have a current. // However, in some of those paths, we might have reentered a hydration state - // and then we might be inside a hydration state. In that case, we'll need to - // exit out of it. + // and then we might be inside a hydration state. In that case, we'll need to exit out of it. resetHydrationState(); if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated and unsuspended. workInProgress.memoizedState = null; } // If nothing suspended, we need to schedule an effect to mark this boundary - // as having hydrated so events know that they're free be invoked. + // as having hydrated so events know that they're free to be invoked. // It's also a signal to replay events and the suspense callback. // If something suspended, schedule an effect to attach retry listeners. // So we might as well always mark this. @@ -17405,7 +16800,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if not prevDidTimeout. if (nextDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. workInProgress.effectTag |= Update; } @@ -17415,9 +16810,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if these values are non equal, i.e. it changed. if (nextDidTimeout || prevDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } @@ -17432,33 +16827,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17469,7 +16849,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17477,9 +16857,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var renderState = workInProgress.memoizedState; if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17595,7 +16975,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // The time it took to render last row is greater than time until + // the expiration. + now() * 2 - renderState.renderingStartTime > + renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -17645,13 +17028,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this + // is a per component value. It should really be since the start + // of the total render or last commit. Consider using something like + // globalMostRecentFallbackTime. That doesn't account for being + // suspended for part of the time or when it's a new render. + // It should probably use a global start time value instead. } // Pop a row. var next = renderState.tail; renderState.rendering = next; renderState.tail = next.sibling; renderState.lastEffect = workInProgress.lastEffect; + renderState.renderingStartTime = now(); next.sibling = null; // Restore the context. // TODO: We can probably just avoid popping it instead and only // setting it the first time we go from not suspended to suspended. @@ -17672,7 +17061,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; + return null; } case FundamentalComponent: { @@ -17727,6 +17116,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } + + return null; } break; @@ -17743,13 +17134,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = scopeInstance; scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners2 = newProps.DEPRECATED_flareListeners; if (_listeners2 != null) { var _rootContainerInstance2 = getRootHostContainer(); - updateEventListeners( + updateDeprecatedEventListeners( _listeners2, workInProgress, _rootContainerInstance2 @@ -17762,9 +17153,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - if (enableFlareAPI) { - var _prevListeners = current.memoizedProps.listeners; - var _nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _prevListeners = + current.memoizedProps.DEPRECATED_flareListeners; + var _nextListeners = newProps.DEPRECATED_flareListeners; if ( _prevListeners !== _nextListeners || @@ -17782,21 +17174,28 @@ function completeWork(current, workInProgress, renderExpirationTime) { markRef$1(workInProgress); } } + + return null; } break; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + case Chunk: + if (enableChunksAPI) { + return null; + } + + break; } - return null; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } function unwindWork(workInProgress, renderExpirationTime) { @@ -17989,7 +17388,8 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console.error(error); // For a more detailed description of this block, see: + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -18026,7 +17426,7 @@ function logCapturedError(capturedError) { // has already printed it. Even if the application swallows the error, it is still // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - console.error(combinedMessage); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -18124,8 +17524,8 @@ function safelyCallDestroy(current$$1, destroy) { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(current$$1, error$$1); } } } @@ -18134,7 +17534,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } @@ -18154,28 +17555,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18191,8 +17591,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -18215,14 +17615,12 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18278,8 +17676,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { addendum = " You returned: " + _destroy; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18299,7 +17696,8 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; @@ -18320,9 +17718,10 @@ function commitLifeCycles( switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + return; } case ClassComponent: { @@ -18339,28 +17738,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18384,28 +17782,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18426,28 +17823,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -18559,14 +17955,12 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18653,8 +18047,7 @@ function commitAttachRef(finishedWork) { } else { { if (!ref.hasOwnProperty("current")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18689,7 +18082,8 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { @@ -18713,7 +18107,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel; - runWithPriority$1(priorityLevel, function() { + runWithPriority(priorityLevel, function() { var effect = firstEffect; do { @@ -18729,7 +18123,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } } - break; + return; } case ClassComponent: { @@ -18744,27 +18138,9 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ - ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); - } - - dependencies.responders = null; - } - } + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + beforeRemoveInstance(current$$1.stateNode); } safelyDetachRef(current$$1); @@ -18814,9 +18190,15 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case ScopeComponent: { + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + } + if (enableScopeAPI) { safelyDetachRef(current$$1); } + + return; } } } @@ -18877,6 +18259,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; if (alternate !== null) { detachFiber(alternate); @@ -18913,14 +18296,12 @@ function commitContainer(finishedWork) { pendingChildren = portalOrRoot.pendingChildren; return; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19256,7 +18637,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19301,7 +18683,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19339,12 +18722,12 @@ function commitWork(current$$1, finishedWork) { ); } - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = oldProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + updateDeprecatedEventListeners(nextListeners, finishedWork, null); } } } @@ -19406,9 +18789,10 @@ function commitWork(current$$1, finishedWork) { if (enableFundamentalAPI) { var fundamentalInstance = finishedWork.stateNode; updateFundamentalComponent(fundamentalInstance); + return; } - return; + break; } case ScopeComponent: { @@ -19416,31 +18800,31 @@ function commitWork(current$$1, finishedWork) { var scopeInstance = finishedWork.stateNode; scopeInstance.fiber = finishedWork; - if (enableFlareAPI) { + if (enableDeprecatedFlareAPI) { var _newProps = finishedWork.memoizedProps; var _oldProps = current$$1 !== null ? current$$1.memoizedProps : _newProps; - var _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + var _prevListeners = _oldProps.DEPRECATED_flareListeners; + var _nextListeners = _newProps.DEPRECATED_flareListeners; - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); + if (_prevListeners !== _nextListeners || current$$1 === null) { + updateDeprecatedEventListeners(_nextListeners, finishedWork, null); } } + + return; } - return; + break; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19472,7 +18856,7 @@ function commitSuspenseComponent(finishedWork) { } } else { if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + error("Unexpected type for suspenseCallback."); } } } @@ -19565,10 +18949,10 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { update.payload = { element: null }; - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.callback = function() { - onUncaughtError(error); + onUncaughtError(error$$1); logError(fiber, errorInfo); }; @@ -19581,11 +18965,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$$1); }; } @@ -19608,9 +18992,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$$1, { componentStack: stack !== null ? stack : "" }); @@ -19619,14 +19003,13 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(fiber.expirationTime === Sync) - ? warningWithoutStack$1( - false, - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ) - : void 0; + if (fiber.expirationTime !== Sync) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } } } }; @@ -19691,6 +19074,20 @@ function throwException( ) { // This is a thenable. var thenable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.expirationTime = currentSource.expirationTime; + } else { + sourceFiber.memoizedState = null; + } + } + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, @@ -20015,7 +19412,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { expirationTime = Sync; break; - case UserBlockingPriority$1: + case UserBlockingPriority: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; @@ -20097,7 +19494,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || + (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -20216,9 +19613,21 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; + var nextLevel = + lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; + + if ( + enableTrainModelFix && + nextLevel <= Idle && + firstPendingTime !== nextLevel + ) { + // Don't work on Idle/Never priority unless everything else is committed. + return NoWork; + } + + return nextLevel; } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the // expiration time of the existing task is the same as the expiration time of @@ -20666,80 +20075,70 @@ function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; - if (root.finishedExpirationTime === expirationTime) { - // There's already a pending commit at this expiration time. - // TODO: This is poorly factored. This case only exists for the - // batch.commit() API. - commitRoot(root); - } else { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } // If we have a work-in-progress fiber, it means there's still work to do - // in this root. + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); } + } while (true); - if (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } else { - // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. - stopFinishedWorkLoopTimer(); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - finishSyncRender(root, workInProgressRootExitStatus, expirationTime); - } // Before exiting, make sure there's a callback scheduled for the next - // pending level. + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); ensureRootIsScheduled(root); + throw fatalError; } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } return null; @@ -20767,12 +20166,13 @@ function flushDiscreteUpdates() { (executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext ) { - if (true && (executionContext & RenderContext) !== NoContext) { - warning$1( - false, - "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + - "already rendering." - ); + { + if ((executionContext & RenderContext) !== NoContext) { + error( + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } } // We're already rendering, so we can't synchronously flush pending work. // This is probably a nested event dispatch triggered by a lifecycle/effect, // like `el.focus()`. Exit. @@ -20787,7 +20187,7 @@ function flushDiscreteUpdates() { } function syncUpdates(fn, a, b, c) { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c)); + return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } function flushPendingDiscreteUpdates() { @@ -20841,7 +20241,7 @@ function discreteUpdates$1(fn, a, b, c) { try { // Should this - return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); } finally { executionContext = prevExecutionContext; @@ -20865,7 +20265,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } finally { executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -21350,7 +20750,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1( + runWithPriority( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -21358,7 +20758,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21452,8 +20861,8 @@ function commitRootImpl(root, renderPriorityLevel) { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(nextEffect, error$$1); nextEffect = nextEffect.nextEffect; } } @@ -21789,7 +21198,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } @@ -21825,8 +21234,8 @@ function flushPassiveEffectsImpl() { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(effect, error$$1); } resetCurrentFiber(); @@ -21866,17 +21275,17 @@ function markLegacyErrorBoundaryAsFailed(instance) { } } -function prepareToThrowUncaughtError(error) { +function prepareToThrowUncaughtError(error$$1) { if (!hasUncaughtError) { hasUncaughtError = true; - firstUncaughtError = error; + firstUncaughtError = error$$1; } } var onUncaughtError = prepareToThrowUncaughtError; -function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - var errorInfo = createCapturedValue(error, sourceFiber); +function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error$$1) { + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createRootErrorUpdate(rootFiber, errorInfo, Sync); enqueueUpdate(rootFiber, update); var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync); @@ -21887,11 +21296,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, error$$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$$1); return; } @@ -21899,7 +21308,7 @@ function captureCommitPhaseError(sourceFiber, error) { while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -21910,7 +21319,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createClassErrorUpdate( fiber, errorInfo, // TODO: This is always sync @@ -21984,7 +21393,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { root.lastPingedTime = suspendedTime; - if (root.finishedExpirationTime === suspendedTime) { + if (!enableTrainModelFix && root.finishedExpirationTime === suspendedTime) { // If there's a pending fallback waiting to commit, throw it away. root.finishedExpirationTime = NoWork; root.finishedWork = null; @@ -22138,8 +21547,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -22194,7 +21603,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Chunk ) { // Only warn for user-defined components, not internal ones like Suspense. return; @@ -22213,8 +21623,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -22305,10 +21714,10 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "setState(...): Cannot call setState() inside getChildContext()" ); + didWarnAboutUpdateInGetChildContext = true; break; @@ -22317,12 +21726,12 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "Cannot update during an existing state transition (such as " + "within `render`). Render methods should be a pure function of " + "props and state." ); + didWarnAboutUpdateInRender = true; break; } @@ -22340,8 +21749,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "It looks like you're using the wrong act() around your test interactions.\n" + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + "// for react-dom:\n" + @@ -22367,8 +21775,7 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22395,8 +21802,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22430,8 +21836,8 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22440,8 +21846,8 @@ function warnIfUnmockedScheduler(fiber) { ); } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'Starting from React v17, the "scheduler" module will need to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22459,7 +21865,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { if ( (sourceFiber.mode & ConcurrentMode) !== NoEffect && - (currentPriorityLevel === UserBlockingPriority$1 || + (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority) ) { var workInProgressNode = sourceFiber; @@ -22478,13 +21884,13 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { - var update = updateQueue.firstUpdate; + var update = updateQueue.baseQueue; while (update !== null) { var priorityLevel = update.priority; if ( - priorityLevel === UserBlockingPriority$1 || + priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority ) { if (componentsThatTriggeredHighPriSuspend === null) { @@ -22509,18 +21915,18 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { case FunctionComponent: case ForwardRef: case SimpleMemoComponent: - if ( - workInProgressNode.memoizedState !== null && - workInProgressNode.memoizedState.baseUpdate !== null - ) { - var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + case Chunk: { + var firstHook = current$$1.memoizedState; // TODO: This just checks the first Hook. Isn't it suppose to check all Hooks? + + if (firstHook !== null && firstHook.baseQueue !== null) { + var _update = firstHook.baseQueue; // Loop through the functional component's memoized state to see whether // the component has triggered any high pri updates while (_update !== null) { var priority = _update.priority; if ( - priority === UserBlockingPriority$1 || + priority === UserBlockingPriority || priority === ImmediatePriority ) { if (componentsThatTriggeredHighPriSuspend === null) { @@ -22536,9 +21942,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { break; } - if ( - _update.next === workInProgressNode.memoizedState.baseUpdate - ) { + if (_update.next === firstHook.baseQueue) { break; } @@ -22547,6 +21951,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { } break; + } default: break; @@ -22569,8 +21974,7 @@ function flushSuspensePriorityWarningInDEV() { componentsThatTriggeredHighPriSuspend = null; if (componentNames.length > 0) { - warningWithoutStack$1( - false, + error( "%s triggered a user-blocking update that suspended." + "\n\n" + "The fix is to split the update into multiple parts: a user-blocking " + @@ -22683,10 +22087,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { try { subscriber.onWorkStarted(interactions, threadID); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22708,10 +22112,10 @@ function finishPendingInteractions(root, committedExpirationTime) { var threadID = computeThreadID(root, committedExpirationTime); subscriber.onWorkStopped(root.memoizedInteractions, threadID); } - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } finally { // Clear completed interactions from the pending Map. @@ -22733,10 +22137,10 @@ function finishPendingInteractions(root, committedExpirationTime) { if (subscriber !== null && interaction.__count === 0) { try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22746,6 +22150,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22767,8 +22172,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "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" @@ -22781,6 +22185,23 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + { + // Only used by Fast Refresh + if (typeof hook.onScheduleFiberRoot === "function") { + onScheduleFiberRoot = function(root, children) { + try { + hook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + }; + } + } + onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -22796,13 +22217,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22811,29 +22231,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation encountered an error: %s.", err); } } // DevTools exists return true; } +function onScheduleRoot(root, children) { + if (typeof onScheduleFiberRoot === "function") { + onScheduleFiberRoot(root, children); + } +} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -22981,6 +22401,12 @@ function resolveLazyComponentTag(Component) { if ($$typeof === REACT_MEMO_TYPE) { return MemoComponent; } + + if (enableChunksAPI) { + if ($$typeof === REACT_CHUNK_TYPE) { + return Chunk; + } + } } return IndeterminateComponent; @@ -23261,6 +22687,10 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; + case REACT_CHUNK_TYPE: + fiberTag = Chunk; + break getTag; + case REACT_FUNDAMENTAL_TYPE: if (enableFundamentalAPI) { return createFiberFromFundamental( @@ -23386,8 +22816,7 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { typeof pendingProps.id !== "string" || typeof pendingProps.onRender !== "function" ) { - warningWithoutStack$1( - false, + error( 'Profiler must specify an "id" string and "onRender" function as props' ); } @@ -23549,6 +22978,7 @@ function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -23642,15 +23072,6 @@ function markRootExpiredAtTime(root, expirationTime) { } } -// This lets us hook into Fiber to debug what it's doing. -// See https://github.com/facebook/react/pull/8033. -// This is not part of the public API, not even for React DevTools. -// You may only inject a debugTool if you work on React Fiber itself. -var ReactFiberInstrumentation = { - debugTool: null -}; -var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; - var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -23737,8 +23158,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23750,8 +23170,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23776,6 +23195,10 @@ function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); @@ -23793,19 +23216,6 @@ function updateContainer(element, container, parentComponent, callback) { current$$1, suspenseConfig ); - - { - if (ReactFiberInstrumentation_1.debugTool) { - if (current$$1.alternate === null) { - ReactFiberInstrumentation_1.debugTool.onMountContainer(container); - } else if (element === null) { - ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); - } else { - ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); - } - } - } - var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -23817,8 +23227,8 @@ function updateContainer(element, container, parentComponent, callback) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23837,14 +23247,16 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ) - : void 0; + ); + } + } + update.callback = callback; } @@ -24002,7 +23414,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.11.0"; +var ReactVersion = "16.12.0-19f6fe170"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -24046,7 +23458,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24092,7 +23504,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24136,7 +23548,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24144,12 +23556,14 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24162,10 +23576,12 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24197,7 +23613,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24205,10 +23621,10 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; } @@ -24299,7 +23715,13 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { return NativeMethodsMixin; }; -var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} + +var ReactNativeComponent = function(findNodeHandle, findHostInstance) { /** * Superclass that provides methods to access the underlying native component. * This can be useful when you want to focus a view or measure its dimensions. @@ -24368,7 +23790,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24412,7 +23834,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24453,7 +23875,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24461,12 +23883,14 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24479,10 +23903,12 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24514,7 +23940,7 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24522,10 +23948,12 @@ var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error( + "Warning: setNativeProps is not currently supported in Fabric" + ); + } + return; } @@ -24669,8 +24097,6 @@ var getInspectorDataForViewTag; }; } -var _nativeFabricUIManage = nativeFabricUIManager; -var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { @@ -24678,17 +24104,17 @@ function findHostInstance_DEPRECATED(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24731,17 +24157,17 @@ function findNodeHandle(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24793,31 +24219,36 @@ setBatchingImplementation( ); var roots = new Map(); var ReactFabric = { - NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), + NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), // This is needed for implementation details of TouchableNativeFeedback // Remove this once TouchableNativeFeedback doesn't use cloneElement findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { - var invalid = - handle._nativeTag == null || handle._internalInstanceHandle == null; - - if (invalid) { - !!invalid - ? warningWithoutStack$1( - false, - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ) - : void 0; + if (handle._nativeTag == null) { + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + return; } - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 1977c28b91768a..3ff91b8b31675a 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -502,53 +502,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -681,13 +655,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1042,7 +1010,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1107,6 +1076,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1494,26 +1465,6 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} -(function(_React$Component) { - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } - _inheritsLoose(ReactNativeComponent, _React$Component); - var _proto = ReactNativeComponent.prototype; - _proto.blur = function() {}; - _proto.focus = function() {}; - _proto.measure = function() {}; - _proto.measureInWindow = function() {}; - _proto.measureLayout = function() {}; - _proto.setNativeProps = function() {}; - return ReactNativeComponent; -})(React.Component); -new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; enableNativeTargetAsInstance @@ -1556,21 +1507,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage$1.createChildSet, - appendChildNode = _nativeFabricUIManage$1.appendChild, - appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, - completeRoot = _nativeFabricUIManage$1.completeRoot, - registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, - fabricMeasure = _nativeFabricUIManage$1.measure, - fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1847,7 +1798,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1879,7 +1830,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -2003,237 +1954,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2250,10 +2159,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2368,6 +2275,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2375,16 +2283,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2400,16 +2300,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2971,39 +2868,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3201,7 +3109,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3209,13 +3117,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3235,53 +3137,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3290,37 +3184,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3348,51 +3247,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3402,7 +3325,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3419,21 +3342,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3453,7 +3378,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3501,6 +3426,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3542,14 +3482,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3612,7 +3549,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3631,23 +3568,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3655,25 +3590,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3715,23 +3638,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3739,25 +3660,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4071,17 +3980,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4127,6 +4033,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4155,17 +4062,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4467,6 +4371,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4475,6 +4380,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4801,16 +4707,17 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && - ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)); + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)) + : (workInProgress.stateNode = current.stateNode); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4836,51 +4743,361 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { + var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + case 5: + popHostContext(workInProgress); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== workInProgress.ref && + (workInProgress.effectTag |= 128); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } + requiredContext(contextStackCursor$1.current); + current = nextReactTag; + nextReactTag += 2; + renderExpirationTime$jscomp$0 = getViewConfigForType( + renderExpirationTime$jscomp$0 + ); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + renderExpirationTime$jscomp$0.validAttributes + ); + rootContainerInstance = createNode( + current, + renderExpirationTime$jscomp$0.uiViewClassName, + rootContainerInstance, + updatePayload, + workInProgress + ); + current = new ReactFabricHostComponent( + current, + renderExpirationTime$jscomp$0, + newProps, + workInProgress + ); + current = { node: rootContainerInstance, canonical: current }; + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.effectTag |= 128); + } return null; - } -} -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + rootContainerInstance = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + rootContainerInstance, + workInProgress + ); + } + return null; + case 13: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.effectTag & 64)) + return ( + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress + ); + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((updatePayload = workInProgress.firstEffect), + null !== updatePayload + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + newProps && (workInProgress.effectTag |= 4); + return null; + case 4: + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); + case 10: + return popProvider(workInProgress), null; + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + updatePayload = newProps.rendering; + if (null === updatePayload) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (updatePayload = rootContainerInstance.alternate), + null === updatePayload + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + updatePayload.childExpirationTime), + (rootContainerInstance.expirationTime = + updatePayload.expirationTime), + (rootContainerInstance.child = updatePayload.child), + (rootContainerInstance.memoizedProps = + updatePayload.memoizedProps), + (rootContainerInstance.memoizedState = + updatePayload.memoizedState), + (rootContainerInstance.updateQueue = + updatePayload.updateQueue), + (renderExpirationTime$jscomp$0 = + updatePayload.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !updatePayload.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); + } else + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = newProps.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); + } + return null !== newProps.tail + ? (0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress + ), + current) + : null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) }; } if ( @@ -4951,8 +5168,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -4966,18 +5184,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -4996,6 +5213,90 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + if (null === current$$1 && finishedWork.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -5004,13 +5305,14 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; @@ -5058,6 +5360,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function commitWork(current$$1, finishedWork) { @@ -5066,6 +5369,7 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); return; case 12: @@ -5079,19 +5383,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: switch (finishedWork.tag) { - case 1: - case 5: - case 6: - case 20: - break a; - case 3: - case 4: - break a; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + a: { + switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5564,44 +5869,41 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || - prepareFreshStack(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -5687,8 +5989,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5856,346 +6165,30 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - a: { - var instance = current$$1; - current$$1 = workInProgress; - var renderExpirationTime$jscomp$0 = renderExpirationTime, - newProps = current$$1.pendingProps; - switch (current$$1.tag) { - case 2: - break; - case 16: - break; - case 15: - case 0: - break; - case 1: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 3: - popHostContainer(current$$1); - popTopLevelContextObject(current$$1); - instance = current$$1.stateNode; - instance.pendingContext && - ((instance.context = instance.pendingContext), - (instance.pendingContext = null)); - updateHostContainer(current$$1); - break; - case 5: - popHostContext(current$$1); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ), - type = current$$1.type; - if (null !== instance && null != current$$1.stateNode) - updateHostComponent$1( - instance, - current$$1, - type, - newProps, - rootContainerInstance - ), - instance.ref !== current$$1.ref && - (current$$1.effectTag |= 128); - else if (newProps) { - requiredContext(contextStackCursor$1.current); - instance = current$$1; - renderExpirationTime$jscomp$0 = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - rootContainerInstance = createNode( - renderExpirationTime$jscomp$0, - type.uiViewClassName, - rootContainerInstance, - updatePayload, - instance - ); - instance = new ReactFabricHostComponent( - renderExpirationTime$jscomp$0, - type, - newProps, - instance - ); - instance = { - node: rootContainerInstance, - canonical: instance - }; - appendAllChildren(instance, current$$1, !1, !1); - current$$1.stateNode = instance; - null !== current$$1.ref && (current$$1.effectTag |= 128); - } else if (null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - if (instance && null != current$$1.stateNode) - updateHostText$1( - instance, - current$$1, - instance.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - instance = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext( - contextStackCursor$1.current - ); - current$$1.stateNode = createTextInstance( - newProps, - instance, - rootContainerInstance, - current$$1 - ); - } - break; - case 11: - break; - case 13: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (0 !== (current$$1.effectTag & 64)) { - current$$1.expirationTime = renderExpirationTime$jscomp$0; - break a; - } - newProps = null !== newProps; - rootContainerInstance = !1; - null !== instance && - ((renderExpirationTime$jscomp$0 = instance.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), - newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = instance.child.sibling), - null !== renderExpirationTime$jscomp$0 && - ((type = current$$1.firstEffect), - null !== type - ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = type)) - : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = null)), - (renderExpirationTime$jscomp$0.effectTag = 8)))); - if ( - newProps && - !rootContainerInstance && - 0 !== (current$$1.mode & 2) - ) - if ( - (null === instance && - !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - newProps && (current$$1.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; - case 4: - popHostContainer(current$$1); - updateHostContainer(current$$1); - break; - case 10: - popProvider(current$$1); - break; - case 9: - break; - case 14: - break; - case 17: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 19: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (null === newProps) break; - rootContainerInstance = 0 !== (current$$1.effectTag & 64); - type = newProps.rendering; - if (null === type) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== instance && 0 !== (instance.effectTag & 64)) - ) - for (instance = current$$1.child; null !== instance; ) { - type = findFirstSuspended(instance); - if (null !== type) { - current$$1.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - instance = type.updateQueue; - null !== instance && - ((current$$1.updateQueue = instance), - (current$$1.effectTag |= 4)); - null === newProps.lastEffect && - (current$$1.firstEffect = null); - current$$1.lastEffect = newProps.lastEffect; - instance = renderExpirationTime$jscomp$0; - for (newProps = current$$1.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime$jscomp$0 = instance), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (type = rootContainerInstance.alternate), - null === type - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - type.childExpirationTime), - (rootContainerInstance.expirationTime = - type.expirationTime), - (rootContainerInstance.child = type.child), - (rootContainerInstance.memoizedProps = - type.memoizedProps), - (rootContainerInstance.memoizedState = - type.memoizedState), - (rootContainerInstance.updateQueue = - type.updateQueue), - (renderExpirationTime$jscomp$0 = - type.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime$jscomp$0 - ? null - : { - expirationTime: - renderExpirationTime$jscomp$0.expirationTime, - firstContext: - renderExpirationTime$jscomp$0.firstContext, - responders: - renderExpirationTime$jscomp$0.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - current$$1 - ); - current$$1 = current$$1.child; - break a; - } - instance = instance.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((instance = findFirstSuspended(type)), null !== instance) - ) { - if ( - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - (instance = instance.updateQueue), - null !== instance && - ((current$$1.updateQueue = instance), - (current$$1.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !type.alternate) - ) { - current$$1 = current$$1.lastEffect = newProps.lastEffect; - null !== current$$1 && (current$$1.nextEffect = null); - break; - } - } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (current$$1.expirationTime = current$$1.childExpirationTime = - renderExpirationTime$jscomp$0 - 1)); - newProps.isBackwards - ? ((type.sibling = current$$1.child), (current$$1.child = type)) - : ((instance = newProps.last), - null !== instance - ? (instance.sibling = type) - : (current$$1.child = type), - (newProps.last = type)); - } - if (null !== newProps.tail) { - 0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500); - instance = newProps.tail; - newProps.rendering = instance; - newProps.tail = instance.sibling; - newProps.lastEffect = current$$1.lastEffect; - instance.sibling = null; - newProps = suspenseStackCursor.current; - newProps = rootContainerInstance - ? (newProps & 1) | 2 - : newProps & 1; - push(suspenseStackCursor, newProps, current$$1); - current$$1 = instance; - break a; - } - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - current$$1.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - current$$1 = null; - } - instance = workInProgress; - if (1 === renderExpirationTime || 1 !== instance.childExpirationTime) { - newProps = 0; + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); + var completedWork = workInProgress; + if ( + 1 === renderExpirationTime || + 1 !== completedWork.childExpirationTime + ) { for ( - rootContainerInstance = instance.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = completedWork.child; + null !== _child; - ) - (renderExpirationTime$jscomp$0 = - rootContainerInstance.expirationTime), - (type = rootContainerInstance.childExpirationTime), - renderExpirationTime$jscomp$0 > newProps && - (newProps = renderExpirationTime$jscomp$0), - type > newProps && (newProps = type), - (rootContainerInstance = rootContainerInstance.sibling); - instance.childExpirationTime = newProps; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + completedWork.childExpirationTime = newChildExpirationTime; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -6234,11 +6227,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6369,101 +6363,34 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$1, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - var current$$1$jscomp$1 = nextEffect.alternate; - current$$1 = nextEffect; - currentRef = effectTag; - switch (current$$1.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, current$$1); - break; - case 1: - var instance = current$$1.stateNode; - if (current$$1.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - current$$1.elementType === current$$1.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - current$$1.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = current$$1.updateQueue; - null !== updateQueue && - commitUpdateQueue( - current$$1, - updateQueue, - instance, - currentRef - ); - break; - case 3: - var _updateQueue = current$$1.updateQueue; - if (null !== _updateQueue) { - root = null; - if (null !== current$$1.child) - switch (current$$1.child.tag) { - case 5: - root = current$$1.child.stateNode.canonical; - break; - case 1: - root = current$$1.child.stateNode; - } - commitUpdateQueue(current$$1, _updateQueue, root, currentRef); - } - break; - case 5: - if (null === current$$1$jscomp$1 && current$$1.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0.canonical; + currentRef = instance.canonical; break; default: - current$$1 = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6533,7 +6460,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6552,6 +6479,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6761,6 +6689,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6798,62 +6727,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -6891,16 +6821,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7384,6 +7315,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7559,7 +7493,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7700,12 +7638,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7714,6 +7657,7 @@ var roots = new Map(), var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -7863,7 +7807,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-experimental-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 21270fe18669b9..521068f8747c5d 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -503,53 +503,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -682,13 +656,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1035,7 +1003,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1100,6 +1069,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1487,26 +1458,6 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} -(function(_React$Component) { - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } - _inheritsLoose(ReactNativeComponent, _React$Component); - var _proto = ReactNativeComponent.prototype; - _proto.blur = function() {}; - _proto.focus = function() {}; - _proto.measure = function() {}; - _proto.measureInWindow = function() {}; - _proto.measureLayout = function() {}; - _proto.setNativeProps = function() {}; - return ReactNativeComponent; -})(React.Component); -new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; eventTarget = nativeEvent.target; @@ -1547,21 +1498,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage$1.createChildSet, - appendChildNode = _nativeFabricUIManage$1.appendChild, - appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, - completeRoot = _nativeFabricUIManage$1.completeRoot, - registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, - fabricMeasure = _nativeFabricUIManage$1.measure, - fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1838,7 +1789,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1870,7 +1821,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1994,237 +1945,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2241,10 +2150,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2359,6 +2266,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2366,16 +2274,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2391,16 +2291,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2962,39 +2859,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3192,7 +3100,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3200,13 +3108,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3226,53 +3128,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3281,37 +3175,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3339,51 +3238,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3393,7 +3316,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3410,21 +3333,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3444,7 +3369,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3492,6 +3417,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3533,14 +3473,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3603,7 +3540,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3622,23 +3559,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3646,25 +3581,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3706,23 +3629,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3730,25 +3651,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4062,17 +3971,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4118,6 +4024,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4146,17 +4053,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4458,6 +4362,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4466,6 +4371,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4792,16 +4698,17 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && - ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)); + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)) + : (workInProgress.stateNode = current.stateNode); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4827,51 +4734,361 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { + var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + case 5: + popHostContext(workInProgress); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== workInProgress.ref && + (workInProgress.effectTag |= 128); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } + requiredContext(contextStackCursor$1.current); + current = nextReactTag; + nextReactTag += 2; + renderExpirationTime$jscomp$0 = getViewConfigForType( + renderExpirationTime$jscomp$0 + ); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + renderExpirationTime$jscomp$0.validAttributes + ); + rootContainerInstance = createNode( + current, + renderExpirationTime$jscomp$0.uiViewClassName, + rootContainerInstance, + updatePayload, + workInProgress + ); + current = new ReactFabricHostComponent( + current, + renderExpirationTime$jscomp$0, + newProps, + workInProgress + ); + current = { node: rootContainerInstance, canonical: current }; + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.effectTag |= 128); + } return null; - } -} -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + rootContainerInstance = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + rootContainerInstance, + workInProgress + ); + } + return null; + case 13: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.effectTag & 64)) + return ( + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress + ); + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((updatePayload = workInProgress.firstEffect), + null !== updatePayload + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + newProps && (workInProgress.effectTag |= 4); + return null; + case 4: + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); + case 10: + return popProvider(workInProgress), null; + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + updatePayload = newProps.rendering; + if (null === updatePayload) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (updatePayload = rootContainerInstance.alternate), + null === updatePayload + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + updatePayload.childExpirationTime), + (rootContainerInstance.expirationTime = + updatePayload.expirationTime), + (rootContainerInstance.child = updatePayload.child), + (rootContainerInstance.memoizedProps = + updatePayload.memoizedProps), + (rootContainerInstance.memoizedState = + updatePayload.memoizedState), + (rootContainerInstance.updateQueue = + updatePayload.updateQueue), + (renderExpirationTime$jscomp$0 = + updatePayload.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !updatePayload.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); + } else + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = newProps.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); + } + return null !== newProps.tail + ? (0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress + ), + current) + : null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) }; } if ( @@ -4942,8 +5159,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -4957,18 +5175,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -4987,6 +5204,90 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + if (null === current$$1 && finishedWork.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4995,13 +5296,14 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; @@ -5049,6 +5351,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function commitWork(current$$1, finishedWork) { @@ -5057,6 +5360,7 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); return; case 12: @@ -5070,19 +5374,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: switch (finishedWork.tag) { - case 1: - case 5: - case 6: - case 20: - break a; - case 3: - case 4: - break a; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + a: { + switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5555,44 +5860,41 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || - prepareFreshStack(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -5678,8 +5980,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5847,346 +6156,30 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - a: { - var instance = current$$1; - current$$1 = workInProgress; - var renderExpirationTime$jscomp$0 = renderExpirationTime, - newProps = current$$1.pendingProps; - switch (current$$1.tag) { - case 2: - break; - case 16: - break; - case 15: - case 0: - break; - case 1: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 3: - popHostContainer(current$$1); - popTopLevelContextObject(current$$1); - instance = current$$1.stateNode; - instance.pendingContext && - ((instance.context = instance.pendingContext), - (instance.pendingContext = null)); - updateHostContainer(current$$1); - break; - case 5: - popHostContext(current$$1); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ), - type = current$$1.type; - if (null !== instance && null != current$$1.stateNode) - updateHostComponent$1( - instance, - current$$1, - type, - newProps, - rootContainerInstance - ), - instance.ref !== current$$1.ref && - (current$$1.effectTag |= 128); - else if (newProps) { - requiredContext(contextStackCursor$1.current); - instance = current$$1; - renderExpirationTime$jscomp$0 = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - rootContainerInstance = createNode( - renderExpirationTime$jscomp$0, - type.uiViewClassName, - rootContainerInstance, - updatePayload, - instance - ); - instance = new ReactFabricHostComponent( - renderExpirationTime$jscomp$0, - type, - newProps, - instance - ); - instance = { - node: rootContainerInstance, - canonical: instance - }; - appendAllChildren(instance, current$$1, !1, !1); - current$$1.stateNode = instance; - null !== current$$1.ref && (current$$1.effectTag |= 128); - } else if (null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - if (instance && null != current$$1.stateNode) - updateHostText$1( - instance, - current$$1, - instance.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - instance = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext( - contextStackCursor$1.current - ); - current$$1.stateNode = createTextInstance( - newProps, - instance, - rootContainerInstance, - current$$1 - ); - } - break; - case 11: - break; - case 13: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (0 !== (current$$1.effectTag & 64)) { - current$$1.expirationTime = renderExpirationTime$jscomp$0; - break a; - } - newProps = null !== newProps; - rootContainerInstance = !1; - null !== instance && - ((renderExpirationTime$jscomp$0 = instance.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), - newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = instance.child.sibling), - null !== renderExpirationTime$jscomp$0 && - ((type = current$$1.firstEffect), - null !== type - ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = type)) - : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = null)), - (renderExpirationTime$jscomp$0.effectTag = 8)))); - if ( - newProps && - !rootContainerInstance && - 0 !== (current$$1.mode & 2) - ) - if ( - (null === instance && - !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - newProps && (current$$1.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; - case 4: - popHostContainer(current$$1); - updateHostContainer(current$$1); - break; - case 10: - popProvider(current$$1); - break; - case 9: - break; - case 14: - break; - case 17: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 19: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (null === newProps) break; - rootContainerInstance = 0 !== (current$$1.effectTag & 64); - type = newProps.rendering; - if (null === type) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== instance && 0 !== (instance.effectTag & 64)) - ) - for (instance = current$$1.child; null !== instance; ) { - type = findFirstSuspended(instance); - if (null !== type) { - current$$1.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - instance = type.updateQueue; - null !== instance && - ((current$$1.updateQueue = instance), - (current$$1.effectTag |= 4)); - null === newProps.lastEffect && - (current$$1.firstEffect = null); - current$$1.lastEffect = newProps.lastEffect; - instance = renderExpirationTime$jscomp$0; - for (newProps = current$$1.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime$jscomp$0 = instance), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (type = rootContainerInstance.alternate), - null === type - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - type.childExpirationTime), - (rootContainerInstance.expirationTime = - type.expirationTime), - (rootContainerInstance.child = type.child), - (rootContainerInstance.memoizedProps = - type.memoizedProps), - (rootContainerInstance.memoizedState = - type.memoizedState), - (rootContainerInstance.updateQueue = - type.updateQueue), - (renderExpirationTime$jscomp$0 = - type.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime$jscomp$0 - ? null - : { - expirationTime: - renderExpirationTime$jscomp$0.expirationTime, - firstContext: - renderExpirationTime$jscomp$0.firstContext, - responders: - renderExpirationTime$jscomp$0.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - current$$1 - ); - current$$1 = current$$1.child; - break a; - } - instance = instance.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((instance = findFirstSuspended(type)), null !== instance) - ) { - if ( - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - (instance = instance.updateQueue), - null !== instance && - ((current$$1.updateQueue = instance), - (current$$1.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !type.alternate) - ) { - current$$1 = current$$1.lastEffect = newProps.lastEffect; - null !== current$$1 && (current$$1.nextEffect = null); - break; - } - } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (current$$1.expirationTime = current$$1.childExpirationTime = - renderExpirationTime$jscomp$0 - 1)); - newProps.isBackwards - ? ((type.sibling = current$$1.child), (current$$1.child = type)) - : ((instance = newProps.last), - null !== instance - ? (instance.sibling = type) - : (current$$1.child = type), - (newProps.last = type)); - } - if (null !== newProps.tail) { - 0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500); - instance = newProps.tail; - newProps.rendering = instance; - newProps.tail = instance.sibling; - newProps.lastEffect = current$$1.lastEffect; - instance.sibling = null; - newProps = suspenseStackCursor.current; - newProps = rootContainerInstance - ? (newProps & 1) | 2 - : newProps & 1; - push(suspenseStackCursor, newProps, current$$1); - current$$1 = instance; - break a; - } - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - current$$1.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - current$$1 = null; - } - instance = workInProgress; - if (1 === renderExpirationTime || 1 !== instance.childExpirationTime) { - newProps = 0; + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); + var completedWork = workInProgress; + if ( + 1 === renderExpirationTime || + 1 !== completedWork.childExpirationTime + ) { for ( - rootContainerInstance = instance.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = completedWork.child; + null !== _child; - ) - (renderExpirationTime$jscomp$0 = - rootContainerInstance.expirationTime), - (type = rootContainerInstance.childExpirationTime), - renderExpirationTime$jscomp$0 > newProps && - (newProps = renderExpirationTime$jscomp$0), - type > newProps && (newProps = type), - (rootContainerInstance = rootContainerInstance.sibling); - instance.childExpirationTime = newProps; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + completedWork.childExpirationTime = newChildExpirationTime; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -6225,11 +6218,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6360,101 +6354,34 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$1, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - var current$$1$jscomp$1 = nextEffect.alternate; - current$$1 = nextEffect; - currentRef = effectTag; - switch (current$$1.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, current$$1); - break; - case 1: - var instance = current$$1.stateNode; - if (current$$1.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - current$$1.elementType === current$$1.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - current$$1.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = current$$1.updateQueue; - null !== updateQueue && - commitUpdateQueue( - current$$1, - updateQueue, - instance, - currentRef - ); - break; - case 3: - var _updateQueue = current$$1.updateQueue; - if (null !== _updateQueue) { - root = null; - if (null !== current$$1.child) - switch (current$$1.child.tag) { - case 5: - root = current$$1.child.stateNode.canonical; - break; - case 1: - root = current$$1.child.stateNode; - } - commitUpdateQueue(current$$1, _updateQueue, root, currentRef); - } - break; - case 5: - if (null === current$$1$jscomp$1 && current$$1.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0.canonical; + currentRef = instance.canonical; break; default: - current$$1 = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6524,7 +6451,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6543,6 +6470,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6752,6 +6680,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6789,62 +6718,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -6882,16 +6812,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7375,6 +7306,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7550,7 +7484,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7691,12 +7629,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7705,6 +7648,7 @@ var roots = new Map(), var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -7854,7 +7798,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 90b9fe4a0821c5..d65855f6d93cbd 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -503,53 +503,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -682,13 +656,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1043,7 +1011,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1108,6 +1077,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1495,26 +1466,6 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} -(function(_React$Component) { - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } - _inheritsLoose(ReactNativeComponent, _React$Component); - var _proto = ReactNativeComponent.prototype; - _proto.blur = function() {}; - _proto.focus = function() {}; - _proto.measure = function() {}; - _proto.measureInWindow = function() {}; - _proto.measureLayout = function() {}; - _proto.setNativeProps = function() {}; - return ReactNativeComponent; -})(React.Component); -new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; enableNativeTargetAsInstance @@ -1557,21 +1508,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage$1.createChildSet, - appendChildNode = _nativeFabricUIManage$1.appendChild, - appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, - completeRoot = _nativeFabricUIManage$1.completeRoot, - registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, - fabricMeasure = _nativeFabricUIManage$1.measure, - fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1855,7 +1806,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1887,7 +1838,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -2024,237 +1975,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2271,10 +2180,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2389,6 +2296,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2396,16 +2304,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2421,16 +2321,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2992,39 +2889,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3222,7 +3130,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3230,13 +3138,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3256,53 +3158,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3311,37 +3205,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3369,51 +3268,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3423,7 +3346,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3440,21 +3363,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3474,7 +3399,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3522,6 +3447,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3563,14 +3503,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3633,7 +3570,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3652,23 +3589,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3676,25 +3611,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3736,23 +3659,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3760,25 +3681,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4103,17 +4012,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4159,6 +4065,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4187,17 +4094,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4517,6 +4421,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4525,6 +4430,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4852,16 +4758,17 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && - ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)); + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)) + : (workInProgress.stateNode = current.stateNode); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4891,24 +4798,32 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( @@ -4925,7 +4840,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; @@ -4955,11 +4877,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } else if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4982,9 +4901,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgress ); } - break; - case 11: - break; + return null; case 13: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; @@ -5032,31 +4949,24 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { )); } newProps && (workInProgress.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 19: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -5151,13 +5061,15 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5176,14 +5088,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + return null !== newProps.tail + ? (0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), (current.sibling = null), (newProps = suspenseStackCursor.current), push( @@ -5191,21 +5103,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, workInProgress ), - current - ); - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + current) + : null; } - return null; + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5322,8 +5227,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -5337,18 +5243,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -5367,6 +5272,101 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + if (null === current$$1 && finishedWork.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + return; + case 6: + return; + case 4: + return; + case 12: + committedExpirationTime = finishedWork.memoizedProps.onRender; + "function" === typeof committedExpirationTime && + committedExpirationTime( + finishedWork.memoizedProps.id, + null === current$$1 ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -5375,13 +5375,14 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; @@ -5429,6 +5430,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function commitWork(current$$1, finishedWork) { @@ -5437,6 +5439,7 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); return; case 12: @@ -5450,19 +5453,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: switch (finishedWork.tag) { - case 1: - case 5: - case 6: - case 20: - break a; - case 3: - case 4: - break a; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + a: { + switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5936,47 +5940,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), prepareFreshStack(root, lastExpiredTime), - startWorkOnPendingInteractions(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root), - prevInteractions = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - tracing.__interactionsRef.current = prevInteractions; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -6065,8 +6066,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6346,11 +6354,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6489,108 +6498,24 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - renderPriorityLevel = effectTag; - var current$$1$jscomp$1 = nextEffect.alternate; - currentRef = nextEffect; - root = current$$1; - switch (currentRef.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, currentRef); - break; - case 1: - var instance = currentRef.stateNode; - if (currentRef.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - currentRef.elementType === currentRef.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - currentRef.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = currentRef.updateQueue; - null !== updateQueue && - commitUpdateQueue(currentRef, updateQueue, instance, root); - break; - case 3: - var _updateQueue = currentRef.updateQueue; - if (null !== _updateQueue) { - renderPriorityLevel = null; - if (null !== currentRef.child) - switch (currentRef.child.tag) { - case 5: - renderPriorityLevel = - currentRef.child.stateNode.canonical; - break; - case 1: - renderPriorityLevel = currentRef.child.stateNode; - } - commitUpdateQueue( - currentRef, - _updateQueue, - renderPriorityLevel, - root - ); - } - break; - case 5: - if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = currentRef.memoizedProps.onRender; - "function" === typeof onRender && - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - renderPriorityLevel.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0.canonical; + currentRef = instance.canonical; break; default: - currentRef = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref ? ref(currentRef) @@ -6630,13 +6555,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6682,7 +6607,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6708,6 +6633,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6930,6 +6856,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6967,62 +6894,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7060,16 +6988,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7648,6 +7577,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7826,7 +7758,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7967,12 +7903,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7983,6 +7924,7 @@ var roots = new Map(), uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8132,7 +8074,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-experimental-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index d36acbd2303fcf..cf5e8cc3c3b89f 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -504,53 +504,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -683,13 +657,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1036,7 +1004,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1101,6 +1070,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1488,26 +1459,6 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} -(function(_React$Component) { - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } - _inheritsLoose(ReactNativeComponent, _React$Component); - var _proto = ReactNativeComponent.prototype; - _proto.blur = function() {}; - _proto.focus = function() {}; - _proto.measure = function() {}; - _proto.measureInWindow = function() {}; - _proto.measureLayout = function() {}; - _proto.setNativeProps = function() {}; - return ReactNativeComponent; -})(React.Component); -new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; eventTarget = nativeEvent.target; @@ -1548,21 +1499,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage$1.createChildSet, - appendChildNode = _nativeFabricUIManage$1.appendChild, - appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, - completeRoot = _nativeFabricUIManage$1.completeRoot, - registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, - fabricMeasure = _nativeFabricUIManage$1.measure, - fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1846,7 +1797,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1878,7 +1829,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -2015,237 +1966,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2262,10 +2171,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2380,6 +2287,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2387,16 +2295,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2412,16 +2312,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2983,39 +2880,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3213,7 +3121,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3221,13 +3129,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3247,53 +3149,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3302,37 +3196,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3360,51 +3259,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3414,7 +3337,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3431,21 +3354,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3465,7 +3390,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3513,6 +3438,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3554,14 +3494,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3624,7 +3561,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3643,23 +3580,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3667,25 +3602,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3727,23 +3650,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3751,25 +3672,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4094,17 +4003,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4150,6 +4056,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4178,17 +4085,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4508,6 +4412,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4516,6 +4421,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4843,16 +4749,17 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && - ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)); + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)) + : (workInProgress.stateNode = current.stateNode); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4882,24 +4789,32 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( @@ -4916,7 +4831,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; @@ -4946,11 +4868,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } else if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4973,9 +4892,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgress ); } - break; - case 11: - break; + return null; case 13: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; @@ -5023,31 +4940,24 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { )); } newProps && (workInProgress.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 19: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -5142,13 +5052,15 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5167,14 +5079,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + return null !== newProps.tail + ? (0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), (current.sibling = null), (newProps = suspenseStackCursor.current), push( @@ -5182,21 +5094,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, workInProgress ), - current - ); - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + current) + : null; } - return null; + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5313,8 +5218,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -5328,18 +5234,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -5358,6 +5263,101 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + if (null === current$$1 && finishedWork.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + return; + case 6: + return; + case 4: + return; + case 12: + committedExpirationTime = finishedWork.memoizedProps.onRender; + "function" === typeof committedExpirationTime && + committedExpirationTime( + finishedWork.memoizedProps.id, + null === current$$1 ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -5366,13 +5366,14 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; @@ -5420,6 +5421,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function commitWork(current$$1, finishedWork) { @@ -5428,6 +5430,7 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); return; case 12: @@ -5441,19 +5444,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: switch (finishedWork.tag) { - case 1: - case 5: - case 6: - case 20: - break a; - case 3: - case 4: - break a; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + a: { + switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5927,47 +5931,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), prepareFreshStack(root, lastExpiredTime), - startWorkOnPendingInteractions(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root), - prevInteractions = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - tracing.__interactionsRef.current = prevInteractions; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -6056,8 +6057,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6337,11 +6345,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6480,108 +6489,24 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - renderPriorityLevel = effectTag; - var current$$1$jscomp$1 = nextEffect.alternate; - currentRef = nextEffect; - root = current$$1; - switch (currentRef.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, currentRef); - break; - case 1: - var instance = currentRef.stateNode; - if (currentRef.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - currentRef.elementType === currentRef.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - currentRef.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = currentRef.updateQueue; - null !== updateQueue && - commitUpdateQueue(currentRef, updateQueue, instance, root); - break; - case 3: - var _updateQueue = currentRef.updateQueue; - if (null !== _updateQueue) { - renderPriorityLevel = null; - if (null !== currentRef.child) - switch (currentRef.child.tag) { - case 5: - renderPriorityLevel = - currentRef.child.stateNode.canonical; - break; - case 1: - renderPriorityLevel = currentRef.child.stateNode; - } - commitUpdateQueue( - currentRef, - _updateQueue, - renderPriorityLevel, - root - ); - } - break; - case 5: - if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = currentRef.memoizedProps.onRender; - "function" === typeof onRender && - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - renderPriorityLevel.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0.canonical; + currentRef = instance.canonical; break; default: - currentRef = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref ? ref(currentRef) @@ -6621,13 +6546,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6673,7 +6598,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6699,6 +6624,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6921,6 +6847,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6958,62 +6885,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7051,16 +6979,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7639,6 +7568,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7817,7 +7749,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7958,12 +7894,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7974,6 +7915,7 @@ var roots = new Map(), uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8123,7 +8065,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = { default: ReactFabric }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index b1ae206b2534e5..ef0fe9a63c622b 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -15,13 +15,110 @@ if (__DEV__) { (function() { "use strict"; +var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); -var React = require("react"); var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// by calls to these methods by a Babel plugin. +// +// In PROD (or in packages without access to React internals), +// they are left as they are instead. + +function warn(format) { + { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); + } +} +function error(format) { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } +} + +function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === "string" && + args[args.length - 1].indexOf("\n in") === 0; + + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } + } + + var argsWithFormat = args.map(function(item) { + return "" + item; + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + } +} + /** * Use invariant() to assert state which your program assumes to be true. * @@ -559,71 +656,6 @@ function clearCaughtError() { } } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var warningWithoutStack = function() {}; - -{ - warningWithoutStack = function(condition, format) { - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - if (format === undefined) { - throw new Error( - "`warningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (args.length > 8) { - // Check before the condition to catch violations early. - throw new Error( - "warningWithoutStack() currently supports at most 8 arguments." - ); - } - - if (condition) { - return; - } - - if (typeof console !== "undefined") { - var argsWithFormat = args.map(function(item) { - return "" + item; - }); - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - - Function.prototype.apply.call(console.error, console, argsWithFormat); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} - }; -} - -var warningWithoutStack$1 = warningWithoutStack; - var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -637,13 +669,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -664,9 +695,10 @@ var validateEventDispatches; : dispatchInstances ? 1 : 0; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -1093,6 +1125,7 @@ var DehydratedFragment = 18; var SuspenseListComponent = 19; var FundamentalComponent = 20; var ScopeComponent = 21; +var Chunk = 22; function getParent(inst) { do { @@ -1230,9 +1263,9 @@ function listenerAtPhase(inst, event, propagationPhase) { function accumulateDirectionalDispatches(inst, phase, event) { { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; + if (!inst) { + error("Dispatching inst must not be null"); + } } var listener = listenerAtPhase(inst, event, phase); @@ -1577,7 +1610,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function set(val) { var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); + warn$$1(action, "This is effectively a no-op"); return val; } @@ -1586,24 +1619,22 @@ function getPooledWarningPropertyDefinition(propName, getVal) { var result = isFunction ? "This is a no-op function" : "This is set to null"; - warn(action, result); + warn$$1(action, result); return getVal; } - function warn(action, result) { - var warningCondition = false; - !warningCondition - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + function warn$$1(action, result) { + { + error( + "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 + ); + } } } @@ -1748,15 +1779,14 @@ function getTouchIdentifier(_ref) { } { - !(identifier <= MAX_TOUCH_BANK) - ? warningWithoutStack$1( - false, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ) - : void 0; + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } } return identifier; @@ -1788,12 +1818,15 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1810,12 +1843,15 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1866,9 +1902,10 @@ var ResponderTouchHistoryStore = { { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } } } } @@ -2397,9 +2434,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2575,11 +2615,13 @@ var enableProfilerTimer = true; var enableSchedulerTracing = true; var enableSuspenseServerRenderer = false; +var enableChunksAPI = false; + var debugRenderPhaseSideEffectsForStrictMode = true; var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; var warnAboutDeprecatedLifecycles = true; -var enableFlareAPI = false; +var enableDeprecatedFlareAPI = false; var enableFundamentalAPI = false; var enableScopeAPI = false; @@ -2590,6 +2632,7 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +var enableTrainModelFix = false; // Only used in www builds. // Flow magic to verify the exports of this file match the original version. @@ -2667,8 +2710,13 @@ function restoreStateOfTarget(target) { ); } - var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - restoreImpl(internalInstance.stateNode, internalInstance.type, props); + var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. + + if (stateNode) { + var _props = getFiberCurrentPropsFromNode(stateNode); + + restoreImpl(internalInstance.stateNode, internalInstance.type, _props); + } } function needsStateRestore() { @@ -2901,10 +2949,7 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - warningWithoutStack$1( - false, - "A view is reporting that a touch occurred on tag zero." - ); + error("A view is reporting that a touch occurred on tag zero."); } } else { rootNodeID = target; @@ -2971,23 +3016,6 @@ function set(key, value) { key._reactInternalFiber = value; } -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} - // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -3014,6 +3042,7 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; +var REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 0xead9; var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 0xead5; @@ -3037,43 +3066,6 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; - -{ - warning = function(condition, format) { - if (condition) { - return; - } - - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args - - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} - -var warning$1 = warning; - var Uninitialized = -1; var Pending = 0; var Resolved = 1; @@ -3094,8 +3086,7 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + "Instead received: %s\n\nYour code should look like: \n " + "const MyComponent = lazy(() => import('./MyComponent'))", @@ -3108,10 +3099,10 @@ function initializeLazyComponentType(lazyComponent) { lazyComponent._result = defaultExport; } }, - function(error) { + function(error$$1) { if (lazyComponent._status === Pending) { lazyComponent._status = Rejected; - lazyComponent._result = error; + lazyComponent._result = error$$1; } } ); @@ -3134,8 +3125,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -3184,6 +3174,9 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); + case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3307,17 +3300,18 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !instance._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%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.type) || "A component" - ) - : void 0; + + if (!instance._warnedAboutRefsInRender) { + error( + "%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.type) || "A component" + ); + } + instance._warnedAboutRefsInRender = true; } } @@ -4042,17 +4036,19 @@ function throwOnStylesProp(component, props) { } } function warnForStyleProps(props, validAttributes) { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - console.error( - "You are setting the style `{ " + - key + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { " + - key + - ": ... } }`" - ); + { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + error( + "You are setting the style `{ %s" + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { %s" + + ": ... } }`", + key, + key + ); + } } } } @@ -4117,10 +4113,12 @@ var ReactNativeFiberHostComponent = } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -4568,7 +4566,7 @@ function unhideInstance(instance, props) { function unhideTextInstance(textInstance, text) { throw new Error("Not yet implemented."); } -function mountResponderInstance( +function DEPRECATED_mountResponderInstance( responder, responderInstance, props, @@ -4577,7 +4575,7 @@ function mountResponderInstance( ) { throw new Error("Not yet implemented."); } -function unmountResponderInstance(responderInstance) { +function DEPRECATED_unmountResponderInstance(responderInstance) { throw new Error("Not yet implemented."); } function getFundamentalComponentInstance(fundamentalInstance) { @@ -4598,6 +4596,9 @@ function unmountFundamentalComponent(fundamentalInstance) { function getInstanceFromNode$1(node) { throw new Error("Not yet implemented."); } +function beforeRemoveInstance(instance) { + // noop +} var BEFORE_SLASH_RE = /^(.*)[\\\/]/; var describeComponentFrame = function(name, source, ownerName) { @@ -5181,7 +5182,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5189,7 +5190,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5376,8 +5377,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%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.", @@ -5896,78 +5897,6 @@ function shallowEqual(objA, objB) { return true; } -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var lowPriorityWarningWithoutStack = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - - if (typeof console !== "undefined") { - console.warn(message); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (!condition) { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(void 0, [format].concat(args)); - } - }; -} - -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; - var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, flushPendingUnsafeLifecycleWarnings: function() {}, @@ -6138,8 +6067,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6153,8 +6082,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6172,8 +6100,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6186,8 +6113,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6205,8 +6131,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6225,8 +6150,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6251,11 +6175,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6288,8 +6212,8 @@ var ReactStrictModeWarnings = { }); var sortedNames = setToSortedString(uniqueNames); var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6822,17 +6746,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue = nextValue; { - !( - context._currentRenderer === undefined || - context._currentRenderer === null || - context._currentRenderer === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer = rendererSigil; } } else { @@ -6840,17 +6764,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue2 = nextValue; { - !( - context._currentRenderer2 === undefined || - context._currentRenderer2 === null || - context._currentRenderer2 === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -6877,14 +6801,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) - ? warning$1( - false, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ) - : void 0; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7080,15 +7003,14 @@ function readContext(context, observedBits) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. - !!isDisallowedContextReadInDEV - ? warning$1( - false, - "Context can only be read while React is rendering. " + - "In classes, you can read it in the render method or getDerivedStateFromProps. " + - "In function components, you can read it directly in the function body, but not " + - "inside Hooks like useReducer() or useMemo()." - ) - : void 0; + if (isDisallowedContextReadInDEV) { + error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } } if (lastContextWithAllBitsObserved === context) { @@ -7229,38 +7151,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { +function initializeUpdateQueue(fiber) { var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { - var queue = { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + fiber.updateQueue = queue; +} +function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + baseQueue: currentQueue.baseQueue, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7268,9 +7184,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7278,136 +7194,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -function appendUpdateToQueue(queue, update) { - // Append the update to the end of the list. - if (queue.lastUpdate === null) { - // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; - } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -function enqueueUpdate(fiber, update) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1; - var queue2; + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } + update.next = pending.next; + pending.next = update; } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update); - appendUpdateToQueue(queue2, update); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - - queue2.lastUpdate = update; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "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." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } // Append the update to the end of the list. + if (current !== null) { + // Ensure the work-in-progress queue is a clone + cloneUpdateQueue(current, workInProgress); + } // Captured updates go only on the work-in-progress queue. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7499,163 +7341,171 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, - queue, props, instance, renderExpirationTime ) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; hasForceUpdate = false; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. + + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - if (updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; // Since this is the first update that was skipped, the current result - // is the new base state. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } else { - // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. - - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var callback = update.callback; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + do { + var updateExpirationTime = update.expirationTime; + + if (updateExpirationTime < renderExpirationTime) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + if (updateExpirationTime > newExpirationTime) { + newExpirationTime = updateExpirationTime; + } + } else { + // This update does have sufficient priority. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + + markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ); // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; - if (_updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is - // the new base state. + if (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // Since this update will remain in the list, update the remaining - // expiration time. - - if (newExpirationTime < _updateExpirationTime) { - newExpirationTime = _updateExpirationTime; - } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + update = baseQueue.next = pendingQueue.next; + pendingQueue.next = first; + queue.baseQueue = baseQueue = pendingQueue; + queue.shared.pending = null; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. - // This should be fine because the only two other things that contribute to - // expiration time are props and context. We're already in the middle of the - // begin phase by the time we start processing the queue, so we've already - // dealt with the props. Context in components that specify - // shouldComponentUpdate is tricky; but we'll have to account for - // that regardless. - - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - { currentlyProcessingQueue = null; } @@ -7684,36 +7534,20 @@ function commitUpdateQueue( instance, renderExpirationTime ) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } // Clear the list of captured updates. - - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; - } // Commit the effects - - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} - -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - effect = effect.nextEffect; + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } + } } } @@ -7758,8 +7592,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7774,8 +7608,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7832,9 +7666,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -7933,14 +7767,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(shouldUpdate !== undefined) - ? warningWithoutStack$1( - false, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ) - : void 0; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -7964,15 +7797,13 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7980,54 +7811,50 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noGetInitialStateOnES6 = - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state; - !noGetInitialStateOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noGetDefaultPropsOnES6 = - !instance.getDefaultProps || - instance.getDefaultProps.isReactClassApproved; - !noGetDefaultPropsOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noInstancePropTypes = !instance.propTypes; - !noInstancePropTypes - ? warningWithoutStack$1( - false, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ) - : void 0; - var noInstanceContextType = !instance.contextType; - !noInstanceContextType - ? warningWithoutStack$1( - false, - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name - ) - : void 0; + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "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 + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "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 + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } if (disableLegacyContext) { if (ctor.childContextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy childContextTypes API which is no longer supported. " + "Use React.createContext() instead.", name @@ -8035,23 +7862,20 @@ function checkClassInstance(workInProgress, ctor, newProps) { } if (ctor.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with static contextType instead.", name ); } } else { - var noInstanceContextTypes = !instance.contextTypes; - !noInstanceContextTypes - ? warningWithoutStack$1( - false, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ) - : void 0; + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ); + } if ( ctor.contextType && @@ -8059,8 +7883,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8068,26 +7892,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noComponentShouldUpdate = - typeof instance.componentShouldUpdate !== "function"; - !noComponentShouldUpdate - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; + if (typeof instance.componentShouldUpdate === "function") { + error( + "%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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8095,70 +7915,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - var noComponentDidUnmount = - typeof instance.componentDidUnmount !== "function"; - !noComponentDidUnmount - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ) - : void 0; - var noComponentDidReceiveProps = - typeof instance.componentDidReceiveProps !== "function"; - !noComponentDidReceiveProps - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; - var noComponentWillRecieveProps = - typeof instance.componentWillRecieveProps !== "function"; - !noComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ) - : void 0; - var noUnsafeComponentWillRecieveProps = - typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - !noUnsafeComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ) - : void 0; + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%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 + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + var hasMutatedProps = instance.props !== newProps; - !(instance.props === undefined || !hasMutatedProps) - ? warningWithoutStack$1( - false, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ) - : void 0; - var noInstanceDefaultProps = !instance.defaultProps; - !noInstanceDefaultProps - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ); + } + + if (instance.defaultProps) { + error( + "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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8166,63 +7977,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - var noInstanceGetDerivedStateFromProps = - typeof instance.getDerivedStateFromProps !== "function"; - !noInstanceGetDerivedStateFromProps - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noInstanceGetDerivedStateFromCatch = - typeof instance.getDerivedStateFromError !== "function"; - !noInstanceGetDerivedStateFromCatch - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noStaticGetSnapshotBeforeUpdate = - typeof ctor.getSnapshotBeforeUpdate !== "function"; - !noStaticGetSnapshotBeforeUpdate - ? warningWithoutStack$1( - false, - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ) - : void 0; - var _state = instance.state; + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } - if (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", name ); } - if (typeof instance.getChildContext === "function") { - !(typeof ctor.childContextTypes === "object") - ? warningWithoutStack$1( - false, - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ) - : void 0; + var _state = instance.state; + + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); } } } @@ -8281,8 +8082,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8326,8 +8126,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -8392,8 +8192,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -8435,8 +8235,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8473,8 +8272,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8501,6 +8300,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { @@ -8518,8 +8318,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -8543,19 +8343,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8578,18 +8367,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8648,18 +8432,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8749,6 +8523,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8792,18 +8567,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8965,8 +8730,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8992,8 +8757,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!didWarnAboutStringRefs[componentName]) { if (warnAboutStringRefs) { - warningWithoutStack$1( - false, + error( 'Component "%s" contains the string ref "%s". Support for string refs ' + "will be removed in a future major release. We recommend using " + "useRef() or createRef() instead. " + @@ -9004,8 +8768,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } else { - warningWithoutStack$1( - false, + error( 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -9118,23 +8881,25 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); + { + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; + } - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - warning$1( - false, - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + + error( + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + ); + } } // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching @@ -9272,33 +9037,51 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current$$1, element, expirationTime) { - if ( - current$$1 !== null && - (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current$$1, element)) - ) { - // Move based on index - var existing = useFiber(current$$1, element.props, expirationTime); - existing.ref = coerceRef(returnFiber, current$$1, element); - existing.return = returnFiber; + if (current$$1 !== null) { + if ( + current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } else if ( + enableChunksAPI && + current$$1.tag === Chunk && + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === current$$1.type.render + ) { + // Same as above but also update the .type field. + var _existing = useFiber(current$$1, element.props, expirationTime); + + _existing.return = returnFiber; + _existing.type = element.type; + + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; } + } // Insert - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; } function updatePortal(returnFiber, current$$1, portal, expirationTime) { @@ -9616,8 +9399,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9625,6 +9407,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; default: @@ -9830,28 +9613,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !didWarnAboutGenerators - ? warning$1( - false, - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ) - : void 0; + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !didWarnAboutMaps - ? warning$1( - false, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ) - : void 0; + if (!didWarnAboutMaps) { + error( + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ); + } + didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10059,33 +9842,79 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - if ( - child.tag === Fragment - ? element.type === REACT_FRAGMENT_TYPE - : child.elementType === element.type || // Keep this check inline so it only runs on the false path: + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.props.children, + expirationTime + ); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } + + break; + } + + case Chunk: + if (enableChunksAPI) { + if ( + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === child.type.render + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing2 = useFiber(child, element.props, expirationTime); + + _existing2.type = element.type; + _existing2.return = returnFiber; + + { + _existing2._debugSource = element._source; + _existing2._debugOwner = element._owner; + } + + return _existing2; + } + } + + // We intentionally fallthrough here if enableChunksAPI is not on. + // eslint-disable-next-lined no-fallthrough + + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber( - child, - element.type === REACT_FRAGMENT_TYPE - ? element.props.children - : element.props, - expirationTime - ); - existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + var _existing3 = useFiber(child, element.props, expirationTime); + + _existing3.ref = coerceRef(returnFiber, child, element); + _existing3.return = returnFiber; + + { + _existing3._debugSource = element._source; + _existing3._debugOwner = element._owner; + } + + return _existing3; + } + + break; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10580,7 +10409,7 @@ function mountEventResponder( } } - mountResponderInstance( + DEPRECATED_mountResponderInstance( responder, responderInstance, responderProps, @@ -10616,8 +10445,7 @@ function updateEventListener( if (visistedResponders.has(responder)) { // show warning { - warning$1( - false, + error( 'Duplicate event responder "%s" found in event listeners. ' + "Event listeners passed to elements cannot use the same event responder more than once.", responder.displayName @@ -10646,7 +10474,11 @@ function updateEventListener( } } -function updateEventListeners(listeners, fiber, rootContainerInstance) { +function updateDeprecatedEventListeners( + listeners, + fiber, + rootContainerInstance +) { var visistedResponders = new Set(); var dependencies = fiber.dependencies; @@ -10662,7 +10494,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { var respondersMap = dependencies.responders; if (respondersMap === null) { - respondersMap = new Map(); + dependencies.responders = respondersMap = new Map(); } if (isArray$2(listeners)) { @@ -10700,7 +10532,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { if (!visistedResponders.has(mountedResponder)) { var responderInstance = _respondersMap.get(mountedResponder); - unmountResponderInstance(responderInstance); + DEPRECATED_unmountResponderInstance(responderInstance); _respondersMap.delete(mountedResponder); } @@ -10708,7 +10540,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { } } } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10720,6 +10552,24 @@ function createResponderListener(responder, props) { return eventResponderListener; } +function unmountDeprecatedResponderListeners(fiber) { + var dependencies = fiber.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + DEPRECATED_unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } +} var NoEffect$1 = /* */ @@ -10764,13 +10614,7 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var nextCurrentHook = null; -var firstWorkInProgressHook = null; -var workInProgressHook = null; -var nextWorkInProgressHook = null; -var remainingExpirationTime = NoWork; -var componentUpdateQueue = null; -var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the // end of the current pass. We can't store these updates on the normal queue, // because if the work is aborted, they should be discarded. Because this is // a relatively rare case, we also don't want to add an additional field to @@ -10828,8 +10672,7 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10865,8 +10708,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -10900,8 +10742,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -10916,8 +10757,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -10945,12 +10785,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10958,24 +10797,25 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // The following should have already been reset // currentHook = null; // workInProgressHook = null; - // remainingExpirationTime = NoWork; - // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; - // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { + if (current !== null && current.memoizedState !== null) { ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, @@ -10989,7 +10829,7 @@ function renderWithHooks( } } - var children = Component(props, refOrContext); + var children = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do { @@ -11002,11 +10842,9 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. @@ -11014,7 +10852,7 @@ function renderWithHooks( } ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); + children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; @@ -11023,14 +10861,9 @@ function renderWithHooks( // at the beginning of the render phase and there's no re-entrancy. ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. @@ -11038,20 +10871,13 @@ function renderWithHooks( renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } - - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above + } // These were reset above // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; @@ -11082,10 +10908,7 @@ function resetHooks() { renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11093,9 +10916,6 @@ function resetHooks() { currentHookNameInDev = null; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -11105,14 +10925,14 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11127,12 +10947,33 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; - nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -11143,20 +10984,18 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11184,13 +11023,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11242,7 +11081,7 @@ function updateReducer(reducer, initialArg, init) { // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. - if (hook.baseUpdate === queue.last) { + if (hook.baseQueue === null) { hook.baseState = newState; } @@ -11252,35 +11091,37 @@ function updateReducer(reducer, initialArg, init) { } return [hook.memoizedState, _dispatch]; - } // The last update in the entire queue + } - var last = queue.last; // The last update that is part of the base state. + var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - var first; + var pendingQueue = queue.pending; - if (baseUpdate !== null) { - if (last !== null) { - // For the first update, the queue is a circular linked list where - // `queue.last.next = queue.first`. Once the first update commits, and - // the `baseUpdate` is no longer empty, we can unravel the list. - last.next = null; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var _newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; var _update = first; - var didSkip = false; do { var updateExpirationTime = _update.expirationTime; @@ -11289,24 +11130,46 @@ function updateReducer(reducer, initialArg, init) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; newBaseState = _newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig @@ -11322,13 +11185,13 @@ function updateReducer(reducer, initialArg, init) { } } - prevUpdate = _update; _update = _update.next; } while (_update !== null && _update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; + if (newBaseQueueLast === null) { newBaseState = _newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. @@ -11337,8 +11200,8 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = _newState; } @@ -11355,13 +11218,13 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11381,9 +11244,11 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -11423,7 +11288,7 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } @@ -11446,7 +11311,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } @@ -11504,14 +11369,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !refObject.hasOwnProperty("current") - ? warning$1( - false, - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ) - : void 0; + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } } var _inst2 = create(); @@ -11525,14 +11389,13 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11547,14 +11410,13 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11637,17 +11499,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -11661,47 +11520,54 @@ function updateDeferredValue(value, config) { updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); return prevValue; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority( + priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, + function() { + setPending(true); + } + ); + runWithPriority( + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + } + ); +} + function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var startTransition = mountCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { @@ -11709,25 +11575,11 @@ function updateTransition(config) { isPending = _updateState2[0], setPending = _updateState2[1]; - var startTransition = updateCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { @@ -11738,14 +11590,13 @@ function dispatchAction(fiber, queue, action) { } { - !(typeof arguments[3] !== "function") - ? warning$1( - false, - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ) - : void 0; + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } } var alternate = fiber.alternate; @@ -11810,23 +11661,17 @@ function dispatchAction(fiber, queue, action) { _update2.priority = getCurrentPriorityLevel(); } // Append the update to the end of the list. - var last = queue.last; + var pending = queue.pending; - if (last === null) { + if (pending === null) { // This is the first update. Create a circular list. _update2.next = _update2; } else { - var first = last.next; - - if (first !== null) { - // Still circular. - _update2.next = first; - } - - last.next = _update2; + _update2.next = pending.next; + pending.next = _update2; } - queue.last = _update2; + queue.pending = _update2; if ( fiber.expirationTime === NoWork && @@ -11862,7 +11707,7 @@ function dispatchAction(fiber, queue, action) { // time the reducer has changed. return; } - } catch (error) { + } catch (error$$1) { // Suppress the error. It will throw again in the render phase. } finally { { @@ -11908,8 +11753,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; { var warnInvalidContextAccess = function() { - warning$1( - false, + error( "Context can only be read while React is rendering. " + "In classes, you can read it in the render method or getDerivedStateFromProps. " + "In function components, you can read it directly in the function body, but not " + @@ -11918,8 +11762,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -12010,7 +11853,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12101,7 +11944,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12192,7 +12035,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12295,7 +12138,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12400,7 +12243,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12480,12 +12323,11 @@ var isHydrating = false; function warnIfHydrating() { { - !!isHydrating - ? warning$1( - false, - "We should not be hydrating here. This is a bug in React. Please file a bug." - ) - : void 0; + if (isHydrating) { + error( + "We should not be hydrating here. This is a bug in React. Please file a bug." + ); + } } } @@ -13012,8 +12854,8 @@ function forceUnmountCurrentAndReconcile( renderExpirationTime ); // In the second pass, we mount the new children. The trick here is that we // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13273,7 +13115,7 @@ function updateSimpleMemoComponent( if ( shallowEqual(prevProps, nextProps) && - current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current$$1.type ) { didReceiveUpdate = false; @@ -13433,6 +13275,73 @@ function updateFunctionComponent( return workInProgress.child; } +function updateChunk( + current$$1, + workInProgress, + chunk, + nextProps, + renderExpirationTime +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + var render = chunk.render; + var data = chunk.query(); // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + function updateClassComponent( current$$1, workInProgress, @@ -13475,9 +13384,9 @@ function updateClassComponent( if (instance === null) { if (current$$1 !== null) { - // An class component without an instance only mounts if it suspended - // inside a non- concurrent tree, in an inconsistent state. We want to - // tree it like a new mount, even though an empty version of it already + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect @@ -13529,14 +13438,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (inst.props !== nextProps) { - !didWarnAboutReassigningProps - ? warning$1( - false, - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" - ) - : void 0; + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); + } + didWarnAboutReassigningProps = true; } } @@ -13578,7 +13487,7 @@ function finishClassComponent( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. @@ -13657,7 +13566,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + if (!(current$$1 !== null && updateQueue !== null)) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); @@ -13666,13 +13575,8 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current$$1, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". @@ -13746,7 +13650,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { if (isDirectTextChild) { // We special case a direct text child of a host node. This is a common // case. We won't handle it as a reified child. We will instead handle - // this in the host environment that also have access to this prop. That + // this in the host environment that also has access to this prop. That // avoids allocating another HostText fiber and traversing it. nextChildren = null; } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { @@ -13796,7 +13700,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. // Disconnect the alternate pointers. @@ -13834,7 +13738,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -13851,7 +13755,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -13868,7 +13772,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -13896,36 +13800,48 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } - default: { - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + case Chunk: { + if (enableChunksAPI) { + // TODO: Resolve for Hot Reloading. + child = updateChunk( + null, + workInProgress, + Component, + props, + renderExpirationTime ); + return child; } + + break; } } - return child; + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } function mountIncompleteClassComponent( @@ -14019,13 +13935,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "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 ); + didWarnAboutBadClass[componentName] = true; } } @@ -14057,8 +13973,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to be a function component that returns a class instance. " + "Change %s to a class that extends React.Component instead. " + "If you can't use a class try assigning the prototype on the function as a workaround. " + @@ -14068,6 +13983,7 @@ function mountIndeterminateComponent( _componentName, _componentName ); + didWarnAboutModulePatternComponent[_componentName] = true; } } // Proceed under the assumption that this is a class instance @@ -14089,6 +14005,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14116,8 +14033,7 @@ function mountIndeterminateComponent( { if (disableLegacyContext && Component.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with React.useContext() instead.", getComponentName(Component) || "Unknown" @@ -14153,86 +14069,87 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; - warning$1( - false, - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - } - if ( - warnAboutDefaultPropsOnFunctionComponents && - Component.defaultProps !== undefined - ) { - var componentName = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { - warningWithoutStack$1( - false, - "%s: Support for defaultProps will be removed from function components " + - "in a future major release. Use JavaScript default parameters instead.", - componentName - ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } } - } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - warningWithoutStack$1( - false, - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14304,8 +14221,8 @@ function updateSuspenseComponent( if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { didWarnAboutMaxDuration = true; - warning$1( - false, + + error( "maxDuration has been removed from React. " + "Remove the maxDuration prop." ); @@ -14677,7 +14594,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -14723,8 +14640,7 @@ function mountDehydratedSuspenseComponent( // Instead, we'll leave the content in place and try to hydrate it later. if ((workInProgress.mode & BlockingMode) === NoMode) { { - warning$1( - false, + error( "Cannot hydrate Suspense in legacy mode. Switch from " + "ReactDOM.hydrate(element, container) to " + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + @@ -14984,40 +14900,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15032,16 +14947,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15059,8 +14974,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15070,6 +14985,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15110,8 +15026,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + error( 'A single row was passed to a . ' + "This is not useful since it needs multiple rows. " + "Did you mean to pass multiple children or an array?", @@ -15137,6 +15052,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15147,6 +15063,7 @@ function initSuspenseListRenderState( // We can reuse the existing object from previous renders. renderState.isBackwards = isBackwards; renderState.rendering = null; + renderState.renderingStartTime = 0; renderState.last = lastContentRow; renderState.tail = tail; renderState.tailExpiration = 0; @@ -15419,8 +15336,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15435,15 +15352,14 @@ function updateContextConsumer( var render = newProps.children; { - !(typeof render === "function") - ? warningWithoutStack$1( - false, - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ) - : void 0; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -16051,6 +15967,22 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; } + + case Chunk: { + if (enableChunksAPI) { + var chunk = workInProgress.type; + var props = workInProgress.pendingProps; + return updateChunk( + current$$1, + workInProgress, + chunk, + props, + renderExpirationTime + ); + } + + break; + } } { @@ -16735,6 +16667,8 @@ if (supportsMutation) { // This lets the parents know that at least one of their children has changed. markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; } }; } else { @@ -16833,14 +16767,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -16849,7 +16785,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -16875,7 +16811,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -16892,9 +16828,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = current.memoizedProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { markUpdate(workInProgress); @@ -16912,12 +16848,12 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return null; } var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on we want to add then top->down or + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. var _wasHydrated = popHydrationState(workInProgress); @@ -16932,16 +16868,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { currentHostContext ) ) { - // If changes to the hydrated node needs to be applied at the + // If changes to the hydrated node need to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } - if (enableFlareAPI) { - var listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var listeners = newProps.DEPRECATED_flareListeners; if (listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( listeners, workInProgress, rootContainerInstance @@ -16960,11 +16896,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = instance; - if (enableFlareAPI) { - var _listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners = newProps.DEPRECATED_flareListeners; if (_listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( _listeners, workInProgress, rootContainerInstance @@ -16993,7 +16929,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17033,12 +16969,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - case ForwardRef: - break; - case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; @@ -17064,15 +16997,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { // We should never have been in a hydration state if we didn't have a current. // However, in some of those paths, we might have reentered a hydration state - // and then we might be inside a hydration state. In that case, we'll need to - // exit out of it. + // and then we might be inside a hydration state. In that case, we'll need to exit out of it. resetHydrationState(); if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated and unsuspended. workInProgress.memoizedState = null; } // If nothing suspended, we need to schedule an effect to mark this boundary - // as having hydrated so events know that they're free be invoked. + // as having hydrated so events know that they're free to be invoked. // It's also a signal to replay events and the suspense callback. // If something suspended, schedule an effect to attach retry listeners. // So we might as well always mark this. @@ -17165,7 +17097,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if not prevDidTimeout. if (nextDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. workInProgress.effectTag |= Update; } @@ -17175,9 +17107,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if these values are non equal, i.e. it changed. if (nextDidTimeout || prevDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } @@ -17192,33 +17124,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17229,7 +17146,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17237,9 +17154,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var renderState = workInProgress.memoizedState; if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17355,7 +17272,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // The time it took to render last row is greater than time until + // the expiration. + now() * 2 - renderState.renderingStartTime > + renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -17405,13 +17325,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this + // is a per component value. It should really be since the start + // of the total render or last commit. Consider using something like + // globalMostRecentFallbackTime. That doesn't account for being + // suspended for part of the time or when it's a new render. + // It should probably use a global start time value instead. } // Pop a row. var next = renderState.tail; renderState.rendering = next; renderState.tail = next.sibling; renderState.lastEffect = workInProgress.lastEffect; + renderState.renderingStartTime = now(); next.sibling = null; // Restore the context. // TODO: We can probably just avoid popping it instead and only // setting it the first time we go from not suspended to suspended. @@ -17432,7 +17358,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; + return null; } case FundamentalComponent: { @@ -17487,6 +17413,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } + + return null; } break; @@ -17503,13 +17431,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = scopeInstance; scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners2 = newProps.DEPRECATED_flareListeners; if (_listeners2 != null) { var _rootContainerInstance2 = getRootHostContainer(); - updateEventListeners( + updateDeprecatedEventListeners( _listeners2, workInProgress, _rootContainerInstance2 @@ -17522,9 +17450,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - if (enableFlareAPI) { - var _prevListeners = current.memoizedProps.listeners; - var _nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _prevListeners = + current.memoizedProps.DEPRECATED_flareListeners; + var _nextListeners = newProps.DEPRECATED_flareListeners; if ( _prevListeners !== _nextListeners || @@ -17542,21 +17471,28 @@ function completeWork(current, workInProgress, renderExpirationTime) { markRef$1(workInProgress); } } + + return null; } break; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + case Chunk: + if (enableChunksAPI) { + return null; + } + + break; } - return null; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } function unwindWork(workInProgress, renderExpirationTime) { @@ -17749,7 +17685,8 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console.error(error); // For a more detailed description of this block, see: + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -17786,7 +17723,7 @@ function logCapturedError(capturedError) { // has already printed it. Even if the application swallows the error, it is still // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - console.error(combinedMessage); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -17884,8 +17821,8 @@ function safelyCallDestroy(current$$1, destroy) { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(current$$1, error$$1); } } } @@ -17894,7 +17831,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } @@ -17914,28 +17852,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -17951,8 +17888,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -17975,14 +17912,12 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18038,8 +17973,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { addendum = " You returned: " + _destroy; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18059,7 +17993,8 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; @@ -18080,9 +18015,10 @@ function commitLifeCycles( switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + return; } case ClassComponent: { @@ -18099,28 +18035,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18144,28 +18079,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18186,28 +18120,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -18318,14 +18251,12 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18412,8 +18343,7 @@ function commitAttachRef(finishedWork) { } else { { if (!ref.hasOwnProperty("current")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18448,7 +18378,8 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { @@ -18488,7 +18419,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } } - break; + return; } case ClassComponent: { @@ -18503,27 +18434,9 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ - ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); - } - - dependencies.responders = null; - } - } + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + beforeRemoveInstance(current$$1.stateNode); } safelyDetachRef(current$$1); @@ -18573,9 +18486,15 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case ScopeComponent: { + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + } + if (enableScopeAPI) { safelyDetachRef(current$$1); } + + return; } } } @@ -18636,6 +18555,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; if (alternate !== null) { detachFiber(alternate); @@ -18674,14 +18594,12 @@ function commitContainer(finishedWork) { replaceContainerChildren(containerInfo, pendingChildren); return; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19015,7 +18933,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19060,7 +18979,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19098,12 +19018,12 @@ function commitWork(current$$1, finishedWork) { ); } - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = oldProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + updateDeprecatedEventListeners(nextListeners, finishedWork, null); } } } @@ -19165,9 +19085,10 @@ function commitWork(current$$1, finishedWork) { if (enableFundamentalAPI) { var fundamentalInstance = finishedWork.stateNode; updateFundamentalComponent(fundamentalInstance); + return; } - return; + break; } case ScopeComponent: { @@ -19175,31 +19096,31 @@ function commitWork(current$$1, finishedWork) { var scopeInstance = finishedWork.stateNode; scopeInstance.fiber = finishedWork; - if (enableFlareAPI) { + if (enableDeprecatedFlareAPI) { var _newProps = finishedWork.memoizedProps; var _oldProps = current$$1 !== null ? current$$1.memoizedProps : _newProps; - var _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + var _prevListeners = _oldProps.DEPRECATED_flareListeners; + var _nextListeners = _newProps.DEPRECATED_flareListeners; - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); + if (_prevListeners !== _nextListeners || current$$1 === null) { + updateDeprecatedEventListeners(_nextListeners, finishedWork, null); } } + + return; } - return; + break; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19231,7 +19152,7 @@ function commitSuspenseComponent(finishedWork) { } } else { if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + error("Unexpected type for suspenseCallback."); } } } @@ -19324,10 +19245,10 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { update.payload = { element: null }; - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.callback = function() { - onUncaughtError(error); + onUncaughtError(error$$1); logError(fiber, errorInfo); }; @@ -19340,11 +19261,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$$1); }; } @@ -19367,9 +19288,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$$1, { componentStack: stack !== null ? stack : "" }); @@ -19378,14 +19299,13 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(fiber.expirationTime === Sync) - ? warningWithoutStack$1( - false, - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ) - : void 0; + if (fiber.expirationTime !== Sync) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } } } }; @@ -19450,6 +19370,20 @@ function throwException( ) { // This is a thenable. var thenable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.expirationTime = currentSource.expirationTime; + } else { + sourceFiber.memoizedState = null; + } + } + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, @@ -19975,9 +19909,21 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; + var nextLevel = + lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; + + if ( + enableTrainModelFix && + nextLevel <= Idle && + firstPendingTime !== nextLevel + ) { + // Don't work on Idle/Never priority unless everything else is committed. + return NoWork; + } + + return nextLevel; } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the // expiration time of the existing task is the same as the expiration time of @@ -20425,80 +20371,70 @@ function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; - if (root.finishedExpirationTime === expirationTime) { - // There's already a pending commit at this expiration time. - // TODO: This is poorly factored. This case only exists for the - // batch.commit() API. - commitRoot(root); - } else { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } // If we have a work-in-progress fiber, it means there's still work to do - // in this root. + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); } + } while (true); - if (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } else { - // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. - stopFinishedWorkLoopTimer(); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - finishSyncRender(root, workInProgressRootExitStatus, expirationTime); - } // Before exiting, make sure there's a callback scheduled for the next - // pending level. + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); ensureRootIsScheduled(root); + throw fatalError; } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } return null; @@ -20526,12 +20462,13 @@ function flushDiscreteUpdates() { (executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext ) { - if (true && (executionContext & RenderContext) !== NoContext) { - warning$1( - false, - "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + - "already rendering." - ); + { + if ((executionContext & RenderContext) !== NoContext) { + error( + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } } // We're already rendering, so we can't synchronously flush pending work. // This is probably a nested event dispatch triggered by a lifecycle/effect, // like `el.focus()`. Exit. @@ -21117,7 +21054,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21211,8 +21157,8 @@ function commitRootImpl(root, renderPriorityLevel) { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(nextEffect, error$$1); nextEffect = nextEffect.nextEffect; } } @@ -21584,8 +21530,8 @@ function flushPassiveEffectsImpl() { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(effect, error$$1); } resetCurrentFiber(); @@ -21625,17 +21571,17 @@ function markLegacyErrorBoundaryAsFailed(instance) { } } -function prepareToThrowUncaughtError(error) { +function prepareToThrowUncaughtError(error$$1) { if (!hasUncaughtError) { hasUncaughtError = true; - firstUncaughtError = error; + firstUncaughtError = error$$1; } } var onUncaughtError = prepareToThrowUncaughtError; -function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - var errorInfo = createCapturedValue(error, sourceFiber); +function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error$$1) { + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createRootErrorUpdate(rootFiber, errorInfo, Sync); enqueueUpdate(rootFiber, update); var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync); @@ -21646,11 +21592,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, error$$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$$1); return; } @@ -21658,7 +21604,7 @@ function captureCommitPhaseError(sourceFiber, error) { while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -21669,7 +21615,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createClassErrorUpdate( fiber, errorInfo, // TODO: This is always sync @@ -21743,7 +21689,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { root.lastPingedTime = suspendedTime; - if (root.finishedExpirationTime === suspendedTime) { + if (!enableTrainModelFix && root.finishedExpirationTime === suspendedTime) { // If there's a pending fallback waiting to commit, throw it away. root.finishedExpirationTime = NoWork; root.finishedWork = null; @@ -21897,8 +21843,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -21953,7 +21899,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Chunk ) { // Only warn for user-defined components, not internal ones like Suspense. return; @@ -21972,8 +21919,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -22064,10 +22010,10 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "setState(...): Cannot call setState() inside getChildContext()" ); + didWarnAboutUpdateInGetChildContext = true; break; @@ -22076,12 +22022,12 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "Cannot update during an existing state transition (such as " + "within `render`). Render methods should be a pure function of " + "props and state." ); + didWarnAboutUpdateInRender = true; break; } @@ -22099,8 +22045,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "It looks like you're using the wrong act() around your test interactions.\n" + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + "// for react-dom:\n" + @@ -22126,8 +22071,7 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22154,8 +22098,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22189,8 +22132,8 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22199,8 +22142,8 @@ function warnIfUnmockedScheduler(fiber) { ); } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'Starting from React v17, the "scheduler" module will need to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22237,7 +22180,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { - var update = updateQueue.firstUpdate; + var update = updateQueue.baseQueue; while (update !== null) { var priorityLevel = update.priority; @@ -22268,11 +22211,11 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { case FunctionComponent: case ForwardRef: case SimpleMemoComponent: - if ( - workInProgressNode.memoizedState !== null && - workInProgressNode.memoizedState.baseUpdate !== null - ) { - var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + case Chunk: { + var firstHook = current$$1.memoizedState; // TODO: This just checks the first Hook. Isn't it suppose to check all Hooks? + + if (firstHook !== null && firstHook.baseQueue !== null) { + var _update = firstHook.baseQueue; // Loop through the functional component's memoized state to see whether // the component has triggered any high pri updates while (_update !== null) { @@ -22295,9 +22238,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { break; } - if ( - _update.next === workInProgressNode.memoizedState.baseUpdate - ) { + if (_update.next === firstHook.baseQueue) { break; } @@ -22306,6 +22247,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { } break; + } default: break; @@ -22328,8 +22270,7 @@ function flushSuspensePriorityWarningInDEV() { componentsThatTriggeredHighPriSuspend = null; if (componentNames.length > 0) { - warningWithoutStack$1( - false, + error( "%s triggered a user-blocking update that suspended." + "\n\n" + "The fix is to split the update into multiple parts: a user-blocking " + @@ -22442,10 +22383,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { try { subscriber.onWorkStarted(interactions, threadID); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22467,10 +22408,10 @@ function finishPendingInteractions(root, committedExpirationTime) { var threadID = computeThreadID(root, committedExpirationTime); subscriber.onWorkStopped(root.memoizedInteractions, threadID); } - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } finally { // Clear completed interactions from the pending Map. @@ -22492,10 +22433,10 @@ function finishPendingInteractions(root, committedExpirationTime) { if (subscriber !== null && interaction.__count === 0) { try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22505,6 +22446,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22526,8 +22468,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "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" @@ -22540,6 +22481,23 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + { + // Only used by Fast Refresh + if (typeof hook.onScheduleFiberRoot === "function") { + onScheduleFiberRoot = function(root, children) { + try { + hook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + }; + } + } + onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -22555,13 +22513,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22570,29 +22527,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation encountered an error: %s.", err); } } // DevTools exists return true; } +function onScheduleRoot(root, children) { + if (typeof onScheduleFiberRoot === "function") { + onScheduleFiberRoot(root, children); + } +} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -22740,6 +22697,12 @@ function resolveLazyComponentTag(Component) { if ($$typeof === REACT_MEMO_TYPE) { return MemoComponent; } + + if (enableChunksAPI) { + if ($$typeof === REACT_CHUNK_TYPE) { + return Chunk; + } + } } return IndeterminateComponent; @@ -23020,6 +22983,10 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; + case REACT_CHUNK_TYPE: + fiberTag = Chunk; + break getTag; + case REACT_FUNDAMENTAL_TYPE: if (enableFundamentalAPI) { return createFiberFromFundamental( @@ -23145,8 +23112,7 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { typeof pendingProps.id !== "string" || typeof pendingProps.onRender !== "function" ) { - warningWithoutStack$1( - false, + error( 'Profiler must specify an "id" string and "onRender" function as props' ); } @@ -23308,6 +23274,7 @@ function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -23401,15 +23368,6 @@ function markRootExpiredAtTime(root, expirationTime) { } } -// This lets us hook into Fiber to debug what it's doing. -// See https://github.com/facebook/react/pull/8033. -// This is not part of the public API, not even for React DevTools. -// You may only inject a debugTool if you work on React Fiber itself. -var ReactFiberInstrumentation = { - debugTool: null -}; -var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; - var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -23496,8 +23454,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23509,8 +23466,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23535,6 +23491,10 @@ function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); @@ -23552,19 +23512,6 @@ function updateContainer(element, container, parentComponent, callback) { current$$1, suspenseConfig ); - - { - if (ReactFiberInstrumentation_1.debugTool) { - if (current$$1.alternate === null) { - ReactFiberInstrumentation_1.debugTool.onMountContainer(container); - } else if (element === null) { - ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); - } else { - ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); - } - } - } - var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -23576,8 +23523,8 @@ function updateContainer(element, container, parentComponent, callback) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23596,14 +23543,16 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ) - : void 0; + ); + } + } + update.callback = callback; } @@ -23761,7 +23710,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.11.0"; +var ReactVersion = "16.12.0-experimental-19f6fe170"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -23805,7 +23754,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23851,7 +23800,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23895,7 +23844,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23903,12 +23852,14 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -23921,10 +23872,12 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -23956,7 +23909,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23964,10 +23917,10 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; } @@ -24133,7 +24086,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24177,7 +24130,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24218,7 +24171,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24226,12 +24179,14 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24244,10 +24199,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24279,7 +24236,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24287,10 +24244,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error( + "Warning: setNativeProps is not currently supported in Fabric" + ); + } + return; } @@ -24435,17 +24394,17 @@ function findHostInstance_DEPRECATED(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24488,17 +24447,17 @@ function findNodeHandle(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24567,21 +24526,29 @@ var ReactNativeRenderer = { findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { if (handle._nativeTag == null) { - !(handle._nativeTag != null) - ? warningWithoutStack$1( - false, - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ) - : void 0; + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + return; } - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index 4aa16ac835491d..991466c68dda2a 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -16,13 +16,110 @@ if (__DEV__) { (function() { "use strict"; +var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); -var React = require("react"); var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// by calls to these methods by a Babel plugin. +// +// In PROD (or in packages without access to React internals), +// they are left as they are instead. + +function warn(format) { + { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + printWarning("warn", format, args); + } +} +function error(format) { + { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 1] = arguments[_key2]; + } + + printWarning("error", format, args); + } +} + +function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. + { + var hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === "string" && + args[args.length - 1].indexOf("\n in") === 0; + + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); + } + } + + var argsWithFormat = args.map(function(item) { + return "" + item; + }); // Careful: RN currently depends on this prefix + + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + + Function.prototype.apply.call(console[level], console, argsWithFormat); + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + } +} + /** * Use invariant() to assert state which your program assumes to be true. * @@ -560,71 +657,6 @@ function clearCaughtError() { } } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var warningWithoutStack = function() {}; - -{ - warningWithoutStack = function(condition, format) { - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - if (format === undefined) { - throw new Error( - "`warningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (args.length > 8) { - // Check before the condition to catch violations early. - throw new Error( - "warningWithoutStack() currently supports at most 8 arguments." - ); - } - - if (condition) { - return; - } - - if (typeof console !== "undefined") { - var argsWithFormat = args.map(function(item) { - return "" + item; - }); - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - - Function.prototype.apply.call(console.error, console, argsWithFormat); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} - }; -} - -var warningWithoutStack$1 = warningWithoutStack; - var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -638,13 +670,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -665,9 +696,10 @@ var validateEventDispatches; : dispatchInstances ? 1 : 0; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -1094,6 +1126,7 @@ var DehydratedFragment = 18; var SuspenseListComponent = 19; var FundamentalComponent = 20; var ScopeComponent = 21; +var Chunk = 22; function getParent(inst) { do { @@ -1231,9 +1264,9 @@ function listenerAtPhase(inst, event, propagationPhase) { function accumulateDirectionalDispatches(inst, phase, event) { { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; + if (!inst) { + error("Dispatching inst must not be null"); + } } var listener = listenerAtPhase(inst, event, phase); @@ -1578,7 +1611,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function set(val) { var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); + warn$$1(action, "This is effectively a no-op"); return val; } @@ -1587,24 +1620,22 @@ function getPooledWarningPropertyDefinition(propName, getVal) { var result = isFunction ? "This is a no-op function" : "This is set to null"; - warn(action, result); + warn$$1(action, result); return getVal; } - function warn(action, result) { - var warningCondition = false; - !warningCondition - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + function warn$$1(action, result) { + { + error( + "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 + ); + } } } @@ -1749,15 +1780,14 @@ function getTouchIdentifier(_ref) { } { - !(identifier <= MAX_TOUCH_BANK) - ? warningWithoutStack$1( - false, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ) - : void 0; + if (identifier > MAX_TOUCH_BANK) { + error( + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ); + } } return identifier; @@ -1789,12 +1819,15 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1811,12 +1844,15 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.warn( - "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1867,9 +1903,10 @@ var ResponderTouchHistoryStore = { { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } } } } @@ -2398,9 +2435,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2575,7 +2615,9 @@ var enableProfilerTimer = true; var enableSchedulerTracing = true; var enableSuspenseServerRenderer = false; -var enableFlareAPI = false; +var enableChunksAPI = false; + +var enableDeprecatedFlareAPI = false; var enableFundamentalAPI = false; var enableScopeAPI = false; @@ -2586,6 +2628,7 @@ var warnAboutDefaultPropsOnFunctionComponents = false; var warnAboutStringRefs = false; var disableLegacyContext = false; var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +var enableTrainModelFix = false; var enableNativeTargetAsInstance = false; // Only used in www builds. @@ -2664,8 +2707,13 @@ function restoreStateOfTarget(target) { ); } - var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - restoreImpl(internalInstance.stateNode, internalInstance.type, props); + var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. + + if (stateNode) { + var _props = getFiberCurrentPropsFromNode(stateNode); + + restoreImpl(internalInstance.stateNode, internalInstance.type, _props); + } } function needsStateRestore() { @@ -2898,10 +2946,7 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - warningWithoutStack$1( - false, - "A view is reporting that a touch occurred on tag zero." - ); + error("A view is reporting that a touch occurred on tag zero."); } } else { rootNodeID = target; @@ -2968,23 +3013,6 @@ function set(key, value) { key._reactInternalFiber = value; } -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} - -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} - // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -3011,6 +3039,7 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; +var REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 0xead9; var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 0xead5; @@ -3034,43 +3063,6 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; - -{ - warning = function(condition, format) { - if (condition) { - return; - } - - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args - - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } - - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} - -var warning$1 = warning; - var Uninitialized = -1; var Pending = 0; var Resolved = 1; @@ -3091,8 +3083,7 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + "Instead received: %s\n\nYour code should look like: \n " + "const MyComponent = lazy(() => import('./MyComponent'))", @@ -3105,10 +3096,10 @@ function initializeLazyComponentType(lazyComponent) { lazyComponent._result = defaultExport; } }, - function(error) { + function(error$$1) { if (lazyComponent._status === Pending) { lazyComponent._status = Rejected; - lazyComponent._result = error; + lazyComponent._result = error$$1; } } ); @@ -3131,8 +3122,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -3181,6 +3171,9 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); + case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3304,17 +3297,18 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !instance._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%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.type) || "A component" - ) - : void 0; + + if (!instance._warnedAboutRefsInRender) { + error( + "%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.type) || "A component" + ); + } + instance._warnedAboutRefsInRender = true; } } @@ -4039,17 +4033,19 @@ function throwOnStylesProp(component, props) { } } function warnForStyleProps(props, validAttributes) { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - console.error( - "You are setting the style `{ " + - key + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { " + - key + - ": ... } }`" - ); + { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + error( + "You are setting the style `{ %s" + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { %s" + + ": ... } }`", + key, + key + ); + } } } } @@ -4114,10 +4110,12 @@ var ReactNativeFiberHostComponent = } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -4565,7 +4563,7 @@ function unhideInstance(instance, props) { function unhideTextInstance(textInstance, text) { throw new Error("Not yet implemented."); } -function mountResponderInstance( +function DEPRECATED_mountResponderInstance( responder, responderInstance, props, @@ -4574,7 +4572,7 @@ function mountResponderInstance( ) { throw new Error("Not yet implemented."); } -function unmountResponderInstance(responderInstance) { +function DEPRECATED_unmountResponderInstance(responderInstance) { throw new Error("Not yet implemented."); } function getFundamentalComponentInstance(fundamentalInstance) { @@ -4595,6 +4593,9 @@ function unmountFundamentalComponent(fundamentalInstance) { function getInstanceFromNode$1(node) { throw new Error("Not yet implemented."); } +function beforeRemoveInstance(instance) { + // noop +} var BEFORE_SLASH_RE = /^(.*)[\\\/]/; var describeComponentFrame = function(name, source, ownerName) { @@ -5178,7 +5179,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5186,7 +5187,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5373,8 +5374,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%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.", @@ -5893,78 +5894,6 @@ function shallowEqual(objA, objB) { return true; } -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ -var lowPriorityWarningWithoutStack = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - - if (typeof console !== "undefined") { - console.warn(message); - } - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - - if (!condition) { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(void 0, [format].concat(args)); - } - }; -} - -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; - var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, flushPendingUnsafeLifecycleWarnings: function() {}, @@ -6135,8 +6064,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6150,8 +6079,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6169,8 +6097,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -6183,8 +6110,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -6202,8 +6128,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6222,8 +6147,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -6248,11 +6172,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6285,8 +6209,8 @@ var ReactStrictModeWarnings = { }); var sortedNames = setToSortedString(uniqueNames); var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6819,17 +6743,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue = nextValue; { - !( - context._currentRenderer === undefined || - context._currentRenderer === null || - context._currentRenderer === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer = rendererSigil; } } else { @@ -6837,17 +6761,17 @@ function pushProvider(providerFiber, nextValue) { context._currentValue2 = nextValue; { - !( - context._currentRenderer2 === undefined || - context._currentRenderer2 === null || - context._currentRenderer2 === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -6874,14 +6798,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) - ? warning$1( - false, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ) - : void 0; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7077,15 +7000,14 @@ function readContext(context, observedBits) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. - !!isDisallowedContextReadInDEV - ? warning$1( - false, - "Context can only be read while React is rendering. " + - "In classes, you can read it in the render method or getDerivedStateFromProps. " + - "In function components, you can read it directly in the function body, but not " + - "inside Hooks like useReducer() or useMemo()." - ) - : void 0; + if (isDisallowedContextReadInDEV) { + error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } } if (lastContextWithAllBitsObserved === context) { @@ -7226,38 +7148,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { +function initializeUpdateQueue(fiber) { var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { - var queue = { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + fiber.updateQueue = queue; +} +function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + baseQueue: currentQueue.baseQueue, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7265,9 +7181,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7275,136 +7191,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -function appendUpdateToQueue(queue, update) { - // Append the update to the end of the list. - if (queue.lastUpdate === null) { - // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; - } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -function enqueueUpdate(fiber, update) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1; - var queue2; + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } + update.next = pending.next; + pending.next = update; } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update); - appendUpdateToQueue(queue2, update); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - - queue2.lastUpdate = update; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "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." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } // Append the update to the end of the list. + if (current !== null) { + // Ensure the work-in-progress queue is a clone + cloneUpdateQueue(current, workInProgress); + } // Captured updates go only on the work-in-progress queue. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7496,163 +7338,171 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, - queue, props, instance, renderExpirationTime ) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; hasForceUpdate = false; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. + + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - if (updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; // Since this is the first update that was skipped, the current result - // is the new base state. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } else { - // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. - - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var callback = update.callback; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + do { + var updateExpirationTime = update.expirationTime; + + if (updateExpirationTime < renderExpirationTime) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + if (updateExpirationTime > newExpirationTime) { + newExpirationTime = updateExpirationTime; + } + } else { + // This update does have sufficient priority. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + + markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ); // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; - if (_updateExpirationTime < renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is - // the new base state. + if (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // Since this update will remain in the list, update the remaining - // expiration time. - - if (newExpirationTime < _updateExpirationTime) { - newExpirationTime = _updateExpirationTime; - } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + update = baseQueue.next = pendingQueue.next; + pendingQueue.next = first; + queue.baseQueue = baseQueue = pendingQueue; + queue.shared.pending = null; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. - // This should be fine because the only two other things that contribute to - // expiration time are props and context. We're already in the middle of the - // begin phase by the time we start processing the queue, so we've already - // dealt with the props. Context in components that specify - // shouldComponentUpdate is tricky; but we'll have to account for - // that regardless. - - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - { currentlyProcessingQueue = null; } @@ -7681,36 +7531,20 @@ function commitUpdateQueue( instance, renderExpirationTime ) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } // Clear the list of captured updates. - - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; - } // Commit the effects - - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} - -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - effect = effect.nextEffect; + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } + } } } @@ -7755,8 +7589,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7771,8 +7605,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7829,9 +7663,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -7930,14 +7764,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(shouldUpdate !== undefined) - ? warningWithoutStack$1( - false, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ) - : void 0; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -7961,15 +7794,13 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7977,54 +7808,50 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noGetInitialStateOnES6 = - !instance.getInitialState || - instance.getInitialState.isReactClassApproved || - instance.state; - !noGetInitialStateOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noGetDefaultPropsOnES6 = - !instance.getDefaultProps || - instance.getDefaultProps.isReactClassApproved; - !noGetDefaultPropsOnES6 - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; - var noInstancePropTypes = !instance.propTypes; - !noInstancePropTypes - ? warningWithoutStack$1( - false, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ) - : void 0; - var noInstanceContextType = !instance.contextType; - !noInstanceContextType - ? warningWithoutStack$1( - false, - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name - ) - : void 0; + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "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 + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "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 + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } if (disableLegacyContext) { if (ctor.childContextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy childContextTypes API which is no longer supported. " + "Use React.createContext() instead.", name @@ -8032,23 +7859,20 @@ function checkClassInstance(workInProgress, ctor, newProps) { } if (ctor.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with static contextType instead.", name ); } } else { - var noInstanceContextTypes = !instance.contextTypes; - !noInstanceContextTypes - ? warningWithoutStack$1( - false, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ) - : void 0; + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ); + } if ( ctor.contextType && @@ -8056,8 +7880,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8065,26 +7889,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - var noComponentShouldUpdate = - typeof instance.componentShouldUpdate !== "function"; - !noComponentShouldUpdate - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; + if (typeof instance.componentShouldUpdate === "function") { + error( + "%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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8092,70 +7912,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - var noComponentDidUnmount = - typeof instance.componentDidUnmount !== "function"; - !noComponentDidUnmount - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ) - : void 0; - var noComponentDidReceiveProps = - typeof instance.componentDidReceiveProps !== "function"; - !noComponentDidReceiveProps - ? warningWithoutStack$1( - false, - "%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 - ) - : void 0; - var noComponentWillRecieveProps = - typeof instance.componentWillRecieveProps !== "function"; - !noComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ) - : void 0; - var noUnsafeComponentWillRecieveProps = - typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - !noUnsafeComponentWillRecieveProps - ? warningWithoutStack$1( - false, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ) - : void 0; + if (typeof instance.componentDidUnmount === "function") { + error( + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ); + } + + if (typeof instance.componentDidReceiveProps === "function") { + error( + "%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 + ); + } + + if (typeof instance.componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ); + } + + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { + error( + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ); + } + var hasMutatedProps = instance.props !== newProps; - !(instance.props === undefined || !hasMutatedProps) - ? warningWithoutStack$1( - false, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ) - : void 0; - var noInstanceDefaultProps = !instance.defaultProps; - !noInstanceDefaultProps - ? warningWithoutStack$1( - false, - "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 - ) - : void 0; + + if (instance.props !== undefined && hasMutatedProps) { + error( + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ); + } + + if (instance.defaultProps) { + error( + "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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8163,63 +7974,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - var noInstanceGetDerivedStateFromProps = - typeof instance.getDerivedStateFromProps !== "function"; - !noInstanceGetDerivedStateFromProps - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noInstanceGetDerivedStateFromCatch = - typeof instance.getDerivedStateFromError !== "function"; - !noInstanceGetDerivedStateFromCatch - ? warningWithoutStack$1( - false, - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ) - : void 0; - var noStaticGetSnapshotBeforeUpdate = - typeof ctor.getSnapshotBeforeUpdate !== "function"; - !noStaticGetSnapshotBeforeUpdate - ? warningWithoutStack$1( - false, - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ) - : void 0; - var _state = instance.state; + if (typeof instance.getDerivedStateFromProps === "function") { + error( + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } - if (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + if (typeof instance.getDerivedStateFromError === "function") { + error( + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ); + } + + if (typeof ctor.getSnapshotBeforeUpdate === "function") { + error( + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", name ); } - if (typeof instance.getChildContext === "function") { - !(typeof ctor.childContextTypes === "object") - ? warningWithoutStack$1( - false, - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ) - : void 0; + var _state = instance.state; + + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + error("%s.state: must be set to an object or null", name); + } + + if ( + typeof instance.getChildContext === "function" && + typeof ctor.childContextTypes !== "object" + ) { + error( + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ); } } } @@ -8278,8 +8079,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8323,8 +8123,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -8389,8 +8189,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -8432,8 +8232,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8470,8 +8269,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8498,6 +8297,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { @@ -8515,8 +8315,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -8540,19 +8340,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8575,18 +8364,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8645,18 +8429,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8746,6 +8520,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8789,18 +8564,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8962,8 +8727,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8989,8 +8754,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!didWarnAboutStringRefs[componentName]) { if (warnAboutStringRefs) { - warningWithoutStack$1( - false, + error( 'Component "%s" contains the string ref "%s". Support for string refs ' + "will be removed in a future major release. We recommend using " + "useRef() or createRef() instead. " + @@ -9001,8 +8765,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } else { - warningWithoutStack$1( - false, + error( 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -9115,23 +8878,25 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); + { + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; + } - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - warning$1( - false, - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + + error( + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + ); + } } // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching @@ -9269,33 +9034,51 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current$$1, element, expirationTime) { - if ( - current$$1 !== null && - (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current$$1, element)) - ) { - // Move based on index - var existing = useFiber(current$$1, element.props, expirationTime); - existing.ref = coerceRef(returnFiber, current$$1, element); - existing.return = returnFiber; + if (current$$1 !== null) { + if ( + current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } else if ( + enableChunksAPI && + current$$1.tag === Chunk && + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === current$$1.type.render + ) { + // Same as above but also update the .type field. + var _existing = useFiber(current$$1, element.props, expirationTime); + + _existing.return = returnFiber; + _existing.type = element.type; + + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; } + } // Insert - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; } function updatePortal(returnFiber, current$$1, portal, expirationTime) { @@ -9613,8 +9396,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9622,6 +9404,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; default: @@ -9827,28 +9610,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !didWarnAboutGenerators - ? warning$1( - false, - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ) - : void 0; + if (!didWarnAboutGenerators) { + error( + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ); + } + didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !didWarnAboutMaps - ? warning$1( - false, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ) - : void 0; + if (!didWarnAboutMaps) { + error( + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ); + } + didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10056,33 +9839,79 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - if ( - child.tag === Fragment - ? element.type === REACT_FRAGMENT_TYPE - : child.elementType === element.type || // Keep this check inline so it only runs on the false path: + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.props.children, + expirationTime + ); + existing.return = returnFiber; + + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; + } + + break; + } + + case Chunk: + if (enableChunksAPI) { + if ( + element.type.$$typeof === REACT_CHUNK_TYPE && + element.type.render === child.type.render + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing2 = useFiber(child, element.props, expirationTime); + + _existing2.type = element.type; + _existing2.return = returnFiber; + + { + _existing2._debugSource = element._source; + _existing2._debugOwner = element._owner; + } + + return _existing2; + } + } + + // We intentionally fallthrough here if enableChunksAPI is not on. + // eslint-disable-next-lined no-fallthrough + + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber( - child, - element.type === REACT_FRAGMENT_TYPE - ? element.props.children - : element.props, - expirationTime - ); - existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + var _existing3 = useFiber(child, element.props, expirationTime); + + _existing3.ref = coerceRef(returnFiber, child, element); + _existing3.return = returnFiber; + + { + _existing3._debugSource = element._source; + _existing3._debugOwner = element._owner; + } + + return _existing3; + } + + break; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10577,7 +10406,7 @@ function mountEventResponder( } } - mountResponderInstance( + DEPRECATED_mountResponderInstance( responder, responderInstance, responderProps, @@ -10613,8 +10442,7 @@ function updateEventListener( if (visistedResponders.has(responder)) { // show warning { - warning$1( - false, + error( 'Duplicate event responder "%s" found in event listeners. ' + "Event listeners passed to elements cannot use the same event responder more than once.", responder.displayName @@ -10643,7 +10471,11 @@ function updateEventListener( } } -function updateEventListeners(listeners, fiber, rootContainerInstance) { +function updateDeprecatedEventListeners( + listeners, + fiber, + rootContainerInstance +) { var visistedResponders = new Set(); var dependencies = fiber.dependencies; @@ -10659,7 +10491,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { var respondersMap = dependencies.responders; if (respondersMap === null) { - respondersMap = new Map(); + dependencies.responders = respondersMap = new Map(); } if (isArray$2(listeners)) { @@ -10697,7 +10529,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { if (!visistedResponders.has(mountedResponder)) { var responderInstance = _respondersMap.get(mountedResponder); - unmountResponderInstance(responderInstance); + DEPRECATED_unmountResponderInstance(responderInstance); _respondersMap.delete(mountedResponder); } @@ -10705,7 +10537,7 @@ function updateEventListeners(listeners, fiber, rootContainerInstance) { } } } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10717,6 +10549,24 @@ function createResponderListener(responder, props) { return eventResponderListener; } +function unmountDeprecatedResponderListeners(fiber) { + var dependencies = fiber.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + DEPRECATED_unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } +} var NoEffect$1 = /* */ @@ -10761,13 +10611,7 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var nextCurrentHook = null; -var firstWorkInProgressHook = null; -var workInProgressHook = null; -var nextWorkInProgressHook = null; -var remainingExpirationTime = NoWork; -var componentUpdateQueue = null; -var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +var workInProgressHook = null; // Updates scheduled during render will trigger an immediate re-render at the // end of the current pass. We can't store these updates on the normal queue, // because if the work is aborted, they should be discarded. Because this is // a relatively rare case, we also don't want to add an additional field to @@ -10825,8 +10669,7 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10862,8 +10705,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -10897,8 +10739,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -10913,8 +10754,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -10942,12 +10782,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10955,24 +10794,25 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // The following should have already been reset // currentHook = null; // workInProgressHook = null; - // remainingExpirationTime = NoWork; - // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; - // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { + if (current !== null && current.memoizedState !== null) { ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, @@ -10986,7 +10826,7 @@ function renderWithHooks( } } - var children = Component(props, refOrContext); + var children = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do { @@ -10999,11 +10839,9 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. @@ -11011,7 +10849,7 @@ function renderWithHooks( } ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); + children = Component(props, secondArg); } while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; @@ -11020,14 +10858,9 @@ function renderWithHooks( // at the beginning of the render phase and there's no re-entrancy. ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. @@ -11035,20 +10868,13 @@ function renderWithHooks( renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; hookTypesDev = null; hookTypesUpdateIndexDev = -1; - } - - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above + } // These were reset above // didScheduleRenderPhaseUpdate = false; // renderPhaseUpdates = null; // numberOfReRenders = 0; @@ -11079,10 +10905,7 @@ function resetHooks() { renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11090,9 +10913,6 @@ function resetHooks() { currentHookNameInDev = null; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -11102,14 +10922,14 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11124,12 +10944,33 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. + var nextCurrentHook; + + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + + if (current !== null) { + nextCurrentHook = current.memoizedState; + } else { + nextCurrentHook = null; + } + } else { + nextCurrentHook = currentHook.next; + } + + var nextWorkInProgressHook; + + if (workInProgressHook === null) { + nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + } else { + nextWorkInProgressHook = workInProgressHook.next; + } + if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; - nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -11140,20 +10981,18 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11181,13 +11020,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11239,7 +11078,7 @@ function updateReducer(reducer, initialArg, init) { // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. - if (hook.baseUpdate === queue.last) { + if (hook.baseQueue === null) { hook.baseState = newState; } @@ -11249,35 +11088,37 @@ function updateReducer(reducer, initialArg, init) { } return [hook.memoizedState, _dispatch]; - } // The last update in the entire queue + } - var last = queue.last; // The last update that is part of the base state. + var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - var first; + var pendingQueue = queue.pending; - if (baseUpdate !== null) { - if (last !== null) { - // For the first update, the queue is a circular linked list where - // `queue.last.next = queue.first`. Once the first update commits, and - // the `baseUpdate` is no longer empty, we can unravel the list. - last.next = null; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var _newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; var _update = first; - var didSkip = false; do { var updateExpirationTime = _update.expirationTime; @@ -11286,24 +11127,46 @@ function updateReducer(reducer, initialArg, init) { // Priority is insufficient. Skip this update. If this is the first // skipped update, the previous update/state is the new base // update/state. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; newBaseState = _newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + if (newBaseQueueLast !== null) { + var _clone = { + expirationTime: Sync, + // This update is going to be committed so we never want uncommit it. + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig @@ -11319,13 +11182,13 @@ function updateReducer(reducer, initialArg, init) { } } - prevUpdate = _update; _update = _update.next; } while (_update !== null && _update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; + if (newBaseQueueLast === null) { newBaseState = _newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. @@ -11334,8 +11197,8 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = _newState; } @@ -11352,13 +11215,13 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11378,9 +11241,11 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -11420,7 +11285,7 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } @@ -11443,7 +11308,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } @@ -11501,14 +11366,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !refObject.hasOwnProperty("current") - ? warning$1( - false, - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ) - : void 0; + if (!refObject.hasOwnProperty("current")) { + error( + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ); + } } var _inst2 = create(); @@ -11522,14 +11386,13 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11544,14 +11407,13 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(typeof create === "function") - ? warning$1( - false, - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ) - : void 0; + if (typeof create !== "function") { + error( + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ); + } } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = @@ -11634,17 +11496,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -11658,47 +11517,54 @@ function updateDeferredValue(value, config) { updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); return prevValue; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority( + priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, + function() { + setPending(true); + } + ); + runWithPriority( + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + } + ); +} + function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var startTransition = mountCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { @@ -11706,25 +11572,11 @@ function updateTransition(config) { isPending = _updateState2[0], setPending = _updateState2[1]; - var startTransition = updateCallback( - function(callback) { - setPending(true); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { @@ -11735,14 +11587,13 @@ function dispatchAction(fiber, queue, action) { } { - !(typeof arguments[3] !== "function") - ? warning$1( - false, - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ) - : void 0; + if (typeof arguments[3] === "function") { + error( + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ); + } } var alternate = fiber.alternate; @@ -11807,23 +11658,17 @@ function dispatchAction(fiber, queue, action) { _update2.priority = getCurrentPriorityLevel(); } // Append the update to the end of the list. - var last = queue.last; + var pending = queue.pending; - if (last === null) { + if (pending === null) { // This is the first update. Create a circular list. _update2.next = _update2; } else { - var first = last.next; - - if (first !== null) { - // Still circular. - _update2.next = first; - } - - last.next = _update2; + _update2.next = pending.next; + pending.next = _update2; } - queue.last = _update2; + queue.pending = _update2; if ( fiber.expirationTime === NoWork && @@ -11859,7 +11704,7 @@ function dispatchAction(fiber, queue, action) { // time the reducer has changed. return; } - } catch (error) { + } catch (error$$1) { // Suppress the error. It will throw again in the render phase. } finally { { @@ -11905,8 +11750,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; { var warnInvalidContextAccess = function() { - warning$1( - false, + error( "Context can only be read while React is rendering. " + "In classes, you can read it in the render method or getDerivedStateFromProps. " + "In function components, you can read it directly in the function body, but not " + @@ -11915,8 +11759,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -12007,7 +11850,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12098,7 +11941,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12189,7 +12032,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12292,7 +12135,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12397,7 +12240,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12477,12 +12320,11 @@ var isHydrating = false; function warnIfHydrating() { { - !!isHydrating - ? warning$1( - false, - "We should not be hydrating here. This is a bug in React. Please file a bug." - ) - : void 0; + if (isHydrating) { + error( + "We should not be hydrating here. This is a bug in React. Please file a bug." + ); + } } } @@ -13009,8 +12851,8 @@ function forceUnmountCurrentAndReconcile( renderExpirationTime ); // In the second pass, we mount the new children. The trick here is that we // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13270,7 +13112,7 @@ function updateSimpleMemoComponent( if ( shallowEqual(prevProps, nextProps) && - current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. workInProgress.type === current$$1.type ) { didReceiveUpdate = false; @@ -13430,6 +13272,73 @@ function updateFunctionComponent( return workInProgress.child; } +function updateChunk( + current$$1, + workInProgress, + chunk, + nextProps, + renderExpirationTime +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + var render = chunk.render; + var data = chunk.query(); // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + data, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + function updateClassComponent( current$$1, workInProgress, @@ -13472,9 +13381,9 @@ function updateClassComponent( if (instance === null) { if (current$$1 !== null) { - // An class component without an instance only mounts if it suspended - // inside a non- concurrent tree, in an inconsistent state. We want to - // tree it like a new mount, even though an empty version of it already + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect @@ -13526,14 +13435,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (inst.props !== nextProps) { - !didWarnAboutReassigningProps - ? warning$1( - false, - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" - ) - : void 0; + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); + } + didWarnAboutReassigningProps = true; } } @@ -13575,7 +13484,7 @@ function finishClassComponent( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. @@ -13654,7 +13563,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + if (!(current$$1 !== null && updateQueue !== null)) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); @@ -13663,13 +13572,8 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current$$1, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". @@ -13743,7 +13647,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { if (isDirectTextChild) { // We special case a direct text child of a host node. This is a common // case. We won't handle it as a reified child. We will instead handle - // this in the host environment that also have access to this prop. That + // this in the host environment that also has access to this prop. That // avoids allocating another HostText fiber and traversing it. nextChildren = null; } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { @@ -13793,7 +13697,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. // Disconnect the alternate pointers. @@ -13831,7 +13735,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -13848,7 +13752,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -13865,7 +13769,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -13893,36 +13797,48 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } - default: { - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + case Chunk: { + if (enableChunksAPI) { + // TODO: Resolve for Hot Reloading. + child = updateChunk( + null, + workInProgress, + Component, + props, + renderExpirationTime ); + return child; } + + break; } } - return child; + var hint = ""; + + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } function mountIncompleteClassComponent( @@ -14016,13 +13932,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "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 ); + didWarnAboutBadClass[componentName] = true; } } @@ -14054,8 +13970,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to be a function component that returns a class instance. " + "Change %s to a class that extends React.Component instead. " + "If you can't use a class try assigning the prototype on the function as a workaround. " + @@ -14065,6 +13980,7 @@ function mountIndeterminateComponent( _componentName, _componentName ); + didWarnAboutModulePatternComponent[_componentName] = true; } } // Proceed under the assumption that this is a class instance @@ -14086,6 +14002,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14113,8 +14030,7 @@ function mountIndeterminateComponent( { if (disableLegacyContext && Component.contextTypes) { - warningWithoutStack$1( - false, + error( "%s uses the legacy contextTypes API which is no longer supported. " + "Use React.createContext() with React.useContext() instead.", getComponentName(Component) || "Unknown" @@ -14150,86 +14066,87 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; - warning$1( - false, - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - } - if ( - warnAboutDefaultPropsOnFunctionComponents && - Component.defaultProps !== undefined - ) { - var componentName = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { - warningWithoutStack$1( - false, - "%s: Support for defaultProps will be removed from function components " + - "in a future major release. Use JavaScript default parameters instead.", - componentName - ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + error( + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } } - } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - warningWithoutStack$1( - false, - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14301,8 +14218,8 @@ function updateSuspenseComponent( if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { didWarnAboutMaxDuration = true; - warning$1( - false, + + error( "maxDuration has been removed from React. " + "Remove the maxDuration prop." ); @@ -14674,7 +14591,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -14720,8 +14637,7 @@ function mountDehydratedSuspenseComponent( // Instead, we'll leave the content in place and try to hydrate it later. if ((workInProgress.mode & BlockingMode) === NoMode) { { - warning$1( - false, + error( "Cannot hydrate Suspense in legacy mode. Switch from " + "ReactDOM.hydrate(element, container) to " + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + @@ -14981,40 +14897,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15029,16 +14944,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15056,8 +14971,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15067,6 +14982,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15107,8 +15023,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + error( 'A single row was passed to a . ' + "This is not useful since it needs multiple rows. " + "Did you mean to pass multiple children or an array?", @@ -15134,6 +15049,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15144,6 +15060,7 @@ function initSuspenseListRenderState( // We can reuse the existing object from previous renders. renderState.isBackwards = isBackwards; renderState.rendering = null; + renderState.renderingStartTime = 0; renderState.last = lastContentRow; renderState.tail = tail; renderState.tailExpiration = 0; @@ -15416,8 +15333,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15432,15 +15349,14 @@ function updateContextConsumer( var render = newProps.children; { - !(typeof render === "function") - ? warningWithoutStack$1( - false, - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ) - : void 0; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -16048,6 +15964,22 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; } + + case Chunk: { + if (enableChunksAPI) { + var chunk = workInProgress.type; + var props = workInProgress.pendingProps; + return updateChunk( + current$$1, + workInProgress, + chunk, + props, + renderExpirationTime + ); + } + + break; + } } { @@ -16732,6 +16664,8 @@ if (supportsMutation) { // This lets the parents know that at least one of their children has changed. markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; } }; } else { @@ -16830,14 +16764,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -16846,7 +16782,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -16872,7 +16808,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -16889,9 +16825,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = current.memoizedProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { markUpdate(workInProgress); @@ -16909,12 +16845,12 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return null; } var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on we want to add then top->down or + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. var _wasHydrated = popHydrationState(workInProgress); @@ -16929,16 +16865,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { currentHostContext ) ) { - // If changes to the hydrated node needs to be applied at the + // If changes to the hydrated node need to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } - if (enableFlareAPI) { - var listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var listeners = newProps.DEPRECATED_flareListeners; if (listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( listeners, workInProgress, rootContainerInstance @@ -16957,11 +16893,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = instance; - if (enableFlareAPI) { - var _listeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners = newProps.DEPRECATED_flareListeners; if (_listeners != null) { - updateEventListeners( + updateDeprecatedEventListeners( _listeners, workInProgress, rootContainerInstance @@ -16990,7 +16926,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17030,12 +16966,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - case ForwardRef: - break; - case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; @@ -17061,15 +16994,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { // We should never have been in a hydration state if we didn't have a current. // However, in some of those paths, we might have reentered a hydration state - // and then we might be inside a hydration state. In that case, we'll need to - // exit out of it. + // and then we might be inside a hydration state. In that case, we'll need to exit out of it. resetHydrationState(); if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated and unsuspended. workInProgress.memoizedState = null; } // If nothing suspended, we need to schedule an effect to mark this boundary - // as having hydrated so events know that they're free be invoked. + // as having hydrated so events know that they're free to be invoked. // It's also a signal to replay events and the suspense callback. // If something suspended, schedule an effect to attach retry listeners. // So we might as well always mark this. @@ -17162,7 +17094,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if not prevDidTimeout. if (nextDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. workInProgress.effectTag |= Update; } @@ -17172,9 +17104,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { // TODO: Only schedule updates if these values are non equal, i.e. it changed. if (nextDidTimeout || prevDidTimeout) { // If this boundary just timed out, schedule an effect to attach a - // retry listener to the proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } @@ -17189,33 +17121,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17226,7 +17143,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17234,9 +17151,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var renderState = workInProgress.memoizedState; if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17352,7 +17269,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // The time it took to render last row is greater than time until + // the expiration. + now() * 2 - renderState.renderingStartTime > + renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -17402,13 +17322,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this + // is a per component value. It should really be since the start + // of the total render or last commit. Consider using something like + // globalMostRecentFallbackTime. That doesn't account for being + // suspended for part of the time or when it's a new render. + // It should probably use a global start time value instead. } // Pop a row. var next = renderState.tail; renderState.rendering = next; renderState.tail = next.sibling; renderState.lastEffect = workInProgress.lastEffect; + renderState.renderingStartTime = now(); next.sibling = null; // Restore the context. // TODO: We can probably just avoid popping it instead and only // setting it the first time we go from not suspended to suspended. @@ -17429,7 +17355,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; + return null; } case FundamentalComponent: { @@ -17484,6 +17410,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } + + return null; } break; @@ -17500,13 +17428,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.stateNode = scopeInstance; scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _listeners2 = newProps.DEPRECATED_flareListeners; if (_listeners2 != null) { var _rootContainerInstance2 = getRootHostContainer(); - updateEventListeners( + updateDeprecatedEventListeners( _listeners2, workInProgress, _rootContainerInstance2 @@ -17519,9 +17447,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - if (enableFlareAPI) { - var _prevListeners = current.memoizedProps.listeners; - var _nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var _prevListeners = + current.memoizedProps.DEPRECATED_flareListeners; + var _nextListeners = newProps.DEPRECATED_flareListeners; if ( _prevListeners !== _nextListeners || @@ -17539,21 +17468,28 @@ function completeWork(current, workInProgress, renderExpirationTime) { markRef$1(workInProgress); } } + + return null; } break; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + case Chunk: + if (enableChunksAPI) { + return null; + } + + break; } - return null; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } function unwindWork(workInProgress, renderExpirationTime) { @@ -17746,7 +17682,8 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console.error(error); // For a more detailed description of this block, see: + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -17783,7 +17720,7 @@ function logCapturedError(capturedError) { // has already printed it. Even if the application swallows the error, it is still // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - console.error(combinedMessage); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -17881,8 +17818,8 @@ function safelyCallDestroy(current$$1, destroy) { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(current$$1, error$$1); } } } @@ -17891,7 +17828,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } @@ -17911,28 +17849,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -17948,8 +17885,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -17972,14 +17909,12 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18035,8 +17970,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { addendum = " You returned: " + _destroy; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18056,7 +17990,8 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; @@ -18077,9 +18012,10 @@ function commitLifeCycles( switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + return; } case ClassComponent: { @@ -18096,28 +18032,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18141,28 +18076,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } @@ -18183,28 +18117,27 @@ function commitLifeCycles( finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps ) { - !(instance.props === finishedWork.memoizedProps) - ? warning$1( - false, - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; - !(instance.state === finishedWork.memoizedState) - ? warning$1( - false, - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ) - : void 0; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -18315,14 +18248,12 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: return; + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -18409,8 +18340,7 @@ function commitAttachRef(finishedWork) { } else { { if (!ref.hasOwnProperty("current")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18445,7 +18375,8 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { @@ -18485,7 +18416,7 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } } - break; + return; } case ClassComponent: { @@ -18500,27 +18431,9 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); - - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ - ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); - } - - dependencies.responders = null; - } - } + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + beforeRemoveInstance(current$$1.stateNode); } safelyDetachRef(current$$1); @@ -18570,9 +18483,15 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { } case ScopeComponent: { + if (enableDeprecatedFlareAPI) { + unmountDeprecatedResponderListeners(current$$1); + } + if (enableScopeAPI) { safelyDetachRef(current$$1); } + + return; } } } @@ -18633,6 +18552,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; if (alternate !== null) { detachFiber(alternate); @@ -18671,14 +18591,12 @@ function commitContainer(finishedWork) { replaceContainerChildren(containerInfo, pendingChildren); return; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19012,7 +18930,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19057,7 +18976,8 @@ function commitWork(current$$1, finishedWork) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { + case SimpleMemoComponent: + case Chunk: { // Note: We currently never use MountMutation, but useLayout uses // UnmountMutation. commitHookEffectList(UnmountMutation, MountMutation, finishedWork); @@ -19095,12 +19015,12 @@ function commitWork(current$$1, finishedWork) { ); } - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + if (enableDeprecatedFlareAPI) { + var prevListeners = oldProps.DEPRECATED_flareListeners; + var nextListeners = newProps.DEPRECATED_flareListeners; if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + updateDeprecatedEventListeners(nextListeners, finishedWork, null); } } } @@ -19162,9 +19082,10 @@ function commitWork(current$$1, finishedWork) { if (enableFundamentalAPI) { var fundamentalInstance = finishedWork.stateNode; updateFundamentalComponent(fundamentalInstance); + return; } - return; + break; } case ScopeComponent: { @@ -19172,31 +19093,31 @@ function commitWork(current$$1, finishedWork) { var scopeInstance = finishedWork.stateNode; scopeInstance.fiber = finishedWork; - if (enableFlareAPI) { + if (enableDeprecatedFlareAPI) { var _newProps = finishedWork.memoizedProps; var _oldProps = current$$1 !== null ? current$$1.memoizedProps : _newProps; - var _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + var _prevListeners = _oldProps.DEPRECATED_flareListeners; + var _nextListeners = _newProps.DEPRECATED_flareListeners; - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); + if (_prevListeners !== _nextListeners || current$$1 === null) { + updateDeprecatedEventListeners(_nextListeners, finishedWork, null); } } + + return; } - return; + break; } + } - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } @@ -19228,7 +19149,7 @@ function commitSuspenseComponent(finishedWork) { } } else { if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + error("Unexpected type for suspenseCallback."); } } } @@ -19321,10 +19242,10 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { update.payload = { element: null }; - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.callback = function() { - onUncaughtError(error); + onUncaughtError(error$$1); logError(fiber, errorInfo); }; @@ -19337,11 +19258,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$$1); }; } @@ -19364,9 +19285,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$$1, { componentStack: stack !== null ? stack : "" }); @@ -19375,14 +19296,13 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(fiber.expirationTime === Sync) - ? warningWithoutStack$1( - false, - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ) - : void 0; + if (fiber.expirationTime !== Sync) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } } } }; @@ -19447,6 +19367,20 @@ function throwException( ) { // This is a thenable. var thenable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.expirationTime = currentSource.expirationTime; + } else { + sourceFiber.memoizedState = null; + } + } + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, @@ -19972,9 +19906,21 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; + var nextLevel = + lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; + + if ( + enableTrainModelFix && + nextLevel <= Idle && + firstPendingTime !== nextLevel + ) { + // Don't work on Idle/Never priority unless everything else is committed. + return NoWork; + } + + return nextLevel; } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the // expiration time of the existing task is the same as the expiration time of @@ -20422,80 +20368,70 @@ function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; - if (root.finishedExpirationTime === expirationTime) { - // There's already a pending commit at this expiration time. - // TODO: This is poorly factored. This case only exists for the - // batch.commit() API. - commitRoot(root); - } else { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } // If we have a work-in-progress fiber, it means there's still work to do - // in this root. + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); } + } while (true); - if (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } else { - // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. - stopFinishedWorkLoopTimer(); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - finishSyncRender(root, workInProgressRootExitStatus, expirationTime); - } // Before exiting, make sure there's a callback scheduled for the next - // pending level. + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); ensureRootIsScheduled(root); + throw fatalError; } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } return null; @@ -20523,12 +20459,13 @@ function flushDiscreteUpdates() { (executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext ) { - if (true && (executionContext & RenderContext) !== NoContext) { - warning$1( - false, - "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + - "already rendering." - ); + { + if ((executionContext & RenderContext) !== NoContext) { + error( + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } } // We're already rendering, so we can't synchronously flush pending work. // This is probably a nested event dispatch triggered by a lifecycle/effect, // like `el.focus()`. Exit. @@ -21114,7 +21051,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + do { + // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + } while (rootWithPendingPassiveEffects !== null); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21208,8 +21154,8 @@ function commitRootImpl(root, renderPriorityLevel) { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(nextEffect, error$$1); nextEffect = nextEffect.nextEffect; } } @@ -21581,8 +21527,8 @@ function flushPassiveEffectsImpl() { throw Error("Should be working on an effect."); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + var error$$1 = clearCaughtError(); + captureCommitPhaseError(effect, error$$1); } resetCurrentFiber(); @@ -21622,17 +21568,17 @@ function markLegacyErrorBoundaryAsFailed(instance) { } } -function prepareToThrowUncaughtError(error) { +function prepareToThrowUncaughtError(error$$1) { if (!hasUncaughtError) { hasUncaughtError = true; - firstUncaughtError = error; + firstUncaughtError = error$$1; } } var onUncaughtError = prepareToThrowUncaughtError; -function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { - var errorInfo = createCapturedValue(error, sourceFiber); +function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error$$1) { + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createRootErrorUpdate(rootFiber, errorInfo, Sync); enqueueUpdate(rootFiber, update); var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync); @@ -21643,11 +21589,11 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, error$$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$$1); return; } @@ -21655,7 +21601,7 @@ function captureCommitPhaseError(sourceFiber, error) { while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -21666,7 +21612,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$$1, sourceFiber); var update = createClassErrorUpdate( fiber, errorInfo, // TODO: This is always sync @@ -21740,7 +21686,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { root.lastPingedTime = suspendedTime; - if (root.finishedExpirationTime === suspendedTime) { + if (!enableTrainModelFix && root.finishedExpirationTime === suspendedTime) { // If there's a pending fallback waiting to commit, throw it away. root.finishedExpirationTime = NoWork; root.finishedWork = null; @@ -21894,8 +21840,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -21950,7 +21896,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Chunk ) { // Only warn for user-defined components, not internal ones like Suspense. return; @@ -21969,8 +21916,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -22061,10 +22007,10 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "setState(...): Cannot call setState() inside getChildContext()" ); + didWarnAboutUpdateInGetChildContext = true; break; @@ -22073,12 +22019,12 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { return; } - warningWithoutStack$1( - false, + error( "Cannot update during an existing state transition (such as " + "within `render`). Render methods should be a pure function of " + "props and state." ); + didWarnAboutUpdateInRender = true; break; } @@ -22096,8 +22042,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "It looks like you're using the wrong act() around your test interactions.\n" + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + "// for react-dom:\n" + @@ -22123,8 +22068,7 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22151,8 +22095,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -22186,8 +22129,8 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22196,8 +22139,8 @@ function warnIfUnmockedScheduler(fiber) { ); } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( 'Starting from React v17, the "scheduler" module will need to be mocked ' + "to guarantee consistent behaviour across tests and browsers. " + "For example, with jest: \n" + @@ -22234,7 +22177,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { - var update = updateQueue.firstUpdate; + var update = updateQueue.baseQueue; while (update !== null) { var priorityLevel = update.priority; @@ -22265,11 +22208,11 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { case FunctionComponent: case ForwardRef: case SimpleMemoComponent: - if ( - workInProgressNode.memoizedState !== null && - workInProgressNode.memoizedState.baseUpdate !== null - ) { - var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + case Chunk: { + var firstHook = current$$1.memoizedState; // TODO: This just checks the first Hook. Isn't it suppose to check all Hooks? + + if (firstHook !== null && firstHook.baseQueue !== null) { + var _update = firstHook.baseQueue; // Loop through the functional component's memoized state to see whether // the component has triggered any high pri updates while (_update !== null) { @@ -22292,9 +22235,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { break; } - if ( - _update.next === workInProgressNode.memoizedState.baseUpdate - ) { + if (_update.next === firstHook.baseQueue) { break; } @@ -22303,6 +22244,7 @@ function checkForWrongSuspensePriorityInDEV(sourceFiber) { } break; + } default: break; @@ -22325,8 +22267,7 @@ function flushSuspensePriorityWarningInDEV() { componentsThatTriggeredHighPriSuspend = null; if (componentNames.length > 0) { - warningWithoutStack$1( - false, + error( "%s triggered a user-blocking update that suspended." + "\n\n" + "The fix is to split the update into multiple parts: a user-blocking " + @@ -22439,10 +22380,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { try { subscriber.onWorkStarted(interactions, threadID); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22464,10 +22405,10 @@ function finishPendingInteractions(root, committedExpirationTime) { var threadID = computeThreadID(root, committedExpirationTime); subscriber.onWorkStopped(root.memoizedInteractions, threadID); } - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } finally { // Clear completed interactions from the pending Map. @@ -22489,10 +22430,10 @@ function finishPendingInteractions(root, committedExpirationTime) { if (subscriber !== null && interaction.__count === 0) { try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { + } catch (error$$1) { // If the subscriber throws, rethrow it in a separate task scheduleCallback(ImmediatePriority, function() { - throw error; + throw error$$1; }); } } @@ -22502,6 +22443,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22523,8 +22465,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "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" @@ -22537,6 +22478,23 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + { + // Only used by Fast Refresh + if (typeof hook.onScheduleFiberRoot === "function") { + onScheduleFiberRoot = function(root, children) { + try { + hook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + }; + } + } + onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -22552,13 +22510,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22567,29 +22524,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation encountered an error: %s.", err); } } // DevTools exists return true; } +function onScheduleRoot(root, children) { + if (typeof onScheduleFiberRoot === "function") { + onScheduleFiberRoot(root, children); + } +} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -22737,6 +22694,12 @@ function resolveLazyComponentTag(Component) { if ($$typeof === REACT_MEMO_TYPE) { return MemoComponent; } + + if (enableChunksAPI) { + if ($$typeof === REACT_CHUNK_TYPE) { + return Chunk; + } + } } return IndeterminateComponent; @@ -23017,6 +22980,10 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; + case REACT_CHUNK_TYPE: + fiberTag = Chunk; + break getTag; + case REACT_FUNDAMENTAL_TYPE: if (enableFundamentalAPI) { return createFiberFromFundamental( @@ -23142,8 +23109,7 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { typeof pendingProps.id !== "string" || typeof pendingProps.onRender !== "function" ) { - warningWithoutStack$1( - false, + error( 'Profiler must specify an "id" string and "onRender" function as props' ); } @@ -23305,6 +23271,7 @@ function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -23398,15 +23365,6 @@ function markRootExpiredAtTime(root, expirationTime) { } } -// This lets us hook into Fiber to debug what it's doing. -// See https://github.com/facebook/react/pull/8033. -// This is not part of the public API, not even for React DevTools. -// You may only inject a debugTool if you work on React Fiber itself. -var ReactFiberInstrumentation = { - debugTool: null -}; -var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; - var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -23493,8 +23451,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23506,8 +23463,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -23532,6 +23488,10 @@ function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { + { + onScheduleRoot(container, element); + } + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); @@ -23549,19 +23509,6 @@ function updateContainer(element, container, parentComponent, callback) { current$$1, suspenseConfig ); - - { - if (ReactFiberInstrumentation_1.debugTool) { - if (current$$1.alternate === null) { - ReactFiberInstrumentation_1.debugTool.onMountContainer(container); - } else if (element === null) { - ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); - } else { - ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); - } - } - } - var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -23573,8 +23520,8 @@ function updateContainer(element, container, parentComponent, callback) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23593,14 +23540,16 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ) - : void 0; + ); + } + } + update.callback = callback; } @@ -23758,7 +23707,7 @@ function createPortal( // TODO: this is special because it gets imported during build. -var ReactVersion = "16.11.0"; +var ReactVersion = "16.12.0-19f6fe170"; var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { /** @@ -23802,7 +23751,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23848,7 +23797,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23892,7 +23841,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23900,12 +23849,14 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -23918,10 +23869,12 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -23953,7 +23906,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -23961,10 +23914,10 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } + return; } @@ -24130,7 +24083,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24174,7 +24127,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24215,7 +24168,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24223,12 +24176,14 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: measureLayout on components using NativeMethodsMixin " + - "or ReactNative.NativeComponent is not currently supported in Fabric. " + - "measureLayout must be called on a native ref. Consider using forwardRef." - ); + { + error( + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + } + return; } else { var relativeNode; @@ -24241,10 +24196,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -24276,7 +24233,7 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { try { maybeInstance = findHostInstance(this); - } catch (error) {} // If there is no host component beneath this we should fail silently. + } catch (error$$1) {} // If there is no host component beneath this we should fail silently. // This is not an error; it could mean a class component rendered null. if (maybeInstance == null) { @@ -24284,10 +24241,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { } if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error( + "Warning: setNativeProps is not currently supported in Fabric" + ); + } + return; } @@ -24432,17 +24391,17 @@ function findHostInstance_DEPRECATED(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24485,17 +24444,17 @@ function findNodeHandle(componentOrHandle) { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - !owner.stateNode._warnedAboutRefsInRender - ? warningWithoutStack$1( - false, - "%s is accessing findNodeHandle 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.type) || "A component" - ) - : void 0; + if (!owner.stateNode._warnedAboutRefsInRender) { + error( + "%s is accessing findNodeHandle 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.type) || "A component" + ); + } + owner.stateNode._warnedAboutRefsInRender = true; } } @@ -24564,21 +24523,29 @@ var ReactNativeRenderer = { findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { if (handle._nativeTag == null) { - !(handle._nativeTag != null) - ? warningWithoutStack$1( - false, - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ) - : void 0; + { + error( + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + return; } - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index c8107e4934204a..8f8de75dd00dee 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -502,53 +502,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -681,13 +655,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1159,7 +1127,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1224,6 +1193,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -2017,237 +1988,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2264,10 +2193,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2382,6 +2309,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2389,16 +2317,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2414,16 +2334,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2985,39 +2902,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3215,7 +3143,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3223,13 +3151,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3249,53 +3171,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3304,37 +3218,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3362,51 +3281,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3416,7 +3359,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3433,21 +3376,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3467,7 +3412,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3515,6 +3460,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3556,14 +3516,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3626,7 +3583,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3645,23 +3602,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3669,25 +3624,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3729,23 +3672,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3753,25 +3694,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4085,17 +4014,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4141,6 +4067,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4169,17 +4096,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4481,6 +4405,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4489,6 +4414,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4695,38 +4621,348 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { + var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: - return popHostContext(workInProgress), null; + popHostContext(workInProgress); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== workInProgress.ref && + (workInProgress.effectTag |= 128); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } + current = requiredContext(contextStackCursor$1.current); + var tag = allocateTag(), + viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + tag, + viewConfig.uiViewClassName, + rootContainerInstance, + updatePayload + ); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, workInProgress, !1, !1); + workInProgress.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (workInProgress.effectTag |= 4); + null !== workInProgress.ref && (workInProgress.effectTag |= 128); + } + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + rootContainerInstance = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + rootContainerInstance, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; + } + return null; case 13: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.effectTag & 64)) + return ( + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress + ); + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; + return null; + case 4: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; + case 10: + return popProvider(workInProgress), null; + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + tag = newProps.rendering; + if (null === tag) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + tag = findFirstSuspended(current); + if (null !== tag) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = tag.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (tag = rootContainerInstance.alternate), + null === tag + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + tag.childExpirationTime), + (rootContainerInstance.expirationTime = + tag.expirationTime), + (rootContainerInstance.child = tag.child), + (rootContainerInstance.memoizedProps = + tag.memoizedProps), + (rootContainerInstance.memoizedState = + tag.memoizedState), + (rootContainerInstance.updateQueue = tag.updateQueue), + (renderExpirationTime$jscomp$0 = tag.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !tag.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); + } else + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + : ((current = newProps.last), + null !== current + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); + } + return null !== newProps.tail + ? (0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress + ), + current) + : null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor, workInProgress), null; case 4: return popHostContainer(workInProgress), null; case 10: @@ -4810,8 +5046,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -4825,18 +5062,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -4855,6 +5091,86 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4863,6 +5179,7 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && @@ -4921,6 +5238,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5187,10 +5505,11 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); - break; + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { @@ -5214,7 +5533,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5225,11 +5544,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5299,21 +5618,16 @@ function commitWork(current$$1, finishedWork) { current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5785,44 +6099,41 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || - prepareFreshStack(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -5908,8 +6219,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6077,361 +6395,30 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - a: { - var current = current$$1; - current$$1 = workInProgress; - var renderExpirationTime$jscomp$0 = renderExpirationTime, - newProps = current$$1.pendingProps; - switch (current$$1.tag) { - case 2: - break; - case 16: - break; - case 15: - case 0: - break; - case 1: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 3: - popHostContainer(current$$1); - popTopLevelContextObject(current$$1); - current = current$$1.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(current$$1); - break; - case 5: - popHostContext(current$$1); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime$jscomp$0 = current$$1.type; - if (null !== current && null != current$$1.stateNode) - updateHostComponent$1( - current, - current$$1, - renderExpirationTime$jscomp$0, - newProps, - rootContainerInstance - ), - current.ref !== current$$1.ref && (current$$1.effectTag |= 128); - else if (newProps) { - current = requiredContext(contextStackCursor$1.current); - var internalInstanceHandle = current$$1, - tag = allocateTag(), - viewConfig = getViewConfigForType( - renderExpirationTime$jscomp$0 - ), - updatePayload = diffProperties( - null, - emptyObject, - newProps, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - tag, - viewConfig.uiViewClassName, - rootContainerInstance, - updatePayload - ); - viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); - instanceCache.set(tag, internalInstanceHandle); - instanceProps.set(tag, newProps); - appendAllChildren(viewConfig, current$$1, !1, !1); - current$$1.stateNode = viewConfig; - finalizeInitialChildren( - viewConfig, - renderExpirationTime$jscomp$0, - newProps, - rootContainerInstance, - current - ) && (current$$1.effectTag |= 4); - null !== current$$1.ref && (current$$1.effectTag |= 128); - } else if (null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - if (current && null != current$$1.stateNode) - updateHostText$1( - current, - current$$1, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - renderExpirationTime$jscomp$0 = requiredContext( - rootInstanceStackCursor.current - ); - rootContainerInstance = requiredContext( - contextStackCursor$1.current - ); - current = current$$1; - if (!rootContainerInstance.isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - rootContainerInstance = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, - "RCTRawText", - renderExpirationTime$jscomp$0, - { text: newProps } - ); - instanceCache.set(rootContainerInstance, current$$1); - current.stateNode = rootContainerInstance; - } - break; - case 11: - break; - case 13: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (0 !== (current$$1.effectTag & 64)) { - current$$1.expirationTime = renderExpirationTime$jscomp$0; - break a; - } - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), - newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = current.child.sibling), - null !== renderExpirationTime$jscomp$0 && - ((internalInstanceHandle = current$$1.firstEffect), - null !== internalInstanceHandle - ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = internalInstanceHandle)) - : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = null)), - (renderExpirationTime$jscomp$0.effectTag = 8)))); - if ( - newProps && - !rootContainerInstance && - 0 !== (current$$1.mode & 2) - ) - if ( - (null === current && - !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) current$$1.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; - case 4: - popHostContainer(current$$1); - updateHostContainer(current$$1); - break; - case 10: - popProvider(current$$1); - break; - case 9: - break; - case 14: - break; - case 17: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 19: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (null === newProps) break; - rootContainerInstance = 0 !== (current$$1.effectTag & 64); - internalInstanceHandle = newProps.rendering; - if (null === internalInstanceHandle) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = current$$1.child; null !== current; ) { - internalInstanceHandle = findFirstSuspended(current); - if (null !== internalInstanceHandle) { - current$$1.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = internalInstanceHandle.updateQueue; - null !== current && - ((current$$1.updateQueue = current), - (current$$1.effectTag |= 4)); - null === newProps.lastEffect && - (current$$1.firstEffect = null); - current$$1.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; - for (newProps = current$$1.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime$jscomp$0 = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (internalInstanceHandle = - rootContainerInstance.alternate), - null === internalInstanceHandle - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - internalInstanceHandle.childExpirationTime), - (rootContainerInstance.expirationTime = - internalInstanceHandle.expirationTime), - (rootContainerInstance.child = - internalInstanceHandle.child), - (rootContainerInstance.memoizedProps = - internalInstanceHandle.memoizedProps), - (rootContainerInstance.memoizedState = - internalInstanceHandle.memoizedState), - (rootContainerInstance.updateQueue = - internalInstanceHandle.updateQueue), - (renderExpirationTime$jscomp$0 = - internalInstanceHandle.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime$jscomp$0 - ? null - : { - expirationTime: - renderExpirationTime$jscomp$0.expirationTime, - firstContext: - renderExpirationTime$jscomp$0.firstContext, - responders: - renderExpirationTime$jscomp$0.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - current$$1 - ); - current$$1 = current$$1.child; - break a; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(internalInstanceHandle)), - null !== current) - ) { - if ( - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((current$$1.updateQueue = current), - (current$$1.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !internalInstanceHandle.alternate) - ) { - current$$1 = current$$1.lastEffect = newProps.lastEffect; - null !== current$$1 && (current$$1.nextEffect = null); - break; - } - } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (current$$1.expirationTime = current$$1.childExpirationTime = - renderExpirationTime$jscomp$0 - 1)); - newProps.isBackwards - ? ((internalInstanceHandle.sibling = current$$1.child), - (current$$1.child = internalInstanceHandle)) - : ((current = newProps.last), - null !== current - ? (current.sibling = internalInstanceHandle) - : (current$$1.child = internalInstanceHandle), - (newProps.last = internalInstanceHandle)); - } - if (null !== newProps.tail) { - 0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500); - current = newProps.tail; - newProps.rendering = current; - newProps.tail = current.sibling; - newProps.lastEffect = current$$1.lastEffect; - current.sibling = null; - newProps = suspenseStackCursor.current; - newProps = rootContainerInstance - ? (newProps & 1) | 2 - : newProps & 1; - push(suspenseStackCursor, newProps, current$$1); - current$$1 = current; - break a; - } - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - current$$1.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - current$$1 = null; - } - current = workInProgress; - if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { - newProps = 0; + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); + var completedWork = workInProgress; + if ( + 1 === renderExpirationTime || + 1 !== completedWork.childExpirationTime + ) { for ( - rootContainerInstance = current.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = completedWork.child; + null !== _child; - ) - (renderExpirationTime$jscomp$0 = - rootContainerInstance.expirationTime), - (internalInstanceHandle = - rootContainerInstance.childExpirationTime), - renderExpirationTime$jscomp$0 > newProps && - (newProps = renderExpirationTime$jscomp$0), - internalInstanceHandle > newProps && - (newProps = internalInstanceHandle), - (rootContainerInstance = rootContainerInstance.sibling); - current.childExpirationTime = newProps; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + completedWork.childExpirationTime = newChildExpirationTime; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -6474,7 +6461,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6585,97 +6573,34 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$0, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - var current$$1$jscomp$1 = nextEffect.alternate; - current$$1 = nextEffect; - currentRef = effectTag; - switch (current$$1.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, current$$1); - break; - case 1: - var instance = current$$1.stateNode; - if (current$$1.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - current$$1.elementType === current$$1.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - current$$1.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = current$$1.updateQueue; - null !== updateQueue && - commitUpdateQueue( - current$$1, - updateQueue, - instance, - currentRef - ); - break; - case 3: - var _updateQueue = current$$1.updateQueue; - if (null !== _updateQueue) { - root = null; - if (null !== current$$1.child) - switch (current$$1.child.tag) { - case 5: - root = current$$1.child.stateNode; - break; - case 1: - root = current$$1.child.stateNode; - } - commitUpdateQueue(current$$1, _updateQueue, root, currentRef); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0; + currentRef = instance; break; default: - current$$1 = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6764,6 +6689,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6973,6 +6899,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7010,62 +6937,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7103,16 +7031,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7596,6 +7525,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7916,11 +7848,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7929,6 +7867,7 @@ var roots = new Map(), var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8088,7 +8027,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-experimental-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index 4cc776abd951fd..df962ae5daff6e 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -503,53 +503,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -682,13 +656,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1149,7 +1117,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1214,6 +1183,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -2007,237 +1978,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2254,10 +2183,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2372,6 +2299,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2379,16 +2307,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2404,16 +2324,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2975,39 +2892,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3205,7 +3133,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3213,13 +3141,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3239,53 +3161,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3294,37 +3208,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3352,51 +3271,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3406,7 +3349,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3423,21 +3366,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3457,7 +3402,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3505,6 +3450,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3546,14 +3506,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3616,7 +3573,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3635,23 +3592,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3659,25 +3614,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3719,23 +3662,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3743,25 +3684,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4075,17 +4004,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4131,6 +4057,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4159,17 +4086,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4471,6 +4395,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4479,6 +4404,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4685,38 +4611,348 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { + var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: - return popHostContext(workInProgress), null; + popHostContext(workInProgress); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent$1( + current, + workInProgress, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== workInProgress.ref && + (workInProgress.effectTag |= 128); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } + current = requiredContext(contextStackCursor$1.current); + var tag = allocateTag(), + viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + tag, + viewConfig.uiViewClassName, + rootContainerInstance, + updatePayload + ); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, workInProgress, !1, !1); + workInProgress.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (workInProgress.effectTag |= 4); + null !== workInProgress.ref && (workInProgress.effectTag |= 128); + } + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText$1( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + rootContainerInstance = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + rootContainerInstance, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; + } + return null; case 13: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.effectTag & 64)) + return ( + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress + ); + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; + return null; + case 4: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; + case 10: + return popProvider(workInProgress), null; + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + tag = newProps.rendering; + if (null === tag) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + tag = findFirstSuspended(current); + if (null !== tag) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = tag.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (tag = rootContainerInstance.alternate), + null === tag + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + tag.childExpirationTime), + (rootContainerInstance.expirationTime = + tag.expirationTime), + (rootContainerInstance.child = tag.child), + (rootContainerInstance.memoizedProps = + tag.memoizedProps), + (rootContainerInstance.memoizedState = + tag.memoizedState), + (rootContainerInstance.updateQueue = tag.updateQueue), + (renderExpirationTime$jscomp$0 = tag.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !tag.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); + } else + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + : ((current = newProps.last), + null !== current + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); + } + return null !== newProps.tail + ? (0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress + ), + current) + : null; + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor, workInProgress), null; case 4: return popHostContainer(workInProgress), null; case 10: @@ -4800,8 +5036,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -4815,18 +5052,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -4845,6 +5081,86 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4853,6 +5169,7 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && @@ -4911,6 +5228,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5177,10 +5495,11 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); - break; + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { @@ -5204,7 +5523,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5215,11 +5534,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5289,21 +5608,16 @@ function commitWork(current$$1, finishedWork) { current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5775,44 +6089,41 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || - prepareFreshStack(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -5898,8 +6209,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6067,361 +6385,30 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - a: { - var current = current$$1; - current$$1 = workInProgress; - var renderExpirationTime$jscomp$0 = renderExpirationTime, - newProps = current$$1.pendingProps; - switch (current$$1.tag) { - case 2: - break; - case 16: - break; - case 15: - case 0: - break; - case 1: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 3: - popHostContainer(current$$1); - popTopLevelContextObject(current$$1); - current = current$$1.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(current$$1); - break; - case 5: - popHostContext(current$$1); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime$jscomp$0 = current$$1.type; - if (null !== current && null != current$$1.stateNode) - updateHostComponent$1( - current, - current$$1, - renderExpirationTime$jscomp$0, - newProps, - rootContainerInstance - ), - current.ref !== current$$1.ref && (current$$1.effectTag |= 128); - else if (newProps) { - current = requiredContext(contextStackCursor$1.current); - var internalInstanceHandle = current$$1, - tag = allocateTag(), - viewConfig = getViewConfigForType( - renderExpirationTime$jscomp$0 - ), - updatePayload = diffProperties( - null, - emptyObject, - newProps, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - tag, - viewConfig.uiViewClassName, - rootContainerInstance, - updatePayload - ); - viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); - instanceCache.set(tag, internalInstanceHandle); - instanceProps.set(tag, newProps); - appendAllChildren(viewConfig, current$$1, !1, !1); - current$$1.stateNode = viewConfig; - finalizeInitialChildren( - viewConfig, - renderExpirationTime$jscomp$0, - newProps, - rootContainerInstance, - current - ) && (current$$1.effectTag |= 4); - null !== current$$1.ref && (current$$1.effectTag |= 128); - } else if (null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; - case 6: - if (current && null != current$$1.stateNode) - updateHostText$1( - current, - current$$1, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === current$$1.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - renderExpirationTime$jscomp$0 = requiredContext( - rootInstanceStackCursor.current - ); - rootContainerInstance = requiredContext( - contextStackCursor$1.current - ); - current = current$$1; - if (!rootContainerInstance.isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - rootContainerInstance = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, - "RCTRawText", - renderExpirationTime$jscomp$0, - { text: newProps } - ); - instanceCache.set(rootContainerInstance, current$$1); - current.stateNode = rootContainerInstance; - } - break; - case 11: - break; - case 13: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (0 !== (current$$1.effectTag & 64)) { - current$$1.expirationTime = renderExpirationTime$jscomp$0; - break a; - } - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), - newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = current.child.sibling), - null !== renderExpirationTime$jscomp$0 && - ((internalInstanceHandle = current$$1.firstEffect), - null !== internalInstanceHandle - ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = internalInstanceHandle)) - : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), - (renderExpirationTime$jscomp$0.nextEffect = null)), - (renderExpirationTime$jscomp$0.effectTag = 8)))); - if ( - newProps && - !rootContainerInstance && - 0 !== (current$$1.mode & 2) - ) - if ( - (null === current && - !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) current$$1.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; - case 4: - popHostContainer(current$$1); - updateHostContainer(current$$1); - break; - case 10: - popProvider(current$$1); - break; - case 9: - break; - case 14: - break; - case 17: - isContextProvider(current$$1.type) && popContext(current$$1); - break; - case 19: - pop(suspenseStackCursor, current$$1); - newProps = current$$1.memoizedState; - if (null === newProps) break; - rootContainerInstance = 0 !== (current$$1.effectTag & 64); - internalInstanceHandle = newProps.rendering; - if (null === internalInstanceHandle) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = current$$1.child; null !== current; ) { - internalInstanceHandle = findFirstSuspended(current); - if (null !== internalInstanceHandle) { - current$$1.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = internalInstanceHandle.updateQueue; - null !== current && - ((current$$1.updateQueue = current), - (current$$1.effectTag |= 4)); - null === newProps.lastEffect && - (current$$1.firstEffect = null); - current$$1.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; - for (newProps = current$$1.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime$jscomp$0 = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (internalInstanceHandle = - rootContainerInstance.alternate), - null === internalInstanceHandle - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - internalInstanceHandle.childExpirationTime), - (rootContainerInstance.expirationTime = - internalInstanceHandle.expirationTime), - (rootContainerInstance.child = - internalInstanceHandle.child), - (rootContainerInstance.memoizedProps = - internalInstanceHandle.memoizedProps), - (rootContainerInstance.memoizedState = - internalInstanceHandle.memoizedState), - (rootContainerInstance.updateQueue = - internalInstanceHandle.updateQueue), - (renderExpirationTime$jscomp$0 = - internalInstanceHandle.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime$jscomp$0 - ? null - : { - expirationTime: - renderExpirationTime$jscomp$0.expirationTime, - firstContext: - renderExpirationTime$jscomp$0.firstContext, - responders: - renderExpirationTime$jscomp$0.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - current$$1 - ); - current$$1 = current$$1.child; - break a; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(internalInstanceHandle)), - null !== current) - ) { - if ( - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((current$$1.updateQueue = current), - (current$$1.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !internalInstanceHandle.alternate) - ) { - current$$1 = current$$1.lastEffect = newProps.lastEffect; - null !== current$$1 && (current$$1.nextEffect = null); - break; - } - } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && - ((current$$1.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (current$$1.expirationTime = current$$1.childExpirationTime = - renderExpirationTime$jscomp$0 - 1)); - newProps.isBackwards - ? ((internalInstanceHandle.sibling = current$$1.child), - (current$$1.child = internalInstanceHandle)) - : ((current = newProps.last), - null !== current - ? (current.sibling = internalInstanceHandle) - : (current$$1.child = internalInstanceHandle), - (newProps.last = internalInstanceHandle)); - } - if (null !== newProps.tail) { - 0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500); - current = newProps.tail; - newProps.rendering = current; - newProps.tail = current.sibling; - newProps.lastEffect = current$$1.lastEffect; - current.sibling = null; - newProps = suspenseStackCursor.current; - newProps = rootContainerInstance - ? (newProps & 1) | 2 - : newProps & 1; - push(suspenseStackCursor, newProps, current$$1); - current$$1 = current; - break a; - } - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - current$$1.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - current$$1 = null; - } - current = workInProgress; - if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { - newProps = 0; + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); + var completedWork = workInProgress; + if ( + 1 === renderExpirationTime || + 1 !== completedWork.childExpirationTime + ) { for ( - rootContainerInstance = current.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = completedWork.child; + null !== _child; - ) - (renderExpirationTime$jscomp$0 = - rootContainerInstance.expirationTime), - (internalInstanceHandle = - rootContainerInstance.childExpirationTime), - renderExpirationTime$jscomp$0 > newProps && - (newProps = renderExpirationTime$jscomp$0), - internalInstanceHandle > newProps && - (newProps = internalInstanceHandle), - (rootContainerInstance = rootContainerInstance.sibling); - current.childExpirationTime = newProps; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + completedWork.childExpirationTime = newChildExpirationTime; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -6464,7 +6451,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6575,97 +6563,34 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$0, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - var current$$1$jscomp$1 = nextEffect.alternate; - current$$1 = nextEffect; - currentRef = effectTag; - switch (current$$1.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, current$$1); - break; - case 1: - var instance = current$$1.stateNode; - if (current$$1.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - current$$1.elementType === current$$1.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - current$$1.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = current$$1.updateQueue; - null !== updateQueue && - commitUpdateQueue( - current$$1, - updateQueue, - instance, - currentRef - ); - break; - case 3: - var _updateQueue = current$$1.updateQueue; - if (null !== _updateQueue) { - root = null; - if (null !== current$$1.child) - switch (current$$1.child.tag) { - case 5: - root = current$$1.child.stateNode; - break; - case 1: - root = current$$1.child.stateNode; - } - commitUpdateQueue(current$$1, _updateQueue, root, currentRef); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0; + currentRef = instance; break; default: - current$$1 = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6754,6 +6679,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -6963,6 +6889,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7000,62 +6927,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7093,16 +7021,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7586,6 +7515,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7906,11 +7838,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -7919,6 +7857,7 @@ var roots = new Map(), var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8078,7 +8017,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index b6719c3c3ecd50..955ccea4e41fec 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -503,53 +503,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -682,13 +656,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1160,7 +1128,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1225,6 +1194,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -2038,237 +2009,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2285,10 +2214,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2403,6 +2330,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2410,16 +2338,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2435,16 +2355,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -3006,39 +2923,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3236,7 +3164,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3244,13 +3172,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3270,53 +3192,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3325,37 +3239,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3383,51 +3302,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3437,7 +3380,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3454,21 +3397,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3488,7 +3433,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3536,6 +3481,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3577,14 +3537,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3647,7 +3604,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3666,23 +3623,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3690,25 +3645,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3750,23 +3693,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3774,25 +3715,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4117,17 +4046,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4173,6 +4099,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4201,17 +4128,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4531,6 +4455,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4539,6 +4464,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4750,24 +4676,32 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( @@ -4784,7 +4718,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } current = requiredContext(contextStackCursor$1.current); var tag = allocateTag(), viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), @@ -4813,11 +4754,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { current ) && (workInProgress.effectTag |= 4); null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } else if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4846,9 +4784,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - break; - case 11: - break; + return null; case 13: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; @@ -4896,31 +4832,24 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { )); } if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 19: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); tag = newProps.rendering; if (null === tag) @@ -5012,13 +4941,15 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !tag.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5036,14 +4967,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = tag), (newProps.last = tag)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + return null !== newProps.tail + ? (0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), (current.sibling = null), (newProps = suspenseStackCursor.current), push( @@ -5051,21 +4982,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, workInProgress ), - current - ); - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + current) + : null; } - return null; + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5182,8 +5106,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -5197,18 +5122,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -5227,6 +5151,97 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + committedExpirationTime = finishedWork.memoizedProps.onRender; + "function" === typeof committedExpirationTime && + committedExpirationTime( + finishedWork.memoizedProps.id, + null === current$$1 ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -5235,6 +5250,7 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && @@ -5293,6 +5309,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5559,10 +5576,11 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); - break; + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { @@ -5586,7 +5604,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5597,11 +5615,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5671,21 +5689,16 @@ function commitWork(current$$1, finishedWork) { current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -6158,47 +6171,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), prepareFreshStack(root, lastExpiredTime), - startWorkOnPendingInteractions(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root), - prevInteractions = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - tracing.__interactionsRef.current = prevInteractions; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -6287,8 +6297,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6572,7 +6589,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6691,103 +6709,24 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - renderPriorityLevel = effectTag; - var current$$1$jscomp$1 = nextEffect.alternate; - currentRef = nextEffect; - root = current$$1; - switch (currentRef.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, currentRef); - break; - case 1: - var instance = currentRef.stateNode; - if (currentRef.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - currentRef.elementType === currentRef.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - currentRef.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = currentRef.updateQueue; - null !== updateQueue && - commitUpdateQueue(currentRef, updateQueue, instance, root); - break; - case 3: - var _updateQueue = currentRef.updateQueue; - if (null !== _updateQueue) { - renderPriorityLevel = null; - if (null !== currentRef.child) - switch (currentRef.child.tag) { - case 5: - renderPriorityLevel = currentRef.child.stateNode; - break; - case 1: - renderPriorityLevel = currentRef.child.stateNode; - } - commitUpdateQueue( - currentRef, - _updateQueue, - renderPriorityLevel, - root - ); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = currentRef.memoizedProps.onRender; - "function" === typeof onRender && - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - renderPriorityLevel.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0; + currentRef = instance; break; default: - currentRef = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref ? ref(currentRef) @@ -6827,13 +6766,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6905,6 +6844,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -7127,6 +7067,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7164,62 +7105,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7257,16 +7199,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7845,6 +7788,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -8168,11 +8114,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -8183,6 +8135,7 @@ var roots = new Map(), uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8342,7 +8295,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-experimental-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index f6ef2ae04e6e38..2d39130d44b105 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -504,53 +504,27 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + touchRecord && + ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord - ? ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.warn( - "Cannot record touch end without a touch start.\nTouch End: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); -} -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, 20)); - 20 < touchBank.length && - (printed += " (original size: " + touchBank.length + ")"); - return printed; + touchRecord && + ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -683,13 +657,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -1150,7 +1118,8 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, + REACT_CHUNK_TYPE = hasSymbol ? Symbol.for("react.chunk") : 60121; hasSymbol && Symbol.for("react.fundamental"); hasSymbol && Symbol.for("react.responder"); hasSymbol && Symbol.for("react.scope"); @@ -1215,6 +1184,8 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); + case REACT_CHUNK_TYPE: + return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -2028,237 +1999,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -function cloneUpdateQueue(currentQueue) { - return { - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; +function cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, update) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update), - appendUpdateToQueue(queue2, update)) - : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); + fiber = fiber.updateQueue; + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; + } } function enqueueCapturedUpdate(workInProgress, update) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); -} -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; -} -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - hasForceUpdate = !0; - } - return prevState; + null !== current && cloneUpdateQueue(current, workInProgress); + workInProgress = workInProgress.updateQueue; + current = workInProgress.baseQueue; + null === current + ? ((workInProgress.baseQueue = update.next = update), + (update.next = update)) + : ((update.next = current.next), (current.next = update)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - - ) { - var updateExpirationTime = update.expirationTime; - updateExpirationTime < renderExpirationTime - ? (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - newExpirationTime < updateExpirationTime && - (newExpirationTime = updateExpirationTime)) - : (markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ), - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update)))); - update = update.next; + var baseQueue = queue.baseQueue, + pendingQueue = queue.shared.pending; + if (null !== pendingQueue) { + if (null !== baseQueue) { + var baseFirst = baseQueue.next; + baseQueue.next = pendingQueue.next; + pendingQueue.next = baseFirst; + } + baseQueue = pendingQueue; + queue.shared.pending = null; + baseFirst = workInProgress$jscomp$0.alternate; + null !== baseFirst && + ((baseFirst = baseFirst.updateQueue), + null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - _updateExpirationTime < renderExpirationTime - ? (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - newExpirationTime < _updateExpirationTime && - (newExpirationTime = _updateExpirationTime)) - : ((resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update)))); - update = update.next; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + newExpirationTime = 0, + newBaseState = null, + newBaseQueueFirst = null, + newBaseQueueLast = null; + if (null !== baseFirst) { + var update = baseFirst; + do { + pendingQueue = update.expirationTime; + if (pendingQueue < renderExpirationTime) { + var clone = { + expirationTime: update.expirationTime, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + null === newBaseQueueLast + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (newBaseState = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + pendingQueue > newExpirationTime && + (newExpirationTime = pendingQueue); + } else { + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: update.suspenseConfig, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }); + markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); + a: { + var workInProgress = workInProgress$jscomp$0, + update$jscomp$0 = update; + pendingQueue = props; + clone = instance; + switch (update$jscomp$0.tag) { + case 1: + workInProgress = update$jscomp$0.payload; + if ("function" === typeof workInProgress) { + newState = workInProgress.call(clone, newState, pendingQueue); + break a; + } + newState = workInProgress; + break a; + case 3: + workInProgress.effectTag = + (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update$jscomp$0.payload; + pendingQueue = + "function" === typeof workInProgress + ? workInProgress.call(clone, newState, pendingQueue) + : workInProgress; + if (null === pendingQueue || void 0 === pendingQueue) break a; + newState = Object.assign({}, newState, pendingQueue); + break a; + case 2: + hasForceUpdate = !0; + } + } + null !== update.callback && + ((workInProgress$jscomp$0.effectTag |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [update]) + : pendingQueue.push(update)); + } + update = update.next; + if (null === update || update === baseFirst) + if (((pendingQueue = queue.shared.pending), null === pendingQueue)) + break; + else + (update = baseQueue.next = pendingQueue.next), + (pendingQueue.next = baseFirst), + (queue.baseQueue = baseQueue = pendingQueue), + (queue.shared.pending = null); + } while (1); + } + null === newBaseQueueLast + ? (newBaseState = newState) + : (newBaseQueueLast.next = newBaseQueueFirst); + queue.baseState = newBaseState; + queue.baseQueue = newBaseQueueLast; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress$jscomp$0.expirationTime = newExpirationTime; + workInProgress$jscomp$0.memoizedState = newState; } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - commitUpdateEffects(finishedQueue.firstEffect, instance); - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; -} -function commitUpdateEffects(effect, instance) { - for (; null !== effect; ) { - var callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); + finishedWork = finishedQueue.effects; + finishedQueue.effects = null; + if (null !== finishedWork) + for ( + finishedQueue = 0; + finishedQueue < finishedWork.length; + finishedQueue++ + ) { + var effect = finishedWork[finishedQueue], + callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2275,10 +2204,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2393,6 +2320,7 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2400,16 +2328,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2425,16 +2345,13 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } @@ -2996,39 +2913,50 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) - if ( - 7 === isUnkeyedTopLevelFragment.tag - ? newChild.type === REACT_FRAGMENT_TYPE - : isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.type === REACT_FRAGMENT_TYPE - ? newChild.props.children - : newChild.props, - expirationTime - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } else { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment - ); - break; + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children, + expirationTime + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3226,7 +3154,7 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, @@ -3234,13 +3162,7 @@ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, didScheduleRenderPhaseUpdate = !1, renderPhaseUpdates = null, numberOfReRenders = 0; @@ -3260,53 +3182,45 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = null !== current ? current.memoizedState : null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = 0; ReactCurrentDispatcher$1.current = - null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; - workInProgress = Component(props, refOrContext); + null === current || null === current.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate; + current = Component(props, secondArg); if (didScheduleRenderPhaseUpdate) { do (didScheduleRenderPhaseUpdate = !1), (numberOfReRenders += 1), - (nextCurrentHook = null !== current ? current.memoizedState : null), - (nextWorkInProgressHook = firstWorkInProgressHook), - (componentUpdateQueue = workInProgressHook = currentHook = null), + (workInProgressHook = currentHook = null), + (workInProgress.updateQueue = null), (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), - (workInProgress = Component(props, refOrContext)); + (current = Component(props, secondArg)); while (didScheduleRenderPhaseUpdate); renderPhaseUpdates = null; numberOfReRenders = 0; } ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; - current = currentlyRenderingFiber$1; - current.memoizedState = firstWorkInProgressHook; - current.expirationTime = remainingExpirationTime; - current.updateQueue = componentUpdateQueue; - current.effectTag |= sideEffectTag; - current = null !== currentHook && null !== currentHook.next; + workInProgress = null !== currentHook && null !== currentHook.next; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; - if (current) + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return workInProgress; + return current; } function resetHooks() { ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; renderExpirationTime$1 = 0; - nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; - remainingExpirationTime = 0; - componentUpdateQueue = null; - sideEffectTag = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; didScheduleRenderPhaseUpdate = !1; renderPhaseUpdates = null; numberOfReRenders = 0; @@ -3315,37 +3229,42 @@ function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { + if (null === currentHook) { + var nextCurrentHook = currentlyRenderingFiber$1.alternate; + nextCurrentHook = + null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook = + null === workInProgressHook + ? currentlyRenderingFiber$1.memoizedState + : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3373,51 +3292,75 @@ function updateReducer(reducer) { while (null !== firstRenderPhaseUpdate); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate === queue.last && (hook.baseState = newState); + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; return [newState, _dispatch]; } } return [hook.memoizedState, _dispatch]; } - _dispatch = queue.last; - var baseUpdate = hook.baseUpdate; - newState = hook.baseState; - null !== baseUpdate - ? (null !== _dispatch && (_dispatch.next = null), - (_dispatch = baseUpdate.next)) - : (_dispatch = null !== _dispatch ? _dispatch.next : null); + newState = currentHook; + _dispatch = newState.baseQueue; + firstRenderPhaseUpdate = queue.pending; + if (null !== firstRenderPhaseUpdate) { + if (null !== _dispatch) { + var baseFirst = _dispatch.next; + _dispatch.next = firstRenderPhaseUpdate.next; + firstRenderPhaseUpdate.next = baseFirst; + } + newState.baseQueue = _dispatch = firstRenderPhaseUpdate; + queue.pending = null; + } if (null !== _dispatch) { - var newBaseUpdate = (firstRenderPhaseUpdate = null), - _update = _dispatch, - didSkip = !1; + _dispatch = _dispatch.next; + newState = newState.baseState; + var newBaseQueueLast = (baseFirst = firstRenderPhaseUpdate = null), + _update = _dispatch; do { var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + if (updateExpirationTime < renderExpirationTime$1) { + var clone = { + expirationTime: _update.expirationTime, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }; + null === newBaseQueueLast + ? ((baseFirst = newBaseQueueLast = clone), + (firstRenderPhaseUpdate = newState)) + : (newBaseQueueLast = newBaseQueueLast.next = clone); + updateExpirationTime > currentlyRenderingFiber$1.expirationTime && + ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), + markUnprocessedUpdateTime(updateExpirationTime)); + } else + null !== newBaseQueueLast && + (newBaseQueueLast = newBaseQueueLast.next = { + expirationTime: 1073741823, + suspenseConfig: _update.suspenseConfig, + action: _update.action, + eagerReducer: _update.eagerReducer, + eagerState: _update.eagerState, + next: null + }), + markRenderEventTimeAndConfig( updateExpirationTime, _update.suspenseConfig ), (newState = _update.eagerReducer === reducer ? _update.eagerState - : reducer(newState, _update.action))); - baseUpdate = _update; + : reducer(newState, _update.action)); _update = _update.next; } while (null !== _update && _update !== _dispatch); - didSkip || - ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + null === newBaseQueueLast + ? (firstRenderPhaseUpdate = newState) + : (newBaseQueueLast.next = baseFirst); is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; hook.baseState = firstRenderPhaseUpdate; + hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; } return [hook.memoizedState, queue.dispatch]; @@ -3427,7 +3370,7 @@ function mountState(initialState) { "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3444,21 +3387,23 @@ function updateState(initialState) { } function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - null === componentUpdateQueue - ? ((componentUpdateQueue = { lastEffect: null }), - (componentUpdateQueue.lastEffect = tag.next = tag)) - : ((create = componentUpdateQueue.lastEffect), - null === create - ? (componentUpdateQueue.lastEffect = tag.next = tag) - : ((destroy = create.next), - (create.next = tag), - (tag.next = destroy), - (componentUpdateQueue.lastEffect = tag))); + create = currentlyRenderingFiber$1.updateQueue; + null === create + ? ((create = { lastEffect: null }), + (currentlyRenderingFiber$1.updateQueue = create), + (create.lastEffect = tag.next = tag)) + : ((destroy = create.lastEffect), + null === destroy + ? (create.lastEffect = tag.next = tag) + : ((deps = destroy.next), + (destroy.next = tag), + (tag.next = deps), + (create.lastEffect = tag))); return tag; } function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( hookEffectTag, create, @@ -3478,7 +3423,7 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { return; } } - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { @@ -3526,6 +3471,21 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } +function startTransition(setPending, config, callback) { + var priorityLevel = getCurrentPriorityLevel(); + runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { + setPending(!0); + }); + runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); +} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw Error( @@ -3567,14 +3527,11 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }; - var last = queue.last; - if (null === last) suspenseConfig.next = suspenseConfig; - else { - var first = last.next; - null !== first && (suspenseConfig.next = first); - last.next = suspenseConfig; - } - queue.last = suspenseConfig; + var pending = queue.pending; + null === pending + ? (suspenseConfig.next = suspenseConfig) + : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); + queue.pending = suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3637,7 +3594,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3656,23 +3613,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3680,25 +3635,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - mountCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; } @@ -3740,23 +3683,21 @@ var ContextOnlyDispatcher = { }, useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3764,25 +3705,13 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _updateState2 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - updateCallback( - function(callback) { - setPending(!0); - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; } @@ -4107,17 +4036,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4163,6 +4089,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current$$1, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4191,17 +4118,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4521,6 +4445,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4529,6 +4454,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4740,24 +4666,32 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + popTopLevelContextObject(workInProgress), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null + ); case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( @@ -4774,7 +4708,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + return null; + } current = requiredContext(contextStackCursor$1.current); var tag = allocateTag(), viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), @@ -4803,11 +4744,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { current ) && (workInProgress.effectTag |= 4); null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } else if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - break; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4836,9 +4774,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - break; - case 11: - break; + return null; case 13: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; @@ -4886,31 +4822,24 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { )); } if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return ( + popHostContainer(workInProgress), + updateHostContainer(workInProgress), + null + ); case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return ( + isContextProvider(workInProgress.type) && popContext(workInProgress), + null + ); case 19: pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); tag = newProps.rendering; if (null === tag) @@ -5002,13 +4931,15 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !tag.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5026,14 +4957,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = tag), (newProps.last = tag)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + return null !== newProps.tail + ? (0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), (current.sibling = null), (newProps = suspenseStackCursor.current), push( @@ -5041,21 +4972,14 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, workInProgress ), - current - ); - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + current) + : null; } - return null; + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5172,8 +5096,9 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case 0: case 11: case 15: + case 22: commitHookEffectList(2, 0, finishedWork); - break; + return; case 1: if (finishedWork.effectTag & 256 && null !== current$$1) { var prevProps = current$$1.memoizedProps, @@ -5187,18 +5112,17 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { ); current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; @@ -5217,6 +5141,97 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + case 22: + commitHookEffectList(16, 32, finishedWork); + return; + case 1: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current$$1) finishedRoot.componentDidMount(); + else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + finishedRoot.componentDidUpdate( + prevProps, + current$$1.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + current$$1 = finishedWork.updateQueue; + null !== current$$1 && + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + return; + case 3: + current$$1 = finishedWork.updateQueue; + if (null !== current$$1) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue( + finishedWork, + current$$1, + finishedRoot, + committedExpirationTime + ); + } + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + committedExpirationTime = finishedWork.memoizedProps.onRender; + "function" === typeof committedExpirationTime && + committedExpirationTime( + finishedWork.memoizedProps.id, + null === current$$1 ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + return; + } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -5225,6 +5240,7 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { case 11: case 14: case 15: + case 22: finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && @@ -5283,6 +5299,7 @@ function detachFiber(current$$1) { current$$1.lastEffect = null; current$$1.pendingProps = null; current$$1.memoizedProps = null; + current$$1.stateNode = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5549,10 +5566,11 @@ function commitWork(current$$1, finishedWork) { case 11: case 14: case 15: + case 22: commitHookEffectList(4, 8, finishedWork); - break; + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { @@ -5576,7 +5594,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5587,11 +5605,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5661,21 +5679,16 @@ function commitWork(current$$1, finishedWork) { current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - break; - case 20: - break; - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -6148,47 +6161,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) { function performSyncWorkOnRoot(root) { var lastExpiredTime = root.lastExpiredTime; lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; - if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); - else { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), prepareFreshStack(root, lastExpiredTime), - startWorkOnPendingInteractions(root, lastExpiredTime); - if (null !== workInProgress) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root), - prevInteractions = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher.current = prevDispatcher; - tracing.__interactionsRef.current = prevInteractions; - if (workInProgressRootExitStatus === RootFatalErrored) - throw ((prevExecutionContext = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - prevExecutionContext); - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - workInProgressRoot = null; - commitRoot(root); - ensureRootIsScheduled(root); - } + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } return null; } @@ -6277,8 +6287,15 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + var thenable = value; + if (0 === (sourceFiber.mode & 2)) { + var currentSource = sourceFiber.alternate; + currentSource + ? ((sourceFiber.memoizedState = currentSource.memoizedState), + (sourceFiber.expirationTime = currentSource.expirationTime)) + : (sourceFiber.memoizedState = null); + } + var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6562,7 +6579,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6681,103 +6699,24 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag$jscomp$0 = nextEffect.effectTag; - if (effectTag$jscomp$0 & 36) { - renderPriorityLevel = effectTag; - var current$$1$jscomp$1 = nextEffect.alternate; - currentRef = nextEffect; - root = current$$1; - switch (currentRef.tag) { - case 0: - case 11: - case 15: - commitHookEffectList(16, 32, currentRef); - break; - case 1: - var instance = currentRef.stateNode; - if (currentRef.effectTag & 4) - if (null === current$$1$jscomp$1) - instance.componentDidMount(); - else { - var prevProps = - currentRef.elementType === currentRef.type - ? current$$1$jscomp$1.memoizedProps - : resolveDefaultProps( - currentRef.type, - current$$1$jscomp$1.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current$$1$jscomp$1.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = currentRef.updateQueue; - null !== updateQueue && - commitUpdateQueue(currentRef, updateQueue, instance, root); - break; - case 3: - var _updateQueue = currentRef.updateQueue; - if (null !== _updateQueue) { - renderPriorityLevel = null; - if (null !== currentRef.child) - switch (currentRef.child.tag) { - case 5: - renderPriorityLevel = currentRef.child.stateNode; - break; - case 1: - renderPriorityLevel = currentRef.child.stateNode; - } - commitUpdateQueue( - currentRef, - _updateQueue, - renderPriorityLevel, - root - ); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = currentRef.memoizedProps.onRender; - "function" === typeof onRender && - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - renderPriorityLevel.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 20: - case 21: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles( + effectTag, + nextEffect.alternate, + nextEffect, + current$$1 + ); if (effectTag$jscomp$0 & 128) { currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0; + currentRef = instance; break; default: - currentRef = instance$jscomp$0; + currentRef = instance; } "function" === typeof ref ? ref(currentRef) @@ -6817,13 +6756,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6895,6 +6834,7 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: + case 22: commitHookEffectList(128, 0, finishedWork), commitHookEffectList(0, 64, finishedWork); } @@ -7117,6 +7057,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== renderState.state && void 0 !== renderState.state ? renderState.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7154,62 +7095,63 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { (workInProgress = workInProgress.child); return workInProgress; case 16: - renderState = workInProgress.elementType; - null !== current$$1 && - ((current$$1.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - initializeLazyComponentType(renderState); - if (1 !== renderState._status) throw renderState._result; - renderState = renderState._result; - workInProgress.type = renderState; - hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); - current$$1 = resolveDefaultProps(renderState, current$$1); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - renderState, - current$$1, - renderExpirationTime - ); - break; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - renderState, - resolveDefaultProps(renderState.type, current$$1), - updateExpirationTime, - renderExpirationTime - ); - break; - default: - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - renderState + - ". Lazy element type must resolve to a class or function." - ); + a: { + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break a; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break a; + } + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: @@ -7247,16 +7189,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current$$1 || null === updateExpirationTime) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); + updateExpirationTime = workInProgress.pendingProps; renderState = workInProgress.memoizedState; renderState = null !== renderState ? renderState.element : null; + cloneUpdateQueue(current$$1, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); @@ -7835,6 +7778,9 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; + case REACT_CHUNK_TYPE: + fiberTag = 22; + break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -8158,11 +8104,17 @@ var roots = new Map(), findNodeHandle: findNodeHandle, dispatchCommand: function(handle, command, args) { null != handle._nativeTag && - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); + (handle._internalInstanceHandle + ? nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ) + : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + )); }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); @@ -8173,6 +8125,7 @@ var roots = new Map(), uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -8332,7 +8285,7 @@ var roots = new Map(), throw Error("getInspectorDataForViewTag() is not available in production"); }, bundleType: 0, - version: "16.11.0", + version: "16.12.0-19f6fe170", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index cf20ce938c2760..013058a996e974 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -204,51 +204,3 @@ export type ReactFaricEvent = { target: number, ... }; - -export type ReactNativeResponderEvent = { - nativeEvent: ReactFaricEvent, - target: null | ReactNativeEventTarget, - type: string, - ... -}; - -export type ReactNativeResponderContext = { - dispatchEvent: ( - eventValue: any, - listener: (any) => void, - eventPriority: EventPriority, - ) => void, - isTargetWithinNode: ( - childTarget: ReactNativeEventTarget, - parentTarget: ReactNativeEventTarget, - ) => boolean, - getTargetBoundingRect( - target: ReactNativeEventTarget, - cb: ({ - left: number, - right: number, - top: number, - bottom: number, - ... - }) => void, - ): void, - addRootEventTypes: (rootEventTypes: Array) => void, - removeRootEventTypes: (rootEventTypes: Array) => void, - getTimeStamp: () => number, - getResponderNode(): ReactNativeEventTarget | null, - ... -}; - -export type PointerType = - | '' - | 'mouse' - | 'keyboard' - | 'pen' - | 'touch' - | 'trackpad'; - -export type EventPriority = 0 | 1 | 2; - -export const DiscreteEvent: EventPriority = 0; -export const UserBlockingEvent: EventPriority = 1; -export const ContinuousEvent: EventPriority = 2; diff --git a/package.json b/package.json index dc7aeba02ad726..e6381a2d9bb8c9 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "test-ios": "./scripts/objc-test.sh test" }, "peerDependencies": { - "react": "16.11.0" + "react": "16.12.0" }, "dependencies": { "@babel/runtime": "^7.0.0", @@ -112,7 +112,7 @@ "react-devtools-core": "^4.0.6", "react-refresh": "^0.4.0", "regenerator-runtime": "^0.13.2", - "scheduler": "0.17.0", + "scheduler": "0.18.0", "stacktrace-parser": "^0.1.3", "use-subscription": "^1.0.0", "whatwg-fetch": "^3.0.0" @@ -148,8 +148,8 @@ "jscodeshift": "^0.6.2", "mkdirp": "^0.5.1", "prettier": "1.17.0", - "react": "16.11.0", - "react-test-renderer": "16.11.0", + "react": "16.12.0", + "react-test-renderer": "16.12.0", "shelljs": "^0.7.8", "signedsource": "^1.0.0", "ws": "^6.1.4", diff --git a/template/package.json b/template/package.json index 513cd7474d888c..36fad4a1bb64f2 100644 --- a/template/package.json +++ b/template/package.json @@ -9,7 +9,7 @@ "test": "jest" }, "dependencies": { - "react": "16.11.0", + "react": "16.12.0", "react-native": "1000.0.0" }, "devDependencies": { @@ -19,7 +19,7 @@ "babel-jest": "^24.9.0", "jest": "^24.9.0", "metro-react-native-babel-preset": "^0.56.0", - "react-test-renderer": "16.11.0" + "react-test-renderer": "16.12.0" }, "jest": { "preset": "react-native" diff --git a/yarn.lock b/yarn.lock index 6dc7390b8a9555..facb8b1112f78d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6222,20 +6222,20 @@ react-refresh@^0.4.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.0.tgz#d421f9bd65e0e4b9822a399f14ac56bda9c92292" integrity sha512-bacjSio8GOtzNZKZZM6EWqbhlbb6pr28JWJWFTLwEBKvPIBRo6/Ob68D2EWZA2VyTdQxAh+TRnCYOPNKsQiXTA== -react-test-renderer@16.11.0: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.11.0.tgz#72574566496462c808ac449b0287a4c0a1a7d8f8" - integrity sha512-nh9gDl8R4ut+ZNNb2EeKO5VMvTKxwzurbSMuGBoKtjpjbg8JK/u3eVPVNi1h1Ue+eYK9oSzJjb+K3lzLxyA4ag== +react-test-renderer@16.12.0: + version "16.12.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f" + integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" react-is "^16.8.6" - scheduler "^0.17.0" + scheduler "^0.18.0" -react@16.11.0: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" - integrity sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g== +react@16.12.0: + version "16.12.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" + integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -6630,10 +6630,10 @@ sax@^1.2.1, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@0.17.0, scheduler@^0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" - integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== +scheduler@0.18.0, scheduler@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" + integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" From 5cd0c8a4d24142a248ae0c52c8dc8f0c5464e2b7 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Mon, 13 Jan 2020 11:13:01 -0800 Subject: [PATCH 0003/1126] Bump detox simulator version to work with latest xcode (#27733) Summary: The latest xcode version removed iPhone 6s, so we need to bump to the latest simulator listed that has 3d touch. ## Changelog [General] [Fix] - Bump e2e simulator version Pull Request resolved: https://github.com/facebook/react-native/pull/27733 Test Plan: - `yarn build-ios-e2e && yarn test-ios-e2e ` Reviewed By: hramos, sammy-SC Differential Revision: D19345576 Pulled By: rickhanlonii fbshipit-source-id: 428cb83ccb899409e972551f18df580174adee91 --- RNTester/RNTesterUnitTests/RCTJSONTests.m | 17 +++++++++-------- RNTester/e2e/__tests__/DatePickerIOS-test.js | 2 +- .../js/examples/Touchable/TouchableExample.js | 2 +- package.json | 4 ++-- scripts/.tests.env | 4 ++-- scripts/run-ci-e2e-tests.js | 4 ++-- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/RNTester/RNTesterUnitTests/RCTJSONTests.m b/RNTester/RNTesterUnitTests/RCTJSONTests.m index 2488e6acc9cb92..1b57668cb8711a 100644 --- a/RNTester/RNTesterUnitTests/RCTJSONTests.m +++ b/RNTester/RNTesterUnitTests/RCTJSONTests.m @@ -105,14 +105,15 @@ - (void)testNaN XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL)); } -- (void)testNotUTF8Convertible -{ - //see https://gist.github.com/0xced/56035d2f57254cf518b5 - NSString *string = [[NSString alloc] initWithBytes:"\xd8\x00" length:2 encoding:NSUTF16StringEncoding]; - NSDictionary *obj = @{@"foo": string}; - NSString *json = @"{\"foo\":null}"; - XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL)); -} +// TODO: This test crashes iOS 13 for bad access, please investigate and re-enable. +// - (void)testNotUTF8Convertible +// { +// //see https://gist.github.com/0xced/56035d2f57254cf518b5 +// NSString *string = [[NSString alloc] initWithBytes:"\xd8\x00" length:2 encoding:NSUTF16StringEncoding]; +// NSDictionary *obj = @{@"foo": string}; +// NSString *json = @"{\"foo\":null}"; +// XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL)); +// } - (void)testErrorPointer { diff --git a/RNTester/e2e/__tests__/DatePickerIOS-test.js b/RNTester/e2e/__tests__/DatePickerIOS-test.js index 6a7c961991aecf..11c73fcb2d5f4b 100644 --- a/RNTester/e2e/__tests__/DatePickerIOS-test.js +++ b/RNTester/e2e/__tests__/DatePickerIOS-test.js @@ -44,7 +44,7 @@ describe('DatePickerIOS', () => { await testElement.setColumnToValue(3, 'AM'); await expect(dateIndicator).toHaveText('12/4/2006'); - await expect(timeIndicator).toHaveText('4:10 AM'); + await expect(timeIndicator).toHaveText('04:10 AM'); }); it('Should change indicator with date-only picker', async () => { diff --git a/RNTester/js/examples/Touchable/TouchableExample.js b/RNTester/js/examples/Touchable/TouchableExample.js index 3fbecac3a14ed4..a9e38145b58249 100644 --- a/RNTester/js/examples/Touchable/TouchableExample.js +++ b/RNTester/js/examples/Touchable/TouchableExample.js @@ -582,7 +582,7 @@ exports.examples = [ { title: '3D Touch / Force Touch', description: - 'iPhone 6s and 6s plus support 3D touch, which adds a force property to touches', + 'iPhone 8 and 8 plus support 3D touch, which adds a force property to touches', render: function(): React.Element { return ; }, diff --git a/package.json b/package.json index e6381a2d9bb8c9..9ef9962e7be99b 100644 --- a/package.json +++ b/package.json @@ -164,13 +164,13 @@ "binaryPath": "RNTester/build/Build/Products/Release-iphonesimulator/RNTester.app/", "build": "xcodebuild -workspace RNTester/RNTesterPods.xcworkspace -scheme RNTester -configuration Release -sdk iphonesimulator -derivedDataPath RNTester/build -UseModernBuildSystem=NO -quiet", "type": "ios.simulator", - "name": "iPhone 6s" + "name": "iPhone 8" }, "ios.sim.debug": { "binaryPath": "RNTester/build/Build/Products/Debug-iphonesimulator/RNTester.app/", "build": "xcodebuild -workspace RNTester/RNTesterPods.xcworkspace -scheme RNTester -configuration Debug -sdk iphonesimulator -derivedDataPath RNTester/build -UseModernBuildSystem=NO -quiet", "type": "ios.simulator", - "name": "iPhone 6s" + "name": "iPhone 8" } } } diff --git a/scripts/.tests.env b/scripts/.tests.env index 94c746b31fec87..4b51b7246a4007 100644 --- a/scripts/.tests.env +++ b/scripts/.tests.env @@ -17,8 +17,8 @@ export AVD_NAME="testAVD" export AVD_ABI=x86 ## IOS ## -export IOS_TARGET_OS="12.4" -export IOS_DEVICE="iPhone 6s" +export IOS_TARGET_OS="13.3" +export IOS_DEVICE="iPhone 8" export TVOS_DEVICE="Apple TV" ## CI OVERRIDES ## diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index 2af2a54f6c5cc2..fabe50b206ba10 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -212,12 +212,12 @@ try { if ( tryExecNTimes( () => { - let destination = 'platform=iOS Simulator,name=iPhone 6s,OS=12.4'; + let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.3'; let sdk = 'iphonesimulator'; let scheme = 'HelloWorld'; if (argv.tvos) { - destination = 'platform=tvOS Simulator,name=Apple TV,OS=12.4'; + destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.3'; sdk = 'appletvsimulator'; scheme = 'HelloWorld-tvOS'; } From aa0ef15335fe27c0c193e3e968789886d82e82ed Mon Sep 17 00:00:00 2001 From: SAEED Date: Mon, 13 Jan 2020 12:51:47 -0800 Subject: [PATCH 0004/1126] Applied missing changes from bumping Gradle wrapper to 6.0.1 (#27639) Summary: This PR is related to https://github.com/facebook/react-native/issues/27290. I just upgraded my project's Gradle wrapper version to 6.0.1 and I realized some files have some differences with the files in react-native `template` folder. so I create this PR to apply differences. the main difference is in the `gradlew` file. I'm not familiar with Linux shell scripts but it seems there was a syntax error in `case` items syntax. `(` should not be used in declaring case's items. it may has building error in Linux OS. ## Changelog [Android] [Fixed] - Applied missing changes from bumping Gradle wrapper to 6.0.1 Pull Request resolved: https://github.com/facebook/react-native/pull/27639 Test Plan: I have no Linux OS right now, so I can't directly test these changes, but because the changes have made by running `gradlew wrapper` command, it should not break CI. (I hope :) ) Differential Revision: D19341671 Pulled By: cpojer fbshipit-source-id: ccfc3c12af3f5468671737e5ba0b1674b4491590 --- gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58702 bytes gradlew | 29 ++++++++---------- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58702 bytes template/android/gradlew | 29 ++++++++---------- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b 100644 GIT binary patch delta 16535 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 Date: Mon, 13 Jan 2020 13:34:07 -0800 Subject: [PATCH 0005/1126] Fabric: Fixing incorrect retaining policy for RCTSurfacePreseter (crash in RCTNativeAnimatedModule) Summary: This fixing a crash in RCTNativeAnimatedModule caused by accessing an `RCTSurfacePreseter` instance as "Objective-C runtime associated object" which was retained with `OBJC_ASSOCIATION_ASSIGN` policy. The documentation for `OBJC_ASSOCIATION_ASSIGN` says "Specifies a weak reference to the associated object." but it's a lie ( https://stackoverflow.com/questions/16569840/using-objc-setassociatedobject-with-weak-references) ). The policy is actually `ASSIGN` (aka `unsafe-unretained`). That's why it's crashing. We change that to `OBJC_ASSOCIATION_RETAIN` to retain the object (which meets the expectation of the interface of the category). We also should not have over-retaining issues because: * SurfacePresenter does not retain a Bridge or any object that can retain a Bridge; * SurfacePresenter is a long-living object, we don't recreate it during bridge reloading or stuff like that. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D19333869 fbshipit-source-id: 1ff03659a880f2742b909c5668c47144719eeee2 --- React/Modules/RCTSurfacePresenterStub.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/React/Modules/RCTSurfacePresenterStub.m b/React/Modules/RCTSurfacePresenterStub.m index 655835c5ca1913..8a78199147b666 100644 --- a/React/Modules/RCTSurfacePresenterStub.m +++ b/React/Modules/RCTSurfacePresenterStub.m @@ -16,7 +16,7 @@ @implementation RCTBridge (RCTSurfacePresenterStub) - (void)setSurfacePresenter:(id)surfacePresenter { - objc_setAssociatedObject(self, @selector(surfacePresenter), surfacePresenter, OBJC_ASSOCIATION_ASSIGN); + objc_setAssociatedObject(self, @selector(surfacePresenter), surfacePresenter, OBJC_ASSOCIATION_RETAIN); } @end From a6c0f5a12079e94b2d5bf3ab4e7bccf9fd700f8d Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Mon, 13 Jan 2020 14:20:51 -0800 Subject: [PATCH 0006/1126] Fix typo in RCTSurface log Summary: title Changelog: [iOS][Internal] Fix typo in RCTSurface log Reviewed By: zackargyle, sammy-SC Differential Revision: D19334748 fbshipit-source-id: 61cc984072d2f109d5ae8bce70688094d9fbe67c --- React/Base/Surface/RCTSurface.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/React/Base/Surface/RCTSurface.mm b/React/Base/Surface/RCTSurface.mm index e796bdc6bc286f..17897ba3728288 100644 --- a/React/Base/Surface/RCTSurface.mm +++ b/React/Base/Surface/RCTSurface.mm @@ -62,7 +62,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initialProperties:(NSDictionary *)initialProperties { - RCTAssert(bridge.valid, @"Valid bridge is required to instanciate `RCTSurface`."); + RCTAssert(bridge.valid, @"Valid bridge is required to instantiate `RCTSurface`."); if (self = [super init]) { _bridge = bridge; From 12f78f145a3ac6f9528ea5a6a93f58a02f9e6356 Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Mon, 13 Jan 2020 22:52:07 -0800 Subject: [PATCH 0007/1126] Fix crash in RCTBlobManager in bridgeless mode Summary: When bridge is nil, RCTBlobManager crashes with `EXC_BAD_ACCESS`. The fix: instead of using the bridge to find RCTNetworking, use TM lookup delegate. Changelog: [iOS][Internal] Fix crash in RCTBlobManager in bridgeless mode Reviewed By: mdvacca Differential Revision: D19320136 fbshipit-source-id: 49aabb3ce53b2ec620fcc02be1c6c1b44066f440 --- Libraries/Blob/RCTBlobManager.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Libraries/Blob/RCTBlobManager.mm b/Libraries/Blob/RCTBlobManager.mm index c4ab554f088faf..e47ea488df5a2b 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -38,6 +38,7 @@ @implementation RCTBlobManager @synthesize bridge = _bridge; @synthesize methodQueue = _methodQueue; +@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; - (void)setBridge:(RCTBridge *)bridge { @@ -139,9 +140,11 @@ - (void)remove:(NSString *)blobId RCT_EXPORT_METHOD(addNetworkingHandler) { - dispatch_async(_bridge.networking.methodQueue, ^{ - [self->_bridge.networking addRequestHandler:self]; - [self->_bridge.networking addResponseHandler:self]; + RCTNetworking *const networking = _bridge ? _bridge.networking : [_turboModuleLookupDelegate moduleForName:"RCTNetworking"]; + + dispatch_async(networking.methodQueue, ^{ + [networking addRequestHandler:self]; + [networking addResponseHandler:self]; }); } From 442dd268733cc1a3ff899f89b7ac2d2e9d5c93b2 Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Mon, 13 Jan 2020 22:52:07 -0800 Subject: [PATCH 0008/1126] Fix error in RCTImageLoader in bridgeless mode Summary: Bridgeless mode hasn't been able to load random images. I was able to repro this 100% with base64 images. Loading these images hits a particular flow in `RCTImageLoader` which relies on the bridge to access `RCTNetworking`. This diff uses the TM Lookup Delegate as a fallback. Changelog: [iOS][Internal] Fix error in RCTImageLoader in bridgeless mode Reviewed By: sammy-SC Differential Revision: D19331467 fbshipit-source-id: 8239ee258425da4ed8cb9f6dcdcd7f37c162eb19 --- Libraries/Image/RCTImageLoader.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Libraries/Image/RCTImageLoader.mm b/Libraries/Image/RCTImageLoader.mm index efa84842206d70..fd436da4285f4e 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -99,6 +99,7 @@ @implementation RCTImageLoader @synthesize maxConcurrentLoadingTasks = _maxConcurrentLoadingTasks; @synthesize maxConcurrentDecodingTasks = _maxConcurrentDecodingTasks; @synthesize maxConcurrentDecodingBytes = _maxConcurrentDecodingBytes; +@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; RCT_EXPORT_MODULE() @@ -583,7 +584,8 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request completionBlock:(void (^)(NSError *error, id imageOrData, NSURLResponse *response))completionHandler { // Check if networking module is available - if (RCT_DEBUG && ![_bridge respondsToSelector:@selector(networking)]) { + if (RCT_DEBUG && ![_bridge respondsToSelector:@selector(networking)] + && ![_turboModuleLookupDelegate moduleForName:"RCTNetworking"]) { RCTLogError(@"No suitable image URL loader found for %@. You may need to " " import the RCTNetwork library in order to load images.", request.URL.absoluteString); @@ -591,6 +593,9 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request } RCTNetworking *networking = [_bridge networking]; + if (!networking) { + networking = [_turboModuleLookupDelegate moduleForName:"RCTNetworking"]; + } // Check if networking module can load image if (RCT_DEBUG && ![networking canHandleRequest:request]) { From 16ada9dfb0b4152f36cd46b306f72ba93d2fce57 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Mon, 13 Jan 2020 23:14:30 -0800 Subject: [PATCH 0009/1126] Fix MountingCoordinator stub view tree printer Summary: On Android/when printing to logcat, output is truncated to a certain max length; outputting a massive string as a single log item will cause some of it to be truncated. In the case of the mutations list and shadow node description, most of it is truncated. Easy fix: split into lines and log each line. This isn't necessary on iOS but works fine. I also removed the conditional and changed to an assert. Most of the time when we're using this block of code, it's because we want to see all mutations; and unless we reintroduce a bug into the core, the assert is never hit and so (before this change) the conditional would never be true and we'd never see this output. It's more generally useful to be able to see this output if the `RN_SHADOW_TREE_INTROSPECTION` macro is defined. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D19378929 fbshipit-source-id: 2f5dffeef7608823ac1ba092090d8c2ab5e965e1 --- .../fabric/mounting/MountingCoordinator.cpp | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/ReactCommon/fabric/mounting/MountingCoordinator.cpp b/ReactCommon/fabric/mounting/MountingCoordinator.cpp index 72ed5637cf735a..d0bf0dc2fb07de 100644 --- a/ReactCommon/fabric/mounting/MountingCoordinator.cpp +++ b/ReactCommon/fabric/mounting/MountingCoordinator.cpp @@ -9,6 +9,7 @@ #ifdef RN_SHADOW_TREE_INTROSPECTION #include +#include #endif #include @@ -89,20 +90,27 @@ better::optional MountingCoordinator::pullTransaction() stubViewTree_.mutate(mutations); auto stubViewTree = stubViewTreeFromShadowNode(lastRevision_->getRootShadowNode()); - if (stubViewTree_ != stubViewTree) { - LOG(ERROR) << "Old tree:" - << "\n" - << baseRevision_.getRootShadowNode().getDebugDescription() - << "\n"; - LOG(ERROR) << "New tree:" - << "\n" - << lastRevision_->getRootShadowNode().getDebugDescription() - << "\n"; - LOG(ERROR) << "Mutations:" - << "\n" - << getDebugDescription(mutations, {}); - assert(false); + + std::string line; + + std::stringstream ssOldTree( + baseRevision_.getRootShadowNode().getDebugDescription()); + while (std::getline(ssOldTree, line, '\n')) { + LOG(ERROR) << "Old tree:" << line; + } + + std::stringstream ssNewTree( + lastRevision_->getRootShadowNode().getDebugDescription()); + while (std::getline(ssNewTree, line, '\n')) { + LOG(ERROR) << "New tree:" << line; } + + std::stringstream ssMutations(getDebugDescription(mutations, {})); + while (std::getline(ssMutations, line, '\n')) { + LOG(ERROR) << "Mutations:" << line; + } + + assert(stubViewTree_ == stubViewTree); #endif baseRevision_ = std::move(*lastRevision_); From cfbd93ccd5670194070a2000a95d2a6290879dca Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 13 Jan 2020 23:17:34 -0800 Subject: [PATCH 0010/1126] Fix crash when accessing nullptr imageRequest Summary: ImageState if created with default constructor is created with `imageRequest_` being nullptr. Calling `getObserverCoordinator()` on it was causing a crash. We create initial state data with `imageRequest` populated. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19332711 fbshipit-source-id: 0266222551dbfb10b3f86e72a43d5306650fd09b --- .../ComponentViews/Image/RCTImageComponentView.mm | 5 +++-- ReactCommon/fabric/components/image/ImageShadowNode.h | 8 ++++++++ ReactCommon/fabric/components/image/ImageState.h | 2 -- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index bb811e260e28ad..32ebeef2503f64 100644 --- a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -20,6 +20,8 @@ #import "RCTConversions.h" #import "RCTFabricComponentsPlugins.h" +using namespace facebook::react; + @interface RCTImageComponentView () @end @@ -79,8 +81,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & [super updateProps:props oldProps:oldProps]; } -- (void)updateState:(facebook::react::State::Shared const &)state - oldState:(facebook::react::State::Shared const &)oldState +- (void)updateState:(State::Shared const &)state oldState:(State::Shared const &)oldState { _state = std::static_pointer_cast(state); auto _oldState = std::static_pointer_cast(oldState); diff --git a/ReactCommon/fabric/components/image/ImageShadowNode.h b/ReactCommon/fabric/components/image/ImageShadowNode.h index 0dbd5f8990b10b..592a67b505a50f 100644 --- a/ReactCommon/fabric/components/image/ImageShadowNode.h +++ b/ReactCommon/fabric/components/image/ImageShadowNode.h @@ -35,6 +35,14 @@ class ImageShadowNode final : public ConcreteViewShadowNode< */ void setImageManager(const SharedImageManager &imageManager); + static ImageState initialStateData( + ShadowNodeFragment const &fragment, + SurfaceId const surfaceId, + ComponentDescriptor const &componentDescriptor) { + auto imageSource = ImageSource{ImageSource::Type::Invalid}; + return {imageSource, {imageSource, nullptr}}; + } + #pragma mark - LayoutableShadowNode void layout(LayoutContext layoutContext) override; diff --git a/ReactCommon/fabric/components/image/ImageState.h b/ReactCommon/fabric/components/image/ImageState.h index 8d591af4d42c33..5280e4b0c65350 100644 --- a/ReactCommon/fabric/components/image/ImageState.h +++ b/ReactCommon/fabric/components/image/ImageState.h @@ -24,8 +24,6 @@ class ImageState final { imageRequest_( std::make_shared(std::move(imageRequest))){}; - ImageState() = default; - /* * Returns stored ImageSource object. */ From 1fbc6a7c178d13421b0b84d6ea01f9174105325f Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Mon, 13 Jan 2020 23:18:03 -0800 Subject: [PATCH 0011/1126] Fix animations in OSS debug builds by modifying `Platform.isTesting()` behaviour Summary: In D14244606 I "fixed" `Platform.isTesting()` in JS. By fixed, I made it return true when running SSTs. People in OSS complained about this in discord and [github](https://github.com/facebook/react-native/issues/27010). The problem is that this call returns true whenever an RN project references Detox in the build.gradle file. In practice, this has been really annoying, because it has disabled animations in debug builds, due to D13811035. The fix is to be more specific, and look for the exact screenshot test activity. I haven't explicitly verified this doesn't trigger from Detox, but it shouldn't. I'll coordinate on the github issue to verify. Changelog: [Android][Fixed] Fix animations in OSS debug builds by modifying `Platform.isTesting()` behaviour Reviewed By: TheSavior Differential Revision: D19384098 fbshipit-source-id: 22c885219f2c00f5dcc3b930b068bfd2ad7e4b8e --- .../facebook/react/modules/systeminfo/AndroidInfoModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java index 335cb2062f6b85..24c6f4deb4cbfc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java @@ -92,7 +92,7 @@ public void invalidate() {} private Boolean isRunningScreenshotTest() { try { - Class.forName("android.support.test.rule.ActivityTestRule"); + Class.forName("com.facebook.testing.react.screenshots.ReactAppScreenshotTestActivity"); return true; } catch (ClassNotFoundException ignored) { return false; From ce9cf3795a92a6d442719d8b2cbae0c82844e1c1 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 13 Jan 2020 23:18:06 -0800 Subject: [PATCH 0012/1126] Fabric: component on iOS, the C++ part Summary: This is C++ part of the implementation of Fabric-compatible component on iOS. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D19169987 fbshipit-source-id: e2eac9beac6d1e124b5176b4a23676b8e05490c3 --- ReactCommon/fabric/components/textinput/BUCK | 4 +- .../components/textinput/iostextinput/BUCK | 99 +++++++++ .../TextInputComponentDescriptor.h | 46 ++++ .../iostextinput/TextInputEventEmitter.cpp | 96 ++++++++ .../iostextinput/TextInputEventEmitter.h | 49 ++++ .../textinput/iostextinput/TextInputProps.cpp | 79 +++++++ .../textinput/iostextinput/TextInputProps.h | 67 ++++++ .../iostextinput/TextInputShadowNode.cpp | 94 ++++++++ .../iostextinput/TextInputShadowNode.h | 70 ++++++ .../textinput/iostextinput/TextInputState.cpp | 12 + .../textinput/iostextinput/TextInputState.h | 51 +++++ .../textinput/iostextinput/conversions.h | 210 ++++++++++++++++++ .../textinput/iostextinput/primitives.h | 209 +++++++++++++++++ .../textinput/iostextinput/propsConversions.h | 116 ++++++++++ .../platform/ios/TextLayoutManager.h | 2 + .../uimanager/ComponentDescriptorRegistry.cpp | 6 + 16 files changed, 1208 insertions(+), 2 deletions(-) create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/BUCK create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputComponentDescriptor.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.cpp create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.cpp create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.cpp create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputState.cpp create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputState.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/conversions.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/primitives.h create mode 100644 ReactCommon/fabric/components/textinput/iostextinput/propsConversions.h diff --git a/ReactCommon/fabric/components/textinput/BUCK b/ReactCommon/fabric/components/textinput/BUCK index 09821ebb43cd42..c0a177d712eb4a 100644 --- a/ReactCommon/fabric/components/textinput/BUCK +++ b/ReactCommon/fabric/components/textinput/BUCK @@ -18,11 +18,11 @@ APPLE_COMPILER_FLAGS = get_apple_compiler_flags() rn_xplat_cxx_library( name = "androidtextinput", srcs = glob( - ["**/*.cpp"], + ["androidtextinput/**/*.cpp"], exclude = glob(["tests/**/*.cpp"]), ), headers = glob( - ["**/*.h"], + ["androidtextinput/**/*.h"], exclude = glob(["tests/**/*.h"]), ), header_namespace = "", diff --git a/ReactCommon/fabric/components/textinput/iostextinput/BUCK b/ReactCommon/fabric/components/textinput/iostextinput/BUCK new file mode 100644 index 00000000000000..60a2178bcc54ff --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/BUCK @@ -0,0 +1,99 @@ +load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags") +load( + "//tools/build_defs/oss:rn_defs.bzl", + "ANDROID", + "APPLE", + "CXX", + "YOGA_CXX_TARGET", + "fb_xplat_cxx_test", + "get_apple_compiler_flags", + "get_apple_inspector_flags", + "react_native_xplat_target", + "rn_xplat_cxx_library", + "subdir_glob", +) + +APPLE_COMPILER_FLAGS = get_apple_compiler_flags() + +rn_xplat_cxx_library( + name = "iostextinput", + srcs = glob( + ["**/*.cpp"], + exclude = glob(["tests/**/*.cpp"]), + ), + headers = glob( + ["**/*.h"], + exclude = glob(["tests/**/*.h"]), + ), + header_namespace = "", + exported_headers = subdir_glob( + [ + ("", "*.h"), + ], + # TODO(shergin) T26519801 Figure out better directories structure + prefix = "react/components/iostextinput", + ), + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++14", + "-Wall", + ], + cxx_tests = [":tests"], + fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, + fbobjc_labels = ["supermodule:ios/isolation/infra.react_native"], + fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(), + force_static = True, + platforms = (ANDROID, APPLE, CXX), + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + visibility = ["PUBLIC"], + deps = [ + "fbsource//xplat/fbsystrace:fbsystrace", + "fbsource//xplat/folly:evicting_cache_map", + "fbsource//xplat/folly:headers_only", + "fbsource//xplat/folly:memory", + "fbsource//xplat/folly:molly", + "fbsource//xplat/third-party/glog:glog", + YOGA_CXX_TARGET, + react_native_xplat_target("utils:utils"), + react_native_xplat_target("fabric/attributedstring:attributedstring"), + react_native_xplat_target("fabric/core:core"), + react_native_xplat_target("fabric/debug:debug"), + react_native_xplat_target("fabric/graphics:graphics"), + react_native_xplat_target("fabric/textlayoutmanager:textlayoutmanager"), + react_native_xplat_target("fabric/components/text:text"), + react_native_xplat_target("fabric/components/view:view"), + react_native_xplat_target("fabric/components/image:image"), + react_native_xplat_target("fabric/uimanager:uimanager"), + react_native_xplat_target("fabric/imagemanager:imagemanager"), + ], +) + +fb_xplat_cxx_test( + name = "tests", + srcs = glob(["tests/**/*.cpp"]), + headers = glob(["tests/**/*.h"]), + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++14", + "-Wall", + ], + contacts = ["oncall+react_native@xmail.facebook.com"], + platforms = ( + # `Apple` and `Android` flavors are disabled because the module depends on `textlayoutmanager` which requires real an Emulator/Simulator to run. + # At the same time, the code of tests does not rely on the simulator capabilities and it would be wasteful to add `fbandroid_use_instrumentation_test = True`. + # (Beware of this option though.) + # ANDROID, + # APPLE, + CXX + ), + deps = [ + "fbsource//xplat/folly:molly", + "fbsource//xplat/third-party/gmock:gtest", + ":iostextinput", + ], +) diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputComponentDescriptor.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputComponentDescriptor.h new file mode 100644 index 00000000000000..d602d02704132b --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputComponentDescriptor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +/* + * Descriptor for component. + */ +class TextInputComponentDescriptor final + : public ConcreteComponentDescriptor { + public: + TextInputComponentDescriptor(ComponentDescriptorParameters const ¶meters) + : ConcreteComponentDescriptor(parameters) { + textLayoutManager_ = + std::make_shared(contextContainer_); + } + + protected: + void adopt(UnsharedShadowNode shadowNode) const override { + ConcreteComponentDescriptor::adopt(shadowNode); + + assert(std::dynamic_pointer_cast(shadowNode)); + auto concreteShadowNode = + std::static_pointer_cast(shadowNode); + + concreteShadowNode->setTextLayoutManager(textLayoutManager_); + concreteShadowNode->dirtyLayout(); + concreteShadowNode->enableMeasurement(); + } + + private: + TextLayoutManager::Shared textLayoutManager_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.cpp b/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.cpp new file mode 100644 index 00000000000000..4a3b6c096639f4 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "TextInputEventEmitter.h" + +namespace facebook { +namespace react { + +static jsi::Value textInputMetricsPayload( + jsi::Runtime &runtime, + TextInputMetrics const &textInputMetrics) { + auto payload = jsi::Object(runtime); + + payload.setProperty( + runtime, + "text", + jsi::String::createFromUtf8(runtime, textInputMetrics.text)); + + { + auto selection = jsi::Object(runtime); + selection.setProperty( + runtime, "start", textInputMetrics.selectionRange.location); + selection.setProperty( + runtime, + "end", + textInputMetrics.selectionRange.location + + textInputMetrics.selectionRange.length); + payload.setProperty(runtime, "selection", selection); + } + + return payload; +}; + +void TextInputEventEmitter::onFocus( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("focus", textInputMetrics); +} + +void TextInputEventEmitter::onBlur( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("blur", textInputMetrics); +} + +void TextInputEventEmitter::onChange( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("change", textInputMetrics); +} + +void TextInputEventEmitter::onChangeText( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("changeText", textInputMetrics); +} + +void TextInputEventEmitter::onContentSizeChange( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("contentSizeChange", textInputMetrics); +} + +void TextInputEventEmitter::onSelectionChange( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("selectionChange", textInputMetrics); +} + +void TextInputEventEmitter::onEndEditing( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("endEditing", textInputMetrics); +} + +void TextInputEventEmitter::onSubmitEditing( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("submitEditing", textInputMetrics); +} + +void TextInputEventEmitter::onKeyPress( + TextInputMetrics const &textInputMetrics) const { + dispatchTextInputEvent("keyPress", textInputMetrics); +} + +void TextInputEventEmitter::dispatchTextInputEvent( + std::string const &name, + TextInputMetrics const &textInputMetrics, + EventPriority priority) const { + dispatchEvent( + name, + [textInputMetrics](jsi::Runtime &runtime) { + return textInputMetricsPayload(runtime, textInputMetrics); + }, + priority); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.h new file mode 100644 index 00000000000000..dbcfefcffb3280 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +class TextInputMetrics { + public: + std::string text; + AttributedString::Range selectionRange; + // ScrollView-like metrics + Size contentSize; + Point contentOffset; + EdgeInsets contentInset; + Size containerSize; +}; + +class TextInputEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + void onFocus(TextInputMetrics const &textInputMetrics) const; + void onBlur(TextInputMetrics const &textInputMetrics) const; + void onChange(TextInputMetrics const &textInputMetrics) const; + void onChangeText(TextInputMetrics const &textInputMetrics) const; + void onContentSizeChange(TextInputMetrics const &textInputMetrics) const; + void onSelectionChange(TextInputMetrics const &textInputMetrics) const; + void onEndEditing(TextInputMetrics const &textInputMetrics) const; + void onSubmitEditing(TextInputMetrics const &textInputMetrics) const; + void onKeyPress(TextInputMetrics const &textInputMetrics) const; + + private: + void dispatchTextInputEvent( + std::string const &name, + TextInputMetrics const &textInputMetrics, + EventPriority priority = EventPriority::AsynchronousBatched) const; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.cpp b/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.cpp new file mode 100644 index 00000000000000..27e5c2cfb9053b --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "TextInputProps.h" + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +TextInputProps::TextInputProps( + TextInputProps const &sourceProps, + RawProps const &rawProps) + : ViewProps(sourceProps, rawProps), + BaseTextProps(sourceProps, rawProps), + traits(convertRawProp(rawProps, sourceProps.traits, {})), + paragraphAttributes( + convertRawProp(rawProps, sourceProps.paragraphAttributes, {})), + defaultValue(convertRawProp( + rawProps, + "defaultValue", + sourceProps.defaultValue, + {})), + placeholder( + convertRawProp(rawProps, "placeholder", sourceProps.placeholder, {})), + placeholderTextColor(convertRawProp( + rawProps, + "placeholderTextColor", + sourceProps.placeholderTextColor, + {})), + maxLength( + convertRawProp(rawProps, "maxLength", sourceProps.maxLength, {})), + cursorColor( + convertRawProp(rawProps, "cursorColor", sourceProps.cursorColor, {})), + selectionColor(convertRawProp( + rawProps, + "selectionColor", + sourceProps.selectionColor, + {})), + underlineColorAndroid(convertRawProp( + rawProps, + "underlineColorAndroid", + sourceProps.underlineColorAndroid, + {})), + text(convertRawProp(rawProps, "text", sourceProps.text, {})){}; + +TextAttributes TextInputProps::getEffectiveTextAttributes() const { + auto result = TextAttributes::defaultTextAttributes(); + result.apply(textAttributes); + return result; +} + +ParagraphAttributes TextInputProps::getEffectiveParagraphAttributes() const { + auto result = paragraphAttributes; + + if (!traits.multiline) { + result.maximumNumberOfLines = 1; + } + + return result; +} + +#ifdef ANDROID +folly::dynamic TextInputProps::getDynamic() const { + folly::dynamic props = folly::dynamic::object(); + props["value"] = value; + return props; +} +#endif + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.h new file mode 100644 index 00000000000000..00f892fd5b285f --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class TextInputProps final : public ViewProps, public BaseTextProps { + public: + TextInputProps() = default; + TextInputProps(TextInputProps const &sourceProps, RawProps const &rawProps); + +#pragma mark - Props + + TextInputTraits const traits{}; + ParagraphAttributes const paragraphAttributes{}; + + std::string const defaultValue{}; + + std::string const placeholder{}; + SharedColor const placeholderTextColor{}; + + int maxLength{}; + + /* + * Tint colors + */ + SharedColor const cursorColor{}; + SharedColor const selectionColor{}; + // TODO: Rename to `tintColor` and make universal. + SharedColor const underlineColorAndroid{}; + + /* + * "Private" (only used by TextInput.js) props + */ + std::string const text{}; + + /* + * Accessors + */ + TextAttributes getEffectiveTextAttributes() const; + ParagraphAttributes getEffectiveParagraphAttributes() const; + +#ifdef ANDROID + folly::dynamic getDynamic() const; +#endif +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.cpp b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.cpp new file mode 100644 index 00000000000000..047464feffba8f --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "TextInputShadowNode.h" + +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +extern char const TextInputComponentName[] = "TextInput"; + +AttributedStringBox TextInputShadowNode::attributedStringBoxToMeasure() const { + bool hasMeaningfulState = getState() && getStateData().revision != 0; + + if (hasMeaningfulState) { + auto attributedStringBox = getStateData().attributedStringBox; + if (attributedStringBox.getMode() == + AttributedStringBox::Mode::OpaquePointer || + !attributedStringBox.getValue().isEmpty()) { + return getStateData().attributedStringBox; + } + } + + auto attributedString = + hasMeaningfulState ? AttributedString{} : getAttributedString(); + + if (attributedString.isEmpty()) { + auto placeholder = getProps()->placeholder; + // Note: `zero-width space` is insufficient in some cases (e.g. when we need + // to measure the "hight" of the font). + auto string = !placeholder.empty() ? placeholder : "I"; + auto textAttributes = getProps()->getEffectiveTextAttributes(); + attributedString.appendFragment({string, textAttributes, {}}); + } + + return AttributedStringBox{attributedString}; +} + +AttributedString TextInputShadowNode::getAttributedString() const { + auto textAttributes = getProps()->getEffectiveTextAttributes(); + auto attributedString = AttributedString{}; + + attributedString.appendFragment( + AttributedString::Fragment{getProps()->text, textAttributes}); + + attributedString.appendAttributedString( + BaseTextShadowNode::getAttributedString(textAttributes, *this)); + return attributedString; +} + +void TextInputShadowNode::setTextLayoutManager( + TextLayoutManager::Shared const &textLayoutManager) { + ensureUnsealed(); + textLayoutManager_ = textLayoutManager; +} + +void TextInputShadowNode::updateStateIfNeeded() { + ensureUnsealed(); + + if (!getState() || getStateData().revision == 0) { + auto state = TextInputState{}; + state.attributedStringBox = AttributedStringBox{getAttributedString()}; + state.paragraphAttributes = getProps()->paragraphAttributes; + state.layoutManager = textLayoutManager_; + state.revision = 1; + setStateData(std::move(state)); + } +} + +#pragma mark - LayoutableShadowNode + +Size TextInputShadowNode::measure(LayoutConstraints layoutConstraints) const { + return textLayoutManager_->measure( + attributedStringBoxToMeasure(), + getProps()->getEffectiveParagraphAttributes(), + layoutConstraints); +} + +void TextInputShadowNode::layout(LayoutContext layoutContext) { + updateStateIfNeeded(); + ConcreteViewShadowNode::layout(layoutContext); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h new file mode 100644 index 00000000000000..435e5b7da9f508 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +extern const char TextInputComponentName[]; + +/* + * `ShadowNode` for component. + */ +class TextInputShadowNode : public ConcreteViewShadowNode< + TextInputComponentName, + TextInputProps, + TextInputEventEmitter, + TextInputState>, + public BaseTextShadowNode { + public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; + + /* + * Returns a `AttributedString` which represents text content of the node. + */ + AttributedString getAttributedString() const; + + /* + * Associates a shared `TextLayoutManager` with the node. + * `TextInputShadowNode` uses the manager to measure text content + * and construct `TextInputState` objects. + */ + void setTextLayoutManager(TextLayoutManager::Shared const &textLayoutManager); + +#pragma mark - LayoutableShadowNode + + Size measure(LayoutConstraints layoutConstraints) const override; + void layout(LayoutContext layoutContext) override; + + private: + /* + * Creates a `State` object if needed. + */ + void updateStateIfNeeded(); + + /* + * Returns an `AttributedStringBox` which represents text content that should + * be used for measuring purposes. It might contain actual text value, + * placeholder value or some character that represents the size of the font. + */ + AttributedStringBox attributedStringBoxToMeasure() const; + + TextLayoutManager::Shared textLayoutManager_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.cpp b/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.cpp new file mode 100644 index 00000000000000..c22ba8bd11d2a1 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "TextInputState.h" + +namespace facebook { +namespace react {} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.h new file mode 100644 index 00000000000000..ed3d4e0254db76 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputState.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +#ifdef ANDROID +#include +#endif + +namespace facebook { +namespace react { + +/* + * State for component. + */ +class TextInputState final { + public: + /* + * All content of component. + */ + AttributedStringBox attributedStringBox; + + /* + * Represents all visual attributes of a paragraph of text represented as + * a ParagraphAttributes. + */ + ParagraphAttributes paragraphAttributes; + + /* + * `TextLayoutManager` provides a connection to platform-specific + * text rendering infrastructure which is capable to render the + * `AttributedString`. + */ + SharedTextLayoutManager layoutManager; + + /* + * Revision of the State object. + */ + size_t revision{0}; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/conversions.h b/ReactCommon/fabric/components/textinput/iostextinput/conversions.h new file mode 100644 index 00000000000000..e4daf98f4c65bd --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/conversions.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +inline void fromRawValue( + const RawValue &value, + AutocapitalizationType &result) { + auto string = (std::string)value; + if (string == "none") { + result = AutocapitalizationType::None; + return; + } + if (string == "words") { + result = AutocapitalizationType::Words; + return; + } + if (string == "sentences") { + result = AutocapitalizationType::Sentences; + return; + } + if (string == "characters") { + result = AutocapitalizationType::Characters; + return; + } + abort(); +} + +inline void fromRawValue(const RawValue &value, KeyboardAppearance &result) { + auto string = (std::string)value; + if (string == "default") { + result = KeyboardAppearance::Default; + return; + } + if (string == "light") { + result = KeyboardAppearance::Light; + return; + } + if (string == "dark") { + result = KeyboardAppearance::Dark; + return; + } + abort(); +} + +inline void fromRawValue(const RawValue &value, ReturnKeyType &result) { + auto string = (std::string)value; + if (string == "default") { + result = ReturnKeyType::Default; + return; + } + if (string == "done") { + result = ReturnKeyType::Done; + return; + } + if (string == "go") { + result = ReturnKeyType::Go; + return; + } + if (string == "next") { + result = ReturnKeyType::Next; + return; + } + if (string == "search") { + result = ReturnKeyType::Search; + return; + } + if (string == "send") { + result = ReturnKeyType::Send; + return; + } + + // Android-only + if (string == "none") { + result = ReturnKeyType::None; + return; + } + if (string == "previous") { + result = ReturnKeyType::Previous; + return; + } + + // iOS-only + if (string == "emergency-call") { + result = ReturnKeyType::EmergencyCall; + return; + } + if (string == "google") { + result = ReturnKeyType::Google; + return; + } + if (string == "join") { + result = ReturnKeyType::Join; + return; + } + if (string == "route") { + result = ReturnKeyType::Route; + return; + } + if (string == "yahoo") { + result = ReturnKeyType::Yahoo; + return; + } + if (string == "continue") { + result = ReturnKeyType::Continue; + return; + } + abort(); +} + +inline void fromRawValue( + const RawValue &value, + TextInputAccessoryVisibilityMode &result) { + auto string = (std::string)value; + if (string == "never") { + result = TextInputAccessoryVisibilityMode::Never; + return; + } + if (string == "while-editing") { + result = TextInputAccessoryVisibilityMode::WhileEditing; + return; + } + if (string == "unless-editing") { + result = TextInputAccessoryVisibilityMode::UnlessEditing; + return; + } + if (string == "always") { + result = TextInputAccessoryVisibilityMode::Always; + return; + } + abort(); +} + +inline void fromRawValue(const RawValue &value, KeyboardType &result) { + auto string = (std::string)value; + if (string == "default") { + result = KeyboardType::Default; + return; + } + if (string == "email-address") { + result = KeyboardType::EmailAddress; + return; + } + if (string == "numeric") { + result = KeyboardType::Numeric; + return; + } + if (string == "phone-pad") { + result = KeyboardType::PhonePad; + return; + } + if (string == "number-pad") { + result = KeyboardType::NumberPad; + return; + } + if (string == "decimal-pad") { + result = KeyboardType::DecimalPad; + return; + } + + // iOS-only + if (string == "ascii-capable") { + result = KeyboardType::ASCIICapable; + return; + } + if (string == "numbers-and-punctuation") { + result = KeyboardType::NumbersAndPunctuation; + return; + } + if (string == "url") { + result = KeyboardType::URL; + return; + } + if (string == "name-phone-pad") { + result = KeyboardType::NamePhonePad; + return; + } + if (string == "twitter") { + result = KeyboardType::Twitter; + return; + } + if (string == "web-search") { + result = KeyboardType::WebSearch; + return; + } + if (string == "ascii-capable-number-pad") { + result = KeyboardType::ASCIICapableNumberPad; + return; + } + + // Android-only + if (string == "visible-password") { + result = KeyboardType::VisiblePassword; + return; + } + abort(); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/primitives.h b/ReactCommon/fabric/components/textinput/iostextinput/primitives.h new file mode 100644 index 00000000000000..1bd7caa9386bd3 --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/primitives.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include + +namespace facebook { +namespace react { + +// iOS & Android. +enum class AutocapitalizationType { + None, + Words, + Sentences, + Characters, +}; + +// iOS-only +enum class KeyboardAppearance { + Default, + Light, + Dark, +}; + +enum class ReturnKeyType { + // Universal + Default, + Done, + Go, + Next, + Search, + Send, + // Android-only + None, + Previous, + // iOS-only + EmergencyCall, + Google, + Join, + Route, + Yahoo, + Continue, +}; + +// iOS-only +enum class TextInputAccessoryVisibilityMode { + Never, + WhileEditing, + UnlessEditing, + Always, +}; + +enum class KeyboardType { + // Universal + Default, + EmailAddress, + Numeric, + PhonePad, + NumberPad, + DecimalPad, + // iOS-only + ASCIICapable, + NumbersAndPunctuation, + URL, + NamePhonePad, + Twitter, + WebSearch, + ASCIICapableNumberPad, + // Android-only + VisiblePassword, +}; + +/* + * Controls features of text inputs. + */ +class TextInputTraits final { + public: + /* + * iOS & Android + * Default value: `false`. + */ + bool multiline{false}; + + /* + * iOS & Android + * Default value: `None`. + */ + AutocapitalizationType autocapitalizationType{AutocapitalizationType::None}; + + /* + * Can be empty (`null` in JavaScript) which means `default`. + * iOS & Android + * Default value: `empty` (`null`). + */ + better::optional autoCorrect{}; + + /* + * iOS & Android + * Default value: `false`. + */ + bool contextMenuHidden{false}; + + /* + * iOS & Android + * Default value: `true`. + */ + bool editable{true}; + + /* + * iOS-only (implemented only on iOS for now) + * If `true`, will automatically disable return key when text widget has + * zero-length contents, and will automatically enable when text widget has + * non-zero-length contents. + * Default value: `false`. + */ + bool enablesReturnKeyAutomatically{false}; + + /* + * Some values iOS- or Android-only (inherently particular-OS-specific) + * Default value: `Default`. + */ + KeyboardAppearance keyboardAppearance{KeyboardAppearance::Default}; + + /* + * Controls the annotation of misspelled words for a text input. + * iOS-only (implemented only on iOS for now) + * Can be empty (`null` in JavaScript) which means `default`. + * Default value: `empty` (`null`). + */ + better::optional spellCheck{}; + + /* + * iOS & Android + * Default value: `false`. + */ + bool caretHidden{false}; + + /* + * Controls the visibility of a `Clean` button. + * iOS-only (implemented only on iOS for now) + * Default value: `Never`. + */ + TextInputAccessoryVisibilityMode clearButtonMode{ + TextInputAccessoryVisibilityMode::Never}; + + /* + * iOS-only (implemented only on iOS for now) + * Default value: `true`. + */ + bool scrollEnabled{true}; + + /* + * iOS & Android + * Default value: `false`. + */ + bool secureTextEntry{false}; + + /* + * iOS & Android + * Default value: `false`. + */ + bool blurOnSubmit{false}; + + /* + * iOS-only (implemented only on iOS for now) + * Default value: `false`. + */ + bool clearTextOnFocus{false}; + + /* + * Some values iOS- or Android-only (inherently particular-OS-specific) + * Default value: `Default`. + */ + KeyboardType keyboardType{KeyboardType::Default}; + + /* + * Some values iOS- or Android-only (inherently particular-OS-specific) + * Default value: `Default`. + */ + ReturnKeyType returnKeyType{ReturnKeyType::Default}; + + /* + * iOS & Android + * Default value: `false`. + */ + bool selectTextOnFocus{false}; + + /* + * iOS-only (inherently iOS-specific) + * Default value: `` (default content type). + */ + std::string textContentType{}; + + /* + * iOS-only (inherently iOS-specific) + * Default value: `` (no rules). + */ + std::string passwordRules{}; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/components/textinput/iostextinput/propsConversions.h b/ReactCommon/fabric/components/textinput/iostextinput/propsConversions.h new file mode 100644 index 00000000000000..6c12a5716a15ab --- /dev/null +++ b/ReactCommon/fabric/components/textinput/iostextinput/propsConversions.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +static TextInputTraits convertRawProp( + RawProps const &rawProps, + TextInputTraits const &sourceTraits, + TextInputTraits const &defaultTraits) { + auto traits = TextInputTraits{}; + + traits.multiline = convertRawProp( + rawProps, "multiline", sourceTraits.multiline, defaultTraits.multiline); + traits.autocapitalizationType = convertRawProp( + rawProps, + "autoCapitalize", + sourceTraits.autocapitalizationType, + defaultTraits.autocapitalizationType); + traits.autoCorrect = convertRawProp( + rawProps, + "autoCorrect", + sourceTraits.autoCorrect, + defaultTraits.autoCorrect); + traits.contextMenuHidden = convertRawProp( + rawProps, + "contextMenuHidden", + sourceTraits.contextMenuHidden, + defaultTraits.contextMenuHidden); + traits.editable = convertRawProp( + rawProps, "editable", sourceTraits.editable, defaultTraits.editable); + traits.enablesReturnKeyAutomatically = convertRawProp( + rawProps, + "enablesReturnKeyAutomatically", + sourceTraits.enablesReturnKeyAutomatically, + defaultTraits.enablesReturnKeyAutomatically); + traits.keyboardAppearance = convertRawProp( + rawProps, + "keyboardAppearance", + sourceTraits.keyboardAppearance, + defaultTraits.keyboardAppearance); + traits.spellCheck = convertRawProp( + rawProps, + "spellCheck", + sourceTraits.spellCheck, + defaultTraits.spellCheck); + traits.caretHidden = convertRawProp( + rawProps, + "caretHidden", + sourceTraits.caretHidden, + defaultTraits.caretHidden); + traits.clearButtonMode = convertRawProp( + rawProps, + "clearButtonMode", + sourceTraits.clearButtonMode, + defaultTraits.clearButtonMode); + traits.scrollEnabled = convertRawProp( + rawProps, + "scrollEnabled", + sourceTraits.scrollEnabled, + defaultTraits.scrollEnabled); + traits.secureTextEntry = convertRawProp( + rawProps, + "secureTextEntry", + sourceTraits.secureTextEntry, + defaultTraits.secureTextEntry); + traits.blurOnSubmit = convertRawProp( + rawProps, + "blurOnSubmit", + sourceTraits.blurOnSubmit, + defaultTraits.blurOnSubmit); + traits.clearTextOnFocus = convertRawProp( + rawProps, + "clearTextOnFocus", + sourceTraits.clearTextOnFocus, + defaultTraits.clearTextOnFocus); + traits.keyboardType = convertRawProp( + rawProps, + "keyboardType", + sourceTraits.keyboardType, + defaultTraits.keyboardType); + traits.returnKeyType = convertRawProp( + rawProps, + "returnKeyType", + sourceTraits.returnKeyType, + defaultTraits.returnKeyType); + traits.selectTextOnFocus = convertRawProp( + rawProps, + "selectTextOnFocus", + sourceTraits.selectTextOnFocus, + defaultTraits.selectTextOnFocus); + traits.textContentType = convertRawProp( + rawProps, + "textContentType", + sourceTraits.textContentType, + defaultTraits.textContentType); + traits.passwordRules = convertRawProp( + rawProps, + "passwordRules", + sourceTraits.passwordRules, + defaultTraits.passwordRules); + + return traits; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h index 82716091961c04..6abf45b979b721 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/TextLayoutManager.h @@ -27,6 +27,8 @@ using SharedTextLayoutManager = std::shared_ptr; */ class TextLayoutManager { public: + using Shared = std::shared_ptr; + TextLayoutManager(ContextContainer::Shared const &contextContainer); ~TextLayoutManager(); diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp index 0e643eba1f1cee..583e657aa5bb19 100644 --- a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp @@ -98,6 +98,12 @@ static std::string componentNameByReactViewName(std::string viewName) { return "View"; } + // iOS-only + if (viewName == "MultilineTextInputView" || + viewName == "SinglelineTextInputView") { + return "TextInput"; + } + return viewName; } From 41557966b5c3ea076782fd9f116f96f344c7d675 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 13 Jan 2020 23:18:06 -0800 Subject: [PATCH 0013/1126] Fabric: component on iOS: RCTTextInputUtils Summary: RCTTextInputUtils contains a bunch of conventions and convenience functions that we use in TextInput. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D19226658 fbshipit-source-id: df72dcdc052b96b6daef2cc0839235761005d914 --- .../TextInput/Singleline/RCTUITextField.m | 1 - .../TextInput/RCTTextInputUtils.h | 43 ++++ .../TextInput/RCTTextInputUtils.mm | 198 ++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index e7874e3cdb7a12..de8f6efe844971 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -9,7 +9,6 @@ #import #import - #import #import diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h new file mode 100644 index 00000000000000..054bf41c811bbd --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +void RCTCopyBackedTextInput( + UIView *fromTextInput, + UIView *toTextInput); + +UITextAutocorrectionType RCTUITextAutocorrectionTypeFromOptionalBool(facebook::better::optional autoCorrect); + +UITextAutocapitalizationType RCTUITextAutocapitalizationTypeFromAutocapitalizationType( + facebook::react::AutocapitalizationType autocapitalizationType); + +UIKeyboardAppearance RCTUIKeyboardAppearanceFromKeyboardAppearance( + facebook::react::KeyboardAppearance keyboardAppearance); + +UITextSpellCheckingType RCTUITextSpellCheckingTypeFromOptionalBool(facebook::better::optional spellCheck); + +UITextFieldViewMode RCTUITextFieldViewModeFromTextInputAccessoryVisibilityMode( + facebook::react::TextInputAccessoryVisibilityMode mode); + +UIKeyboardType RCTUIKeyboardTypeFromKeyboardType(facebook::react::KeyboardType keyboardType); + +UIReturnKeyType RCTUIReturnKeyTypeFromReturnKeyType(facebook::react::ReturnKeyType returnKeyType); + +API_AVAILABLE(ios(10.0)) +UITextContentType RCTUITextContentTypeFromString(std::string const &contentType); + +API_AVAILABLE(ios(12.0)) +UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(std::string const &passwordRules); + +NS_ASSUME_NONNULL_END diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm new file mode 100644 index 00000000000000..2540925b3d9e1f --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm @@ -0,0 +1,198 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTTextInputUtils.h" + +#import + +using namespace facebook::react; + +static NSAttributedString *RCTSanitizeAttributedString(NSAttributedString *attributedString) +{ + // Here we need to remove text attributes specific to particular kind of TextInput on iOS (e.g. limiting line number). + // TODO: Implement it properly. + return [[NSAttributedString alloc] initWithString:attributedString.string]; +} + +void RCTCopyBackedTextInput( + UIView *fromTextInput, + UIView *toTextInput) +{ + toTextInput.attributedText = RCTSanitizeAttributedString(fromTextInput.attributedText); + toTextInput.placeholder = fromTextInput.placeholder; + toTextInput.placeholderColor = fromTextInput.placeholderColor; + toTextInput.textContainerInset = fromTextInput.textContainerInset; + toTextInput.inputAccessoryView = fromTextInput.inputAccessoryView; + toTextInput.textInputDelegate = fromTextInput.textInputDelegate; + toTextInput.placeholderColor = fromTextInput.placeholderColor; + toTextInput.defaultTextAttributes = fromTextInput.defaultTextAttributes; + toTextInput.autocapitalizationType = fromTextInput.autocapitalizationType; + toTextInput.autocorrectionType = fromTextInput.autocorrectionType; + toTextInput.contextMenuHidden = fromTextInput.contextMenuHidden; + toTextInput.editable = fromTextInput.editable; + toTextInput.enablesReturnKeyAutomatically = fromTextInput.enablesReturnKeyAutomatically; + toTextInput.keyboardAppearance = fromTextInput.keyboardAppearance; + toTextInput.spellCheckingType = fromTextInput.spellCheckingType; + toTextInput.caretHidden = fromTextInput.caretHidden; + toTextInput.clearButtonMode = fromTextInput.clearButtonMode; + toTextInput.scrollEnabled = fromTextInput.scrollEnabled; + toTextInput.secureTextEntry = fromTextInput.secureTextEntry; + toTextInput.keyboardType = fromTextInput.keyboardType; + + if (@available(iOS 10.0, *)) { + toTextInput.textContentType = fromTextInput.textContentType; + } + + if (@available(iOS 12.0, *)) { + toTextInput.passwordRules = fromTextInput.passwordRules; + } + + [toTextInput setSelectedTextRange:fromTextInput.selectedTextRange notifyDelegate:NO]; +} + +UITextAutocorrectionType RCTUITextAutocorrectionTypeFromOptionalBool(facebook::better::optional autoCorrect) +{ + return autoCorrect.has_value() ? (*autoCorrect ? UITextAutocorrectionTypeYes : UITextAutocorrectionTypeNo) + : UITextAutocorrectionTypeDefault; +} + +UITextAutocapitalizationType RCTUITextAutocapitalizationTypeFromAutocapitalizationType( + AutocapitalizationType autocapitalizationType) +{ + switch (autocapitalizationType) { + case AutocapitalizationType::None: + return UITextAutocapitalizationTypeNone; + case AutocapitalizationType::Words: + return UITextAutocapitalizationTypeWords; + case AutocapitalizationType::Sentences: + return UITextAutocapitalizationTypeSentences; + case AutocapitalizationType::Characters: + return UITextAutocapitalizationTypeAllCharacters; + } +} + +UIKeyboardAppearance RCTUIKeyboardAppearanceFromKeyboardAppearance(KeyboardAppearance keyboardAppearance) +{ + switch (keyboardAppearance) { + case KeyboardAppearance::Default: + return UIKeyboardAppearanceDefault; + case KeyboardAppearance::Light: + return UIKeyboardAppearanceLight; + case KeyboardAppearance::Dark: + return UIKeyboardAppearanceDark; + } +} + +UITextSpellCheckingType RCTUITextSpellCheckingTypeFromOptionalBool(facebook::better::optional spellCheck) +{ + return spellCheck.has_value() ? (*spellCheck ? UITextSpellCheckingTypeYes : UITextSpellCheckingTypeNo) + : UITextSpellCheckingTypeDefault; +} + +UITextFieldViewMode RCTUITextFieldViewModeFromTextInputAccessoryVisibilityMode( + facebook::react::TextInputAccessoryVisibilityMode mode) +{ + switch (mode) { + case TextInputAccessoryVisibilityMode::Never: + return UITextFieldViewModeNever; + case TextInputAccessoryVisibilityMode::WhileEditing: + return UITextFieldViewModeWhileEditing; + case TextInputAccessoryVisibilityMode::UnlessEditing: + return UITextFieldViewModeUnlessEditing; + case TextInputAccessoryVisibilityMode::Always: + return UITextFieldViewModeAlways; + } +} + +UIKeyboardType RCTUIKeyboardTypeFromKeyboardType(KeyboardType keyboardType) +{ + switch (keyboardType) { + // Universal + case KeyboardType::Default: + return UIKeyboardTypeDefault; + case KeyboardType::EmailAddress: + return UIKeyboardTypeEmailAddress; + case KeyboardType::Numeric: + return UIKeyboardTypeDecimalPad; + case KeyboardType::PhonePad: + return UIKeyboardTypePhonePad; + case KeyboardType::NumberPad: + return UIKeyboardTypeNumberPad; + case KeyboardType::DecimalPad: + return UIKeyboardTypeDecimalPad; + // iOS-only + case KeyboardType::ASCIICapable: + return UIKeyboardTypeASCIICapable; + case KeyboardType::NumbersAndPunctuation: + return UIKeyboardTypeNumbersAndPunctuation; + case KeyboardType::URL: + return UIKeyboardTypeURL; + case KeyboardType::NamePhonePad: + return UIKeyboardTypeNamePhonePad; + case KeyboardType::Twitter: + return UIKeyboardTypeTwitter; + case KeyboardType::WebSearch: + return UIKeyboardTypeWebSearch; + case KeyboardType::ASCIICapableNumberPad: + if (@available(iOS 10.0, *)) { + return UIKeyboardTypeASCIICapableNumberPad; + } else { + return UIKeyboardTypeNumberPad; + } + // Android-only + case KeyboardType::VisiblePassword: + return UIKeyboardTypeDefault; + } +} + +UIReturnKeyType RCTUIReturnKeyTypeFromReturnKeyType(ReturnKeyType returnKeyType) +{ + switch (returnKeyType) { + case ReturnKeyType::Default: + return UIReturnKeyDefault; + case ReturnKeyType::Done: + return UIReturnKeyDone; + case ReturnKeyType::Go: + return UIReturnKeyGo; + case ReturnKeyType::Next: + return UIReturnKeyNext; + case ReturnKeyType::Search: + return UIReturnKeySearch; + case ReturnKeyType::Send: + return UIReturnKeySend; + // iOS-only + case ReturnKeyType::EmergencyCall: + return UIReturnKeyEmergencyCall; + case ReturnKeyType::Google: + return UIReturnKeyGoogle; + case ReturnKeyType::Join: + return UIReturnKeyJoin; + case ReturnKeyType::Route: + return UIReturnKeyRoute; + case ReturnKeyType::Yahoo: + return UIReturnKeyYahoo; + case ReturnKeyType::Continue: + return UIReturnKeyContinue; + // Android-only + case ReturnKeyType::None: + case ReturnKeyType::Previous: + return UIReturnKeyDefault; + } +} + +API_AVAILABLE(ios(10.0)) +UITextContentType RCTUITextContentTypeFromString(std::string const &contentType) +{ + // TODO: Implement properly (T26519801). + return RCTNSStringFromStringNilIfEmpty(contentType); +} + +API_AVAILABLE(ios(12.0)) +UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(std::string const &passwordRules) +{ + return [UITextInputPasswordRules passwordRulesWithDescriptor:RCTNSStringFromStringNilIfEmpty(passwordRules)]; +} From 8219db9a4ab42a07c08b4c4261297c7d410671e1 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 13 Jan 2020 23:18:06 -0800 Subject: [PATCH 0014/1126] Fabric: The basic implementation of for iOS Summary: This is the partial implementation of Fabric-compatible component on iOS. All features are supported besides those: * `focus()`, `blur()`, `clear()` imperative calls; * Controlled TextInput as the whole feature in general; * Controlling selection from JavaScript side; * `autoFocus` prop; * KeyboardAccessoryView. Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D17400907 fbshipit-source-id: 0ccd0e0923293e5f504d5fae7b7ba9f048f7d259 --- .../TextInput/RCTTextInputComponentView.h | 21 ++ .../TextInput/RCTTextInputComponentView.mm | 345 ++++++++++++++++++ .../Mounting/RCTComponentViewFactory.mm | 2 + 3 files changed, 368 insertions(+) create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h new file mode 100644 index 00000000000000..7540f05274c063 --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * UIView class for component. + */ +@interface RCTTextInputComponentView : RCTViewComponentView + +@end + +NS_ASSUME_NONNULL_END diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm new file mode 100644 index 00000000000000..532cc5754e8665 --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -0,0 +1,345 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTTextInputComponentView.h" + +#import +#import +#import +#import + +#import +#import +#import + +#import "RCTConversions.h" +#import "RCTTextInputUtils.h" + +using namespace facebook::react; + +@interface RCTTextInputComponentView () +@end + +@implementation RCTTextInputComponentView { + TextInputShadowNode::ConcreteState::Shared _state; + UIView *_backedTextInputView; + size_t _stateRevision; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + auto &props = *defaultProps; + + _backedTextInputView = props.traits.multiline ? [[RCTUITextView alloc] init] : [[RCTUITextField alloc] init]; + _backedTextInputView.frame = self.bounds; + _backedTextInputView.textInputDelegate = self; + [self addSubview:_backedTextInputView]; + } + + return self; +} + +#pragma mark - RCTComponentViewProtocol + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps +{ + auto const &oldTextInputProps = *std::static_pointer_cast(_props); + auto const &newTextInputProps = *std::static_pointer_cast(props); + + // Traits: + if (newTextInputProps.traits.multiline != oldTextInputProps.traits.multiline) { + [self _setMultiline:newTextInputProps.traits.multiline]; + } + + if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) { + _backedTextInputView.autocapitalizationType = + RCTUITextAutocapitalizationTypeFromAutocapitalizationType(newTextInputProps.traits.autocapitalizationType); + } + + if (newTextInputProps.traits.autoCorrect != oldTextInputProps.traits.autoCorrect) { + _backedTextInputView.autocorrectionType = + RCTUITextAutocorrectionTypeFromOptionalBool(newTextInputProps.traits.autoCorrect); + } + + if (newTextInputProps.traits.contextMenuHidden != oldTextInputProps.traits.contextMenuHidden) { + _backedTextInputView.contextMenuHidden = newTextInputProps.traits.contextMenuHidden; + } + + if (newTextInputProps.traits.editable != oldTextInputProps.traits.editable) { + _backedTextInputView.editable = newTextInputProps.traits.editable; + } + + if (newTextInputProps.traits.enablesReturnKeyAutomatically != + oldTextInputProps.traits.enablesReturnKeyAutomatically) { + _backedTextInputView.enablesReturnKeyAutomatically = newTextInputProps.traits.enablesReturnKeyAutomatically; + } + + if (newTextInputProps.traits.keyboardAppearance != oldTextInputProps.traits.keyboardAppearance) { + _backedTextInputView.keyboardAppearance = + RCTUIKeyboardAppearanceFromKeyboardAppearance(newTextInputProps.traits.keyboardAppearance); + } + + if (newTextInputProps.traits.spellCheck != oldTextInputProps.traits.spellCheck) { + _backedTextInputView.spellCheckingType = + RCTUITextSpellCheckingTypeFromOptionalBool(newTextInputProps.traits.spellCheck); + } + + if (newTextInputProps.traits.caretHidden != oldTextInputProps.traits.caretHidden) { + _backedTextInputView.caretHidden = newTextInputProps.traits.caretHidden; + } + + if (newTextInputProps.traits.clearButtonMode != oldTextInputProps.traits.clearButtonMode) { + _backedTextInputView.clearButtonMode = + RCTUITextFieldViewModeFromTextInputAccessoryVisibilityMode(newTextInputProps.traits.clearButtonMode); + } + + if (newTextInputProps.traits.scrollEnabled != oldTextInputProps.traits.scrollEnabled) { + _backedTextInputView.scrollEnabled = newTextInputProps.traits.scrollEnabled; + } + + if (newTextInputProps.traits.secureTextEntry != oldTextInputProps.traits.secureTextEntry) { + _backedTextInputView.secureTextEntry = newTextInputProps.traits.secureTextEntry; + } + + if (newTextInputProps.traits.keyboardType != oldTextInputProps.traits.keyboardType) { + _backedTextInputView.keyboardType = RCTUIKeyboardTypeFromKeyboardType(newTextInputProps.traits.keyboardType); + } + + if (newTextInputProps.traits.returnKeyType != oldTextInputProps.traits.returnKeyType) { + _backedTextInputView.returnKeyType = RCTUIReturnKeyTypeFromReturnKeyType(newTextInputProps.traits.returnKeyType); + } + + if (newTextInputProps.traits.textContentType != oldTextInputProps.traits.textContentType) { + if (@available(iOS 10.0, *)) { + _backedTextInputView.textContentType = RCTUITextContentTypeFromString(newTextInputProps.traits.textContentType); + } + } + + if (newTextInputProps.traits.passwordRules != oldTextInputProps.traits.passwordRules) { + if (@available(iOS 12.0, *)) { + _backedTextInputView.passwordRules = + RCTUITextInputPasswordRulesFromString(newTextInputProps.traits.passwordRules); + } + } + + // Traits `blurOnSubmit`, `clearTextOnFocus`, and `selectTextOnFocus` were omitted intentially here + // because they are being checked on-demand. + + // Other props: + if (newTextInputProps.placeholder != oldTextInputProps.placeholder) { + _backedTextInputView.placeholder = RCTNSStringFromString(newTextInputProps.placeholder); + } + + if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) { + _backedTextInputView.defaultTextAttributes = + RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes()); + } + + if (newTextInputProps.selectionColor != oldTextInputProps.selectionColor) { + _backedTextInputView.tintColor = RCTUIColorFromSharedColor(newTextInputProps.selectionColor); + } + + [super updateProps:props oldProps:oldProps]; +} + +- (void)updateState:(State::Shared const &)state oldState:(State::Shared const &)oldState +{ + _state = std::static_pointer_cast(state); + + if (!_state) { + assert(false && "State is `null` for component."); + _backedTextInputView.attributedText = nil; + return; + } + + auto data = _state->getData(); + + if (data.revision != _stateRevision) { + _stateRevision = data.revision; + _backedTextInputView.attributedText = RCTNSAttributedStringFromAttributedStringBox(data.attributedStringBox); + } +} + +- (void)updateLayoutMetrics:(LayoutMetrics const &)layoutMetrics + oldLayoutMetrics:(LayoutMetrics const &)oldLayoutMetrics +{ + [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics]; + + _backedTextInputView.frame = + UIEdgeInsetsInsetRect(self.bounds, RCTUIEdgeInsetsFromEdgeInsets(layoutMetrics.borderWidth)); + _backedTextInputView.textContainerInset = + RCTUIEdgeInsetsFromEdgeInsets(layoutMetrics.contentInsets - layoutMetrics.borderWidth); +} + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + _backedTextInputView.attributedText = [[NSAttributedString alloc] init]; + _state.reset(); + _stateRevision = 0; +} + +#pragma mark - RCTComponentViewProtocol + +- (void)_setMultiline:(BOOL)multiline +{ + [_backedTextInputView removeFromSuperview]; + UIView *backedTextInputView = + multiline ? [[RCTUITextView alloc] init] : [[RCTUITextField alloc] init]; + backedTextInputView.frame = _backedTextInputView.frame; + RCTCopyBackedTextInput(_backedTextInputView, backedTextInputView); + _backedTextInputView = backedTextInputView; + [self addSubview:_backedTextInputView]; +} + +#pragma mark - RCTBackedTextInputDelegate + +- (BOOL)textInputShouldBeginEditing +{ + return YES; +} + +- (void)textInputDidBeginEditing +{ + auto const &props = *std::static_pointer_cast(_props); + + if (props.traits.clearTextOnFocus) { + _backedTextInputView.attributedText = [NSAttributedString new]; + [self textInputDidChange]; + } + + if (props.traits.selectTextOnFocus) { + [_backedTextInputView selectAll:nil]; + [self textInputDidChangeSelection]; + } + + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onFocus([self _textInputMetrics]); + } +} + +- (BOOL)textInputShouldEndEditing +{ + return YES; +} + +- (void)textInputDidEndEditing +{ + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onEndEditing([self _textInputMetrics]); + std::static_pointer_cast(_eventEmitter)->onBlur([self _textInputMetrics]); + } +} + +- (BOOL)textInputShouldReturn +{ + // We send `submit` event here, in `textInputShouldReturn` + // (not in `textInputDidReturn)`, because of semantic of the event: + // `onSubmitEditing` is called when "Submit" button + // (the blue key on onscreen keyboard) did pressed + // (no connection to any specific "submitting" process). + + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onSubmitEditing([self _textInputMetrics]); + } + + auto const &props = *std::static_pointer_cast(_props); + return props.traits.blurOnSubmit; +} + +- (void)textInputDidReturn +{ + // Does nothing. +} + +- (NSString *)textInputShouldChangeText:(NSString *)text inRange:(NSRange)range +{ + if (!_backedTextInputView.textWasPasted) { + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onKeyPress([self _textInputMetrics]); + } + } + + auto const &props = *std::static_pointer_cast(_props); + if (props.maxLength) { + NSInteger allowedLength = props.maxLength - _backedTextInputView.attributedText.string.length + range.length; + + if (allowedLength <= 0) { + return nil; + } + + return allowedLength > text.length ? text : [text substringToIndex:allowedLength]; + } + + return text; +} + +- (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text +{ + return YES; +} + +- (void)textInputDidChange +{ + [self _updateState]; + + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onChange([self _textInputMetrics]); + } +} + +- (void)textInputDidChangeSelection +{ + if (_eventEmitter) { + std::static_pointer_cast(_eventEmitter)->onSelectionChange([self _textInputMetrics]); + } +} + +#pragma mark - Other + +- (TextInputMetrics)_textInputMetrics +{ + TextInputMetrics metrics; + metrics.text = RCTStringFromNSString(_backedTextInputView.attributedText.string); + metrics.selectionRange = [self _selectionRange]; + return metrics; +} + +- (void)_updateState +{ + NSAttributedString *attributedString = _backedTextInputView.attributedText; + + if (!_state) { + return; + } + + auto data = _state->getData(); + data.revision++; + _stateRevision = data.revision; + data.attributedStringBox = RCTAttributedStringBoxFromNSAttributedString(attributedString); + _state->updateState(std::move(data), EventPriority::SynchronousUnbatched); +} + +- (AttributedString::Range)_selectionRange +{ + UITextRange *selectedTextRange = _backedTextInputView.selectedTextRange; + NSInteger start = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument + toPosition:selectedTextRange.start]; + NSInteger end = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument + toPosition:selectedTextRange.end]; + return AttributedString::Range{(int)start, (int)(end - start)}; +} + +@end diff --git a/React/Fabric/Mounting/RCTComponentViewFactory.mm b/React/Fabric/Mounting/RCTComponentViewFactory.mm index a80af0122587f9..1ef6801e67e864 100644 --- a/React/Fabric/Mounting/RCTComponentViewFactory.mm +++ b/React/Fabric/Mounting/RCTComponentViewFactory.mm @@ -30,6 +30,7 @@ #import "RCTMountingTransactionObserving.h" #import "RCTParagraphComponentView.h" #import "RCTRootComponentView.h" +#import "RCTTextInputComponentView.h" #import "RCTUnimplementedViewComponentView.h" #import "RCTViewComponentView.h" @@ -55,6 +56,7 @@ + (RCTComponentViewFactory *)standardComponentViewFactory [componentViewFactory registerComponentViewClass:[RCTRootComponentView class]]; [componentViewFactory registerComponentViewClass:[RCTViewComponentView class]]; [componentViewFactory registerComponentViewClass:[RCTParagraphComponentView class]]; + [componentViewFactory registerComponentViewClass:[RCTTextInputComponentView class]]; Class imageClass = RCTComponentViewClassWithName("Image"); if (imageClass) { From 35c6bb9ac0fc452428e85fee72affb4fc29f500c Mon Sep 17 00:00:00 2001 From: Christoph Nakazawa Date: Mon, 13 Jan 2020 23:18:22 -0800 Subject: [PATCH 0015/1126] Only set dimensions if the window attributes change Differential Revision: D19386339 fbshipit-source-id: b7f14c540ceec40cae0c4eb9fc93f2020a6ee16f --- Libraries/Utilities/useWindowDimensions.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Libraries/Utilities/useWindowDimensions.js b/Libraries/Utilities/useWindowDimensions.js index 3de619a5eab877..f298649c943ccc 100644 --- a/Libraries/Utilities/useWindowDimensions.js +++ b/Libraries/Utilities/useWindowDimensions.js @@ -15,19 +15,26 @@ import {type DisplayMetrics} from './NativeDeviceInfo'; import {useEffect, useState} from 'react'; export default function useWindowDimensions(): DisplayMetrics { - const [dims, setDims] = useState(() => Dimensions.get('window')); + const [dimensions, setDimensions] = useState(() => Dimensions.get('window')); useEffect(() => { function handleChange({window}) { - setDims(window); + if ( + dimensions.width !== window.width || + dimensions.height !== window.height || + dimensions.scale !== window.scale || + dimensions.fontScale !== window.fontScale + ) { + setDimensions(window); + } } Dimensions.addEventListener('change', handleChange); // We might have missed an update between calling `get` in render and // `addEventListener` in this handler, so we set it here. If there was // no change, React will filter out this update as a no-op. - setDims(Dimensions.get('window')); + handleChange({window: Dimensions.get('window')}); return () => { Dimensions.removeEventListener('change', handleChange); }; - }, []); - return dims; + }, [dimensions]); + return dimensions; } From 8d57691a606ce81e6d861f93ccc11875088f58b6 Mon Sep 17 00:00:00 2001 From: Nate Stedman Date: Mon, 13 Jan 2020 23:23:14 -0800 Subject: [PATCH 0016/1126] Add extension API parameters to libraries Summary: Changelog: [Internal] Differential Revision: D19377037 fbshipit-source-id: 3026a34005707fb371df60eaacd142988b012751 --- Libraries/FBLazyVector/BUCK | 1 + Libraries/FBReactNativeSpec/BUCK | 1 + Libraries/RCTRequired/BUCK | 1 + React/CoreModules/BUCK | 1 + 4 files changed, 4 insertions(+) diff --git a/Libraries/FBLazyVector/BUCK b/Libraries/FBLazyVector/BUCK index 6c3c798d9ca06b..afefaac8f86f46 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -5,6 +5,7 @@ fb_apple_library( autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = False, + extension_api_only = True, frameworks = [], labels = ["supermodule:ios/isolation/infra.react_native"], link_whole = False, diff --git a/Libraries/FBReactNativeSpec/BUCK b/Libraries/FBReactNativeSpec/BUCK index 72cb95bac5beb6..8d9b6b2126cea0 100644 --- a/Libraries/FBReactNativeSpec/BUCK +++ b/Libraries/FBReactNativeSpec/BUCK @@ -10,6 +10,7 @@ fb_apple_library( prefix = "FBReactNativeSpec", ), contacts = ["oncall+react_native@xmail.facebook.com"], + extension_api_only = True, frameworks = [ "Foundation", "UIKit", diff --git a/Libraries/RCTRequired/BUCK b/Libraries/RCTRequired/BUCK index d061b9e31e92aa..f3459e05bb749a 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -4,6 +4,7 @@ fb_apple_library( name = "RCTRequired", autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], + extension_api_only = True, frameworks = ["Foundation"], labels = ["supermodule:ios/isolation/infra.react_native"], ) diff --git a/React/CoreModules/BUCK b/React/CoreModules/BUCK index f42fcca46f2485..f856c64f8ea546 100644 --- a/React/CoreModules/BUCK +++ b/React/CoreModules/BUCK @@ -26,6 +26,7 @@ rn_apple_library( "WebKit", ], exported_preprocessor_flags = rn_extra_build_flags(), + extension_api_only = True, frameworks = [ "Foundation", "UIKit", From d5ba113bb2cd839ea38768785e527fbbc9636e41 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Tue, 14 Jan 2020 01:02:22 -0800 Subject: [PATCH 0017/1126] clang-format cpp Summary: Ran `arc f` against some CPP files to be modified with the next diff to reduce the churn on it. ## Changelog [Android] [Changed] - Formatted cpp/h code with clang-format Reviewed By: javache Differential Revision: D19371785 fbshipit-source-id: b7f7b92c4cb9ec7f8da728bb577db29cf11fbb39 --- .../com/facebook/react/fabric/jni/Binding.cpp | 221 +++++++++++------- .../com/facebook/react/fabric/jni/Binding.h | 14 +- .../fabric/jni/ComponentFactoryDelegate.h | 4 +- .../react/fabric/jni/EventBeatManager.cpp | 4 +- .../react/fabric/jni/EventEmitterWrapper.cpp | 4 +- .../react/fabric/jni/EventEmitterWrapper.h | 4 +- .../react/fabric/jni/NodeStateWrapper.cpp | 6 +- .../react/fabric/jni/NodeStateWrapper.h | 7 +- .../com/facebook/react/fabric/jni/OnLoad.cpp | 2 +- .../fabric/jni/ReactNativeConfigHolder.cpp | 8 +- .../fabric/jni/ReactNativeConfigHolder.h | 8 +- .../react/fabric/jni/StateWrapperImpl.cpp | 10 +- .../react/fabric/jni/StateWrapperImpl.h | 3 +- .../react/modules/blob/jni/BlobCollector.cpp | 4 +- .../core/jni/ReactCommon/CallInvokerHolder.h | 5 +- .../core/jni/ReactCommon/OnLoad.cpp | 3 +- .../jni/ReactCommon/TurboModuleManager.cpp | 161 +++++++------ .../core/jni/ReactCommon/TurboModuleManager.h | 47 ++-- .../ReactCommon/TurboModuleManagerDelegate.h | 26 ++- .../jni/react/jni/CatalystInstanceImpl.cpp | 8 +- .../main/jni/react/jni/CxxModuleWrapperBase.h | 17 +- .../src/main/jni/react/jni/JCallback.h | 17 +- .../src/main/jni/react/jni/JInspector.h | 46 ++-- .../jni/react/jni/JMessageQueueThread.cpp | 53 +++-- .../main/jni/react/jni/JMessageQueueThread.h | 20 +- .../src/main/jni/react/jni/JReactMarker.cpp | 23 +- .../src/main/jni/react/jni/JReactMarker.h | 21 +- .../src/main/jni/react/jni/JSLoader.cpp | 42 ++-- .../src/main/jni/react/jni/JSLoader.h | 10 +- .../main/jni/react/jni/JavaModuleWrapper.cpp | 165 +++++++------ .../main/jni/react/jni/JavaModuleWrapper.h | 58 +++-- .../jni/react/jni/JavaScriptExecutorHolder.h | 8 +- .../src/main/jni/react/jni/MethodInvoker.cpp | 162 +++++++------ .../src/main/jni/react/jni/MethodInvoker.h | 25 +- .../jni/react/jni/ModuleRegistryBuilder.h | 19 +- .../src/main/jni/react/jni/NativeArray.cpp | 12 +- .../src/main/jni/react/jni/NativeArray.h | 6 +- .../src/main/jni/react/jni/NativeCommon.h | 8 +- .../src/main/jni/react/jni/NativeMap.h | 7 +- .../src/main/jni/react/jni/ProxyExecutor.cpp | 90 +++---- .../src/main/jni/react/jni/ProxyExecutor.h | 52 +++-- .../main/jni/react/jni/WritableNativeArray.h | 14 +- .../main/jni/react/jni/WritableNativeMap.h | 17 +- .../src/main/jni/react/perftests/OnLoad.cpp | 141 ++++++----- 44 files changed, 924 insertions(+), 658 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index ed881126d224ba..4e88dda6afdd22 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -16,9 +16,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -73,7 +73,6 @@ std::shared_ptr Binding::getScheduler() { return scheduler_; } - void Binding::startSurface( jint surfaceId, jni::alias_ref moduleName, @@ -89,7 +88,11 @@ void Binding::startSurface( LayoutContext context; context.pointScaleFactor = pointScaleFactor_; scheduler->startSurface( - surfaceId, moduleName->toStdString(), initialProps->consume(), {}, context); + surfaceId, + moduleName->toStdString(), + initialProps->consume(), + {}, + context); } void Binding::startSurfaceWithConstraints( @@ -200,10 +203,12 @@ void Binding::installFabricUIManager( LOG(WARNING) << "Binding::installFabricUIManager() was called (address: " << this << ")."; - // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time + // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes + // at the same time std::lock(schedulerMutex_, javaUIManagerMutex_); std::lock_guard schedulerLock(schedulerMutex_, std::adopt_lock); - std::lock_guard uiManagerLock(javaUIManagerMutex_, std::adopt_lock); + std::lock_guard uiManagerLock( + javaUIManagerMutex_, std::adopt_lock); javaUIManager_ = make_global(javaUIManager); @@ -226,13 +231,15 @@ void Binding::installFabricUIManager( // TODO: T31905686 Create synchronous Event Beat jni::global_ref localJavaUIManager = javaUIManager_; EventBeat::Factory synchronousBeatFactory = - [eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) { + [eventBeatManager, runtimeExecutor, localJavaUIManager]( + EventBeat::SharedOwnerBox const &ownerBox) { return std::make_unique( ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); }; EventBeat::Factory asynchronousBeatFactory = - [eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) { + [eventBeatManager, runtimeExecutor, localJavaUIManager]( + EventBeat::SharedOwnerBox const &ownerBox) { return std::make_unique( ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); }; @@ -244,12 +251,14 @@ void Binding::installFabricUIManager( // Keep reference to config object and cache some feature flags here reactNativeConfig_ = config; - shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool("react_fabric:enable_removedelete_collation_android"); + shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool( + "react_fabric:enable_removedelete_collation_android"); collapseDeleteCreateMountingInstructions_ = reactNativeConfig_->getBool( "react_fabric:enabled_collapse_delete_create_mounting_instructions"); ; - disablePreallocateViews_ = reactNativeConfig_->getBool("react_fabric:disabled_view_preallocation_android"); + disablePreallocateViews_ = reactNativeConfig_->getBool( + "react_fabric:disabled_view_preallocation_android"); auto toolbox = SchedulerToolbox{}; toolbox.contextContainer = contextContainer; @@ -263,10 +272,12 @@ void Binding::installFabricUIManager( void Binding::uninstallFabricUIManager() { LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: " << this << ")."; - // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time + // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes + // at the same time std::lock(schedulerMutex_, javaUIManagerMutex_); std::lock_guard schedulerLock(schedulerMutex_, std::adopt_lock); - std::lock_guard uiManagerLock(javaUIManagerMutex_, std::adopt_lock); + std::lock_guard uiManagerLock( + javaUIManagerMutex_, std::adopt_lock); scheduler_ = nullptr; javaUIManager_ = nullptr; @@ -279,8 +290,9 @@ inline local_ref castReadableMap( } inline local_ref castReadableArray( - local_ref nativeArray) { - return make_local(reinterpret_cast(nativeArray.get())); + local_ref nativeArray) { + return make_local( + reinterpret_cast(nativeArray.get())); } // TODO: this method will be removed when binding for components are code-gen @@ -351,8 +363,8 @@ local_ref createUpdateLayoutMountItem( oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) { static auto updateLayoutInstruction = jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jint, jint, jint, jint, jint, jint)>( - "updateLayoutMountItem"); + ->getMethod( + jint, jint, jint, jint, jint, jint)>("updateLayoutMountItem"); auto layoutMetrics = newChildShadowView.layoutMetrics; auto pointScaleFactor = layoutMetrics.pointScaleFactor; auto frame = layoutMetrics.frame; @@ -361,7 +373,8 @@ local_ref createUpdateLayoutMountItem( int y = round(frame.origin.y * pointScaleFactor); int w = round(frame.size.width * pointScaleFactor); int h = round(frame.size.height * pointScaleFactor); - auto layoutDirection = toInt(newChildShadowView.layoutMetrics.layoutDirection); + auto layoutDirection = + toInt(newChildShadowView.layoutMetrics.layoutDirection); return updateLayoutInstruction( javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection); } @@ -370,20 +383,20 @@ local_ref createUpdateLayoutMountItem( } local_ref createUpdatePaddingMountItem( - const jni::global_ref &javaUIManager, - const ShadowViewMutation &mutation) { - + const jni::global_ref &javaUIManager, + const ShadowViewMutation &mutation) { auto oldChildShadowView = mutation.oldChildShadowView; auto newChildShadowView = mutation.newChildShadowView; - if (oldChildShadowView.layoutMetrics.contentInsets == newChildShadowView.layoutMetrics.contentInsets) { + if (oldChildShadowView.layoutMetrics.contentInsets == + newChildShadowView.layoutMetrics.contentInsets) { return nullptr; } static auto updateLayoutInstruction = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jint, jint, jint, jint, jint)>( - "updatePaddingMountItem"); + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod(jint, jint, jint, jint, jint)>( + "updatePaddingMountItem"); auto layoutMetrics = newChildShadowView.layoutMetrics; auto pointScaleFactor = layoutMetrics.pointScaleFactor; @@ -394,7 +407,8 @@ local_ref createUpdatePaddingMountItem( int right = round(contentInsets.right * pointScaleFactor); int bottom = round(contentInsets.bottom * pointScaleFactor); - return updateLayoutInstruction(javaUIManager, newChildShadowView.tag, left, top, right, bottom); + return updateLayoutInstruction( + javaUIManager, newChildShadowView.tag, left, top, right, bottom); } local_ref createInsertMountItem( @@ -439,9 +453,9 @@ local_ref createUpdateStateMountItem( const jni::global_ref &javaUIManager, const ShadowViewMutation &mutation) { static auto updateStateInstruction = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jint, jobject)>( - "updateStateMountItem"); + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod(jint, jobject)>( + "updateStateMountItem"); auto state = mutation.newChildShadowView.state; @@ -456,9 +470,9 @@ local_ref createUpdateStateMountItem( } return updateStateInstruction( - javaUIManager, - mutation.newChildShadowView.tag, - (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr)); + javaUIManager, + mutation.newChildShadowView.tag, + (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr)); } local_ref createRemoveMountItem( @@ -487,14 +501,13 @@ local_ref createDeleteMountItem( } local_ref createRemoveAndDeleteMultiMountItem( - const jni::global_ref &javaUIManager, - const std::vector &metadata) { - + const jni::global_ref &javaUIManager, + const std::vector &metadata) { auto env = Environment::current(); - auto removeAndDeleteArray = env->NewIntArray(metadata.size()*4); + auto removeAndDeleteArray = env->NewIntArray(metadata.size() * 4); int position = 0; jint temp[4]; - for (const auto& x : metadata) { + for (const auto &x : metadata) { temp[0] = x.tag; temp[1] = x.parentTag; temp[2] = x.index; @@ -504,30 +517,34 @@ local_ref createRemoveAndDeleteMultiMountItem( } static auto removeDeleteMultiInstruction = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jintArray)>("removeDeleteMultiMountItem"); + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod(jintArray)>( + "removeDeleteMultiMountItem"); auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray); - // It is not strictly necessary to manually delete the ref here, in this particular case. - // If JNI memory is being allocated in a loop, it's easy to overload the localref table - // and crash; this is not possible in this case since the JNI would automatically clear this - // ref when it goes out of scope, anyway. However, this is being left here as a reminder of - // good hygiene and to be careful with JNI-allocated memory in general. + // It is not strictly necessary to manually delete the ref here, in this + // particular case. If JNI memory is being allocated in a loop, it's easy to + // overload the localref table and crash; this is not possible in this case + // since the JNI would automatically clear this ref when it goes out of scope, + // anyway. However, this is being left here as a reminder of good hygiene and + // to be careful with JNI-allocated memory in general. env->DeleteLocalRef(removeAndDeleteArray); return ret; } -// TODO T48019320: because we pass initial props and state to the Create (and preallocate) mount instruction, -// we technically don't need to pass the first Update to any components. Dedupe? +// TODO T48019320: because we pass initial props and state to the Create (and +// preallocate) mount instruction, we technically don't need to pass the first +// Update to any components. Dedupe? local_ref createCreateMountItem( const jni::global_ref &javaUIManager, const ShadowViewMutation &mutation, const Tag surfaceId) { static auto createJavaInstruction = jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>( + ->getMethod( + jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>( "createMountItem"); auto newChildShadowView = mutation.newChildShadowView; @@ -539,7 +556,7 @@ local_ref createCreateMountItem( newChildShadowView.layoutMetrics != EmptyLayoutMetrics; local_ref props = castReadableMap( - ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps)); + ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps)); // Do not hold onto Java object from C // We DO want to hold onto C object from Java, since we don't know the @@ -570,7 +587,8 @@ void Binding::schedulerDidFinishTransaction( jni::global_ref localJavaUIManager = getJavaUIManager(); if (!localJavaUIManager) { - LOG(ERROR) << "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared"; + LOG(ERROR) + << "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared"; return; } @@ -651,16 +669,20 @@ void Binding::schedulerDidFinishTransaction( oldChildShadowView.layoutMetrics == EmptyLayoutMetrics; // Handle accumulated removals/deletions - if (shouldCollateRemovesAndDeletes_ && mutation.type != ShadowViewMutation::Remove && mutation.type != ShadowViewMutation::Delete) { + if (shouldCollateRemovesAndDeletes_ && + mutation.type != ShadowViewMutation::Remove && + mutation.type != ShadowViewMutation::Delete) { if (toRemove.size() > 0) { - mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); + mountItems[position++] = + createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); toRemove.clear(); } } switch (mutation.type) { case ShadowViewMutation::Create: { - if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 || + if (disablePreallocateViews_ || + mutation.newChildShadowView.props->revision > 1 || deletedViewTags.find(mutation.newChildShadowView.tag) != deletedViewTags.end()) { mountItems[position++] = @@ -671,9 +693,15 @@ void Binding::schedulerDidFinishTransaction( case ShadowViewMutation::Remove: { if (!isVirtual) { if (shouldCollateRemovesAndDeletes_) { - toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, mutation.parentShadowView.tag, mutation.index, true, false}); + toRemove.push_back( + RemoveDeleteMetadata{mutation.oldChildShadowView.tag, + mutation.parentShadowView.tag, + mutation.index, + true, + false}); } else { - mountItems[position++] = createRemoveMountItem(localJavaUIManager, mutation); + mountItems[position++] = + createRemoveMountItem(localJavaUIManager, mutation); } } break; @@ -681,15 +709,22 @@ void Binding::schedulerDidFinishTransaction( case ShadowViewMutation::Delete: { if (shouldCollateRemovesAndDeletes_) { // It is impossible to delete without removing node first - const auto& it = std::find_if(std::begin(toRemove), std::end(toRemove), [&mutation](const auto& x) { return x.tag == mutation.oldChildShadowView.tag; }); + const auto &it = std::find_if( + std::begin(toRemove), + std::end(toRemove), + [&mutation](const auto &x) { + return x.tag == mutation.oldChildShadowView.tag; + }); if (it != std::end(toRemove)) { it->shouldDelete = true; } else { - toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, -1, -1, false, true}); + toRemove.push_back(RemoveDeleteMetadata{ + mutation.oldChildShadowView.tag, -1, -1, false, true}); } } else { - mountItems[position++] = createDeleteMountItem(localJavaUIManager, mutation); + mountItems[position++] = + createDeleteMountItem(localJavaUIManager, mutation); } deletedViewTags.insert(mutation.oldChildShadowView.tag); @@ -719,7 +754,8 @@ void Binding::schedulerDidFinishTransaction( mountItems[position++] = updateLayoutMountItem; } - auto updatePaddingMountItem = createUpdatePaddingMountItem(localJavaUIManager, mutation); + auto updatePaddingMountItem = + createUpdatePaddingMountItem(localJavaUIManager, mutation); if (updatePaddingMountItem) { mountItems[position++] = updatePaddingMountItem; } @@ -741,7 +777,8 @@ void Binding::schedulerDidFinishTransaction( mountItems[position++] = createInsertMountItem(localJavaUIManager, mutation); - if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 || + if (disablePreallocateViews_ || + mutation.newChildShadowView.props->revision > 1 || deletedViewTags.find(mutation.newChildShadowView.tag) != deletedViewTags.end()) { mountItems[position++] = @@ -769,7 +806,7 @@ void Binding::schedulerDidFinishTransaction( // Padding auto updatePaddingMountItem = - createUpdatePaddingMountItem(localJavaUIManager, mutation); + createUpdatePaddingMountItem(localJavaUIManager, mutation); if (updatePaddingMountItem) { mountItems[position++] = updatePaddingMountItem; } @@ -792,12 +829,14 @@ void Binding::schedulerDidFinishTransaction( // Handle remaining removals and deletions if (shouldCollateRemovesAndDeletes_ && toRemove.size() > 0) { - mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); + mountItems[position++] = + createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); toRemove.clear(); } if (position <= 0) { - // If there are no mountItems to be sent to the platform, then it is not necessary to even call. + // If there are no mountItems to be sent to the platform, then it is not + // necessary to even call. return; } @@ -810,10 +849,17 @@ void Binding::schedulerDidFinishTransaction( auto batch = createMountItemsBatchContainer( localJavaUIManager, mountItemsArray.get(), position, commitNumber); - static auto scheduleMountItem = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod( - "scheduleMountItem"); + static auto scheduleMountItem = jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod("scheduleMountItem"); long finishTransactionEndTime = monotonicTimeInMilliseconds(); @@ -837,14 +883,14 @@ void Binding::setPixelDensity(float pointScaleFactor) { void Binding::schedulerDidRequestPreliminaryViewAllocation( const SurfaceId surfaceId, const ShadowView &shadowView) { - if (disablePreallocateViews_) { return; } jni::global_ref localJavaUIManager = getJavaUIManager(); if (!localJavaUIManager) { - LOG(ERROR) << "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared"; + LOG(ERROR) + << "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared"; return; } @@ -881,28 +927,28 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation( } void Binding::schedulerDidDispatchCommand( - const ShadowView &shadowView, - std::string const &commandName, - folly::dynamic const args) { - + const ShadowView &shadowView, + std::string const &commandName, + folly::dynamic const args) { jni::global_ref localJavaUIManager = getJavaUIManager(); if (!localJavaUIManager) { - LOG(ERROR) << "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared"; + LOG(ERROR) + << "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared"; return; } static auto dispatchCommand = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod( - "dispatchCommand"); + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod( + "dispatchCommand"); local_ref command = make_jstring(commandName); - local_ref argsArray = castReadableArray( - ReadableNativeArray::newObjectCxxArgs(args)); + local_ref argsArray = + castReadableArray(ReadableNativeArray::newObjectCxxArgs(args)); - dispatchCommand(localJavaUIManager, shadowView.tag, command.get(), argsArray.get()); + dispatchCommand( + localJavaUIManager, shadowView.tag, command.get(), argsArray.get()); } void Binding::schedulerDidSetJSResponder( @@ -910,7 +956,6 @@ void Binding::schedulerDidSetJSResponder( const ShadowView &shadowView, const ShadowView &initialShadowView, bool blockNativeResponder) { - jni::global_ref localJavaUIManager = getJavaUIManager(); if (!localJavaUIManager) { LOG(ERROR) << "Binding::schedulerSetJSResponder: JavaUIManager disappeared"; @@ -919,23 +964,25 @@ void Binding::schedulerDidSetJSResponder( static auto setJSResponder = jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod( - "setJSResponder"); + ->getMethod("setJSResponder"); - setJSResponder(localJavaUIManager, shadowView.tag, initialShadowView.tag, (jboolean) blockNativeResponder); + setJSResponder( + localJavaUIManager, + shadowView.tag, + initialShadowView.tag, + (jboolean)blockNativeResponder); } void Binding::schedulerDidClearJSResponder() { jni::global_ref localJavaUIManager = getJavaUIManager(); if (!localJavaUIManager) { - LOG(ERROR) << "Binding::schedulerClearJSResponder: JavaUIManager disappeared"; + LOG(ERROR) + << "Binding::schedulerClearJSResponder: JavaUIManager disappeared"; return; } - static auto clearJSResponder = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod("clearJSResponder"); + static auto clearJSResponder = jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod("clearJSResponder"); clearJSResponder(localJavaUIManager); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h index 8c26a3ccb99bfe..a2c1f71a43e2bc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h @@ -76,17 +76,17 @@ class Binding : public jni::HybridClass, public SchedulerDelegate { const ShadowView &shadowView); void schedulerDidDispatchCommand( - const ShadowView &shadowView, - std::string const &commandName, - folly::dynamic const args); + const ShadowView &shadowView, + std::string const &commandName, + folly::dynamic const args); void setPixelDensity(float pointScaleFactor); void schedulerDidSetJSResponder( - SurfaceId surfaceId, - const ShadowView &shadowView, - const ShadowView &initialShadowView, - bool blockNativeResponder); + SurfaceId surfaceId, + const ShadowView &shadowView, + const ShadowView &initialShadowView, + bool blockNativeResponder); void schedulerDidClearJSResponder(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h index 43b4d1b0128230..e9d091df5ad529 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include #include @@ -25,7 +25,7 @@ class Instance; class ComponentFactoryDelegate : public jni::HybridClass { public: - constexpr static const char* const kJavaDescriptor = + constexpr static const char *const kJavaDescriptor = "Lcom/facebook/react/fabric/ComponentFactoryDelegate;"; static void registerNatives(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp index 4117d5a74d7640..fb825461a43e9c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp @@ -13,8 +13,8 @@ namespace facebook { namespace react { EventBeatManager::EventBeatManager( - jni::alias_ref jhybridobject) - : jhybridobject_(jhybridobject) {} + jni::alias_ref jhybridobject) + : jhybridobject_(jhybridobject) {} jni::local_ref EventBeatManager::initHybrid( jni::alias_ref jhybridobject) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp index ecf147aac4f4f5..cdcc13fc306ca2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp @@ -20,7 +20,7 @@ EventEmitterWrapper::initHybrid(jni::alias_ref) { void EventEmitterWrapper::invokeEvent( std::string eventName, - NativeMap* payload) { + NativeMap *payload) { eventEmitter->dispatchEvent( eventName, payload->consume(), EventPriority::AsynchronousBatched); } @@ -33,4 +33,4 @@ void EventEmitterWrapper::registerNatives() { } } // namespace react -} // namespace facebook \ No newline at end of file +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h index 28ab46b4e878f1..353aa24171941d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h @@ -18,14 +18,14 @@ class Instance; class EventEmitterWrapper : public jni::HybridClass { public: - constexpr static const char* const kJavaDescriptor = + constexpr static const char *const kJavaDescriptor = "Lcom/facebook/react/fabric/events/EventEmitterWrapper;"; static void registerNatives(); SharedEventEmitter eventEmitter; - void invokeEvent(std::string eventName, NativeMap* params); + void invokeEvent(std::string eventName, NativeMap *params); private: static jni::local_ref initHybrid(jni::alias_ref); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp index 77aaca433a67eb..7101bb7032aaad 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp @@ -14,8 +14,8 @@ using namespace facebook::jni; namespace facebook { namespace react { -jni::local_ref -NodeStateWrapper::initHybrid(jni::alias_ref) { +jni::local_ref NodeStateWrapper::initHybrid( + jni::alias_ref) { return makeCxxInstance(); } @@ -26,7 +26,7 @@ jni::local_ref NodeStateWrapper::getState() { return readableNativeMap; } -void NodeStateWrapper::updateState(ReadableNativeMap* map) { +void NodeStateWrapper::updateState(ReadableNativeMap *map) { // Get folly::dynamic from map auto dynamicMap = map->consume(); // Set state diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h index fa4e6c33880eda..d19cae44ad1199 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h @@ -16,7 +16,7 @@ namespace react { class NodeStateWrapper : public jni::HybridClass { public: - constexpr static const char* const kJavaDescriptor = + constexpr static const char *const kJavaDescriptor = "Lcom/facebook/react/fabric/NodeStateWrapper;"; NodeStateWrapper() {} @@ -24,9 +24,10 @@ class NodeStateWrapper : public jni::HybridClass { static void registerNatives(); jni::local_ref getState(); - void updateState(ReadableNativeMap* map); + void updateState(ReadableNativeMap *map); + + const State *state_; - const State* state_; private: static jni::local_ref initHybrid(jni::alias_ref); }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp index 824d2b9705ef40..f8b87bddd2dae5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp @@ -13,7 +13,7 @@ #include "EventEmitterWrapper.h" #include "StateWrapperImpl.h" -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { return facebook::xplat::initialize(vm, [] { facebook::react::Binding::registerNatives(); facebook::react::EventBeatManager::registerNatives(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp index dd567aff94de3b..e35531e9325dba 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp @@ -11,14 +11,14 @@ using namespace facebook::react; -bool ReactNativeConfigHolder::getBool(const std::string& param) const { +bool ReactNativeConfigHolder::getBool(const std::string ¶m) const { static const auto method = facebook::jni::findClassStatic( "com/facebook/react/fabric/ReactNativeConfig") ->getMethod("getBool"); return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); } -std::string ReactNativeConfigHolder::getString(const std::string& param) const { +std::string ReactNativeConfigHolder::getString(const std::string ¶m) const { static const auto method = facebook::jni::findClassStatic( "com/facebook/react/fabric/ReactNativeConfig") ->getMethod("getString"); @@ -26,14 +26,14 @@ std::string ReactNativeConfigHolder::getString(const std::string& param) const { ->toString(); } -int64_t ReactNativeConfigHolder::getInt64(const std::string& param) const { +int64_t ReactNativeConfigHolder::getInt64(const std::string ¶m) const { static const auto method = facebook::jni::findClassStatic( "com/facebook/react/fabric/ReactNativeConfig") ->getMethod("getInt64"); return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); } -double ReactNativeConfigHolder::getDouble(const std::string& param) const { +double ReactNativeConfigHolder::getDouble(const std::string ¶m) const { static const auto method = facebook::jni::findClassStatic( "com/facebook/react/fabric/ReactNativeConfig") ->getMethod("getDouble"); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h index eb2a689a610191..8b28ffb0a953d0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h @@ -25,10 +25,10 @@ class ReactNativeConfigHolder : public ReactNativeConfig { ReactNativeConfigHolder(jni::alias_ref reactNativeConfig) : reactNativeConfig_(make_global(reactNativeConfig)){}; - bool getBool(const std::string& param) const override; - std::string getString(const std::string& param) const override; - int64_t getInt64(const std::string& param) const override; - double getDouble(const std::string& param) const override; + bool getBool(const std::string ¶m) const override; + std::string getString(const std::string ¶m) const override; + int64_t getInt64(const std::string ¶m) const override; + double getDouble(const std::string ¶m) const override; private: jni::global_ref reactNativeConfig_; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp index 63d3d2e3c5a23b..73898875e87d93 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp @@ -17,8 +17,8 @@ namespace react { /** * Called from Java constructor through the JNI. */ -jni::local_ref -StateWrapperImpl::initHybrid(jni::alias_ref) { +jni::local_ref StateWrapperImpl::initHybrid( + jni::alias_ref) { return makeCxxInstance(); } @@ -29,7 +29,7 @@ jni::local_ref StateWrapperImpl::getState() { return readableNativeMap; } -void StateWrapperImpl::updateStateImpl(NativeMap* map) { +void StateWrapperImpl::updateStateImpl(NativeMap *map) { // Get folly::dynamic from map auto dynamicMap = map->consume(); // Set state @@ -38,8 +38,8 @@ void StateWrapperImpl::updateStateImpl(NativeMap* map) { void StateWrapperImpl::registerNatives() { registerHybrid({ - makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid), - makeNativeMethod("getState", StateWrapperImpl::getState), + makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid), + makeNativeMethod("getState", StateWrapperImpl::getState), makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl), }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h index 4e00fb004b2df9..fc93083c3b534d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h @@ -18,7 +18,7 @@ class Instance; class StateWrapperImpl : public jni::HybridClass { public: - constexpr static const char* const kJavaDescriptor = + constexpr static const char *const kJavaDescriptor = "Lcom/facebook/react/fabric/StateWrapperImpl;"; static void registerNatives(); @@ -27,6 +27,7 @@ class StateWrapperImpl : public jni::HybridClass { void updateStateImpl(NativeMap *map); State::Shared state_; + private: jni::alias_ref jhybridobject_; diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp index 4d95e17c99bf1b..a4ede5d71e3946 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp @@ -27,7 +27,7 @@ BlobCollector::BlobCollector( BlobCollector::~BlobCollector() { jni::ThreadScope::WithClassLoader([&] { static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor) - ->getMethod("remove"); + ->getMethod("remove"); removeMethod(blobModule_, jni::make_jstring(blobId_).get()); }); } @@ -36,7 +36,7 @@ void BlobCollector::nativeInstall( jni::alias_ref jThis, jni::alias_ref blobModule, jlong jsContextNativePointer) { - auto &runtime = *((jsi::Runtime *) jsContextNativePointer); + auto &runtime = *((jsi::Runtime *)jsContextNativePointer); auto blobModuleRef = jni::make_global(blobModule); runtime.global().setProperty( runtime, diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h index c982be0f6d5196..148ff2538b4856 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h @@ -7,15 +7,14 @@ #pragma once -#include #include +#include #include namespace facebook { namespace react { -class CallInvokerHolder - : public jni::HybridClass { +class CallInvokerHolder : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;"; diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp index 99d2ee106f3221..3a9e269fe32008 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp @@ -12,7 +12,8 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { return facebook::xplat::initialize(vm, [] { - // TODO: dvacca ramanpreet unify this with the way "ComponentDescriptorFactory" is defined in Fabric + // TODO: dvacca ramanpreet unify this with the way + // "ComponentDescriptorFactory" is defined in Fabric facebook::react::TurboModuleManager::registerNatives(); }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp index 051ea471653493..eae88b38143e1f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp @@ -11,8 +11,8 @@ #include #include -#include #include +#include #include #include "TurboModuleManager.h" @@ -21,37 +21,40 @@ namespace facebook { namespace react { TurboModuleManager::TurboModuleManager( - jni::alias_ref jThis, - jsi::Runtime* rt, - std::shared_ptr jsCallInvoker, - std::shared_ptr nativeCallInvoker, - jni::alias_ref delegate -): - javaPart_(jni::make_global(jThis)), - runtime_(rt), - jsCallInvoker_(jsCallInvoker), - nativeCallInvoker_(nativeCallInvoker), - delegate_(jni::make_global(delegate)), - turboModuleCache_(std::make_shared()) - {} + jni::alias_ref jThis, + jsi::Runtime *rt, + std::shared_ptr jsCallInvoker, + std::shared_ptr nativeCallInvoker, + jni::alias_ref delegate) + : javaPart_(jni::make_global(jThis)), + runtime_(rt), + jsCallInvoker_(jsCallInvoker), + nativeCallInvoker_(nativeCallInvoker), + delegate_(jni::make_global(delegate)), + turboModuleCache_(std::make_shared()) {} jni::local_ref TurboModuleManager::initHybrid( - jni::alias_ref jThis, - jlong jsContext, - jni::alias_ref jsCallInvokerHolder, - jni::alias_ref nativeCallInvokerHolder, - jni::alias_ref delegate -) { + jni::alias_ref jThis, + jlong jsContext, + jni::alias_ref jsCallInvokerHolder, + jni::alias_ref nativeCallInvokerHolder, + jni::alias_ref delegate) { auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker(); auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker(); - return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker, nativeCallInvoker, delegate); + return makeCxxInstance( + jThis, + (jsi::Runtime *)jsContext, + jsCallInvoker, + nativeCallInvoker, + delegate); } void TurboModuleManager::registerNatives() { registerHybrid({ - makeNativeMethod("initHybrid", TurboModuleManager::initHybrid), - makeNativeMethod("installJSIBindings", TurboModuleManager::installJSIBindings), + makeNativeMethod("initHybrid", TurboModuleManager::initHybrid), + makeNativeMethod( + "installJSIBindings", TurboModuleManager::installJSIBindings), }); } @@ -60,57 +63,67 @@ void TurboModuleManager::installJSIBindings() { return; // Runtime doesn't exist when attached to Chrome debugger. } - TurboModuleBinding::install(*runtime_, std::make_shared( - [ - turboModuleCache_ = std::weak_ptr(turboModuleCache_), - jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), - nativeCallInvoker_ = std::weak_ptr(nativeCallInvoker_), - delegate_ = jni::make_weak(delegate_), - javaPart_ = jni::make_weak(javaPart_) - ] - (const std::string &name) -> std::shared_ptr { - auto turboModuleCache = turboModuleCache_.lock(); - auto jsCallInvoker = jsCallInvoker_.lock(); - auto nativeCallInvoker = nativeCallInvoker_.lock(); - auto delegate = delegate_.lockLocal(); - auto javaPart = javaPart_.lockLocal(); - - if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || !delegate || !javaPart) { - return nullptr; - } - - auto turboModuleLookup = turboModuleCache->find(name); - if (turboModuleLookup != turboModuleCache->end()) { - return turboModuleLookup->second; - } - - auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); - if (cxxModule) { - turboModuleCache->insert({name, cxxModule}); - return cxxModule; - } - - static auto getLegacyCxxModule = delegate->getClass()->getMethod(const std::string&)>("getLegacyCxxModule"); - auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name); - - if (legacyCxxModule) { - auto turboModule = std::make_shared(legacyCxxModule->cthis()->getModule(), jsCallInvoker); - turboModuleCache->insert({name, turboModule}); - return turboModule; - } - - static auto getJavaModule = javaPart->getClass()->getMethod(const std::string&)>("getJavaModule"); - auto moduleInstance = getJavaModule(javaPart.get(), name); - - if (moduleInstance) { - auto turboModule = delegate->cthis()->getTurboModule(name, moduleInstance, jsCallInvoker, nativeCallInvoker); - turboModuleCache->insert({name, turboModule}); - return turboModule; - } - - return nullptr; - }) - ); + TurboModuleBinding::install( + *runtime_, + std::make_shared( + [turboModuleCache_ = + std::weak_ptr(turboModuleCache_), + jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), + nativeCallInvoker_ = std::weak_ptr(nativeCallInvoker_), + delegate_ = jni::make_weak(delegate_), + javaPart_ = jni::make_weak(javaPart_)]( + const std::string &name) -> std::shared_ptr { + auto turboModuleCache = turboModuleCache_.lock(); + auto jsCallInvoker = jsCallInvoker_.lock(); + auto nativeCallInvoker = nativeCallInvoker_.lock(); + auto delegate = delegate_.lockLocal(); + auto javaPart = javaPart_.lockLocal(); + + if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || + !delegate || !javaPart) { + return nullptr; + } + + auto turboModuleLookup = turboModuleCache->find(name); + if (turboModuleLookup != turboModuleCache->end()) { + return turboModuleLookup->second; + } + + auto cxxModule = + delegate->cthis()->getTurboModule(name, jsCallInvoker); + if (cxxModule) { + turboModuleCache->insert({name, cxxModule}); + return cxxModule; + } + + static auto getLegacyCxxModule = + delegate->getClass() + ->getMethod( + const std::string &)>("getLegacyCxxModule"); + auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name); + + if (legacyCxxModule) { + auto turboModule = std::make_shared( + legacyCxxModule->cthis()->getModule(), jsCallInvoker); + turboModuleCache->insert({name, turboModule}); + return turboModule; + } + + static auto getJavaModule = + javaPart->getClass() + ->getMethod( + const std::string &)>("getJavaModule"); + auto moduleInstance = getJavaModule(javaPart.get(), name); + + if (moduleInstance) { + auto turboModule = delegate->cthis()->getTurboModule( + name, moduleInstance, jsCallInvoker, nativeCallInvoker); + turboModuleCache->insert({name, turboModule}); + return turboModule; + } + + return nullptr; + })); } } // namespace react diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h index 26be4a311341a1..131d77095be9c1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h @@ -7,40 +7,42 @@ #pragma once -#include -#include +#include +#include +#include +#include #include #include -#include -#include #include #include -#include -#include +#include +#include namespace facebook { namespace react { class TurboModuleManager : public jni::HybridClass { -public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManager;"; + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/turbomodule/core/TurboModuleManager;"; static jni::local_ref initHybrid( - jni::alias_ref jThis, - jlong jsContext, - jni::alias_ref jsCallInvokerHolder, - jni::alias_ref nativeCallInvokerHolder, - jni::alias_ref delegate - ); + jni::alias_ref jThis, + jlong jsContext, + jni::alias_ref jsCallInvokerHolder, + jni::alias_ref nativeCallInvokerHolder, + jni::alias_ref delegate); static void registerNatives(); -private: + + private: friend HybridBase; jni::global_ref javaPart_; - jsi::Runtime* runtime_; + jsi::Runtime *runtime_; std::shared_ptr jsCallInvoker_; std::shared_ptr nativeCallInvoker_; jni::global_ref delegate_; - using TurboModuleCache = std::unordered_map>; + using TurboModuleCache = + std::unordered_map>; /** * TODO(T48018690): @@ -52,12 +54,11 @@ class TurboModuleManager : public jni::HybridClass { void installJSIBindings(); explicit TurboModuleManager( - jni::alias_ref jThis, - jsi::Runtime *rt, - std::shared_ptr jsCallInvoker, - std::shared_ptr nativeCallInvoker, - jni::alias_ref delegate - ); + jni::alias_ref jThis, + jsi::Runtime *rt, + std::shared_ptr jsCallInvoker, + std::shared_ptr nativeCallInvoker, + jni::alias_ref delegate); }; } // namespace react diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h index 720b54915c7324..6577d915f416a1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h @@ -7,23 +7,31 @@ #pragma once -#include -#include #include -#include +#include +#include #include +#include namespace facebook { namespace react { -class TurboModuleManagerDelegate : public jni::HybridClass { -public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;"; +class TurboModuleManagerDelegate + : public jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;"; - virtual std::shared_ptr getTurboModule(std::string name, jni::alias_ref turboModule, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker) = 0; - virtual std::shared_ptr getTurboModule(std::string name, std::shared_ptr jsInvoker) = 0; + virtual std::shared_ptr getTurboModule( + std::string name, + jni::alias_ref turboModule, + std::shared_ptr jsInvoker, + std::shared_ptr nativeInvoker) = 0; + virtual std::shared_ptr getTurboModule( + std::string name, + std::shared_ptr jsInvoker) = 0; -private: + private: friend HybridBase; }; diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 07ea9e43a92ee3..424e3c57ccc648 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -290,8 +290,8 @@ void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) { jni::alias_ref CatalystInstanceImpl::getJSCallInvokerHolder() { if (!jsCallInvokerHolder_) { - jsCallInvokerHolder_ = - jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared(instance_))); + jsCallInvokerHolder_ = jni::make_global(CallInvokerHolder::newObjectCxxArgs( + std::make_shared(instance_))); } return jsCallInvokerHolder_; @@ -301,7 +301,9 @@ jni::alias_ref CatalystInstanceImpl::getNativeCallInvokerHolder() { if (!nativeCallInvokerHolder_) { nativeCallInvokerHolder_ = - jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared(moduleMessageQueue_))); + jni::make_global(CallInvokerHolder::newObjectCxxArgs( + std::make_shared( + moduleMessageQueue_))); } return nativeCallInvokerHolder_; diff --git a/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h b/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h index b012b4eb648e4f..107d0ee71a156b 100644 --- a/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h +++ b/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h @@ -18,7 +18,7 @@ namespace react { struct JNativeModule : jni::JavaClass { constexpr static const char *const kJavaDescriptor = - "Lcom/facebook/react/bridge/NativeModule;"; + "Lcom/facebook/react/bridge/NativeModule;"; }; /** @@ -26,15 +26,14 @@ struct JNativeModule : jni::JavaClass { * must extend this base class. */ class CxxModuleWrapperBase - : public jni::HybridClass { -public: + : public jni::HybridClass { + public: constexpr static const char *const kJavaDescriptor = - "Lcom/facebook/react/bridge/CxxModuleWrapperBase;"; + "Lcom/facebook/react/bridge/CxxModuleWrapperBase;"; static void registerNatives() { - registerHybrid({ - makeNativeMethod("getName", CxxModuleWrapperBase::getName) - }); + registerHybrid( + {makeNativeMethod("getName", CxxModuleWrapperBase::getName)}); } // JNI method @@ -44,5 +43,5 @@ class CxxModuleWrapperBase virtual std::unique_ptr getModule() = 0; }; -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JCallback.h b/ReactAndroid/src/main/jni/react/jni/JCallback.h index 994b4161c44006..4e744c4ccb3436 100644 --- a/ReactAndroid/src/main/jni/react/jni/JCallback.h +++ b/ReactAndroid/src/main/jni/react/jni/JCallback.h @@ -20,30 +20,33 @@ namespace react { class Instance; struct JCallback : public jni::JavaClass { - constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/Callback;"; + constexpr static auto kJavaDescriptor = + "Lcom/facebook/react/bridge/Callback;"; }; class JCxxCallbackImpl : public jni::HybridClass { -public: - constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/CxxCallbackImpl;"; + public: + constexpr static auto kJavaDescriptor = + "Lcom/facebook/react/bridge/CxxCallbackImpl;"; static void registerNatives() { javaClassStatic()->registerNatives({ makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke), }); } -private: + + private: friend HybridBase; using Callback = std::function; JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {} - void invoke(NativeArray* arguments) { + void invoke(NativeArray *arguments) { callback_(arguments->consume()); } Callback callback_; }; -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JInspector.h b/ReactAndroid/src/main/jni/react/jni/JInspector.h index 6dca06401aee24..ccb4df91445f3b 100644 --- a/ReactAndroid/src/main/jni/react/jni/JInspector.h +++ b/ReactAndroid/src/main/jni/react/jni/JInspector.h @@ -19,23 +19,27 @@ namespace facebook { namespace react { class JPage : public jni::JavaClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$Page;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/Inspector$Page;"; - static jni::local_ref create(int id, const std::string& title, const std::string& vm); + static jni::local_ref + create(int id, const std::string &title, const std::string &vm); }; class JRemoteConnection : public jni::JavaClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$RemoteConnection;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/Inspector$RemoteConnection;"; - void onMessage(const std::string& message) const; + void onMessage(const std::string &message) const; void onDisconnect() const; }; class JLocalConnection : public jni::HybridClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$LocalConnection;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/Inspector$LocalConnection;"; JLocalConnection(std::unique_ptr connection); @@ -43,29 +47,35 @@ class JLocalConnection : public jni::HybridClass { void disconnect(); static void registerNatives(); -private: + + private: std::unique_ptr connection_; }; class JInspector : public jni::HybridClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/Inspector;"; - static jni::global_ref instance(jni::alias_ref); + static jni::global_ref instance( + jni::alias_ref); jni::local_ref> getPages(); - jni::local_ref connect(int pageId, jni::alias_ref remote); + jni::local_ref connect( + int pageId, + jni::alias_ref remote); static void registerNatives(); -private: + + private: friend HybridBase; - JInspector(IInspector* inspector) : inspector_(inspector) {} + JInspector(IInspector *inspector) : inspector_(inspector) {} - IInspector* inspector_; + IInspector *inspector_; }; -} -} +} // namespace react +} // namespace facebook #endif diff --git a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp index 9c70f668e87346..92ab920aec3b61 100644 --- a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp @@ -22,16 +22,17 @@ namespace react { namespace { struct JavaJSException : jni::JavaClass { - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/JSException;"; + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/devsupport/JSException;"; - static local_ref create(const char* message, const char* stack, - const std::exception& ex) { + static local_ref + create(const char *message, const char *stack, const std::exception &ex) { local_ref cause = jni::JCppException::create(ex); return newInstance(make_jstring(message), make_jstring(stack), cause.get()); } }; -std::function wrapRunnable(std::function&& runnable) { +std::function wrapRunnable(std::function &&runnable) { return [runnable = std::move(runnable)]() mutable { if (!runnable) { // Runnable is empty, nothing to run. @@ -46,33 +47,39 @@ std::function wrapRunnable(std::function&& runnable) { try { localRunnable(); - } catch (const jsi::JSError& ex) { + } catch (const jsi::JSError &ex) { throwNewJavaException( - JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex) - .get()); + JavaJSException::create( + ex.getMessage().c_str(), ex.getStack().c_str(), ex) + .get()); } }; } -} +} // namespace -JMessageQueueThread::JMessageQueueThread(alias_ref jobj) : - m_jobj(make_global(jobj)) { -} +JMessageQueueThread::JMessageQueueThread( + alias_ref jobj) + : m_jobj(make_global(jobj)) {} -void JMessageQueueThread::runOnQueue(std::function&& runnable) { +void JMessageQueueThread::runOnQueue(std::function &&runnable) { // For C++ modules, this can be called from an arbitrary thread // managed by the module, via callJSCallback or callJSFunction. So, // we ensure that it is registered with the JVM. jni::ThreadScope guard; - static auto method = JavaMessageQueueThread::javaClassStatic()-> - getMethod("runOnQueue"); - method(m_jobj, JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable))).get()); + static auto method = + JavaMessageQueueThread::javaClassStatic() + ->getMethod("runOnQueue"); + method( + m_jobj, + JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable))) + .get()); } -void JMessageQueueThread::runOnQueueSync(std::function&& runnable) { - static auto jIsOnThread = JavaMessageQueueThread::javaClassStatic()-> - getMethod("isOnThread"); +void JMessageQueueThread::runOnQueueSync(std::function &&runnable) { + static auto jIsOnThread = + JavaMessageQueueThread::javaClassStatic()->getMethod( + "isOnThread"); if (jIsOnThread(m_jobj)) { wrapRunnable(std::move(runnable))(); @@ -81,7 +88,7 @@ void JMessageQueueThread::runOnQueueSync(std::function&& runnable) { std::condition_variable signalCv; bool runnableComplete = false; - runOnQueue([&] () mutable { + runOnQueue([&]() mutable { std::lock_guard lock(signalMutex); runnable(); @@ -96,9 +103,11 @@ void JMessageQueueThread::runOnQueueSync(std::function&& runnable) { } void JMessageQueueThread::quitSynchronous() { - static auto method = JavaMessageQueueThread::javaClassStatic()-> - getMethod("quitSynchronous"); + static auto method = + JavaMessageQueueThread::javaClassStatic()->getMethod( + "quitSynchronous"); method(m_jobj); } -} } +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h index d23544903b96ee..e3389ea4e3fc4c 100644 --- a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h +++ b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h @@ -18,29 +18,30 @@ namespace facebook { namespace react { class JavaMessageQueueThread : public jni::JavaClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/queue/MessageQueueThread;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/queue/MessageQueueThread;"; }; class JMessageQueueThread : public MessageQueueThread { -public: + public: JMessageQueueThread(alias_ref jobj); /** * Enqueues the given function to run on this MessageQueueThread. */ - void runOnQueue(std::function&& runnable) override; + void runOnQueue(std::function &&runnable) override; /** * Synchronously executes the given function to run on this * MessageQueueThread, waiting until it completes. Can be called from any * thread, but will block if not called on this MessageQueueThread. */ - void runOnQueueSync(std::function&& runnable) override; + void runOnQueueSync(std::function &&runnable) override; /** - * Synchronously quits the current MessageQueueThread. Can be called from any thread, but will - * block if not called on this MessageQueueThread. + * Synchronously quits the current MessageQueueThread. Can be called from any + * thread, but will block if not called on this MessageQueueThread. */ void quitSynchronous() override; @@ -48,8 +49,9 @@ class JMessageQueueThread : public MessageQueueThread { return m_jobj.get(); } -private: + private: global_ref m_jobj; }; -} } +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp b/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp index 1e3f0093df55c5..4d0505f3401535 100644 --- a/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp @@ -6,33 +6,38 @@ */ #include "JReactMarker.h" -#include #include #include +#include namespace facebook { namespace react { void JReactMarker::setLogPerfMarkerIfNeeded() { - static std::once_flag flag {}; - std::call_once(flag, [](){ + static std::once_flag flag{}; + std::call_once(flag, []() { ReactMarker::logTaggedMarker = JReactMarker::logPerfMarker; }); } -void JReactMarker::logMarker(const std::string& marker) { +void JReactMarker::logMarker(const std::string &marker) { static auto cls = javaClassStatic(); static auto meth = cls->getStaticMethod("logMarker"); meth(cls, marker); } -void JReactMarker::logMarker(const std::string& marker, const std::string& tag) { +void JReactMarker::logMarker( + const std::string &marker, + const std::string &tag) { static auto cls = javaClassStatic(); - static auto meth = cls->getStaticMethod("logMarker"); + static auto meth = + cls->getStaticMethod("logMarker"); meth(cls, marker, tag); } -void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag) { +void JReactMarker::logPerfMarker( + const ReactMarker::ReactMarkerId markerId, + const char *tag) { switch (markerId) { case ReactMarker::RUN_JS_BUNDLE_START: JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag); @@ -68,5 +73,5 @@ void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, cons } } -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JReactMarker.h b/ReactAndroid/src/main/jni/react/jni/JReactMarker.h index a1327250aa692d..66e6584d3ec3d7 100644 --- a/ReactAndroid/src/main/jni/react/jni/JReactMarker.h +++ b/ReactAndroid/src/main/jni/react/jni/JReactMarker.h @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include @@ -16,15 +16,18 @@ namespace facebook { namespace react { class JReactMarker : public facebook::jni::JavaClass { -public: - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/ReactMarker;"; + public: + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/ReactMarker;"; static void setLogPerfMarkerIfNeeded(); -private: - static void logMarker(const std::string& marker); - static void logMarker(const std::string& marker, const std::string& tag); - static void logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag); + private: + static void logMarker(const std::string &marker); + static void logMarker(const std::string &marker, const std::string &tag); + static void logPerfMarker( + const ReactMarker::ReactMarkerId markerId, + const char *tag); }; -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp b/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp index b5e1eccab74cea..41c42214995f95 100644 --- a/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp @@ -28,30 +28,33 @@ using namespace facebook::jni; namespace facebook { namespace react { -__attribute__((visibility("default"))) -AAssetManager *extractAssetManager(alias_ref assetManager) { +__attribute__((visibility("default"))) AAssetManager *extractAssetManager( + alias_ref assetManager) { auto env = Environment::current(); return AAssetManager_fromJava(env, assetManager.get()); } -__attribute__((visibility("default"))) -std::unique_ptr loadScriptFromAssets( - AAssetManager *manager, - const std::string& assetName) { - #ifdef WITH_FBSYSTRACE - FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "reactbridge_jni_loadScriptFromAssets", - "assetName", assetName); - #endif +__attribute__((visibility("default"))) std::unique_ptr +loadScriptFromAssets(AAssetManager *manager, const std::string &assetName) { +#ifdef WITH_FBSYSTRACE + FbSystraceSection s( + TRACE_TAG_REACT_CXX_BRIDGE, + "reactbridge_jni_loadScriptFromAssets", + "assetName", + assetName); +#endif if (manager) { auto asset = AAssetManager_open( - manager, - assetName.c_str(), - AASSET_MODE_STREAMING); // Optimized for sequential read: see AssetManager.java for docs + manager, + assetName.c_str(), + AASSET_MODE_STREAMING); // Optimized for sequential read: see + // AssetManager.java for docs if (asset) { auto buf = std::make_unique(AAsset_getLength(asset)); size_t offset = 0; int readbytes; - while ((readbytes = AAsset_read(asset, buf->data() + offset, buf->size() - offset)) > 0) { + while ((readbytes = AAsset_read( + asset, buf->data() + offset, buf->size() - offset)) > 0) { offset += readbytes; } AAsset_close(asset); @@ -61,9 +64,12 @@ std::unique_ptr loadScriptFromAssets( } } - throw std::runtime_error(folly::to("Unable to load script. Make sure you're " - "either running a Metro server (run 'react-native start') or that your bundle '", assetName, - "' is packaged correctly for release.")); + throw std::runtime_error(folly::to( + "Unable to load script. Make sure you're " + "either running a Metro server (run 'react-native start') or that your bundle '", + assetName, + "' is packaged correctly for release.")); } -}} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JSLoader.h b/ReactAndroid/src/main/jni/react/jni/JSLoader.h index aa781a0d0e6316..b808080389e23c 100644 --- a/ReactAndroid/src/main/jni/react/jni/JSLoader.h +++ b/ReactAndroid/src/main/jni/react/jni/JSLoader.h @@ -23,8 +23,12 @@ struct JAssetManager : jni::JavaClass { /** * Helper method for loading JS script from android asset */ -AAssetManager *extractAssetManager(jni::alias_ref assetManager); +AAssetManager *extractAssetManager( + jni::alias_ref assetManager); -std::unique_ptr loadScriptFromAssets(AAssetManager *assetManager, const std::string& assetName); +std::unique_ptr loadScriptFromAssets( + AAssetManager *assetManager, + const std::string &assetName); -} } +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.cpp b/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.cpp index 8e1c93c533a67f..5ba12675d7cafc 100644 --- a/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.cpp @@ -9,13 +9,13 @@ #include -#include -#include #include #include #include #include #include +#include +#include #ifdef WITH_FBSYSTRACE #include @@ -45,7 +45,8 @@ std::string JMethodDescriptor::getType() const { } std::string JavaNativeModule::getName() { - static auto getNameMethod = wrapper_->getClass()->getMethod("getName"); + static auto getNameMethod = + wrapper_->getClass()->getMethod("getName"); return getNameMethod(wrapper_)->toStdString(); } @@ -53,35 +54,34 @@ std::vector JavaNativeModule::getMethods() { std::vector ret; syncMethods_.clear(); auto descs = wrapper_->getMethodDescriptors(); - for (const auto& desc : *descs) { + for (const auto &desc : *descs) { auto methodName = desc->getName(); auto methodType = desc->getType(); if (methodType == "sync") { - // allow for the sync methods vector to have empty values, resize on demand + // allow for the sync methods vector to have empty values, resize on + // demand size_t methodIndex = ret.size(); if (methodIndex >= syncMethods_.size()) { syncMethods_.resize(methodIndex + 1); } - syncMethods_.insert(syncMethods_.begin() + methodIndex, MethodInvoker( - desc->getMethod(), - desc->getSignature(), - getName() + "." + methodName, - true - )); + syncMethods_.insert( + syncMethods_.begin() + methodIndex, + MethodInvoker( + desc->getMethod(), + desc->getSignature(), + getName() + "." + methodName, + true)); } - ret.emplace_back( - std::move(methodName), - std::move(methodType) - ); + ret.emplace_back(std::move(methodName), std::move(methodType)); } return ret; } folly::dynamic JavaNativeModule::getConstants() { static auto constantsMethod = - wrapper_->getClass()->getMethod("getConstants"); + wrapper_->getClass()->getMethod("getConstants"); auto constants = constantsMethod(wrapper_); if (!constants) { return nullptr; @@ -90,46 +90,60 @@ folly::dynamic JavaNativeModule::getConstants() { } } -void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) { - messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] { - static auto invokeMethod = wrapper_->getClass()->getMethod("invoke"); - #ifdef WITH_FBSYSTRACE - if (callId != -1) { - fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); - } - #endif - invokeMethod( - wrapper_, - static_cast(reactMethodId), - ReadableNativeArray::newObjectCxxArgs(std::move(params)).get()); - }); +void JavaNativeModule::invoke( + unsigned int reactMethodId, + folly::dynamic &¶ms, + int callId) { + messageQueueThread_->runOnQueue( + [this, reactMethodId, params = std::move(params), callId] { + static auto invokeMethod = + wrapper_->getClass() + ->getMethod( + "invoke"); +#ifdef WITH_FBSYSTRACE + if (callId != -1) { + fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); + } +#endif + invokeMethod( + wrapper_, + static_cast(reactMethodId), + ReadableNativeArray::newObjectCxxArgs(std::move(params)).get()); + }); } -MethodCallResult JavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) { +MethodCallResult JavaNativeModule::callSerializableNativeHook( + unsigned int reactMethodId, + folly::dynamic &¶ms) { // TODO: evaluate whether calling through invoke is potentially faster if (reactMethodId >= syncMethods_.size()) { - throw std::invalid_argument( - folly::to("methodId ", reactMethodId, " out of range [0..", syncMethods_.size(), "]")); + throw std::invalid_argument(folly::to( + "methodId ", + reactMethodId, + " out of range [0..", + syncMethods_.size(), + "]")); } - auto& method = syncMethods_[reactMethodId]; - CHECK(method.hasValue() && method->isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook"; + auto &method = syncMethods_[reactMethodId]; + CHECK(method.hasValue() && method->isSyncHook()) + << "Trying to invoke a asynchronous method as synchronous hook"; return method->invoke(instance_, wrapper_->getModule(), params); } NewJavaNativeModule::NewJavaNativeModule( - std::weak_ptr instance, - jni::alias_ref wrapper, - std::shared_ptr messageQueueThread) -: instance_(std::move(instance)) -, wrapper_(make_global(wrapper)) -, module_(make_global(wrapper->getModule())) -, messageQueueThread_(std::move(messageQueueThread)) { + std::weak_ptr instance, + jni::alias_ref wrapper, + std::shared_ptr messageQueueThread) + : instance_(std::move(instance)), + wrapper_(make_global(wrapper)), + module_(make_global(wrapper->getModule())), + messageQueueThread_(std::move(messageQueueThread)) { auto descs = wrapper_->getMethodDescriptors(); std::string moduleName = getName(); methods_.reserve(descs->size()); - for (const auto& desc : *descs) { + for (const auto &desc : *descs) { auto type = desc->getType(); auto name = desc->getName(); methods_.emplace_back( @@ -143,7 +157,8 @@ NewJavaNativeModule::NewJavaNativeModule( } std::string NewJavaNativeModule::getName() { - static auto getNameMethod = wrapper_->getClass()->getMethod("getName"); + static auto getNameMethod = + wrapper_->getClass()->getMethod("getName"); return getNameMethod(wrapper_)->toStdString(); } @@ -153,7 +168,7 @@ std::vector NewJavaNativeModule::getMethods() { folly::dynamic NewJavaNativeModule::getConstants() { static auto constantsMethod = - wrapper_->getClass()->getMethod("getConstants"); + wrapper_->getClass()->getMethod("getConstants"); auto constants = constantsMethod(wrapper_); if (!constants) { return nullptr; @@ -162,39 +177,59 @@ folly::dynamic NewJavaNativeModule::getConstants() { } } -void NewJavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) { +void NewJavaNativeModule::invoke( + unsigned int reactMethodId, + folly::dynamic &¶ms, + int callId) { if (reactMethodId >= methods_.size()) { - throw std::invalid_argument( - folly::to("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]")); + throw std::invalid_argument(folly::to( + "methodId ", + reactMethodId, + " out of range [0..", + methods_.size(), + "]")); } - CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously"; - messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] () mutable { - #ifdef WITH_FBSYSTRACE - if (callId != -1) { - fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); - } - #endif - invokeInner(reactMethodId, std::move(params)); - }); + CHECK(!methods_[reactMethodId].isSyncHook()) + << "Trying to invoke a synchronous hook asynchronously"; + messageQueueThread_->runOnQueue( + [this, reactMethodId, params = std::move(params), callId]() mutable { +#ifdef WITH_FBSYSTRACE + if (callId != -1) { + fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); + } +#endif + invokeInner(reactMethodId, std::move(params)); + }); } -MethodCallResult NewJavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) { +MethodCallResult NewJavaNativeModule::callSerializableNativeHook( + unsigned int reactMethodId, + folly::dynamic &¶ms) { if (reactMethodId >= methods_.size()) { - throw std::invalid_argument( - folly::to("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]")); + throw std::invalid_argument(folly::to( + "methodId ", + reactMethodId, + " out of range [0..", + methods_.size(), + "]")); } - CHECK(methods_[reactMethodId].isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook"; + CHECK(methods_[reactMethodId].isSyncHook()) + << "Trying to invoke a asynchronous method as synchronous hook"; return invokeInner(reactMethodId, std::move(params)); } -MethodCallResult NewJavaNativeModule::invokeInner(unsigned int reactMethodId, folly::dynamic&& params) { +MethodCallResult NewJavaNativeModule::invokeInner( + unsigned int reactMethodId, + folly::dynamic &¶ms) { return methods_[reactMethodId].invoke(instance_, module_.get(), params); } -jni::local_ref JMethodDescriptor::getMethod() const { - static auto method = javaClassStatic()->getField("method"); +jni::local_ref JMethodDescriptor::getMethod() + const { + static auto method = + javaClassStatic()->getField("method"); return getFieldValue(method); } -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h b/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h index 1e8804b56bd0e9..16205d6038ce85 100644 --- a/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h +++ b/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h @@ -21,7 +21,7 @@ class MessageQueueThread; struct JMethodDescriptor : public jni::JavaClass { static constexpr auto kJavaDescriptor = - "Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;"; + "Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;"; jni::local_ref getMethod() const; std::string getSignature() const; @@ -30,12 +30,15 @@ struct JMethodDescriptor : public jni::JavaClass { }; struct JavaModuleWrapper : jni::JavaClass { - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/JavaModuleWrapper;"; + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/JavaModuleWrapper;"; jni::local_ref getModule() { // This is the call which causes a lazy Java module to actually be // created. - static auto getModule = javaClassStatic()->getMethod("getModule"); + static auto getModule = + javaClassStatic()->getMethod( + "getModule"); return getModule(self()); } @@ -44,9 +47,13 @@ struct JavaModuleWrapper : jni::JavaClass { return getName(self())->toStdString(); } - jni::local_ref::javaobject> getMethodDescriptors() { - static auto getMethods = getClass() - ->getMethod::javaobject()>("getMethodDescriptors"); + jni::local_ref::javaobject> + getMethodDescriptors() { + static auto getMethods = + getClass() + ->getMethod< + jni::JList::javaobject()>( + "getMethodDescriptors"); return getMethods(self()); } }; @@ -54,18 +61,21 @@ struct JavaModuleWrapper : jni::JavaClass { class JavaNativeModule : public NativeModule { public: JavaNativeModule( - std::weak_ptr instance, - jni::alias_ref wrapper, - std::shared_ptr messageQueueThread) - : instance_(std::move(instance)) - , wrapper_(make_global(wrapper)) - , messageQueueThread_(std::move(messageQueueThread)) {} + std::weak_ptr instance, + jni::alias_ref wrapper, + std::shared_ptr messageQueueThread) + : instance_(std::move(instance)), + wrapper_(make_global(wrapper)), + messageQueueThread_(std::move(messageQueueThread)) {} std::string getName() override; folly::dynamic getConstants() override; std::vector getMethods() override; - void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override; - MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override; + void invoke(unsigned int reactMethodId, folly::dynamic &¶ms, int callId) + override; + MethodCallResult callSerializableNativeHook( + unsigned int reactMethodId, + folly::dynamic &¶ms) override; private: std::weak_ptr instance_; @@ -78,15 +88,18 @@ class JavaNativeModule : public NativeModule { class NewJavaNativeModule : public NativeModule { public: NewJavaNativeModule( - std::weak_ptr instance, - jni::alias_ref wrapper, - std::shared_ptr messageQueueThread); + std::weak_ptr instance, + jni::alias_ref wrapper, + std::shared_ptr messageQueueThread); std::string getName() override; std::vector getMethods() override; folly::dynamic getConstants() override; - void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override; - MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override; + void invoke(unsigned int reactMethodId, folly::dynamic &¶ms, int callId) + override; + MethodCallResult callSerializableNativeHook( + unsigned int reactMethodId, + folly::dynamic &¶ms) override; private: std::weak_ptr instance_; @@ -96,7 +109,10 @@ class NewJavaNativeModule : public NativeModule { std::vector methods_; std::vector methodDescriptors_; - MethodCallResult invokeInner(unsigned int reactMethodId, folly::dynamic&& params); + MethodCallResult invokeInner( + unsigned int reactMethodId, + folly::dynamic &¶ms); }; -}} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JavaScriptExecutorHolder.h b/ReactAndroid/src/main/jni/react/jni/JavaScriptExecutorHolder.h index e88a842cc8f73d..1474d0671cd917 100644 --- a/ReactAndroid/src/main/jni/react/jni/JavaScriptExecutorHolder.h +++ b/ReactAndroid/src/main/jni/react/jni/JavaScriptExecutorHolder.h @@ -13,10 +13,11 @@ namespace facebook { namespace react { -class JavaScriptExecutorHolder : public jni::HybridClass { +class JavaScriptExecutorHolder + : public jni::HybridClass { public: static constexpr auto kJavaDescriptor = - "Lcom/facebook/react/bridge/JavaScriptExecutor;"; + "Lcom/facebook/react/bridge/JavaScriptExecutor;"; std::shared_ptr getExecutorFactory() { return mExecutorFactory; @@ -30,4 +31,5 @@ class JavaScriptExecutorHolder : public jni::HybridClass mExecutorFactory; }; -}} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/MethodInvoker.cpp b/ReactAndroid/src/main/jni/react/jni/MethodInvoker.cpp index 6a1e4365a08deb..f82659d3cffc43 100644 --- a/ReactAndroid/src/main/jni/react/jni/MethodInvoker.cpp +++ b/ReactAndroid/src/main/jni/react/jni/MethodInvoker.cpp @@ -32,9 +32,12 @@ namespace { using dynamic_iterator = folly::dynamic::const_iterator; struct JPromiseImpl : public JavaClass { - constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/PromiseImpl;"; + constexpr static auto kJavaDescriptor = + "Lcom/facebook/react/bridge/PromiseImpl;"; - static local_ref create(local_ref resolve, local_ref reject) { + static local_ref create( + local_ref resolve, + local_ref reject) { return newInstance(resolve, reject); } }; @@ -42,10 +45,10 @@ struct JPromiseImpl : public JavaClass { // HACK: Exposes constructor struct ExposedReadableNativeArray : public ReadableNativeArray { explicit ExposedReadableNativeArray(folly::dynamic array) - : ReadableNativeArray(std::move(array)) {} + : ReadableNativeArray(std::move(array)) {} }; -jdouble extractDouble(const folly::dynamic& value) { +jdouble extractDouble(const folly::dynamic &value) { if (value.isInt()) { return static_cast(value.getInt()); } else { @@ -53,7 +56,7 @@ jdouble extractDouble(const folly::dynamic& value) { } } -jint extractInteger(const folly::dynamic& value) { +jint extractInteger(const folly::dynamic &value) { // The logic here is taken from convertDynamicIfIntegral, but the // return type and exception are different. if (value.isInt()) { @@ -62,14 +65,16 @@ jint extractInteger(const folly::dynamic& value) { double dbl = value.getDouble(); jint result = static_cast(dbl); if (dbl != result) { - throw std::invalid_argument( - folly::to( - "Tried to convert jint argument, but got a non-integral double: ", dbl)); + throw std::invalid_argument(folly::to( + "Tried to convert jint argument, but got a non-integral double: ", + dbl)); } return result; } -local_ref extractCallback(std::weak_ptr& instance, const folly::dynamic& value) { +local_ref extractCallback( + std::weak_ptr &instance, + const folly::dynamic &value) { if (value.isNull()) { return local_ref(nullptr); } else { @@ -77,7 +82,10 @@ local_ref extractCallback(std::weak_ptr extractPromise(std::weak_ptr& instance, dynamic_iterator& it, dynamic_iterator& end) { +local_ref extractPromise( + std::weak_ptr &instance, + dynamic_iterator &it, + dynamic_iterator &end) { auto resolve = extractCallback(instance, *it++); CHECK(it != end); auto reject = extractCallback(instance, *it++); @@ -95,11 +103,16 @@ bool isNullable(char type) { case 'X': return true; default: - return false;; + return false; + ; } } -jvalue extract(std::weak_ptr& instance, char type, dynamic_iterator& it, dynamic_iterator& end) { +jvalue extract( + std::weak_ptr &instance, + char type, + dynamic_iterator &it, + dynamic_iterator &end) { CHECK(it != end); jvalue value; if (type == 'P') { @@ -107,7 +120,7 @@ jvalue extract(std::weak_ptr& instance, char type, dynamic_iterator& i return value; } - const auto& arg = *it++; + const auto &arg = *it++; if (isNullable(type) && arg.isNull()) { value.l = nullptr; return value; @@ -118,7 +131,8 @@ jvalue extract(std::weak_ptr& instance, char type, dynamic_iterator& i value.z = static_cast(arg.getBool()); break; case 'Z': - value.l = JBoolean::valueOf(static_cast(arg.getBool())).release(); + value.l = + JBoolean::valueOf(static_cast(arg.getBool())).release(); break; case 'i': value.i = extractInteger(arg); @@ -130,7 +144,8 @@ jvalue extract(std::weak_ptr& instance, char type, dynamic_iterator& i value.f = static_cast(extractDouble(arg)); break; case 'F': - value.l = JFloat::valueOf(static_cast(extractDouble(arg))).release(); + value.l = + JFloat::valueOf(static_cast(extractDouble(arg))).release(); break; case 'd': value.d = extractDouble(arg); @@ -156,7 +171,7 @@ jvalue extract(std::weak_ptr& instance, char type, dynamic_iterator& i return value; } -std::size_t countJsArgs(const std::string& signature) { +std::size_t countJsArgs(const std::string &signature) { std::size_t count = 0; for (char c : signature) { switch (c) { @@ -171,29 +186,38 @@ std::size_t countJsArgs(const std::string& signature) { return count; } +} // namespace + +MethodInvoker::MethodInvoker( + alias_ref method, + std::string signature, + std::string traceName, + bool isSync) + : method_(method->getMethodID()), + signature_(signature), + jsArgCount_(countJsArgs(signature) - 2), + traceName_(std::move(traceName)), + isSync_(isSync) { + CHECK(signature_.at(1) == '.') << "Improper module method signature"; + CHECK(isSync_ || signature_.at(0) == 'v') + << "Non-sync hooks cannot have a non-void return type"; } -MethodInvoker::MethodInvoker(alias_ref method, std::string signature, std::string traceName, bool isSync) - : method_(method->getMethodID()), - signature_(signature), - jsArgCount_(countJsArgs(signature) -2), - traceName_(std::move(traceName)), - isSync_(isSync) { - CHECK(signature_.at(1) == '.') << "Improper module method signature"; - CHECK(isSync_ || signature_.at(0) == 'v') << "Non-sync hooks cannot have a non-void return type"; -} - -MethodCallResult MethodInvoker::invoke(std::weak_ptr& instance, alias_ref module, const folly::dynamic& params) { - #ifdef WITH_FBSYSTRACE +MethodCallResult MethodInvoker::invoke( + std::weak_ptr &instance, + alias_ref module, + const folly::dynamic ¶ms) { +#ifdef WITH_FBSYSTRACE fbsystrace::FbSystraceSection s( TRACE_TAG_REACT_CXX_BRIDGE, isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod", "method", traceName_); - #endif +#endif if (params.size() != jsArgCount_) { - throw std::invalid_argument(folly::to("expected ", jsArgCount_, " arguments, got ", params.size())); + throw std::invalid_argument(folly::to( + "expected ", jsArgCount_, " arguments, got ", params.size())); } auto env = Environment::current(); @@ -201,44 +225,48 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr& instance, alias_ JniLocalScope scope(env, argCount); jvalue args[argCount]; std::transform( - signature_.begin() + 2, - signature_.end(), - args, - [&instance, it = params.begin(), end = params.end()] (char type) mutable { - return extract(instance, type, it, end); - }); - -#define PRIMITIVE_CASE(METHOD) { \ - auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \ - throwPendingJniExceptionAsCppException(); \ - return folly::dynamic(result); \ -} + signature_.begin() + 2, + signature_.end(), + args, + [&instance, it = params.begin(), end = params.end()](char type) mutable { + return extract(instance, type, it, end); + }); + +#define PRIMITIVE_CASE(METHOD) \ + { \ + auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \ + throwPendingJniExceptionAsCppException(); \ + return folly::dynamic(result); \ + } -#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) { \ - auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \ - throwPendingJniExceptionAsCppException(); \ - return folly::dynamic(static_cast(result)); \ -} +#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) \ + { \ + auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \ + throwPendingJniExceptionAsCppException(); \ + return folly::dynamic(static_cast(result)); \ + } -#define OBJECT_CASE(JNI_CLASS, ACTIONS) { \ - auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ - throwPendingJniExceptionAsCppException(); \ - if (!jobject) { \ - return folly::dynamic(nullptr); \ - } \ - auto result = adopt_local(static_cast(jobject)); \ - return folly::dynamic(result->ACTIONS()); \ -} +#define OBJECT_CASE(JNI_CLASS, ACTIONS) \ + { \ + auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ + throwPendingJniExceptionAsCppException(); \ + if (!jobject) { \ + return folly::dynamic(nullptr); \ + } \ + auto result = adopt_local(static_cast(jobject)); \ + return folly::dynamic(result->ACTIONS()); \ + } -#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) { \ - auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ - throwPendingJniExceptionAsCppException(); \ - if (!jobject) { \ - return folly::dynamic(nullptr); \ - } \ - auto result = adopt_local(static_cast(jobject)); \ - return folly::dynamic(static_cast(result->ACTIONS())); \ -} +#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) \ + { \ + auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ + throwPendingJniExceptionAsCppException(); \ + if (!jobject) { \ + return folly::dynamic(nullptr); \ + } \ + auto result = adopt_local(static_cast(jobject)); \ + return folly::dynamic(static_cast(result->ACTIONS())); \ + } char returnType = signature_.at(0); switch (returnType) { @@ -277,5 +305,5 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr& instance, alias_ } } -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h b/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h index ea67271c03839b..766c599bad3974 100644 --- a/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h +++ b/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h @@ -29,19 +29,28 @@ struct JReflectMethod : public jni::JavaClass { }; struct JBaseJavaModule : public jni::JavaClass { - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/BaseJavaModule;"; + static constexpr auto kJavaDescriptor = + "Lcom/facebook/react/bridge/BaseJavaModule;"; }; class MethodInvoker { -public: - MethodInvoker(jni::alias_ref method, std::string signature, std::string traceName, bool isSync); - - MethodCallResult invoke(std::weak_ptr& instance, jni::alias_ref module, const folly::dynamic& params); + public: + MethodInvoker( + jni::alias_ref method, + std::string signature, + std::string traceName, + bool isSync); + + MethodCallResult invoke( + std::weak_ptr &instance, + jni::alias_ref module, + const folly::dynamic ¶ms); bool isSyncHook() const { return isSync_; } -private: + + private: jmethodID method_; std::string signature_; std::size_t jsArgCount_; @@ -49,5 +58,5 @@ class MethodInvoker { bool isSync_; }; -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h index 63693918d92c33..5f84e1f93be9fa 100644 --- a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h +++ b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h @@ -22,16 +22,19 @@ class MessageQueueThread; class ModuleHolder : public jni::JavaClass { public: static auto constexpr kJavaDescriptor = - "Lcom/facebook/react/bridge/ModuleHolder;"; + "Lcom/facebook/react/bridge/ModuleHolder;"; std::string getName() const; - xplat::module::CxxModule::Provider getProvider(const std::string& moduleName) const; + xplat::module::CxxModule::Provider getProvider( + const std::string &moduleName) const; }; std::vector> buildNativeModuleList( - std::weak_ptr winstance, - jni::alias_ref::javaobject> javaModules, - jni::alias_ref::javaobject> cxxModules, - std::shared_ptr moduleMessageQueue); -} -} + std::weak_ptr winstance, + jni::alias_ref::javaobject> + javaModules, + jni::alias_ref::javaobject> + cxxModules, + std::shared_ptr moduleMessageQueue); +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp b/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp index 6af3c6b5c957f6..738037b84ea97f 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp +++ b/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp @@ -18,8 +18,10 @@ namespace react { NativeArray::NativeArray(folly::dynamic array) : isConsumed(false), array_(std::move(array)) { if (!array_.isArray()) { - throwNewJavaException(exceptions::gUnexpectedNativeTypeExceptionClass, - "expected Array, got a %s", array_.typeName()); + throwNewJavaException( + exceptions::gUnexpectedNativeTypeExceptionClass, + "expected Array, got a %s", + array_.typeName()); } } @@ -30,7 +32,7 @@ local_ref NativeArray::toString() { void NativeArray::registerNatives() { registerHybrid({ - makeNativeMethod("toString", NativeArray::toString), + makeNativeMethod("toString", NativeArray::toString), }); } @@ -44,5 +46,5 @@ void NativeArray::throwIfConsumed() { exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed"); } -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/NativeArray.h b/ReactAndroid/src/main/jni/react/jni/NativeArray.h index 419e47485587e8..7fd3cf56d08e04 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeArray.h +++ b/ReactAndroid/src/main/jni/react/jni/NativeArray.h @@ -17,7 +17,8 @@ namespace react { class NativeArray : public jni::HybridClass { public: - static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/NativeArray;"; + static constexpr const char *kJavaDescriptor = + "Lcom/facebook/react/bridge/NativeArray;"; jni::local_ref toString(); @@ -37,4 +38,5 @@ class NativeArray : public jni::HybridClass { explicit NativeArray(folly::dynamic array); }; -}} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/NativeCommon.h b/ReactAndroid/src/main/jni/react/jni/NativeCommon.h index 9562ccdbf5a0e7..daed3ad62a6299 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeCommon.h +++ b/ReactAndroid/src/main/jni/react/jni/NativeCommon.h @@ -18,7 +18,8 @@ namespace facebook { namespace react { struct ReadableType : public jni::JavaClass { - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/ReadableType;"; + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/ReadableType;"; static jni::local_ref getType(folly::dynamic::Type type); }; @@ -28,9 +29,10 @@ namespace exceptions { extern const char *gUnexpectedNativeTypeExceptionClass; template -void throwIfObjectAlreadyConsumed(const T& t, const char* msg) { +void throwIfObjectAlreadyConsumed(const T &t, const char *msg) { if (t->isConsumed) { - jni::throwNewJavaException("com/facebook/react/bridge/ObjectAlreadyConsumedException", msg); + jni::throwNewJavaException( + "com/facebook/react/bridge/ObjectAlreadyConsumedException", msg); } } diff --git a/ReactAndroid/src/main/jni/react/jni/NativeMap.h b/ReactAndroid/src/main/jni/react/jni/NativeMap.h index 4b0ce25a730d35..3b616a16611107 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeMap.h +++ b/ReactAndroid/src/main/jni/react/jni/NativeMap.h @@ -17,7 +17,8 @@ namespace react { class NativeMap : public jni::HybridClass { public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/NativeMap;"; + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/NativeMap;"; std::string toString(); @@ -38,5 +39,5 @@ class NativeMap : public jni::HybridClass { explicit NativeMap(folly::dynamic s) : isConsumed(false), map_(s) {} }; -} // namespace react -} // namespace facebook +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp index 4c4a369a6bc9af..3c15e7a27cf2bb 100644 --- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp +++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -25,28 +25,29 @@ const auto EXECUTOR_BASECLASS = "com/facebook/react/bridge/JavaJSExecutor"; static std::string executeJSCallWithProxy( jobject executor, - const std::string& methodName, - const folly::dynamic& arguments) { + const std::string &methodName, + const folly::dynamic &arguments) { static auto executeJSCall = - jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod("executeJSCall"); + jni::findClassStatic(EXECUTOR_BASECLASS) + ->getMethod("executeJSCall"); auto result = executeJSCall( - executor, - jni::make_jstring(methodName).get(), - jni::make_jstring(folly::toJson(arguments).c_str()).get()); + executor, + jni::make_jstring(methodName).get(), + jni::make_jstring(folly::toJson(arguments).c_str()).get()); return result->toString(); } std::unique_ptr ProxyExecutorOneTimeFactory::createJSExecutor( - std::shared_ptr delegate, std::shared_ptr) { + std::shared_ptr delegate, + std::shared_ptr) { return std::make_unique(std::move(m_executor), delegate); } -ProxyExecutor::ProxyExecutor(jni::global_ref&& executorInstance, - std::shared_ptr delegate) - : m_executor(std::move(executorInstance)) - , m_delegate(delegate) -{} +ProxyExecutor::ProxyExecutor( + jni::global_ref &&executorInstance, + std::shared_ptr delegate) + : m_executor(std::move(executorInstance)), m_delegate(delegate) {} ProxyExecutor::~ProxyExecutor() { m_executor.reset(); @@ -55,79 +56,88 @@ ProxyExecutor::~ProxyExecutor() { void ProxyExecutor::loadApplicationScript( std::unique_ptr, std::string sourceURL) { - folly::dynamic nativeModuleConfig = folly::dynamic::array; { SystraceSection s("collectNativeModuleDescriptions"); auto moduleRegistry = m_delegate->getModuleRegistry(); - for (const auto& name : moduleRegistry->moduleNames()) { + for (const auto &name : moduleRegistry->moduleNames()) { auto config = moduleRegistry->getConfig(name); nativeModuleConfig.push_back(config ? config->config : nullptr); } } - folly::dynamic config = - folly::dynamic::object - ("remoteModuleConfig", std::move(nativeModuleConfig)); + folly::dynamic config = folly::dynamic::object( + "remoteModuleConfig", std::move(nativeModuleConfig)); { SystraceSection t("setGlobalVariable"); setGlobalVariable( - "__fbBatchedBridgeConfig", - std::make_unique(folly::toJson(config))); + "__fbBatchedBridgeConfig", + std::make_unique(folly::toJson(config))); } static auto loadApplicationScript = - jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod("loadApplicationScript"); + jni::findClassStatic(EXECUTOR_BASECLASS) + ->getMethod("loadApplicationScript"); // The proxy ignores the script data passed in. - loadApplicationScript( - m_executor.get(), - jni::make_jstring(sourceURL).get()); + loadApplicationScript(m_executor.get(), jni::make_jstring(sourceURL).get()); // We can get pending calls here to native but the queue will be drained when // we launch the application. } void ProxyExecutor::setBundleRegistry(std::unique_ptr) { jni::throwNewJavaException( - "java/lang/UnsupportedOperationException", - "Loading application RAM bundles is not supported for proxy executors"); + "java/lang/UnsupportedOperationException", + "Loading application RAM bundles is not supported for proxy executors"); } -void ProxyExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) { +void ProxyExecutor::registerBundle( + uint32_t bundleId, + const std::string &bundlePath) { jni::throwNewJavaException( - "java/lang/UnsupportedOperationException", - "Loading application RAM bundles is not supported for proxy executors"); + "java/lang/UnsupportedOperationException", + "Loading application RAM bundles is not supported for proxy executors"); } -void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) { +void ProxyExecutor::callFunction( + const std::string &moduleId, + const std::string &methodId, + const folly::dynamic &arguments) { auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments)); - std::string result = executeJSCallWithProxy(m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call)); + std::string result = executeJSCallWithProxy( + m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call)); m_delegate->callNativeModules(*this, folly::parseJson(result), true); } -void ProxyExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) { +void ProxyExecutor::invokeCallback( + const double callbackId, + const folly::dynamic &arguments) { auto call = folly::dynamic::array(callbackId, std::move(arguments)); - std::string result = executeJSCallWithProxy(m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call)); + std::string result = executeJSCallWithProxy( + m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call)); m_delegate->callNativeModules(*this, folly::parseJson(result), true); } -void ProxyExecutor::setGlobalVariable(std::string propName, - std::unique_ptr jsonValue) { +void ProxyExecutor::setGlobalVariable( + std::string propName, + std::unique_ptr jsonValue) { static auto setGlobalVariable = - jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod("setGlobalVariable"); + jni::findClassStatic(EXECUTOR_BASECLASS) + ->getMethod("setGlobalVariable"); setGlobalVariable( - m_executor.get(), - jni::make_jstring(propName).get(), - jni::make_jstring(jsonValue->c_str()).get()); + m_executor.get(), + jni::make_jstring(propName).get(), + jni::make_jstring(jsonValue->c_str()).get()); } std::string ProxyExecutor::getDescription() { return "Chrome"; } -} } +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h index d81a98c1a3a736..0af379cb47b853 100644 --- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h +++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h @@ -17,48 +17,50 @@ namespace facebook { namespace react { /** - * This executor factory can only create a single executor instance because it moves - * executorInstance global reference to the executor instance it creates. + * This executor factory can only create a single executor instance because it + * moves executorInstance global reference to the executor instance it creates. */ class ProxyExecutorOneTimeFactory : public JSExecutorFactory { -public: - ProxyExecutorOneTimeFactory(jni::global_ref&& executorInstance) : - m_executor(std::move(executorInstance)) {} + public: + ProxyExecutorOneTimeFactory(jni::global_ref &&executorInstance) + : m_executor(std::move(executorInstance)) {} virtual std::unique_ptr createJSExecutor( - std::shared_ptr delegate, - std::shared_ptr queue) override; + std::shared_ptr delegate, + std::shared_ptr queue) override; -private: + private: jni::global_ref m_executor; }; class ProxyExecutor : public JSExecutor { -public: - ProxyExecutor(jni::global_ref&& executorInstance, - std::shared_ptr delegate); + public: + ProxyExecutor( + jni::global_ref &&executorInstance, + std::shared_ptr delegate); virtual ~ProxyExecutor() override; virtual void loadApplicationScript( - std::unique_ptr script, - std::string sourceURL) override; + std::unique_ptr script, + std::string sourceURL) override; virtual void setBundleRegistry( - std::unique_ptr bundle) override; - virtual void registerBundle( - uint32_t bundleId, const std::string& bundlePath) override; + std::unique_ptr bundle) override; + virtual void registerBundle(uint32_t bundleId, const std::string &bundlePath) + override; virtual void callFunction( - const std::string& moduleId, - const std::string& methodId, - const folly::dynamic& arguments) override; + const std::string &moduleId, + const std::string &methodId, + const folly::dynamic &arguments) override; virtual void invokeCallback( - const double callbackId, - const folly::dynamic& arguments) override; + const double callbackId, + const folly::dynamic &arguments) override; virtual void setGlobalVariable( - std::string propName, - std::unique_ptr jsonValue) override; + std::string propName, + std::unique_ptr jsonValue) override; virtual std::string getDescription() override; -private: + private: jni::global_ref m_executor; std::shared_ptr m_delegate; }; -} } +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/WritableNativeArray.h b/ReactAndroid/src/main/jni/react/jni/WritableNativeArray.h index 3f820f068782ae..79209609f16875 100644 --- a/ReactAndroid/src/main/jni/react/jni/WritableNativeArray.h +++ b/ReactAndroid/src/main/jni/react/jni/WritableNativeArray.h @@ -19,12 +19,14 @@ namespace react { struct WritableNativeMap; struct WritableArray : jni::JavaClass { - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableArray;"; + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/WritableArray;"; }; struct WritableNativeArray : public jni::HybridClass { - static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeArray;"; + static constexpr const char *kJavaDescriptor = + "Lcom/facebook/react/bridge/WritableNativeArray;"; WritableNativeArray(); static jni::local_ref initHybrid(jni::alias_ref); @@ -34,11 +36,11 @@ struct WritableNativeArray void pushDouble(jdouble value); void pushInt(jint value); void pushString(jstring value); - void pushNativeArray(WritableNativeArray* otherArray); - void pushNativeMap(WritableNativeMap* map); + void pushNativeArray(WritableNativeArray *otherArray); + void pushNativeMap(WritableNativeMap *map); static void registerNatives(); }; -} -} +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/WritableNativeMap.h b/ReactAndroid/src/main/jni/react/jni/WritableNativeMap.h index caacb8795c543c..b6d3bb88a85463 100644 --- a/ReactAndroid/src/main/jni/react/jni/WritableNativeMap.h +++ b/ReactAndroid/src/main/jni/react/jni/WritableNativeMap.h @@ -18,14 +18,17 @@ namespace facebook { namespace react { struct WritableMap : jni::JavaClass { - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableMap;"; + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/WritableMap;"; }; -struct WritableNativeMap : jni::HybridClass { - static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeMap;"; +struct WritableNativeMap + : jni::HybridClass { + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/WritableNativeMap;"; WritableNativeMap(); - WritableNativeMap(folly::dynamic&& val); + WritableNativeMap(folly::dynamic &&val); static jni::local_ref initHybrid(jni::alias_ref); @@ -34,9 +37,9 @@ struct WritableNativeMap : jni::HybridClass val); - void putNativeArray(std::string key, WritableNativeArray* val); - void putNativeMap(std::string key, WritableNativeMap* val); - void mergeNativeMap(ReadableNativeMap* other); + void putNativeArray(std::string key, WritableNativeArray *val); + void putNativeMap(std::string key, WritableNativeMap *val); + void mergeNativeMap(ReadableNativeMap *other); static void registerNatives(); diff --git a/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp b/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp index 2b7e0b6ec4eeeb..e2c40008838dbd 100644 --- a/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include #include #include +#include +#include -#include #include +#include namespace facebook { namespace react { @@ -27,9 +27,9 @@ namespace { // really desperate, you can fix this by using ToReflectedMethod on the // underlying jmethodid and invoking that. class JavaJSModule : public jni::JavaClass { -public: + public: static constexpr auto kJavaDescriptor = - "Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;"; + "Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;"; static void bounceCxx(alias_ref obj, int iters) { static auto method = javaClassLocal()->getMethod("bounceCxx"); @@ -39,20 +39,35 @@ class JavaJSModule : public jni::JavaClass { static void bounceArgsCxx( alias_ref obj, int iters, - int a, int b, - double x, double y, - const std::string& s, const std::string& t) { + int a, + int b, + double x, + double y, + const std::string &s, + const std::string &t) { static auto method = - javaClassLocal()->getMethod("bounceArgsCxx"); - method(obj, iters, a, b, x, y, jni::make_jstring(s).get(), jni::make_jstring(t).get()); + javaClassLocal() + ->getMethod( + "bounceArgsCxx"); + method( + obj, + iters, + a, + b, + x, + y, + jni::make_jstring(s).get(), + jni::make_jstring(t).get()); } }; // This is just the test instance itself. Used only to countdown the latch. -class CatalystBridgeBenchmarks : public jni::JavaClass { -public: +class CatalystBridgeBenchmarks + : public jni::JavaClass { + public: static constexpr auto kJavaDescriptor = - "Lcom/facebook/react/CatalystBridgeBenchmarks;"; + "Lcom/facebook/react/CatalystBridgeBenchmarks;"; static void countDown(alias_ref obj) { static auto method = javaClassLocal()->getMethod("countDown"); @@ -72,7 +87,7 @@ Data data; void runBounce(jni::alias_ref, bool isLeft, int iters) { for (int i = 0; i < iters; i++) { std::unique_lock lk(data.m); - data.cv.wait(lk, [&]{ return data.leftActive == isLeft; }); + data.cv.wait(lk, [&] { return data.leftActive == isLeft; }); data.leftActive = !isLeft; data.cv.notify_one(); } @@ -82,30 +97,35 @@ static jni::global_ref jsModule; static jni::global_ref javaTestInstance; class CxxBenchmarkModule : public xplat::module::CxxModule { -public: + public: virtual std::string getName() override { return "CxxBenchmarkModule"; } - virtual auto getConstants() -> std::map override { + virtual auto getConstants() + -> std::map override { return std::map(); } virtual auto getMethods() -> std::vector override { return std::vector{ - Method("bounce", [this] (folly::dynamic args) { - this->bounce(xplat::jsArgAsInt(args, 0)); - }), - Method("bounceArgs", [this] (folly::dynamic args) { - this->bounceArgs( - xplat::jsArgAsInt(args, 0), - xplat::jsArgAsInt(args, 1), - xplat::jsArgAsInt(args, 2), - xplat::jsArgAsDouble(args, 3), - xplat::jsArgAsDouble(args, 4), - xplat::jsArgAsString(args, 5), - xplat::jsArgAsString(args, 6)); - }), + Method( + "bounce", + [this](folly::dynamic args) { + this->bounce(xplat::jsArgAsInt(args, 0)); + }), + Method( + "bounceArgs", + [this](folly::dynamic args) { + this->bounceArgs( + xplat::jsArgAsInt(args, 0), + xplat::jsArgAsInt(args, 1), + xplat::jsArgAsInt(args, 2), + xplat::jsArgAsDouble(args, 3), + xplat::jsArgAsDouble(args, 4), + xplat::jsArgAsString(args, 5), + xplat::jsArgAsString(args, 6)); + }), }; } @@ -119,9 +139,12 @@ class CxxBenchmarkModule : public xplat::module::CxxModule { void bounceArgs( int iters, - int a, int b, - double x, double y, - const std::string& s, const std::string& t) { + int a, + int b, + double x, + double y, + const std::string &s, + const std::string &t) { if (iters == 0) { CatalystBridgeBenchmarks::countDown(javaTestInstance); } else { @@ -130,7 +153,6 @@ class CxxBenchmarkModule : public xplat::module::CxxModule { } }; - void setUp( alias_ref obj, alias_ref mod) { @@ -138,8 +160,7 @@ void setUp( jsModule = jni::make_global(mod); } -void tearDown( - alias_ref) { +void tearDown(alias_ref) { javaTestInstance.reset(); jsModule.reset(); } @@ -163,17 +184,21 @@ static void stubLogHandler(int pri, const char *tag, const char *msg) { gHasSeenMessage |= priorityMatches && substringFound; } -static jboolean hasSeenExpectedLogMessage(JNIEnv*, jclass) { +static jboolean hasSeenExpectedLogMessage(JNIEnv *, jclass) { return gHasSeenMessage ? JNI_TRUE : JNI_FALSE; } -static void stopWatchingLogMessages(JNIEnv*, jclass) { +static void stopWatchingLogMessages(JNIEnv *, jclass) { gMessageToLookFor = ""; gHasSeenMessage = false; setLogHandler(NULL); } -static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring jmsg, jint priority) { +static void startWatchingForLogMessage( + JNIEnv *env, + jclass loggerClass, + jstring jmsg, + jint priority) { stopWatchingLogMessages(env, loggerClass); gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString(); gMessagePriorityToLookFor = priority; @@ -187,24 +212,34 @@ static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring using namespace facebook::react; -extern "C" facebook::xplat::module::CxxModule* CxxBenchmarkModule() { +extern "C" facebook::xplat::module::CxxModule *CxxBenchmarkModule() { return new facebook::react::CxxBenchmarkModule(); } -extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { +extern "C" jint JNI_OnLoad(JavaVM *vm, void *) { return facebook::jni::initialize(vm, [] { - facebook::jni::registerNatives( - "com/facebook/catalyst/testing/LogWatcher", { - makeNativeMethod("startWatchingForLogMessage", "(Ljava/lang/String;I)V", logwatcher::startWatchingForLogMessage), - makeNativeMethod("stopWatchingLogMessages", "()V", logwatcher::stopWatchingLogMessages), - makeNativeMethod("hasSeenExpectedLogMessage", "()Z", logwatcher::hasSeenExpectedLogMessage), - }); - facebook::jni::registerNatives( - "com/facebook/react/CatalystBridgeBenchmarks", { - makeNativeMethod("runNativeBounce", runBounce), - makeNativeMethod("nativeSetUp", setUp), - makeNativeMethod("nativeTearDown", tearDown), + facebook::jni::registerNatives( + "com/facebook/catalyst/testing/LogWatcher", + { + makeNativeMethod( + "startWatchingForLogMessage", + "(Ljava/lang/String;I)V", + logwatcher::startWatchingForLogMessage), + makeNativeMethod( + "stopWatchingLogMessages", + "()V", + logwatcher::stopWatchingLogMessages), + makeNativeMethod( + "hasSeenExpectedLogMessage", + "()Z", + logwatcher::hasSeenExpectedLogMessage), }); - }); + facebook::jni::registerNatives( + "com/facebook/react/CatalystBridgeBenchmarks", + { + makeNativeMethod("runNativeBounce", runBounce), + makeNativeMethod("nativeSetUp", setUp), + makeNativeMethod("nativeTearDown", tearDown), + }); + }); } - From 461d68e6568d6e5ad2f4c40b9fd19e92ec09221b Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Tue, 14 Jan 2020 03:42:23 -0800 Subject: [PATCH 0018/1126] Use commands instead of setNativeProps for CheckBox Summary: As a part of the migration from setNativeProps in Fabric and Paper, we are replacing it by view commands in the Checkbox component on Android. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18451749 fbshipit-source-id: 49d786ef3383df95b10260ba2b7f68489ad31789 --- Libraries/Components/CheckBox/CheckBox.android.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/CheckBox/CheckBox.android.js b/Libraries/Components/CheckBox/CheckBox.android.js index b953fdc2a60ead..179680a7e44a57 100644 --- a/Libraries/Components/CheckBox/CheckBox.android.js +++ b/Libraries/Components/CheckBox/CheckBox.android.js @@ -17,7 +17,9 @@ const processColor = require('../../StyleSheet/processColor'); const nullthrows = require('nullthrows'); const setAndForwardRef = require('../../Utilities/setAndForwardRef'); -import AndroidCheckBoxNativeComponent from './AndroidCheckBoxNativeComponent'; +import AndroidCheckBoxNativeComponent, { + Commands as AndroidCheckBoxCommands, +} from './AndroidCheckBoxNativeComponent'; import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; @@ -141,7 +143,7 @@ class CheckBox extends React.Component { _onChange = (event: CheckBoxEvent) => { const value = this.props.value ?? false; - nullthrows(this._nativeRef).setNativeProps({value: value}); + AndroidCheckBoxCommands.setNativeValue(nullthrows(this._nativeRef), value); // Change the props after the native props are set in case the props // change removes the component this.props.onChange && this.props.onChange(event); From 1e6e37a3a8c8a00661b3fbe7a8ee289da3bf01b7 Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Tue, 14 Jan 2020 03:51:29 -0800 Subject: [PATCH 0019/1126] Use commands instead of setNativeProps for AndroidSwipeRefreshLayout Summary: As a part of the migration from setNativeProps in Fabric and Paper, we are replacing it by view commands in the RefreshControl component on Android. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18475450 fbshipit-source-id: ad89547fada3444f725fd9b00e8482cfc8f4d7fc --- .../RefreshControl/RefreshControl.js | 41 +++++++++++-------- .../RefreshControl/RefreshControlExample.js | 1 + 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Libraries/Components/RefreshControl/RefreshControl.js b/Libraries/Components/RefreshControl/RefreshControl.js index c0d600c0e8740c..3e98f4adf2464f 100644 --- a/Libraries/Components/RefreshControl/RefreshControl.js +++ b/Libraries/Components/RefreshControl/RefreshControl.js @@ -15,8 +15,9 @@ const React = require('react'); import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import AndroidSwipeRefreshLayoutNativeComponent from './AndroidSwipeRefreshLayoutNativeComponent'; - +import AndroidSwipeRefreshLayoutNativeComponent, { + Commands as AndroidSwipeRefreshLayoutCommands, +} from './AndroidSwipeRefreshLayoutNativeComponent'; import PullToRefreshViewNativeComponent, { Commands as PullToRefreshCommands, } from './PullToRefreshViewNativeComponent'; @@ -138,11 +139,12 @@ export type RefreshControlProps = $ReadOnly<{| class RefreshControl extends React.Component { static SIZE: any = RefreshLayoutConsts.SIZE; - _setNativePropsOnRef: ?({refreshing: boolean, ...}) => void; + _nativeRef: ?React.ElementRef< + | typeof PullToRefreshViewNativeComponent + | typeof AndroidSwipeRefreshLayoutNativeComponent, + >; _lastNativeRefreshing = false; - _nativeRef: ?React.ElementRef; - componentDidMount() { this._lastNativeRefreshing = this.props.refreshing; } @@ -155,13 +157,14 @@ class RefreshControl extends React.Component { this._lastNativeRefreshing = this.props.refreshing; } else if ( this.props.refreshing !== this._lastNativeRefreshing && - this._setNativePropsOnRef + this._nativeRef ) { if (Platform.OS === 'android') { - this._setNativePropsOnRef({ - refreshing: this.props.refreshing, - }); - } else if (this._nativeRef) { + AndroidSwipeRefreshLayoutCommands.setNativeRefreshing( + this._nativeRef, + this.props.refreshing, + ); + } else { PullToRefreshCommands.setNativeRefreshing( this._nativeRef, this.props.refreshing, @@ -172,11 +175,6 @@ class RefreshControl extends React.Component { } render(): React.Node { - const setRef = ref => { - this._setNativePropsOnRef = ref ? ref.setNativeProps.bind(ref) : null; - this._nativeRef = ref; - }; - if (Platform.OS === 'ios') { const { enabled, @@ -189,7 +187,7 @@ class RefreshControl extends React.Component { return ( ); @@ -198,7 +196,7 @@ class RefreshControl extends React.Component { return ( ); @@ -214,6 +212,15 @@ class RefreshControl extends React.Component { // make sure it stays in sync with the js component. this.forceUpdate(); }; + + _setNativeRef = ( + ref: ?React.ElementRef< + | typeof PullToRefreshViewNativeComponent + | typeof AndroidSwipeRefreshLayoutNativeComponent, + >, + ) => { + this._nativeRef = ref; + }; } module.exports = RefreshControl; diff --git a/RNTester/js/examples/RefreshControl/RefreshControlExample.js b/RNTester/js/examples/RefreshControl/RefreshControlExample.js index bff7198e5abecc..06493b0971b82a 100644 --- a/RNTester/js/examples/RefreshControl/RefreshControlExample.js +++ b/RNTester/js/examples/RefreshControl/RefreshControlExample.js @@ -116,6 +116,7 @@ class RefreshControlExample extends React.Component { exports.title = ''; exports.description = 'Adds pull-to-refresh support to a scrollview.'; +exports.simpleExampleContainer = true; exports.examples = [ { title: 'Simple refresh', From e848b0036da0644d2fb1202b51c05df389fa0364 Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Tue, 14 Jan 2020 03:54:38 -0800 Subject: [PATCH 0020/1126] Use commands instead of setNativeProps for PickerAndroid Summary: Fabric doesn't support setNativeProps, so we are using view commands instead. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18044169 fbshipit-source-id: d5f199b930244d02f174ea8a7ef732e9a8ef2476 --- .../Picker/PickerAndroid.android.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Libraries/Components/Picker/PickerAndroid.android.js b/Libraries/Components/Picker/PickerAndroid.android.js index 4fddefb8014887..6788aefd06fabc 100644 --- a/Libraries/Components/Picker/PickerAndroid.android.js +++ b/Libraries/Components/Picker/PickerAndroid.android.js @@ -10,8 +10,12 @@ 'use strict'; -import AndroidDropdownPickerNativeComponent from './AndroidDropdownPickerNativeComponent'; -import AndroidDialogPickerNativeComponent from './AndroidDialogPickerNativeComponent'; +import AndroidDropdownPickerNativeComponent, { + Commands as AndroidDropdownPickerCommands, +} from './AndroidDropdownPickerNativeComponent'; +import AndroidDialogPickerNativeComponent, { + Commands as AndroidDialogPickerCommands, +} from './AndroidDialogPickerNativeComponent'; import * as React from 'react'; import StyleSheet from '../../StyleSheet/StyleSheet'; import processColor from '../../StyleSheet/processColor'; @@ -83,13 +87,22 @@ function PickerAndroid(props: Props): React.Node { onValueChange(null, position); } } - const {current} = pickerRef; if (current != null && position !== selected) { - current.setNativeProps({selected}); + const Commands = + props.mode === 'dropdown' + ? AndroidDropdownPickerCommands + : AndroidDialogPickerCommands; + Commands.setNativeSelectedPosition(current, selected); } }, - [props.children, props.onValueChange, props.selectedValue, selected], + [ + props.children, + props.onValueChange, + props.selectedValue, + props.mode, + selected, + ], ); const rootProps = { From 139bf7cffe7fc8091a397e9504815ec7242e76e7 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 14 Jan 2020 04:03:14 -0800 Subject: [PATCH 0021/1126] Add plugin assertion to ensure image component is loaded Summary: With plugins being used for components, there is danger that someone will remove buck target as dependency and component in the target won't be available for Fabric. That's where `plugin_assertion` comes into play. For now I hardcoded a list of components. In the future, this list will be generated from JS components that are used in the app. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19197548 fbshipit-source-id: 0d31f53b573c343561715a8fb6fc7f0abfdb5b76 --- React/Fabric/Mounting/RCTComponentViewFactory.mm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/React/Fabric/Mounting/RCTComponentViewFactory.mm b/React/Fabric/Mounting/RCTComponentViewFactory.mm index 1ef6801e67e864..773eba1ccc2958 100644 --- a/React/Fabric/Mounting/RCTComponentViewFactory.mm +++ b/React/Fabric/Mounting/RCTComponentViewFactory.mm @@ -9,7 +9,6 @@ #import #import -#import #import #import @@ -59,11 +58,7 @@ + (RCTComponentViewFactory *)standardComponentViewFactory [componentViewFactory registerComponentViewClass:[RCTTextInputComponentView class]]; Class imageClass = RCTComponentViewClassWithName("Image"); - if (imageClass) { - [componentViewFactory registerComponentViewClass:imageClass]; - } else { - LOG(FATAL) << "Image component not found"; - } + [componentViewFactory registerComponentViewClass:imageClass]; auto providerRegistry = &componentViewFactory->_providerRegistry; From fca833e2ae402a7c9c9b1d95188edf05350796eb Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 14 Jan 2020 06:27:56 -0800 Subject: [PATCH 0022/1126] Fix handling of nil event in legacy interop layer's eventInterceptor Summary: interop layer doesn't deal with `nil` being sent as event, example https://fburl.com/diffusion/t5zx6xm0. This later triggers following assertion https://fburl.com/diffusion/dr5xzgic. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19309356 fbshipit-source-id: 82b3841c337f949ce7ca0b875c98f608edddb599 --- .../RCTLegacyViewManagerInteropCoordinator.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm index 764883117f6198..1874f8d5d1c45f 100644 --- a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm +++ b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm @@ -41,7 +41,7 @@ - (instancetype)initWithComponentData:(RCTComponentData *)componentData bridge:( __typeof(self) strongSelf = weakSelf; InterceptorBlock block = [strongSelf->_eventInterceptors objectForKey:reactTag]; if (block) { - block(std::string([RCTNormalizeInputEventName(eventName) UTF8String]), convertIdToFollyDynamic(event)); + block(std::string([RCTNormalizeInputEventName(eventName) UTF8String]), convertIdToFollyDynamic(event ?: @{})); } }; } From f15b80b67586d6bec1d2a1a04717529efc27854e Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 14 Jan 2020 06:27:56 -0800 Subject: [PATCH 0023/1126] Migrate Keyframes to Fabric using interop layer Summary: Adds Keyframes to interop whitelist of supported components. In `RCTKeyframesManager.m` we look into subviews in order to find `RCTKeyframesView`, this is because the view returned from paper's `UIManager` is interop itself. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19309355 fbshipit-source-id: f9b598ee6ad5340a4e4b3914330c70eea9f43926 --- React/Views/RCTDatePickerManager.m | 5 ++++- React/Views/RCTPickerManager.m | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/React/Views/RCTDatePickerManager.m b/React/Views/RCTDatePickerManager.m index b7710ba4b04b81..a5c6ce1d6b4eea 100644 --- a/React/Views/RCTDatePickerManager.m +++ b/React/Views/RCTDatePickerManager.m @@ -46,10 +46,13 @@ - (UIView *)view { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { UIView *view = viewRegistry[viewTag]; - + if ([view isKindOfClass:[RCTDatePicker class]]) { [(RCTDatePicker *)view setDate:date]; } else { + // This component is used in Fabric through LegacyInteropLayer. + // `RCTPicker` view is subview of `RCTLegacyViewManagerInteropComponentView`. + // `viewTag` passed as parameter to this method is tag of the `RCTLegacyViewManagerInteropComponentView`. UIView *subview = view.subviews.firstObject; if ([subview isKindOfClass:[RCTDatePicker class]]) { [(RCTDatePicker *)subview setDate:date]; diff --git a/React/Views/RCTPickerManager.m b/React/Views/RCTPickerManager.m index aac54436b78e06..7585735d598233 100644 --- a/React/Views/RCTPickerManager.m +++ b/React/Views/RCTPickerManager.m @@ -48,10 +48,13 @@ - (UIView *)view { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { UIView *view = viewRegistry[viewTag]; - + if ([view isKindOfClass:[RCTPicker class]]) { [(RCTPicker *)view setSelectedIndex:index.integerValue]; } else { + // This component is used in Fabric through LegacyInteropLayer. + // `RCTPicker` view is subview of `RCTLegacyViewManagerInteropComponentView`. + // `viewTag` passed as parameter to this method is tag of the `RCTLegacyViewManagerInteropComponentView`. UIView *subview = view.subviews.firstObject; if ([subview isKindOfClass:[RCTPicker class]]) { [(RCTPicker *)subview setSelectedIndex:index.integerValue]; From 6bdfd84a452fb807abc46f1a7ecddf4f126d5c1e Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 14 Jan 2020 06:37:03 -0800 Subject: [PATCH 0024/1126] Move event structs into event emitter namespace Summary: In codegen we generate structs that represents events. These structs are later dispatched by generated `EventEmitter`. They had unpleasant naming, for example `SliderOnValueChangeStruct`. This diff changes the code generated so it becomes `SliderEventEmitter::OnValueChange`, this better expresses the relationship of the two classes. Changelog: [Internal] Motivation: Better express relationship between EventEmitter and classes that represent events. Reviewed By: rickhanlonii, shergin Differential Revision: D19373850 fbshipit-source-id: a5eea085013dbc119169e2b06ba9f9fe44c7fcd9 --- .../Modal/RCTModalHostViewComponentView.mm | 10 +- .../Slider/RCTSliderComponentView.mm | 4 +- .../Switch/RCTSwitchComponentView.mm | 2 +- .../src/generators/components/CppHelpers.js | 6 + .../components/GenerateEventEmitterCpp.js | 7 +- .../components/GenerateEventEmitterH.js | 57 +++++---- .../GenerateEventEmitterCpp-test.js.snap | 14 +- .../GenerateEventEmitterH-test.js.snap | 120 +++++++++--------- 8 files changed, 114 insertions(+), 106 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm index cb6f3039a5904c..7fcbd62147f92d 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -85,10 +85,12 @@ static UIModalPresentationStyle presentationConfiguration(ModalHostViewProps con } } -static ModalHostViewOnOrientationChangeStruct onOrientationChangeStruct(CGRect rect) +static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(CGRect rect) { - auto orientation = rect.size.width < rect.size.height ? ModalHostViewOnOrientationChangeOrientationStruct::Portrait - : ModalHostViewOnOrientationChangeOrientationStruct::Landscape; + ; + auto orientation = rect.size.width < rect.size.height + ? ModalHostViewEventEmitter::OnOrientationChangeOrientation::Portrait + : ModalHostViewEventEmitter::OnOrientationChangeOrientation::Landscape; return {orientation}; } @@ -136,7 +138,7 @@ - (void)ensurePresentedOnlyIfNeeded assert(std::dynamic_pointer_cast(self->_eventEmitter)); auto eventEmitter = std::static_pointer_cast(self->_eventEmitter); - eventEmitter->onShow(ModalHostViewOnShowStruct{}); + eventEmitter->onShow(ModalHostViewEventEmitter::OnShow{}); }]; } diff --git a/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm b/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm index fddefa4d99c480..bff3b25519802f 100644 --- a/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm @@ -309,11 +309,11 @@ - (void)onChange:(UISlider *)sender withContinuous:(BOOL)continuous if (continuous && _previousValue != value) { std::dynamic_pointer_cast(_eventEmitter) - ->onValueChange(SliderOnValueChangeStruct{.value = static_cast(value)}); + ->onValueChange(SliderEventEmitter::OnValueChange{.value = static_cast(value)}); } if (!continuous) { std::dynamic_pointer_cast(_eventEmitter) - ->onSlidingComplete(SliderOnSlidingCompleteStruct{.value = static_cast(value)}); + ->onSlidingComplete(SliderEventEmitter::OnSlidingComplete{.value = static_cast(value)}); } _previousValue = value; diff --git a/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm b/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm index 4e384bca67f5be..4528488f52d3b8 100644 --- a/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm @@ -99,7 +99,7 @@ - (void)onChange:(UISwitch *)sender } std::dynamic_pointer_cast(_eventEmitter) - ->onChange(SwitchOnChangeStruct{.value = static_cast(sender.on)}); + ->onChange(SwitchEventEmitter::OnChange{.value = static_cast(sender.on)}); } #pragma mark - Native Commands diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index 6b92c5df968c8a..80854623221241 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -98,6 +98,11 @@ function getImports(properties: $ReadOnlyArray): Set { return imports; } +function generateEventStructName(parts: $ReadOnlyArray = []): string { + const additional = parts.map(toSafeCppString).join(''); + return `${additional}`; +} + function generateStructName( componentName: string, parts: $ReadOnlyArray = [], @@ -206,4 +211,5 @@ module.exports = { toSafeCppString, toIntEnumValueName, generateStructName, + generateEventStructName, }; diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index 76f029bc7bec67..8577df4309ebe6 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -10,7 +10,7 @@ 'use strict'; -const {generateStructName} = require('./CppHelpers.js'); +const {generateEventStructName} = require('./CppHelpers.js'); import type { ComponentShape, @@ -151,10 +151,7 @@ function generateEvent(componentName: string, event): string { .replace(/::_CLASSNAME_::/g, componentName) .replace(/::_EVENT_NAME_::/g, event.name) .replace(/::_DISPATCH_EVENT_NAME_::/g, dispatchEventName) - .replace( - '::_STRUCT_NAME_::', - generateStructName(componentName, [event.name]), - ) + .replace('::_STRUCT_NAME_::', generateEventStructName([event.name])) .replace('::_IMPLEMENTATION_::', implementation); } diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index 104d4e9726f093..a1d6956f8557cc 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -15,7 +15,7 @@ const nullthrows = require('nullthrows'); const { getCppTypeForAnnotation, toSafeCppString, - generateStructName, + generateEventStructName, } = require('./CppHelpers.js'); import type { @@ -55,31 +55,45 @@ namespace react { `; const componentTemplate = ` -::_STRUCTS_:: - class ::_CLASSNAME_::EventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; + ::_STRUCTS_:: + ::_EVENTS_:: }; `.trim(); const structTemplate = ` -struct ::_STRUCT_NAME_:: { - ::_FIELDS_:: -}; + struct ::_STRUCT_NAME_:: { + ::_FIELDS_:: + }; `.trim(); const enumTemplate = `enum class ::_ENUM_NAME_:: { ::_VALUES_:: }; -inline char const *toString(const ::_ENUM_NAME_:: value) { +static char const *toString(const ::_ENUM_NAME_:: value) { switch (value) { ::_TO_CASES_:: } -}`.trim(); +} +`.trim(); + +function indent(nice: string, spaces: number) { + return nice + .split('\n') + .map((line, index) => { + if (line.length === 0 || index === 0) { + return line; + } + const emptySpaces = new Array(spaces + 1).join(' '); + return emptySpaces + line; + }) + .join('\n'); +} function getNativeTypeFromAnnotation( componentName: string, @@ -96,22 +110,16 @@ function getNativeTypeFromAnnotation( case 'FloatTypeAnnotation': return getCppTypeForAnnotation(type); case 'StringEnumTypeAnnotation': - return generateStructName( - componentName, - nameParts.concat([eventProperty.name]), - ); + return generateEventStructName(nameParts.concat([eventProperty.name])); case 'ObjectTypeAnnotation': - return generateStructName( - componentName, - nameParts.concat([eventProperty.name]), - ); + return generateEventStructName(nameParts.concat([eventProperty.name])); default: (type: empty); throw new Error(`Received invalid event property type ${type}`); } } -function generateEnum(structs, componentName, options, nameParts) { - const structName = generateStructName(componentName, nameParts); +function generateEnum(structs, options, nameParts) { + const structName = generateEventStructName(nameParts); const fields = options .map((option, index) => `${toSafeCppString(option.name)}`) .join(',\n '); @@ -141,7 +149,7 @@ function generateStruct( properties: $ReadOnlyArray, ): void { const structNameParts = nameParts; - const structName = generateStructName(componentName, structNameParts); + const structName = generateEventStructName(structNameParts); const fields = properties .map(property => { @@ -171,12 +179,7 @@ function generateStruct( ); return; case 'StringEnumTypeAnnotation': - generateEnum( - structs, - componentName, - property.options, - nameParts.concat([name]), - ); + generateEnum(structs, property.options, nameParts.concat([name])); return; default: (property: empty); @@ -213,7 +216,7 @@ function generateStructs(componentName: string, component): string { function generateEvent(componentName: string, event: EventTypeShape): string { if (event.typeAnnotation.argument) { - const structName = generateStructName(componentName, [event.name]); + const structName = generateEventStructName([event.name]); return `void ${event.name}(${structName} value) const;`; } @@ -261,7 +264,7 @@ module.exports = { .replace(/::_CLASSNAME_::/g, componentName) .replace( '::_STRUCTS_::', - generateStructs(componentName, component), + indent(generateStructs(componentName, component), 2), ) .replace( '::_EVENTS_::', diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap index 9fa0d8359c31e0..a13aedb1303c47 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -176,7 +176,7 @@ Map { namespace facebook { namespace react { -void EventsNestedObjectNativeComponentEventEmitter::onChange(EventsNestedObjectNativeComponentOnChangeStruct event) const { +void EventsNestedObjectNativeComponentEventEmitter::onChange(OnChange event) const { dispatchEvent(\\"change\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); { @@ -217,7 +217,7 @@ Map { namespace facebook { namespace react { -void EventsNativeComponentEventEmitter::onChange(EventsNativeComponentOnChangeStruct event) const { +void EventsNativeComponentEventEmitter::onChange(OnChange event) const { dispatchEvent(\\"change\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"value\\", event.value); @@ -227,14 +227,14 @@ payload.setProperty(runtime, \\"scale\\", event.scale); return payload; }); } -void EventsNativeComponentEventEmitter::onEventDirect(EventsNativeComponentOnEventDirectStruct event) const { +void EventsNativeComponentEventEmitter::onEventDirect(OnEventDirect event) const { dispatchEvent(\\"eventDirect\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"value\\", event.value); return payload; }); } -void EventsNativeComponentEventEmitter::onOrientationChange(EventsNativeComponentOnOrientationChangeStruct event) const { +void EventsNativeComponentEventEmitter::onOrientationChange(OnOrientationChange event) const { dispatchEvent(\\"orientationChange\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"orientation\\", toString(event.orientation)); @@ -266,14 +266,14 @@ Map { namespace facebook { namespace react { -void InterfaceOnlyComponentEventEmitter::onChange(InterfaceOnlyComponentOnChangeStruct event) const { +void InterfaceOnlyComponentEventEmitter::onChange(OnChange event) const { dispatchEvent(\\"change\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"value\\", event.value); return payload; }); } -void InterfaceOnlyComponentEventEmitter::onDire tChange(InterfaceOnlyComponentOnDire tChangeStruct event) const { +void InterfaceOnlyComponentEventEmitter::onDire tChange(OnDire tChange event) const { dispatchEvent(\\"dire tChange\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"value\\", event.value); @@ -440,7 +440,7 @@ Map { namespace facebook { namespace react { -void InterfaceOnlyComponentEventEmitter::onChange(InterfaceOnlyComponentOnChangeStruct event) const { +void InterfaceOnlyComponentEventEmitter::onChange(OnChange event) const { dispatchEvent(\\"change\\", [event=std::move(event)](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); payload.setProperty(runtime, \\"value\\", event.value); diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap index 24434f94decdfa..6b0076238052ea 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -184,25 +184,25 @@ Map { namespace facebook { namespace react { -struct EventsNestedObjectNativeComponentOnChangeLocationSourceStruct { - std::string url; -}; - -struct EventsNestedObjectNativeComponentOnChangeLocationStruct { - EventsNestedObjectNativeComponentOnChangeLocationSourceStruct source; - int x; - int y; -}; - -struct EventsNestedObjectNativeComponentOnChangeStruct { - EventsNestedObjectNativeComponentOnChangeLocationStruct location; -}; - class EventsNestedObjectNativeComponentEventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; - void onChange(EventsNestedObjectNativeComponentOnChangeStruct value) const; + struct OnChangeLocationSource { + std::string url; + }; + + struct OnChangeLocation { + OnChangeLocationSource source; + int x; + int y; + }; + + struct OnChange { + OnChangeLocation location; + }; + + void onChange(OnChange value) const; }; } // namespace react @@ -227,42 +227,42 @@ Map { namespace facebook { namespace react { -struct EventsNativeComponentOnChangeStruct { - bool value; - std::string source; - int progress; - Float scale; -}; - -struct EventsNativeComponentOnEventDirectStruct { - bool value; -}; - -enum class EventsNativeComponentOnOrientationChangeOrientationStruct { - Landscape, - Portrait -}; - -inline char const *toString(const EventsNativeComponentOnOrientationChangeOrientationStruct value) { - switch (value) { - case EventsNativeComponentOnOrientationChangeOrientationStruct::Landscape: return \\"landscape\\"; - case EventsNativeComponentOnOrientationChangeOrientationStruct::Portrait: return \\"portrait\\"; - } -} - -struct EventsNativeComponentOnOrientationChangeStruct { - EventsNativeComponentOnOrientationChangeOrientationStruct orientation; -}; - class EventsNativeComponentEventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; - void onChange(EventsNativeComponentOnChangeStruct value) const; + struct OnChange { + bool value; + std::string source; + int progress; + Float scale; + }; + + struct OnEventDirect { + bool value; + }; + + enum class OnOrientationChangeOrientation { + Landscape, + Portrait + }; + + static char const *toString(const OnOrientationChangeOrientation value) { + switch (value) { + case OnOrientationChangeOrientation::Landscape: return \\"landscape\\"; + case OnOrientationChangeOrientation::Portrait: return \\"portrait\\"; + } + } + + struct OnOrientationChange { + OnOrientationChangeOrientation orientation; + }; - void onEventDirect(EventsNativeComponentOnEventDirectStruct value) const; + void onChange(OnChange value) const; - void onOrientationChange(EventsNativeComponentOnOrientationChangeStruct value) const; + void onEventDirect(OnEventDirect value) const; + + void onOrientationChange(OnOrientationChange value) const; void onEnd() const; }; @@ -289,21 +289,21 @@ Map { namespace facebook { namespace react { -struct InterfaceOnlyComponentOnChangeStruct { - bool value; -}; - -struct InterfaceOnlyComponentOnDire tChangeStruct { - bool value; -}; - class InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; - void onChange(InterfaceOnlyComponentOnChangeStruct value) const; + struct OnChange { + bool value; + }; + + struct OnDire tChange { + bool value; + }; - void onDire tChange(InterfaceOnlyComponentOnDire tChangeStruct value) const; + void onChange(OnChange value) const; + + void onDire tChange(OnDire tChange value) const; }; } // namespace react @@ -472,15 +472,15 @@ Map { namespace facebook { namespace react { -struct InterfaceOnlyComponentOnChangeStruct { - bool value; -}; - class InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; - void onChange(InterfaceOnlyComponentOnChangeStruct value) const; + struct OnChange { + bool value; + }; + + void onChange(OnChange value) const; }; } // namespace react From 7e3a43c23d028a4481bc455dd28c391a81ff1a94 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 14 Jan 2020 07:54:08 -0800 Subject: [PATCH 0025/1126] Fix NativeJSCHeapCapture Summary: In D15393464, we introduced `NativeHeapCapture`, but it had a few problems: 1. It required `JSCHeapCapture` by doing `TurboModuleRegistry.get('HeapCapture')`, when it should have done `TurboModuleRegistry.get('JSCHeapCapture')`. 2. It had an additional method `captureHeap`, which didn't exist on the Android NativeModule. This diff corrects those mistakes. Changelog: [Both][Fixed] - Fix JSCHeapCapture Reviewed By: PeteTheHeat Differential Revision: D19383511 fbshipit-source-id: 30e69afbcdba673f3f32c16bde4f0342568ab97d --- .../FBReactNativeSpec-generated.mm | 47 ++++++++----------- .../FBReactNativeSpec/FBReactNativeSpec.h | 39 ++++++++------- Libraries/HeapCapture/HeapCapture.js | 6 +-- ...HeapCapture.js => NativeJSCHeapCapture.js} | 6 +-- .../specs/NativeJSCHeapCaptureSpec.java | 29 ++++++++++++ 5 files changed, 72 insertions(+), 55 deletions(-) rename Libraries/HeapCapture/{NativeHeapCapture.js => NativeJSCHeapCapture.js} (76%) create mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeJSCHeapCaptureSpec.java diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index bce1dea35f5dce..a9a9a4c4329de2 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -1204,33 +1204,6 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) - } - - } // namespace react -} // namespace facebook -namespace facebook { - namespace react { - - - static facebook::jsi::Value __hostFunction_NativeHeapCaptureSpecJSI_captureHeap(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureHeap", @selector(captureHeap:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeHeapCaptureSpecJSI_captureComplete(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureComplete", @selector(captureComplete:error:), args, count); - } - - - NativeHeapCaptureSpecJSI::NativeHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("HeapCapture", instance, jsInvoker) { - - methodMap_["captureHeap"] = MethodMetadata {1, __hostFunction_NativeHeapCaptureSpecJSI_captureHeap}; - - - methodMap_["captureComplete"] = MethodMetadata {2, __hostFunction_NativeHeapCaptureSpecJSI_captureComplete}; - - - } } // namespace react @@ -1522,6 +1495,26 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr + } + + } // namespace react +} // namespace facebook +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeJSCHeapCaptureSpecJSI_captureComplete(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureComplete", @selector(captureComplete:error:), args, count); + } + + + NativeJSCHeapCaptureSpecJSI::NativeJSCHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("JSCHeapCapture", instance, jsInvoker) { + + methodMap_["captureComplete"] = MethodMetadata {2, __hostFunction_NativeJSCHeapCaptureSpecJSI_captureComplete}; + + + } } // namespace react diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index 6bf1ef4a9934c4..c2d82d8f05f51c 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -1304,26 +1304,6 @@ namespace facebook { }; } // namespace react } // namespace facebook -@protocol NativeHeapCaptureSpec - -- (void)captureHeap:(NSString *)path; -- (void)captureComplete:(NSString *)path - error:(NSString * _Nullable)error; - -@end -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'HeapCapture' - */ - - class JSI_EXPORT NativeHeapCaptureSpecJSI : public ObjCTurboModule { - public: - NativeHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker); - - }; - } // namespace react -} // namespace facebook namespace JS { namespace NativeI18nManager { @@ -1631,6 +1611,25 @@ namespace facebook { }; } // namespace react } // namespace facebook +@protocol NativeJSCHeapCaptureSpec + +- (void)captureComplete:(NSString *)path + error:(NSString * _Nullable)error; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'JSCHeapCapture' + */ + + class JSI_EXPORT NativeJSCHeapCaptureSpecJSI : public ObjCTurboModule { + public: + NativeJSCHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker); + + }; + } // namespace react +} // namespace facebook @protocol NativeJSCSamplingProfilerSpec - (void)operationComplete:(double)token diff --git a/Libraries/HeapCapture/HeapCapture.js b/Libraries/HeapCapture/HeapCapture.js index 9cbabc60417487..903343a05b0601 100644 --- a/Libraries/HeapCapture/HeapCapture.js +++ b/Libraries/HeapCapture/HeapCapture.js @@ -10,7 +10,7 @@ 'use strict'; -import NativeHeapCapture from './NativeHeapCapture'; +import NativeJSCHeapCapture from './NativeJSCHeapCapture'; const HeapCapture = { captureHeap: function(path: string) { @@ -22,8 +22,8 @@ const HeapCapture = { console.log('HeapCapture.captureHeap error: ' + e.toString()); error = e.toString(); } - if (NativeHeapCapture) { - NativeHeapCapture.captureComplete(path, error); + if (NativeJSCHeapCapture) { + NativeJSCHeapCapture.captureComplete(path, error); } }, }; diff --git a/Libraries/HeapCapture/NativeHeapCapture.js b/Libraries/HeapCapture/NativeJSCHeapCapture.js similarity index 76% rename from Libraries/HeapCapture/NativeHeapCapture.js rename to Libraries/HeapCapture/NativeJSCHeapCapture.js index 5d778e44771467..05e941f17e7b83 100644 --- a/Libraries/HeapCapture/NativeHeapCapture.js +++ b/Libraries/HeapCapture/NativeJSCHeapCapture.js @@ -14,11 +14,7 @@ import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { - // Common interface - +captureHeap: (path: string) => void; - - // Android only +captureComplete: (path: string, error: ?string) => void; } -export default (TurboModuleRegistry.get('HeapCapture'): ?Spec); +export default (TurboModuleRegistry.get('JSCHeapCapture'): ?Spec); diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeJSCHeapCaptureSpec.java b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeJSCHeapCaptureSpec.java new file mode 100644 index 00000000000000..f74a8a12912e92 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeJSCHeapCaptureSpec.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + * + *

Generated by an internal genrule from Flow types. + * + * @generated + * @nolint + */ + +package com.facebook.fbreact.specs; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactModuleWithSpec; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import javax.annotation.Nullable; + +public abstract class NativeJSCHeapCaptureSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule { + public NativeJSCHeapCaptureSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @ReactMethod + public abstract void captureComplete(String path, @Nullable String error); +} From dbb7eacb429adb4160e740017c212bfd6df0f03a Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 14 Jan 2020 09:02:54 -0800 Subject: [PATCH 0026/1126] Add support to render with no fixed size nested within a Summary: This diff fixes the redbox error: Views nested within a must have a width and height This error is reproducible when rendering a View with no fixed size, inside a . e.g. ``` function PlaygroundContent(props: {}) { return ( ); } ``` changelog: Add support to render with no fixed size nested within a Reviewed By: shergin Differential Revision: D19387760 fbshipit-source-id: a9cee8410e56a2d362d6b8f993e602719c416925 --- .../react/config/ReactFeatureFlags.java | 5 ++++ .../java/com/facebook/react/views/text/BUCK | 1 + .../views/text/ReactBaseTextShadowNode.java | 24 +++++++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index b746fcdc1cc200..b06df9eaaacb67 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -90,4 +90,9 @@ public class ReactFeatureFlags { *

The react flag is disabled by default because this is increasing ANRs (T57363204) */ public static boolean clipChildRectsIfOverflowIsHidden = false; + + /** + * This react flag enables the rendering of s with no fixed size within a component. + */ + public static boolean supportInlineViewsWithDynamicSize = true; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK index 62458f6ae265ae..9d05a349159b17 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK @@ -21,6 +21,7 @@ rn_android_library( react_native_dep("third-party/java/jsr-305:jsr-305"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/common:common"), + react_native_target("java/com/facebook/react/config:config"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/uimanager:uimanager"), react_native_target("java/com/facebook/react/uimanager/annotations:annotations"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index 76c658212edd15..013ec3b5283085 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -20,6 +20,7 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.NativeViewHierarchyOptimizer; @@ -136,12 +137,23 @@ private static void buildSpannedFromShadowNode( YogaValue widthValue = child.getStyleWidth(); YogaValue heightValue = child.getStyleHeight(); + float width; + float height; if (widthValue.unit != YogaUnit.POINT || heightValue.unit != YogaUnit.POINT) { - throw new IllegalViewOperationException( - "Views nested within a must have a width and height"); + if (ReactFeatureFlags.supportInlineViewsWithDynamicSize) { + // If the measurement of the child isn't calculated, we calculate the layout for the + // view using Yoga + child.calculateLayout(); + width = child.getLayoutWidth(); + height = child.getLayoutHeight(); + } else { + throw new IllegalViewOperationException( + "Views nested within a must have a width and height"); + } + } else { + width = widthValue.value; + height = heightValue.value; } - float width = widthValue.value; - float height = heightValue.value; // We make the inline view take up 1 character in the span and put a corresponding character // into @@ -360,9 +372,7 @@ protected Spannable spannedFromShadowNode( */ protected @Nullable String mFontFamily = null; - /** - * @see android.graphics.Paint#setFontFeatureSettings - */ + /** @see android.graphics.Paint#setFontFeatureSettings */ protected @Nullable String mFontFeatureSettings = null; protected boolean mContainsImages = false; From 7c066ae9526a0ee570b159b3828ff2b5ff28889e Mon Sep 17 00:00:00 2001 From: Oleksandr Melnykov Date: Tue, 14 Jan 2020 11:34:51 -0800 Subject: [PATCH 0027/1126] Integrate WebView into Fabric on Android Summary: This diff integrates WebView into Fabric on Android. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D19177933 fbshipit-source-id: 0586f2a44201ee867756e000923859a73ec68ab9 --- .../main/java/com/facebook/react/fabric/FabricComponents.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java index d26f518952eaf4..c091ed2e381a1c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricComponents.java @@ -38,6 +38,7 @@ public class FabricComponents { sComponentNames.put("Video", "RCTVideo"); sComponentNames.put("StickerInputView", "RCTStickerInputView"); sComponentNames.put("Map", "RCTMap"); + sComponentNames.put("WebView", "RCTWebView"); } /** @return the name of component in the Fabric environment */ From 9fb2ca0b5343f7cd25eabfecd8a523c766646e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 14 Jan 2020 13:27:53 -0800 Subject: [PATCH 0028/1126] Bump Xcode to 11.2.1 (#27434) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/27434 Pull Request resolved: https://github.com/facebook/react-native/pull/27295 - Use Xcode version 11.2.1 in both internal and external tests. - Update snapshot reference images to use iPhone 8 test device. Xcode 11.3.0 will be available in Sandcastle in the next week or so. Changelog: [Internal] - Bump Xcode version used in tests to 11.2.1. [Internal] - Update iOS Snapshots. Reviewed By: cs01 Differential Revision: D18849584 fbshipit-source-id: 9e3b92f080a4dc6a15dac0535b7562ff6a5c08a9 --- .circleci/config.yml | 2 +- .../testLayoutExample_1-iOS13@2x.png | Bin 0 -> 169616 bytes .../testScrollViewExample_1-iOS13@2x.png | Bin 0 -> 254282 bytes .../testSwitchExample_1-iOS13@2x.png | Bin 0 -> 127031 bytes .../testTextExample_1-iOS13@2x.png | Bin 0 -> 326309 bytes .../testViewExample_1-iOS13@2x.png | Bin 0 -> 238945 bytes RNTester/RNTesterUnitTests/RCTJSONTests.m | 17 ++++++++--------- scripts/.tests.env | 2 +- scripts/objc-test.sh | 8 +++++++- scripts/run-ci-e2e-tests.js | 5 +++-- 10 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png create mode 100644 RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testScrollViewExample_1-iOS13@2x.png create mode 100644 RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testSwitchExample_1-iOS13@2x.png create mode 100644 RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testTextExample_1-iOS13@2x.png create mode 100644 RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testViewExample_1-iOS13@2x.png diff --git a/.circleci/config.yml b/.circleci/config.yml index fa3fbf102e9b17..aa6abb99688433 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ executors: reactnativeios: <<: *defaults macos: - xcode: "10.3.0" + xcode: "11.2.1" # ------------------------- # COMMANDS diff --git a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..271e80d3f6b48708ddb8a2c9c8745b85d6eddb4d GIT binary patch literal 169616 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 z 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 literal 0 HcmV?d00001 diff --git a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testScrollViewExample_1-iOS13@2x.png b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testScrollViewExample_1-iOS13@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..809bc84dcc15d9950d069ae396d135cdb9970544 GIT binary patch literal 254282 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 Z)NeD3pR9eUY&ruFc)I$ztaD0e0s!ayFyln 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

-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

1T7lMeM_;5uWLt)Z2LE3 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%0AYVvl7c)M?H=V%zS6*hNQI0kZb*dc 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μ;^n5(_kQ&aH?+O>T$TL!=kJs2 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 RU!Zf1!d>^fGCGghFfO)sC43`} z(UWZ(M%W9)LwGhD14-DUp*%b644&eMF9)pMeW%?sGm=Cog3P>`kas5{PE(l=?S6cF&iXwZ=cBM`SgmyraX+Mc!}kQvTA&2$}$eq<#PH1H;mx7m^9E z<0ZR}v5r?k<@Xi|X19k6%kNC1EV=(KfEUkIXc^N8FT{d{So+-DqG~#8YbiSSaw>gAWTccoTbx-@E8A%Ku zkQYI~#?J;7l@3Gg*tAF46F5@L{fS8~VJE=52|Dfd{-jqXT+#p(4-w zVRdN}(e>!N-xN53E)I>YxF|v1Dv4vk#A!%>D)>7|XF>SbaqhwyO-y!-$wip+WezT10(((-f3zreL4)WEYM&? z6ypO&tH;<*A|qdL_5&yVFLIZpN_dY1Gc3yX}sh}IMlfeRe$SL-^gm6j@faS@N;=01_-brmxAm!Acgz6n~2ZM z>6eg?*+0&BdXOv7yDnb}`p%{PM2u#iK|S8o&0qM=g77kvb1!kC_9h1b226i%w)K7B zIedPcRaaiOxxEKuYk7nVm;u_KohS`@GscfDG@*!Xq`+8*@=dZfa=LvhVcNf|oTDfR%mE#A%~%m6E3AVCGB+>1{rWp+>OiM@Um5M+;DIQ0549X^RrI?vIWM^vIMa8xJfqZI`11I24tBM z3R&{2GQx{_I)8pLhsV$pwiTJ(S{ zzprHyJk1U;Z=Zah81SX_Cc>T~rf2yM0!jGl3L^*~UH+6{FWweQ#DywVko`fm4Ug)8fhelY2#J78nOYEW zunkQk|J8`^(>U6MqbkH^sVQ~Q`+D&JBr**&h=TLLuXO9IQsb7{l~QbzPO?F%v5@@PK?Mq~>?A@(vT?H6>d3Ze1{o&2fsPEdJj|8W#a za3?-s=1y_n-L?LJ7B(N!6BKS3DZ;@}Anf#9RHgtyIv>MD+8s=PS&D=O1@XpgqkJA=p@Kb$aH8NH9PR z6^eBT^RU999g-+BH5Dv7Zowo#=Vs%Zs;YC6VhySL)^#t^YC5y?k8 z!mw}?AjR&t_9i)QYiB$l@^I35(1w_^g%$#5F8k$wxTL=k4DIpP`(;NXcxNteK&1wi zYz9TtpZ=*7NcHX1J|_Zp6NRcJpgJ@M9Ls9KkefC1eY`B`{kQxbmLvDdEA{#9EZ%LQ zA&-?jOh}i8Q0OD5F^YDQ^6@>Itqyqvp=Z2jEN&y8Jm;D6R( z`L8!Ne|w}##w8I{H98L84V_z7N#a=KD*In%&Zg1u)nEc>Bjy`RQq91xJ_~=o;69DW z3eFv_yg*tbCvD*5POE%dh?<(ahlEVNBcBuq_CgGX0Je?j(zmNiR)wt~it3;j8X?r6 z_gdO3ESXi8C*CKUO~tYKG#H*-Jm~ZBy_PzF8^8E+Drx~`!qrEOB+Y(K3$jx3p*nKi z>vr?b?Gw+ssQ{{)S3>X#j_-|x*_aPO>wLYft3^C@xx}$;;a8e3NK(&$&m);b(R^!Y z>(5Wm(g)$3n*$YR)`N~PNOnMW5A6Zw6Cyz4#_6*Utd!JNlL~#Zr@|O$k@D2BUV6%r)fB!ik0t#|+&h`(LL4BiM8Lt6Jo=U^qrQ2=IZ46I0V!L~R zLm@i`kb-lGJ9b3w-DMt_k%GYB=4Lq}?b5MLh1x<~Rk&nlf6N%~Tori(#&S7RI z5F3-M;%!>?9SH{NiO`roj7`yW9R5bnC!5sKH2rZ;U`|UNp!P|OZ0hmwNN9^{B5P(F znbLuJ=h(%!S7hmeS-4zXjL3u*_Ch=-BYvHRN5o zJT^^%Xg9HUrILY1(X#Avu-HUsMCikyR;v>?YBwzv%^JgZMNvTexb82D>b0?E@u5V~ zT^G(Ol0UqW55@;}o%$GAID=PQQwR~;0(~Gw#5spP$-oH+SzL){nXkhUzEDBAWHjKZ zo4(0F?R3#XGPP>uQMf-jd249&`>I#;iGvZ*^i;)evOsSiog6^0OY6~crcmMsd737S zSzesXAVF~IvP}-%qMTYi6u{kcBu`VDsVM4EKY)Tfu-H{Juh$2IlDa<+!-<#?ruXj< z_^MKY>Tusm=!ihc-)xrv_8(ywz}4<}FCX-~sE@8W$7t_aNGv^D$hBq?Q+=i5^Ft#< z87uXCjf8Ett}cESdxTjuH8TGEm)I*0FUI&vMw&0fsA0_f`fTJb)3Xw$SN(bl4o=C=C85!m9JS zJ;S1NBrO;LCtEJ}r(-fe$n9K~}_U z4t}jik55H?hU}e89Y3M5&{?WlHJ|7Jc1zK<@DPLh;i5!y*VCzu(D?nE|&{ z-{FeCjB<)(U0WpWiygtY45mi=Gd+0-b~fo8Zr~zT9!9|vPQg_F_i*h4dTAM*{zn-JL5e(|MKO2Q}jfL zcua5x>d}u3NCMan9$U!kRLGAukZhK(m*nQ}-LNQJrFa0bO%^{?3WFZ;W{iK@R2Pt@ zsI%M_YrgSz1*hqg2qC9oJgB)dBVbfg;F{p6ea0SI?ygH6N+O#RJM{1w69mNASaEMv z5dF>)iE=%VeI7C&J@k&PxvO=>dW&eAMZa;PZclb3AmjV)3vgO}UrZ>~AU5{TAX~dw z61h?)S4bWY3h<4&kfXxL*{vs%Oj<-rlwA}}BPa&Y?FgZpC=)<81(^|%LK~c#Zaf)o zYhgV+qsl2oH5QZM-Y4y-b^06I;_;sAQM@RzFj}h_UNgsj*=J=o;euiAaya{vO}M+MN|a{0xO>ffI={bdy&hNXHFk%<`j z@_yV*j3l6r+ULlXQQKT#Y~L!)O16*21o*y;*_tY@Q=V|7x5pg*OU|W#jsn@sw5==t zm^1aud*>ufjlHhxAALdo>la(R z3Dya}KL16q+vIc(Lqli~64X<`5b`NbV36)D;6q{U0=3%JHpKW0CBmwPqor8%{+y6< z)3htxa$Ic523(N}g=kT!rW)E7(pjnd`cS*fK$%e;NaeVLABAaY_`TqHEPvl@L{rDYQfxGx>)8_g zMMelx%uEkp$Llv`CKn1Vs}n0K`(l^?gp2S-e_XNoD>}Y7x41as^wJLrOPsW@zq~k6M5Y?b zOa0j7Zdf=$Ro){mpNgww0EZMhzba(dFJc-`tIUr}{GGn@?)M(O(^&3a$fM^r@2;5p zJ3C-d(Qt?n7VtO~G$}$3P_x;9)^l=hzvhJUs@%Vb37F-YG+b&r2i{uUVc>@1lAQgz zeGE3^TsGr^i)*yS9(_yq1z@Y*yWvJqa}57Teo|hW^kN3bvI5KLvL0>(XRSJ?%_J?0 zeH@8@hgMLSln8oV5rbW1t-sx?GE=v?KMmI(j4|mqID#$)w#bllx48|F7_<_*ZN1DU zi{8upz8dYte-Z0&Bsi5P=RrqrnEe=;&PAF)usq}THP;~JzU_-@ED1o1MQ6ht-Xn4P zmW=-!$8Z3X5JQ{b65f(K$0Nx(${>OKn{Lcoid*~xnsW2%R7wqJLFNy8pIuH=b+t1X zif7hsy}H&JX!Bm}nU6D^JFo#rUm4$9xGcF#DN(EVSj{E6TOTj=dst4tj*pMuR0?0F z2-w~#wLx!Ne++q(>N@cDx zc9ZG2@)k0$d2eq6rNQDdmURw-Sd&TzwU^&q;H`F*nOydkVjI3S2Df;2IID79rEp*u zeHI}K@Mbm(azp(h-LmS`hc$4*bbq?MAcP|ix|iH9$CyDl^QuQMQ-z~bTYozGU6_c- zCxt!3nY_)klfMPz1Qdv}m=Qptse=7Bh?Lm`7&wL9l2{ z>f1GiWJt8fb6=NwDf~&p2I3{SQJqb&UZ$YfW^tCPO<+m$e~yKt+P2v8R4a1j1!m1vpefk<0{!H@69&$sboWPFzds#Y(s8e(wr!s zYpf_33U_ZPO@SRZ6CGRD7+=9y0ZLsl^7{QJ zx+rA2%mnH{?c5XH-E^AkCXf;|m8{YF9fb@SE0r?N?~41*DrERdpKCkUe*OF78cC|{ zndysnbzEmOH#HDgMImT)e)h1zyb?jteap|Mj0)IO0Ld&_YV`Cl&bBmuE@!?=x+{dI zp@^=1A$&nU`X7YG#lyIc$_soy4?$-WHO#3CL>K9w9$injU_;_(|LrfiMMTdeFEvtt zJ?l|C+lHgnM|VbOGr`I~E`lTkQv|Pk$d+QmyKJJ3p#psy=0(u)tl#_ko-(MOuPGbv zdaT_0xFvgk6;#S|PtE7b#K`7%FyKBUX<;+^M2JOawPq>u&~%wy(vbm6Ue(KF{obVb zC*r3$?22fjFZXIEUuxr?Gj1uqfCNer&}S8rxWq6akTUeT`(*x4{Zdj>W32C7 zAh1#2hV5VVGOs&FQ%<~@n4uY@{mxyrlUH%gjMYvX6qn*i52%jLRGQX$WgCjG+ca$a z{sj>$baUP({WvQTj6Ro&7L1lgG>czx@mq9D!=T}Q5@I9g$uE&-or^Ie0J5`MZE{?>M^6+zW@ zhU?ZjsSDvMW0V3`CSLHU-)vI9;%{QcLIZG^VBYWyr6sf)8^5j_N>Ejrz6_dTcj`M%7Z z$iPTiHter@FKd0?wGxU>C|e=z3=#&FY(yq)7gLwd%-@_N2F1*LxP@^TAH$X+GO+5* zGRGA(@#9#>rwkh~@UjozoWLOi-fsC_Js|z~pVi42^9GT`{<2rs)lCylLxacmNJ^nq z{oEtC`d3g;t&IPxgavQ~cim!l;dA{c>wG83BFElwn39eiJH<@GS>)U4^s{1fzK3fn z=*`5}tm9Vr5))1-fX{O|m)9gY6%ERJ%3X@oMyl?Qm=Pqe7v6W}M9B-ri7ouyxD)_( zF8x_8UVzQ_y;uk}0&3`EKdZ>z5Y@2Bk~(0w(q`6N;r=FWMI04SY=D^pg@C)kZ_!&{ zE5wv+H@WGQse*)c+2K+|c{BtI3FUYeLoJ->AZvj2Jj{wjz~}YVy;A}++NmoRAVIOP z{4=;Y$>z!4>gHrMhtr=sf1QS8vO4OHBp>&dp()nc6lPj?`&IuEnJh^`2%Xw^JU^-* zT@6QCuA-Lb^7L%*c$;Na12Hy;h5D^dNR3tgeh8MkAB8I^Tb{EL-3L$y4diX{D~G<5 z{pGKD}c>o|) z^gDH7n-gziDbk6^UE;(fBDZql#CIu7R?*KLyrRngf)GUU?IPx;5AXMi3&D7#FXiCr z;jPv$s?Ke><-FgF4yuT06Rm}U$%GMQJsr~cmt>=F0|T)n8{OMEAoNx<&t*+sy!TcK zl95v>N;`tAw)s`iq5Z*9LCT_;S)1j9-MGWUMYb@2EYC8uLiGEtOkvOGy&wLhVE`Sp z2#=B+uks{6C6a=gr`ULNxLnC$dOZ(7&E(0i1&k6#60_wo5c-Jx^oNZ!hHyr2M_6r% z$^&TGKpGS&LAqjNduLbh+rm@@3XNPq6qLRlnEZtUWLDb5*0!772l9vF104XB*X|aT zLH|517K_{yECObST&3Uzp0#J z849i+X^6NIFTWR}zq)iXWwT7}gT@Xk5=-`T^1I|12=%HbG6VGI`c(PILQ&6?tUiLw z-MJ?iBZn;$5c;i;CFPn3Uxa8VQ=gDR5Cb6nbRgOgV^1OG{w8nPt#a4qYazr)9mv+H zwV3mn{|VErefu5s2e8RW4+yg`tFqFiFr8`ZvCE3(#()Z1bO|M?Sl zKFmbG;9b1Zt8f)b6a8Atf*9lA343w${i#F;t470>+U#fie9QDA{~Sx(U9niHuHRcyNO=D;&FMgg&FEzn5ze&-V6SN4B#&B#V*h| z#g~bmHSGdM1xo!Ms=USnSZ{SNp7qc7@Pk!HdA%eH#9?+-6|g6sOMxind-4erP-HV0 zk4lSK2kX_UCBb&CGS2`!pS56e8+Q5Jj&A{lz>2V0x6K}6lVfh)EWP~bY2Zqmc(b44 zmHr8z6zu42Hb~}?nTHoPn{qJZpLTj7Lty#ryvC>(T0_-gY_^eorMeLaTu`@_)H(M~ z)X-=>KumtAvmGi%S`~~%De!(ULC97BKr?1>04HwU$fnD){s8`Z-JxhfH8!#M;jq8p zg@2%oqUXa4?E44?T_tm*z!nOiXqeWRY}69XDuv%Gqym=wZu$2oi$8mr2Ma%`0%EdF zv8!U!BwZE}I(rdU3Tju`7Dh8RyLYp-meWEd7I20fo9R;zl(iU1g$n)g(?C;kAp46C z`5SXwdz^$Jeb8HM&WBdbKRGs>tnFnSpQfkvVxx0&a{i+$1W=`kKM!pi3hQ!URsMIc zsrRJNNa^R~ueiN2J!PwcbAXBdNARjo#Ghop2vJ+gf7PTZ9G3kTFsfn!j)<`Q3g&!N z8jB{eWQ(F@AgWfnTk9Aod&?siFh@ifuH0!4lld|A?i zh+QD@d$2X4@%U{4(e+7AZ(DEIHcYFnq zSI6^ODrzBbx)%dZg-x)D)joj1cWjP>i;ebqtH-53zrZi#$g9)B`#2x>AvD{9ft;q=j)T%F*DE!wOjPPeZEsQ2l8xjR2=VC7uo!1z4yw zMcvGpnAh!R<2(KBv^z#IO0z^KG!h2^a*USfC^6K-WD7opGbWd-+f~@VnSG=ob)0bV z_1S;Gt70cHJ*p2PX@0hw_Z!$vg~;#Yjd#PBng<~{6J2CuDH1^zimkS%BtIw{dOqn z3_m+P9pc!&X-BkHy~A)GT?a_$oZ`EhE)^~cBQ)~8y) zFqJKZqLOwoDS7LZFdITM0<|yQ;Y8uZowL@QzHJn9!{lRaG%;*qnTFyRAU?4_*aRSb z2h{HOa08<}pZInLP;l#HmO=`z;k?GWznu8-uJTh=sD0RocmOQTxUe&xl_Zn;zS)b_&BcR(Pk7pxLt`kFu6usNY z?YaB@MEap+fr4{W6n-1yumIx1z8nzzdH$U~A%lPGO<$9r>&B~KVWWDR$hgr2)L?01 z+^WLMd4wmg!1_$vDOTvGxZu}db502l!7i; z);p_M-}htQF~*W{eIk894pPsCA_j)uw8^68zt>G>)>7Ji_5jMBEqh5{O=HAaWn!xE zN=u=6n#hlk5XvghNN_IR^;Uw|Gs#J*rRb={b2(}#a{H_PiGr7%^J4N=YpA^e2x3y# zj&qd%1_dlgRP4bfpld#P4X%ySVV9)S=;p(`+Z)==G)!I5$&-|pKl+e1@FMKl92Nxx z!5cv~%&gA2d7@F|2cdR)3?5ga85>AquJy`QR{ez7jv8n~(OpSB!W5V!-ePE9x;&NU zOn1=0nfk`Bw>yG_c^1YMCl`eEd$KTZn8zLVw}ARQ|G+C6^}lZuz5_Z?^XvnK(+h~? zd&Uf>_$!*33S$Y(=y3R}*W1fm?NwgBpN{_{u+p1`$emJ;)MJF{;rS-0I2wwPWoKhd-V9+ZV`>61mI7y4! z4a1tt7of+-@8fib#PZc03LQZ&&S0Gd3Y)RKusYH2zT(?M&s=wFAC`a>I3fVR;S|0M z9|1rN_&0`dkb#;`FXLVxM8MAnd#1$a$H6lr387^qhtQ%TGMM(85ny?RQahj|#D#Lc z%$CK)AGjq{`XC@zknZ>^!D-;~l56ny{P;ANezh=H{rLUF@$@v;BGHn^Pn&yD+n^=T z>CgE~dM{YdjO(HFdBB0k@}UGV3h&B&$&KQ9?q=t!w+hxJ$+eYcP8vqMZS=aI4Q-dh z@5)2w&VFh&TbSRS4PCdwA0^HkJ1LK1hrzCdL;S~E_w+;fWVw&?OUJu$_~SBMG4dQl z&CF{*L7!Hkb+3JkOY1CHwmYFucKZ(baqSXNkd5rzFu!>86*Tak{@fEML&eW7a(EvX zp^*7x=>%*e!)i>sD;zd9WqIs2Ja-MoXp0(S!Ds{fyF5>fn=u1W&!Gjt!)S=e zMBf8wTlC!g-8^}@*CsRhpe-{1_Cnwn^R18b5`*q%30dhj;1$(PrpkK+0yxFuy`Z7u z*ymo)rSnWb`&(7#t<=v~-G&y14nFh?=b6_E$@(s{l8W%NQd;iX8idf-+Cn1^K-v>nh=Vy6sLC026=ir*^)b z>;Q%@9ivUXvrq8*R`|U3wBgfPvc%zs1I4C>*8AVB^V&Y-5Lv_3_7C1-$*s%VBG+;x z`c8jMia9QwW&{*QTOKyqj;nXepZ3a8rr@VBzFvk4KkhziQ+{V%zR2fQ{PQr#)+)5P zZ*cv*kHaeT+$6ATJoBoi=VAG>%vG@@+U%j5&8PBju6n1eDuBrThmq%Vf1eIUo>;1H({iKU18!(S=f^t8;(O+k@`#Pm*&1Fy2yb`6}_JwdG5acB3&}uHW7Y< zeb=N736(kCRrb9b1>4K@KFp7I)2*43mki&wD_VIsjaPD`1uV=T>p_FgusQy+KX@Vm zcQSeftf$0Ev=7_9PoGV1jZwF|(Za0jX7ektf;kyC<61Z3-;D_$*~dtei=3y9n9&WB zwS-K&wwz}i2szTNu|AHAK92X?)mYc-c{;4W`nNRBbAL-oGfmPDeZiLIo2l#65w9(~ z0Al;=>a0gA(}urW5kxSsf!9kuc+-X|Qh~P5>lM#1B8`QJb1&{(Ah`HS-*JeWyoHmD zm|d8D`?v#qP){nSzkvNc<%h@UrxZtnNT6x&XYttLvCnmn1F2%;)7?H-;ik+g>LI29 zIPq3>?A9xo4;rHJ3apu=H=2fGOxc+E*T# zMX-f5cKo<>%>A_)B&TwJ=4mHgxAOIQF?~6C#!cnphS5u8Uav}37=Z^vrE*&tHCEfZ z4rCNE4)Ac8KWPFDSMkr61`gGqC_39ZgOv>L#**tejQ74cKJ|3KXrzLzdhu@3V!0G^ z{$!3s5aGL-6}wM*`~ESdN+@eO8?aZetT#8W9^x5fx_+N^H_`VoKEDim($ek;+&2Oa zPm@T0kRQRluwBAg%)?T*IKXp~`>oqK&9=qeq!Pug%faLq4BLZ5v}GMVKOkd5fUz&xYE%GSPc`D!PiupU zH#sygpRK`13K3#a+a8ZxTXP;m8uCc=?8MXdtWIidz1GQ5r{b;zZdL+NmqHHnwp^4j zunaOppVmdGbP9I3;3@|*qb>%Fxsc8+9qA9w+dOaAmY)untM+HWe!fuKAH>pPiOabj za$BMJ*f1YEFdF>K%911GMwcm#r=W_xy&f(2TKL2d=g&{&S|2alahsAB-|OGY`u7y> z8+6dr$Lsh1zFgdLY5kC&2KPO@EviT55qCm1kcyXdJ_+Xd2(cyCpaUdJ=E>$Xb890p zffD~_;>Fx_3r{gi@SlGcwcUhVQ*YL7;9#$tzxb(!`@0E;Us8UI=fb+h;Fsqf&!vDf zQy9(u9{l&2s}CPoj-ZMt>WP;hr$2dmI)?jDqXrT(i+pB%*kBYT(=KozKfhIe+EB)4 z&cB6o%CCfAQ%#6V3}bx}*%8NiZXrWXW4{_i@`;Vl*l#?!<>E&Tn6#+=oJotm0MB8z z$HnEx#ZeEW_rd1M!j}_q121Jh{av8WRF%Gc;PpM{4TElimbs?`nFOYjnpQ>0KeY2zDsQ)aSGVlx{Phzy3I`9uX17k(~AHrf3Iy*DgkkG34vS zK-{s(Z~{JT=B#nL`E}Z>Cf-@Igo|}3{Fi;%iwMLkHc&KpRh=b#fg@e}?9_lYi2dkl zd)g(sm)lKfooqz*q1_te;cPqPuVdEzf}eqCUAkDH%#!oAD$)w0=xu+Fdz@(N*l*mM z`M($N@@U5CrQ2cGVHSS|Kf_Y4#}IGo5pZC@uUL^x?Q{5Wgu%u4o>p|j+W{>P??xS^ zTTgNt@lN*MhIGU6&zdh=!S~a3r}fvFfrCpE=E{CnBDjqqCS<}d;nHPH z>Y>xix5fQz&(&&8ueW4(E>Ck1yUH|gf!hT-x?p*=S+emQ^zq4Z#r^5N`9E+a@@VS?_CyrdOG!u6R3veKIh#Qd@tEk zDYHeSr58ta78}Ac5KJM6+MP2L!@rfXBoY^})^*ukM?R9=XF5Zs`z@0WykkT#Me-W# zeNua6i1rgfibv}lv0x5wN}aH6<8J24JgOWnH$;iKV^X$E+BxL~&K!)e> zxNq1he*cCxv6XinR99 z4ju`)2(gBIZpXo+{e^gb=diV2TZ)sZQg;%@E(htm$kp>q1MMDw&+5R~-x*)#db)}3_dt*D^b?nF z=uCBK^elZDhfv=`ygiop#dO|dy&Sq2i)p69(Y+E$XT~d>W%$$eJ@rfA-Y)Xth3h`< z945_Q7w3aM6eV`Ze6!Hq-chHt`7T^{*cuEj{vI0-v>kv#j8ZF`3zImZx=lO#mBS-ANm> zP)a?ZCv*FU-jSGrWfEM9Y{qObqpQ;3OTE+AQ;&BVK;8Zqtm4YI!Ue1hl|`MwBgvKM_vKl zu7&M#bQ?x!2-Ex#?0S%?pZ(!sVBveo>ofcr*=XE1WW3j;McCk0ivJ%cMoN znuz>$Pad+-L}aO&w0DvkrB?7r3RG}Mkq@Jdy5+`kJT3IQ{taYuvTbX59iQMq`xOpU zGu0XmLdrv7--XwV%o3qLf#*##9O=S74bCWCMbPH^e9{VDc*N;EI!hIJ07KIIQ7wp) z8h}u;TkGl;zwe`XH@^3I(7M4z|Ui-V_yua`Y@!CHHarCkgOUr$-_yScg-YzqH1wqP(}+q&lFY`;*-C;eqxkoYv~1BEBCOoH%;b>ICynfsfhzfSP8 z?~%$Ry^rKpWL+yU5l&E+=<|r&qLMF*qLme!rQN4BYbg54Z_Po9L=neQnKnW7!T zbNhQR!}$Wv!uLh{`#x*)&lB!eGM`194@OvOecBRc1Gv_4stcH2&-;izoX~~ieRnn$ z{+HvB@*lBBOE(mnk4i)Yh)y}x9251{byqstQ>aiB5cLjqbJU188xEqXI(gYs|GHhj z7wvBMZR{oPMGRl(=stZ|oB7TsqC=reg4!W5b&EAc+~o2yx-{JMd~K$LkLm-3uNDP4 zd`ob8cRZOm#Hyed*2;WZLFVLh$Z1K?bwtzcC+7Cio|=iufWlXo0_Rn90denO__}xZ z>Hb=ZhP{`r@%`S~OaWhuE(Me+T8pGNA$;AhyHd`+3H(?UisjeQ!V#t#_J2C6x4w1^ zSBD2QJ{I!1utj%<2iz^`P~<*D@z;fl?!cw>7>`xYN+LX+<4~`B8u)HJ-979ly2+ia zDRfLljyW)CkXKUtzGWcMQ~T8+In=corwmd1ZOT(`AF4G4eUu1shy2QUR`kjcqK(-7 z4nG!##6$0w&)ZNDvPfTdF%#=tXN4a5HhY&<{7;b{23&>^#@d_0D1am+AH!Al@1LR* ztPp+T2;|=RgXA25^p(pmzxhr(uaeLoK?U-Q@Ggf(Rt$kl45sz%8NQF+=VQ?;*Eh08 zb4YH#M?0ymD*RB7PeHiqVb{=iIIng75YxsFTtXN|+mBJ4T5$w??KPx-e$73ux}wMK zBf4v~qfKS_VA#FHanXw|s?Znx16WF zB03IJ0`sY-X1wy301=GNg)H}-7{Xv&o2IVy@{+cuEt3`)*%ZIA1|2{DHifsMg2Sx(NRJI<>!-&wEwig_g-l^P*uEqD2 zF`Kqu&PGG>bw|Ji0!-m-2>oKb4@^PotvRcYKXGM9+bcXn{7ty`{Me-XGE?FS{Y_ItJoOOL- z_%wdqGYm0gqj?cC4|Lh=PNXI9eZVU+GjsP5>{3wX8%^dbQ6o`HWCnB`))!oaDgTLR zBgZtp$wn0}tZb#7IC3ucjM{Wg|Fix3e(^X{V=HaxB43<)w^c*|xazgKRD=`)R+D}T zED&_3gtng=#bf#16nPBgDA)DS&cF*BwHnO`hFCg)?)(IaxY#l^WV!~UexU%Wg9Qb{ zqvc@_R~y0*Ew6$M7kP5qCi^Kk&Vc7cE|rFYMiWgHsgEYW!0S)7B-O+W0k59OkJ5F4 z;}DEOcl+pK6l5suC6)WUOWaOcHeRsFHC?nkWK&$E3XfpnlM4EQ;Ulvl|2DE$pM=M! zCNQh+-}}8O;yvQI#MQjTT`u=8w;ZpVx0%;f?`Ue_8WG~6yev}w(H#B-*N`bV)ldaX zZn=PO;7b~~ne>n1Uq2PM%I_+<%I_+}ootK;u?6$g(fa4u6#!!AcgpVa@>l`M5~seu zT!o3FPx9lwzwUmBN(^s&aYbd8^rR{?RPcNUB6LuZSg~pg=ULvm)$2VMhwxEFZ_)l+ z+1LL{h~lWsCQ%n{AE#{p8I&~g*s{rkYX%pxPQ}Xz%nJNKt0#_l!NVq^b-y2c<1^iH z-}~DS({xI7>FLTtvJ+`#Jd-C`nMU)zgUa)dK3mtP#;du+r_=w7z4r=ha*NtULkJS2 zB!D!j0R$1GDmC=3RFNhfL_|QkhTb8FG)0OaMMV*$DOFm4Py_@;DFV`qf|Ssac4l1b z*S+t~#W@%I+3U{dlYDc2vyAzUcf4av&LI&5Yr4^U6LIwdhR})Q;GlP9AxR$^*gAF+ zp&o%kAGD!#NjQJl$Vpu3(6UjLwSaXJjvGFE5@&T+w{2Wd02P>^*jUPCGIksOiOF%i z7^$nMDP2z3NDNNt|MBu=MYpg(!=f=I_fnC~^4r>-{CJ2^)jMr{|0|b5ww(kRvb%l0 z=e_bEyxg1NROJPGPxW)-S0seWa-D%Y zop}#_U40Ft8fVEQw~f_hx|c}BGxS7BFUN{WRtU#bLDwj4&Mpid?@b|c1m7~NtZYDn zXL*)gS48r+q{wVtB5!bknYR@UGbH137qi`ZrVOR$H((4E$~wy#vd&Mb`Uu`y_s#9L z*`r!_)fSK~kM8gKW>_CZWMU|tCc5XxqYkl}J+ZH*5Amw4aW-hC)rsQ<#cLKMm`>E; z-lL|5&3tc1g}wKO(6ZtWbK>o5<|NW5us2Y|R*_+rBwFb4O8<+QA5Zg&QbSP?@@3M_ zlOvSET0cJL=>0$(+3I}}-C1sDT`G1Uy%C*2={`Ch1^4fc;LKXF>4{=hpEaHte`PkX z51_E3TlKd)&LCn&ImhVE`@?U0P49Mj+a!bhS0XmfD`oqU3=2koGL>sHW-w1 zrrEji=|aC5#RUqSmmN8K%Dtet`N$7xjaM5V_O~&;+8rQSq#=kRG>YQxxv9XjO@wNmvp|%(G(5KjrxbF}?A)8tz6m zS!ViefCA?^46e!e@fyNLuk|(=EK1PJo>O2qaxui!x`_l%sa*7v)3wyRF27SN;8tmT z2_WsUr7twnTnwzX!tjeG-;ek}Cdmt_tbm|;ujMaB3nu;IuUR=X)i^jVS${C0X+sod z?>gK}GwzZh=N4+IAmf^=s+4i%{0!!aFX;vkm?tGDUAh4D*-0fy8I7dFRz;z!8-TAs z-ksPVZ`oRZDOhTWHKGfhJG&HgBi(PQ*yz_Y#mATTJ3_`d^D!bGeW~^sjG>(>99JbN zQus82UI0S=mXPrKOSE$9V1Tx*uY{89jtmKl?v)-tu4{jqtX$*?++txGXKymw6x^t^ zR)^=fpXbFh<9po~=La6i2T+Pdhm0VJORCl7!nzgNWM`)iaUp}Qeuof8XX8i(dpOHa z`6v;Mw4al?LmPpbeyQM#ax;glRGPZysR0jjfiY9<@%o;iO~&Q!q_y+aLStV;j-$}W z6UP=c)<^iKv{i8e(s$>o$cXkYt+^y9nUXjZ`J7iT01Tw|WW( zbS1Tad~nx`CF7Vw4d2RFJR+nVO^Yx_JHB5^PSp8FC1S-ddxOUicpch{pvG} zyJx?>vOh^4lNRtlWdBLKY{}t00&EEa8$sRrLE0QQ&feEQuY3nT@_a-AcO|H``2xP}Zuw z^H#sROewQ>ES9j&7S}%X=cile~ z`nBNx*?*>pnJ4URNLGKNeyJi2=8jle$?(rz{B-55v^Pml(>a}nJzxnUjE~Ds?mHod zJtXhfUjG9=!SA`^aIu`-6N9r(Z5GnK2i7K48jm3)WVYAd-msb}H`IG>IGuZinmES5 zi0aY8Np>Gj2&03dn1why8b$I|Z45D4MIwSyjIePxQ z?mzRBtOUm`2j8vPO8Y4#waLt?%(*oStzn7gi^g@gv@pN(hrE9h(g7-OIJQVglK zC-kr`pkF8+9?Dqg?cUrd+w)y`;j;$tv|S$4kuGv|wn8(Y7A)OdYu7FhP0m~t+ad8KfEdes!cn#CyQ-9EVG zJUV>8GvE4UU{&XFT}1bBn_`cj;gV3z%1@bci}_PIAy?`jtZceJ|H2DlvWTJFNq@`o z$&WA|^}Ws^gxw_QRqu4Ur4b~7>{-UYTTFwujG3hKqdWGY_uZc&Yugs{=(}Sb`_T)O zhIa?bqm+IHUaC8sv%JQbI_BdTaxFStHSni-ee2GH!#HWvmp;pdDJCIu`A?3o3on<1 zSpU>As=rgr=0C^Cq22ZENKb(MXt9OIbokERRFuca8|3rj8ruzL8^M=C>$mJAWTGHr z3-7(3?k1%%lt%7rUxFLs2afu#oeh|i+wYzqJwJ3FKEJ%0)qig&-)CG;z^eS|TC=_~rl|_~cJ$PppAY&6_)FY3(g9BBfc3i)w9PyKiewm?t^Kbdh~pzpLG(we zm)y(=hdEJCY2CyW*Jk^KEK7s09TwMC$c;a%F`8vSsr8hEnDnI8$&^Tf+x^sQ1+5jO zj|TWpZ4fx*r1(YV2P!Kw`c)t+n7&{;^Qy>dOk`+LZ`i>P&Yo`$pO=+MM!y!upbMd8 zZtPvqGLW(URpQ0cNt{^N1=io|GYO{!V>|_SRW;(K0p5-z-5#^$1jjf*F zj50$}y=O|~h*S1zAyc&IM2JaTy6Ga}2xf7|IpXpSW;vMcYVoIg|{dAWhG)}`w<)0RnD4`&bf*Dh(NRbbE%{V6;$Cxl?-`ULl zK(41v-f5p~#@$M)`ik^=dp8E>9XEitIU9Y(R2W|rY_DhYy!I%3@!QnI=!nh=3XW%HpnSEirT*yw;l5Ukmb&|gc@Tg={0Kar@iLAS0U7JLj@%{}Wk_TIoIT>dU zn;hs6!7|P-tJ^lKz{|%rC^!?ocsrTAnLczVvALM|?f6{&L&eIYHII}yQ?D;b=ORby zed|gY7?(v2)k)weYUgAXIVCLHxfny*x9lWMS063qLfDRiWv&(ix0+~TKMD{(lmB)l zSMOj}RcJ)eG4eEKrFT>&f8(y3LW#U1Drk>>T&doHO6)DC6^814j$h!MOn8q4Wmqfp zkztFp>unxL-}s&8JB$HTl!D`;Ox5Qgql3!8p<^3dt>^#!G3>meg^=sbB-zriA&%oQ zL}anP3U=xYo0IMB)0y0wM?d43!j`S4{rxZ(R}gZEt@D!5B>$-8Gi+4t3=z@H*GAdCYD9(0xK6z)TB($x@u(gzD>D}lm{YGIyoq9X`SB8smAou(u*SsfHr3ejUD?KiyKc_7;QPg+Yx20pi$$ke|$KWs|I?UnNa^~;fVQ^RNd ztM~ibUeSlTE#^Y5Lbi|H*E4@3K%Z=I<B+o$7t0N?8)3h8iE462$Q=Pes>{w`S&H z*JSvkz5K{5@yb3cm4vZDQPgQaV@ptDOXhGy;vQ-`K;*fT+-XUtgac{LwXBvS6&;gS zdpEwEDrgdVm=qb%I+(q@W40T-c6lBzv9ko@@)N3}0S7bJVaGqVvm1*OCBY8cHS{2GV{t1k4>U&jT>iCKo}t^QfQu#MhfLJ_+==xRZR~4)G z6(PK{!-k4*+%euj#=gRIwZCXxsqh z8L(5K8M*iQ{xJ~X`8yRQlHo_G6&(MdCGec*lTTDAv`p~4v;5x<@`1+r z&OX!r=NF*u5~Km-PX3wVm_HrtXj}{I_!c+gAVCoc|2+f2S4TJO4Y% z|HT^r7vY@LVhFhM+i^W9>^F5;_M54E`;lDS*XmA%qafrh1&iSyu;+6h04@jWTfTpf zO?m*h=uxX69QltK4NIT}fa|q#@xPodcz%;R7vjo28}vUoj`yP&0E7t_3kLqBumQf) z1!zwp5*pt-&Xtex9rR-np919wcP1^Y%S}{qf1E5j4!CVu~KOMXP8keM9Z~O!H zzB7aVb)5dP_!o`xfyVh%#?$_wQFb1HM$ICwvH$I$8faXtbN_GK4xoSRE(S&aGT;D> zJ_e0v!u@RiwEchb;MkVKN^0jHZ@$+L_Bt8{@oT2cffL$y!Ns00R|6O1oV(9g>k!qK z{tI#w88ourbE)mSr77isEHc1t{gr-D;a%(M+u!`ZP6Y2S6H`Ne1WfE(zuWA;JXE(z zMjTdSFzDxKn=adC(ABK9P=4m&AYeDwVieKxKkX2giE?wNaQxPgO^(859%Acf`<;Y> zjzJ4|d3s;w8?zu)dbv^7Dqy*CNnLYS{Tt^-ddKskl6SWnq^*e#jR9XSMCkL{TUe@C z7^QHHt+g5#-wkz0@D?%lCl`t2_Q(VQx;;j9NOZ1x`Va+J?(-gFCJCI-$Imd7zO@t=vxa~~WD`SXYR3NnT--+6p7 z)ZB``Ovv&a^It0V{gjHYT!UzgexXo`UYSu?km!|m&>k+K1*~xYnOunFJGWD3c9=blEjHd985*}Wi-J7M#^UmYA?0ET?@*JDV{XOoV7z5o zU@X+bB{E>|G`P^Am<%NA+p`d&RQmM|WiW!%XhA6QQz4}1mOT&fv#7z&pbo7+A2z1~ z`h;oc6M&R9{#vZqU#WXZ)X)Bi;5@MX1*STyajV!ppQwqCb+d|&B1X4~Ve^I=t5tu~ zoTUA&(h&KO#2~6yMv*`jd;4g-ZsKsI(FaHx7Y^jt8-Z|{+q{UF4v~51o9|HM%XN^> z5K@|r)pvC%bUM{D9_?6ujUUn{yYyON-@SG&Rcjn`;~39*_+1l3508BMG)71gdIW`H z9_q)wD08}}z(w1a6%VEmpPhide6w+cx2wIKV{%Uv*4$ z?7T7basosZhdSb$BdI6q(LsSO!rr60DYxgA3f{p$qL^;hBc{a#1R@hZ>D3%PuO8m- zyuUVB-B?)~j4u|oWjd=g@F8yROI~u zBvf?TJK;jI%~;V%rD^pstdYETQ#?fNi+VQd#k8gA5mB3-$11get@C2*x=k1QlYX~A zQ~s9q0hv^9Gry}wCvk%az_^BDD3rRK1havukZIWa;J!lN?7PK(bR*MEGDW!(u?xaR zH}!#O&CZk2%B6>?K-wchvY;NIilg&GUCAHx8t|l{h8155!aB&A5pLLR6Ir3Bghx1m zB!eYCC<48P%Vwh0pY8^WsPO`EW*1gHbL=MIp!nangN7GAaY0W;dgWHfoDja4IYFDR ztiP@|DW|VLerL9>YwZ9+SJ6*zf%zZ< zTSh>s3Qo}j4O>5Fi@rER7wY=PlD}p#8bjCxQE!pu4HYpp>9ctI1mx-3I2kQXc1>NW zPMVUp0z@UwcfU~<75UANsxA+?baM83oO;s|;ipeAd75r#4aC;1qm`!z+nSN{Tk?DF z^;cp`3yv+u*HgFV_tnR$8GKEt}&?{?M`~c9ZW6wpZ+2p43o^*kND2lg6&RRM>j8!Eq^i z7F5I9e8;_C@+4^cD~0=w*$=h7q-IvhPdv+j`wmJ-y8z&TqglUH@#dx zm_sFq78iZrn`2U!;d&;5<0qs9L9i<8ueI8sW&KI83cdf{&s8&u(2)C)G?B z3)k{CbPh=KsjW1B)DSRyjeo^UZ5pUUzwu9NWOy^FWUk9B0+R{hp;>k4rGU@hRD5xg z8PGC60B5Ba^EO}0_C384*dysNyV9`9#E^p-zfWP4Dv`4%80l=uB|X3R(G<1tns!D3 z9j*80xshzv#3J){LAG91ENsjISjixmn%=wXMWxp2v1`fG>nn>-f z(-XvOq^=C;9BJ;Ma$mzg`^#dr#LOr73`o2Y($sF`JnGG$Ci$;m9a z7X0n5lwXxs>}D&B zYfcg5LKS{^xxyV6&TT_x%Z@75wiO3w+rz0_C3NXBK#iiBbYB(Hc)0AoDnG{4C%u77 z?1M)mrRJ7UC#M5@#5!JgRG?ux9K=O1x9@%{Dx)f|m7^ z=|RND*yc7EAJ_?&3l1y>IVRYDd8r3^vuZPTTphAs{Z8msX?e5Ha0%qK`m8#IP9#`^ z+-4uHLf>i<*C4(F1@Y@}pY7oAbDa+Ss7#&@>eSY(_Ef%jruQWUC^lwK%AiBBc}R}h zAJLVIw3=+6MvsNp@!2osmz^7Qlgl6GO?kAcS3`^Q6;J_7R0-3e?eg3d*Ff_|7k0W5R%DMIM zNa70RYKf^=L1%%yB?re!GZHhsm>@SYuGU7^a=IQSzW>m})NBb(8-tp}erGv|Dp zF5Mgo$GtIQjUiu~juXjdV#g+egfNM(ff!XX!H}7P%UFoeXqMn?7l+c%F0kiGhd{>6 zk-K##Dn(CjxkA}+q4aIDxMR#&Rz65KVG(cjl~ilb*R!N%`re*tMKb5AT`xrs!$IHi zL7$(Twgo?Al!_##=6dHC;I?&Qz^uz=omYom&Q`)eR9)}4l4|82&nO-_Sbs08mB>_; zB2()i=9cXF05nl_>!Hx#!iCpySASzx=dMzhxQbS5GR-W*=+G^Q%2!}}=z;CYsXcSaR+|op%Uk2YNfrRI zg6hBHKDRFQ3BUXPG>?ji|I{wW`GZJZJ zlN7J0AuvX<(-*xddT7Gd!S463^7sl=?fyk3gj3XVT?CWYX64rT6WdkQTNKY1K;Cx) zL-RnfRxe2EjO2pnHD@eq-mWLKZ>`U&z;W0dxs-rTRLthrR>4lQj6mScd`bQ6lWhEk z&^T5`hTx1-aUu#Cnk;Mz;Z8c6 z=`$ybnyzU~ALx?%S*9vdDlQ_aAN;|^`r-J&ywuLP8`~YP8;?X)KN$vtIlc|%H~<3n zu%763VXjpZ8jGg~yVmmVZ{G9CPus3BUqL~clTQRuf5eAnK;h4BGAChgar$`zKu zC8`Bk|G1FHfe3-A1eRDYaCq-5LgQqshVA3_Dva}J{n~xUEyJAL%#NnKt%!H=>zn%PpAJRv!I>x1QgBCp}m19QQ$L zqQ0-!>#+5Pnw(%31sqocl)H3Jr%0GpaVez`q3Q=YXZ|;j41f?wFCl~6f6p5m`c6W{ zF$n^LsW!Uq9;8;+=chScw24+XUn77lO`*6^d->308SgQqBvHJpKNcwuk~U`pKwjj_ zYOrp92!K4_dfRXYUsZ?%6*)Udi(U7b2X>U$k^sYG$2)epx{u0s=R}R#_-5PL^2s=pUd|xM&l6oGbmj&# z(4XyVSl8$T7gXw-&*yQ`gIpEnUyg`&=3jFMU zhS?^erbAvh2sl08-QYo>WaJA_?R-lOm1)7V-8G#kPf9#ks`%1@jNA+g%<1J^+6%%-*@UInDL2ZAq0jFpfY%~5^646ptYMCYv^M{&V}h3Y zYk*tp9WB?kMrKf4ua zA7-EXKeYf*`#ix%8#($yy9J}CZ?u}by$4;91_Vxr@+b7~NMa~NB{7Qg1b`j;pu6AP z9bEoZr-4uY1^#f~V^{qz(~|?B$-bK_^mou>HWyuVZw zk!EV0V*1N61%ZiJsV={mLj1*V<|_y^9wdG6uWAFl=^fEsI+U!6{!2wAg2oXsHh(F& z9RQu{CfW!8O7J!TQLsI=7WY4|rTeY``nNMWeEPRc?RN(iK;sH*!G9^ZZ~UNt!K@al ze>40XLRoap3g&v>x0IhCp{pfJo&mJ<<8&Ui-9jppm_fE?|_>V9h*m~{d#}8FG^(k z{;Gb!SBnyZ%5VFxj0pVU8QY1A`>(VW4EYTZRrWBsc1iBf?BddiOXaV^3M`)20HXI^ zy6pV&&k!>MCUi1g>2ds@C+WnXyScN#^56M&095GzqTL0(e+#1S(t_vnpZpyX9neV! zsI%nXC;vYT(sjBTa7n>u;5ZM;i9cliC#asv0=_}q#iMAH9g5lvMu4g<=fQ0Y7>q`gAlo{I0L& zg1bzgvVE5tvIz;21u!q515|D9sy+mA!5%=*PTs$mK7R=U1qFD$-w}xwP_4Ybq;BOg za82vl9b(w;XaPcU=b*LjS7_SL^)t9cY%7hNYa@akGa1&vN$JRKY7^wUs(B(Po|73| z3UO0K`ZU;pUqP5Z>%*PTi;kDL>P3mi_OGvf!Gi&|8=}Gi2f>6mo9Dl|D2ZvLzAb)g zssWU7$XBJ2;RSUh9GCq3ZmjSabZqZe-4z|y%?R7*3 zG(XMyv2;%GuOB~#9TJ!QZr=eFGWITDNVQe7KslyL30n~WwS4fjn$L;w{w|j*)dyG! zKv#YwSX_jSF{I^zLOUW3u!G>D!+vdfeIM_YcCdO=xxt8Dab<9OphQg)J*o%na5gzY zpPG9Gpd>%psYrVN>~v)n;reK&EKd#n%_z;JO^hcp&WZxiQ+n`kYuBxU_vU*2dTv^R z6r6X>)Cf;wh`1x9bdik7G6^{%HRhqJ(W?Q>M(R0YOKvR750qjd(+T7v;UXOUff`@t zdRw^>jNy|g)q`Y2YqQRQ({KeP35O#|r>GQkSTqX^j`$%x*H|?8l<&?J-B(BGH?m82oEJ4|RyRl=$KcNRNvNjLW)d zvOPS>aNopQyZr&^57A0oai&;K!hveJ4XEq(-%~dl_g69*>!``Im0%N~B*o`((i{nE z+zaF8F{d+Uo%PWK{P>tkuPbNE){9L;`TF=TF?MRbjtIV-j5JJ_z{{S6kUQneoy5#3 zgCtRqOz~;9gY9BfBL(X1t%1UE-xW{X>-RjJDs=V5u2C%q+BEAj;I5Rn3-xyHDes+B zsM;h%=;hw0x2=Vt?4rBY#So)rc3?T;ZtE%^5Fgp|IfU(N-V(NUeOAYSO;ix zP6?ccY}dZZ_Ff?2@Iv>fe3?9)nHuL?<7$hjIX>Foq2cI?hz_G=M%NQgN5k6~qmv!Z zve3q!J!8EWX6?kILRQM-_Y+*p5<8IpJWr3xMH8gtf7uTur72*zfHg>0tG9E4HRsko zfMWqQTcWR&>V~pm94mvr6uP#w$UJ_be@6FNFg6GIEtx6Yu{;Y9$TRlhzaX9kOx$H`>7=aC zoTF%uwiB?`G6h_cBxQjYnMU94%$EjOpxAg~HcUed8sVeXFOAmJ4aJyo zpYp3|pYKmegkN9b5(FSHJ|adEVW;+mOH4Zhvx%vBc!C7Wk0qDm4s*dmyJoNlsu$MQ zI%dqa4<^s68JNsGWctA)(hDysys4ZuY7b#G1i;~JL+b}DE_ZfGW~ zTa{VlYcA?my$2@0lU}SlA}dCM+`65Zz9n^VTD5F!Ax|$bf#|4>yTHlSpkS%7(z>&9 zUzmQtG&G|mZAu1F?S*Ugb1@>BQ~Zcgjzz8UKpHs}10;`)5mBj-SM5(O#Rr<$&$(dXQGCAGzkzza~V z-FYD8_{sFCjlI+!Px#V^kQpWw=LL>@OX2fw@=mFcjhEBPU9D8f5gzXcB(SYt0_x zH{6It<^8FF{z6S?;f>DZ34ys-jUhwJxP+gQ5yA^NZs;4;ad#Csr06$dW!H;O zOpEjOA)>K~XP*@pqF}c8h`W``$Pst}mNf1b+j@QjvsaY!Ci^cT`;w8nT8XBN$vOu& z$-9)0_NFqC5Gqz_BgOi7->S$DbAhy-#&TVb;4JAT;*i>kimfbjXiwigat?$zNAE+L z6c$8)npIB|>s4XI)#xE)n4MsFa$sQ?d9XPo`a397kXdNB&?GTy-pd+LI33!F9&62v zVb_Hsm1)P-@u$XL$s){|!wXb)BTZw)krl>=B&6bUE`q1!`-T%|}4 zu9=+@o1}?zptLqY7Y&3;KWo6YhLKmFD*)H?xZ_y>r}9xOOW)EgDddsiu+oIxu2l3S zPe}dUfuo3_3nOtDyxneadhU#Z8|&V@5a#44`f_eJaRcABS{kH)V#KDW+A?A$c}WpQ z^Do3IH2fmeR0mGLNUiIUnsBk`*rKrdZbSe~V4=x)W&tgA!b6VrbGmTsN$a*kh?>?TP((zs$P-yWrB7}&!Xj4`SU6`Sg2#OAj;kr^^;JL6XnG!0ZkKNR zlC4X4M+)5-@k?z$xaoiU1~g3dD&eC;@F4gIPmcDKw&n597QDmM9JF2+fzbNywn0T^)Dunw1Bgi2XuU{1jg;=PTJtaNNj18N=YpF1kPwA=Y&&YjMouNe#MuG5N?|p^vo>1Y! zJ-bcG5KZR|sJ#Z%*>VO?Wvc><%HV-ju?aC|iDxyQ-`R~X$P>@#=o}G2)AS^T@)rxUZi}PB8gizGRQD3u9<6bM^Mjx(^l@*v~kq;CF=JerF2jH#$eRb+Aq_GuY^?=W)PE85~4QWRQN-`34VVz#}4N-csS^K@+D*PRn@W!=hr z)RZQFUx@0}ZHtHM06q$UVIOb%*9{z*wyB{lIvQ(~$$|!WWR59N~ z`(!LJI1+GeMkexW=RD8%dNv)f_g#Jhp+Zcag^J?Y?<6Oz4j?%S%Glk9x%A3&xu(UB zUzgB$7W*godzH{6cbqd*BM%R<40~5bO*MXr*;dX`l6nq0=Z5Ccl62;k0F$fD1AfbiB;&C8zVR=rB!}jp~>!h5ekXl#+7(h zX&QYUPs3dSQFY6%;%9DjyVN8mUeVR}V$8mg`kyjGyZY5kt54gO7^Bx%-n2TX$gp8_ z%pjp@E?=Hyxev!A*9Ym2dUZlrpNpf0!?EaUz&keElvJW zfkhK zc2OQT2pSi!lG%PcX#=zMYf^xD8;9E2WGEh0zzT6172PKl5oJqJI*L z6!Xx5gVU3_zqn+!c!YU^aEs^Gv*1}HM~iKpx6%UqxcDR8#!cTBQXp`W-Xkv*T3n+uQNJ|X;R{p8@}y5vu<|nVux&=x#8w|-d<6p?w(g|ZbTGb1Vba+n;1c5t zlZsOH$3O847t?oCp>~t2B~ffc*Rf0ovA@?e!R)fWB!ie;N_;Q;qj3skLA(LO@?XoE|p+>3E~FkQcb2W`B@+o-DrGa%a8EVX!o zGM(xqwsq~a1No0=3f$TlZCdaZhTfj@LUAtASC`_?&!L>Uo*!8jZI_p2`lWm-!6Pha zYvvC2EIGP9%-!=y2!gbZvO5Lns4rF z&8!J*uj?RX_oSZ|QiBbhpbqeQ661kCbG|6K$XdK>`t;Knav@1tCWP&ig&6W+?1f0S zr(*mm4FS&`Xs%tH{C1z=^Ke)i7G;1pGS^X)EkQl7&lhq=^7vW{noMwSV_8+m2xd|p z)Qq1bYgNv;p7v=s8Ic-EI+()NoQt~{J?`v{r}H%b9u7(o@j@IDn{F<#k#r^n(ip8r zvc#F*4EXuXX7b6brpB;FPC~Hm>0j0|1}5eZakeM)yNbx5@FQ&w;(kH=UU1rwW`=O# zNR7Ro2w}XLCE`=d-AEE^T8{PzD8f<=ff%`EjltC<@F(^eo^Vpr__i%#s0UY?=AK0w z%b?H($q5WE213&)@(dZZ@e6Wy2F`EV=8?3fj`81S3)G~VW}!@`+nH=`P#$l2L!N}0 zIf;2YXxs_=0KV6tGbk5T=qp8j6J*UJ7%BQ)EOu33r%{bw*Q&KmqW>w7neb%K*c&#NhVZIZ-RP0#VN@((iL`K zFGlX^#pGQkdS;vHxemVZ&(_(1F;Cl@r8i8jEl$ZyDc@smeby53VCl728)M8lItlZ6N-r*A%QRkVW+B~tw;z=nDsZS*v8$vz@JJeQaK90{ z!14w`q9rpI3VELB$zD=h)IoSmC)Gco%YHU(#)(3R3EE5Y+vkwehZu(6#gYpnoaz;` z_IkJYK0Tm>lSEpSc$~K2NZc8z z-KETvU%T&!1GjMIc(%SCU){A2EeCpdG)VPMsec1&= zGg>>#_OEQ86RFdvYuJ&JAJ~-U zO;X8t;#|`kZHY}>22GeZ&I|w3gwmu~OzG`MUQ`={PYBS#^Hi6S1*qyY6~UW8(edy1{Wna1hshNVt)2)Dct@;;Of5C`@vbGf9wwHj zBu%l@qFVSHsMh`iu+H6*8M~kk<&2i|8wq!;)>p^K#(SX-a z&OvjiBN%^iYQRiIz>uD4mR{N;A;*UKdSw=RhNf~OXcj5Pol~2xcFFFHc?Y;DS%3>C!YbL2K_Ha)D=^?m z;QIR?Kn`nl&iEq@SR0p!YXj;gMmKB#=paz}*nH&fL{I?v^yEiXgf6iL(W>-%Cl9@5 zpdwL_GYzrRI^D~LuLXi!m$nvgXV;fF)j+jLBCR>F$Q@X~H0Rx3cd<9riJmqPP}$ow zXt&E^SwJ7Pu`H?ux4HYx_XoIUGJ6%#!4crv=TdWO>6tEA$FpFq@plYnohjpmi{fK2 z%FLczN5b`MEqPVR(Rp@g7r3e#J9mo4xRl+@nPrg_2*d8OC^Dl)&ZmTSIOr4DPM>N~I64pzMF9*Fn|H%V5vgR)nM z10XWn#Ir(a>^zS47MzT5`)#5qXPGsjDGHv6e7XX}ov3)@u#rJMbPko9=FyOK!19B_ zkS_>OEpPfgyHw2C4x(z07|nV+5k05`jfbtxM~NyyrVm-ph(-ni&g;WMm{ZwL$C-_h zN|yi?`tpoAOeE%c-NAbIXCm`2$E?sk?!_^iICQUG#&qGel}9s~yj^#_)S@|~0=~^5 z2HSf1ea0$$)Q-E#lCK^p+5*eYBoxX&D~qog)(JMX^i)q&9lp22Xc7JOv>zZXvPZ>Z zu%xED(aXAQ+*VW(tq6p;TQpL5h@G|D?`?X)X>8(9^15^PoA@yv{a+TfN3#!&j&GR< z0~z}X5Nf2kF~d&b6AeKaps%wD{Zzum(;;<0G0L$(4kFL*PUbw@j1+)UkZ7==C&}f@ zY7@TmAk;1mw`FXy4P$_Ki8qqH>Y<`HGPd>LqMC{fm)06aeNV_o$u`TYOF-Vv?0m#( zIgSiv#E4232|u;Z-6tLM#B=_aeN3bPQ*$*S!~OQV=hRq+PlmV_zGcXq^1m}h!b?pa z-XPTb)EX;{erMQg?(}4Uzlw*$Ntzp<&X1)|zWaQx2XPO?U5YzGcYDasa4dU*s@|z@ zmx9^@bXXtU0rhp{-Ng^1q6Fq7U#I$lIMa@r(_T!oe?|Z>@SVUv?a^>lqv#PPsh2`q z`eD7-K60L!Oa>q6A8px(04#F>`wq+G)Xxn;zQCTq>y4@MawQ?Du~5ME zdMPoBX^Qk4H0|D3Qbv2k%iNp&P`Mri(=ir8iPK&k_MML9-`+J;_<@v}ZIh>|xAxsS zKWcWU^VmpV-glg4UESk~skDJ4w8~PXOOu(WqL8HOd8~hP@iqSbkCMZjgtJ9ssmUVQ zW@^{*GgMNp+|<^F3KB0<0yaflV;CmNGcg09lP{=aBjRV38}{_9Kbd%_V^T-&0gjaD zy;gvrtZUy#Hr}#X3NB_$`iAIS!A8#)W2jwd%*ju*&VINVE5R5{fo7I6hZvp{;WzE6 zaX;DA7)@aRbT3y~ORX`B7C{x4O3I<4riNG5;SySmG@tzd#lFGhy)I-oJh7$vTJ0!e zk%^GmTR|S4a!~fD_zu$2SA~j}2`bn1^03fz&$^eMaFri26%V;zKWXqGPBO+DA9j9d zaed~rBC_yc&su6I5Z@*V>UeqzHZZqg(kbgFMIBIHjU{0M7V};~N7MW(GHDW42JQbX#xo4VoC&gvB zCyXnOR89sd55MWE1T$R%a5NOJjQ1=)%{169|t@y)Bcz=IUYPVMZD3Lq$*TOKL!(Y3@<1DJNm{nVFs`&T~c4S(3VrDSl0bA2J}pBz^Cd3o>+@B+xO~~IC?qe{CV)vva#oX!Q&U;K_7&eK$fEg?#u&nTkOmp4vBI9yI z@p7M^CZ95)naYb>&(I${Rfe!*az=)Jc_xfRAe``Sf)Lsp!}s}V7@H&C*^%4FfRUqE zE zM&G6%oI^AL6-+AtZ7~~!5+Hcw!Yjk!kz|y-V2xVf7sBG53WQE|In!FgX{Nm=%Zu98 z@hHn_RJI)KzEbW_t(Y>UiWF6N#aTrsJuAS7(X5Vg*>xbLT7=d)PnEiU&h1NK4NpC= zjl(%)e=AdB!!tM|BL*P+=+LnkhVUj3DUoZDz_gT%nN(Q8FRT~dTfS9GU>EuJwTZC) zKuXeN;TBz5aMVJgbcN$LQQuh>r{OhH9*h|KZ~Fm6C$1fRU+B^)py=zZq%m0A8ZoEz z6mnUD4Cdxc!z)U3F6|@Q>f7VYP_ijn&$aJgC{k`64V&x5log!BA#Wz{aOqpixT_(c zXZj7=x$HEL;CQUuS!4?E{&-krNTJy7-ta7e; zJ&>wDXW@gqM>L=Iq~(&yE;`5G$OEAbN@jw(r0*mK;FWjPPA^`ghF5zvR#;fE;_kiE zu=cgD8Z*7=9SoSCF8!T6b;%g{I$wDm}=RI~m8hQ(n>L zgpcaM6{Jvlf-VOYHP7aI%DPF-rk3%ta=qaPnzP!EvqEpiZ@2MvNdXsP8Njzufr-=*R(oV>dpl+Maj2)}Y?SV_-BgSy({13?L6uqqgRbW+I$M zK~&Ue&V|RwkBdZ-kz4cNW9-CXHxV#NH+L>OT(djU@2lCs=hK{*hw+_c#BI&wp#B~TF4*V5u3HE7vw(fQi{*kEAX!y%7Px>erz@Q;3=)geKqQS|>|@2#Vv-2S%l zp`^r-5DNu^X6KwxnE4 zHG=;(1;D_MOX*UYwHfjo$NK2jc*F7$;5Pc2!2k6OF%n_P_>=~=izc(%m|HuoS<63J z56@Ri6w+``%zKyX-*|6JX}-qs{Vxuz+0e@ySo)0l zz4V?)(OBs=EEV>u&e`aEK>i>3%ZU~3)Y?@Dm3oa=oFSiBq&xc0pMinvOBkRR+iTJA zug>wM8NV@t{bn+|ZSR4D8X(6CmOO{@#h~Keg(Up;O_2HqMSHUo2>&*LMPCuB3hu+6 zcPX|m3vYLCFy(KH1--OiKfYMW`{NAjiqwwS2beQp-@3%N4{&gewjTVpjdgqW>!Dp* z$iE$Cv!Sec2ml%D5h1*_h!>W#6#jl{n-X~DUC4R=+dqZIIIViHibYWMW?<^#QB;PO zeqq@9o8MmsFJS@yv$)EWf7#cn=pjKk-bUp_QhB?rS1al7r-o;MXDUKY(mH|3?VlET zGk{Cx+L~T{{()P)vdfrbwDtFwjNRZ10%4c^;eVPoyX^$5=n?QEdS|ilq)M6fKc>0& z)WI{8A$!WPf49*ZR%<$Fr7%_ZQ$mwM=lEgG!mxkZT1pWTW6|(%Ib7FYmPP4C#1)}4 zJm~e`HoJe>@KW~Rc1h_oarM!AXw5w&#;`k{AKd$-Retgb&DRA+{KdC4Y{&Qi3r)QW zaql}cUBgkMWG$DaCnYInqW8Ie>Q$3j0olh8TFW;4<@bc_cReQgsO_K9vG|JHH(sf!pzn|C3rP*i=GqBmW<2a8Fy3(XsWcGIjZ&pI@F+mozXy^zTN)32*`mj81P8`H9FT^x)yF;V|L z{6G`_=N^W8PC{vQo|={^19<2aE|j4LLOJLAw3kmtr>svsk=li)=)Q#*nibjr!kaMe z(KY+>S&)M5X>1q&(UfQpIuqcYW96aaFF%0E@~4~j?_3~=qiVLr(S;BNCFy7s*NBVg z;QbS`VSiE?UY(Wn+AE#Grzm>$;St=E)2dtw*GXW>(5n!$6XMng4gw;9CB)%(z@g{P zP_s5%q`iz5F^=db_&GFk0u^_~N%_ToR%|8O8@p&T2KD&_q;`7W7#w>xXMe$>B!xl_ z_3ERDG#d4ba%n)8wLl~?0(H;ddD?!*W$|^{G$n^4#t{&*I$qqOex%=Z>~CA9d(vTB zxY1Xu6An46hC1KtTmadzo+Yga61rHme0vRiwGHx7yeoD~@m>sdcN@7!oowaL^NqbQ z&1(e%^`=ojxJQIadceSB!1x$uH0#F`BLti{o_t4jPN=%7%X~GvVQZ^3HXdCcU#$N5 zReeS=KN<6en!W|OExA`cg^H7^Q;x=KRp$JBtBc*l!&Vm=(;(f4hcRo%^Y#n$OcBQm zt^8&|Ji6D-%C=t-zpmK|QIIiNy4CCdy_wW?r^p5MB-+FEIQgq&aD_v=bI4ws(_ZmYaK++)VNn&-5@~uk5wut;7LTiVOqY=UDPAN zQV)$#)run}A~2ihnucI74{4NsV5 zuTuzBBMms;Ie1R%1%s(RRY0cH_Y7z@90p;|N1sm*MmJYvgx<{sYyi%^l@@Z}x<5bT zs_UeSPz^W?=}NUvn%>?YtQ`xy1>=nt9og1902!HNHvqHN6i;D()Y!ho(}|LAZ#S}o zP4)&6?7~kWnIgcUSU$_-Sb<~Gm$y-gPIr|3b*0Kp$r6I0 zk^oT@VJ%&Imjfw7UEr1oUKRgzRE@WDTRt7{k<*F^kad*yD{GC%o_fe%P>Gc752*7C zLTdAyO^7mw!Bt~iy;7v7XlIfqyqZAL_R}D^u;+p>?3$8FcM3Gg{PTJ}xjO3#XQ*=C zfWCdAPC}wp|7~h+H6zzODO-n^#UzK@TuPbP)G z^3jhyFw5^2AK&4u3|{Sm!ZAh*D0l1uAJ!6=#!7DQcA!-3893}4EPbJ*`r{j6vj?dR zQq(nj1n13*cmm}!E4AHVRspI!^6cRLUXkmA$T(!ERzSO!NC<7_U+q&_4> zRzv2sM4X*sm^^6%`SPZ7Un3DhQYi%mi{DNdi*AWodUa7 ztsD`R=g{*&W)zq$0}UL#8A6*f#1KF$!r9x>iPo%)o7eh{JM~&g+0X)2<+GyMnG~8> z;LH-uYj}~ja0`k%C0u?(7&5>N0YmKl(LyN@Cs>zmZvbDF?QMgk=z;aZ(T$BBNe)Yr zn+{tkdUd7~9A#UtiuOPX+|AipU-lAxuB}JVZ{UB13>?TM(;`FX+%JM8+5H02F1o}vPXDo8Xc*+o;=g-l zlqevI!K@QcaS6Y?U_gzf1>I+CQ;BlVUL+buUO^7pFiV80o7yK)RRRUi$a*E}LMCDG zg|7j3J^~!>mJaKCQukv|f#Q-ca$KJ8jQ65lF;cSi+wPCMyPFdUNk6<{jl}nr!%HQX zJ|$bZp8lmy4Ux8h1leZZ0jX2Cy3=+&OQw!SR`X7ei$<1B#mv`^XYl+~5#{z68U>R* zFfpm19D>gX;DaSn>h_ejHaL>L52btsisL-cR zwDc`n)1Tw+sNR;x6orxxKlPFH7K00ox<7#~29kjnFs!tz`8+(vvg4;kg##sHCrjO9 zIQt5W;v~^hfhc+{ZJ0Yvl~qc2wB{*Pf`5|>;~3~Z?;y}dJ`MIf>M`*U#S4=8X78{4 zvG>xCU%rjDo;h2;@ksvLyRfMoT{S{8d?WrR_}N=_d1Fnau0S0o`88`tnbb18sIVTs zD~+D>KU*py#11h+vJ4S2JNMg|*1v+eFDKciv*TgL>3i&4n!)l%=Nh78doy~C{Z^)f zpCT_zP~ccz?lYrQCpQ$y3&AyT2UIt)6x%Nvm>{x?=lo#_*Rde8Q(%v)Q`9 zp~x$EiZEcC6|_23p;rXe&PH3~YmI&l&nMlx=MU~XSIQtv0e6o@1GHWQbE{ew|6*dmKX1i6;9KA2<8>AU(+*)g&c^IzURhj_vt#=`=H zE*`T|(pv>%@{zf!!eutgd3X_>-i(pSGXhcb;xUl1*1>OTKT{d+32=-mk#0YiWV_aw z#t5N)_+8%&w-3hg^+Sg5%VA!QO%DsFMLGW(zw4gqiE-(;4w@omAUEx{v<9^PUS?e|KG%F+ zzmhtT2su{VmZ20HyMm*X%YExpQX=!PQiclew;a$G9UD5D(>BbnKoC5^t2v~YxG-=} zx;VoP&$FCw%ByjwuwQ4gM{rB{5QE>|!02J9GP(~O&kgrtjh{*RvqEze6ih>D`Vmon z<{lQm-ntS?rc>`Fcz6~V9%^gqaEzg*hj(MY;lvqwwxj0M&f!Ex`#6^aI`7q9-p(oA ztVo(sp_KjBX{;ak%uZ^QitCMZHI)?O7@1bVl7qq1hDD*<5U|*a{~8?H?`VbL7%3?- zlaF6i3XvMj1_)K4W#S5Eb%yWz7w5SQZFk#?%+bUIuE-Y!1U9|01j5(8R)`rknh1hD zEMNcYlx2<#8;Jt^fwmMqZSS)5IO3mr%HKMho_jzPV@31AUZypV?Ue6!l+M_pm5^mF zg~NKSd+JbCNe+>a{MZ96=@n1kp47{|GyS<)pLZ_fXz%PgGz-*@(85t48bvX}2N#XN zB?0$yE!o~vt76Ixit#e^yp4S$drV4j1O~u_C0Du+xhqw(Sz)k|w59G?530f*3*0Hg{?ICZOA^nPx`7{^M(_1SHHwDNEs+i9E=%;hc`K2MAl=K#D zr?7W)l91HUZsTOnyL${jGt{Jg)ukZ=j{c#_-I#J5PGDuC8Q3e|9~hM%yJ}X>ocJRT zX;yKp^vPSZ&DiA~4fnM)LJ6fjs|PeF`>9$CUO7S#CR*bOdvoCvIL4*GqJ#&q?mOWb zsnbls1$}6fBS~4wa11cJ2qX)XQ|~AceT$4TarK%{(G!%G$T%|OD?E3&Y7{5RrqdNC zvMriagdHa?7P$#xENN-yNwA>iOnNGhs8JdUyA4C5#Cm6#4&mxCI;uu1q2JH9DkD$Z zJAnW;_qHh~W;UMbYkcA3tj`+@MJKmB7s*V$+{IdMLw4;LU#>^?Rneah9;a67HvKI7 z$2J(;z=%0p9MO^bo>!4#LT+LU=V)qG^6lN19G2)iJj?T#hB35WpKt z!wF$uF<{ARywhQr*_k_NZ10JAPgUV-8|T+cOb_o^b7IOJbG7;jU?eA+%+7)!JVMo3 zXV5bjPuN=aX=w1d^7Uc+v^C?(fdMnw#$bgqkL{XeZ?1iLFvLiLx!-)!T>I2Y;_=L% zzIO*E4*{`226`^J1%aoS9EF-;!E4lRz)6$bTmZSF0qXC79XH&gFYLJG@&3+N0i~MS znZc3`HjLzycWX|4xN-$)1t%{h%YePqgTmOgQG?|#Nrr}S9N$E@&qD(_daayft}~JY zbK|Mr1zCmq8Mu|liPm|T*{Y^<_*Le7q(qn!j?3Limuuaa1#dz6rEk||53Gxs*FE^- z1#s1eK{r-Yoqg< zU1(3tAy@iZK@{kRDJRXxl2!K3iB3uArsGqO^Wq>V&b5yS>qHD18&WVsz|ReORB@0K zcQdZ`pXn~w;=9y(xhFobua&+2St`p}B{zc#JEOKa&QTK5(wKd~Vr0q*|Iljo!GZAr z-QQo8^%)46C?=Y7N$npaYBPqxtPr;*Ii;3YJ|AC=J$-Cc^O|38RW5|9M<^3rX<=`* zeM!!hQMsbeYHpTy|2i${K(T~}r@_!dH9D-L1F!ND2z_cA zFjMqPS_eA$X_nosu8$+;{*U>yKug_*yh*x_ZmMA=7lm3`BMk}?B-OCt>4%>tMG_Fh zAd^;6BWd{rj29%YJ>L{qe=OKv?Ejg3Nv7ZgSa`juZ+eR?yf3Yvy3pw)Uqs|LQ`r%) zF+j$X8l6w2rLowIh$V514D0Ff!hFtQV*?HJ3)6J?xnP-QvvK2zK$Tm^90)Lqbw>So z%rZKI4Gev^-pdC|@s7YFGrJe9 zM|?67g(>HJwrK=Ikyb9eeaE&<(Q%9NB({hxo;5xApa$h|HSIdP@q5!kblln;;(CIZ-($e*9E#ZVMh49a7Lcw(V0z1wS z4s1~nNr*R0u}%_(q-l^aS6-lL9%s#Kdv39-Wl{g-_UD8Vfzsn7(Drf}v3wuACcR%! z_1{jxXMQMeuF^$fL#1j&)4;~jPoAtKl5oHFsBnA~luckpXp}LB?*40MBev-xAos6B z?zSyD4Ah8CGF~wfd81C5=E+1D1~x)>ATRO~I#H@7anT9b5)*^cK3839Qsqtiz)MF( zyp8dTl!6ll*`-pMuO2erf3r9$fx#@2xQR+F9A8+Da=AEGco^Fdd(}v~;QN9x{=?IY z%nlKo{;UT##A5X%&u<0nx93kMU0lW*m#i7llZ0`fr!L5yGp&bbyztjiCh3jy?H!rUMPOBFL)-f=x#CibxcTiE-BpKUw$ zjSKreuBO|qEjqYkfthcQ6OJg2RXDHGlD$Ues_V=yd+8bp&!)tb0asq4gc^ViqQwQ( zd$Ufu4QZt^-8z0=Vm4}_x{@#S*TdRyETkGANKurO8R1oMNp|@D(akU_hT+7BZt5?V7w&(wVZYppOId%|T5xbV{SO2;n`lmDv zpk!Xxc+K?Z9Yhn#m^uEshd$1)s!p8zbw6}uc4ZcVnO#dzcFl}9>Q)TgAR*C#}zLoth(={+(--g(){(5o0YQ*;m>j$wb*j|LtxniKp z{kx`-i^2xjak>~7S0R5s%z&h)ee2#UY;0l3?@x<6D3HLL4@oy6n7==Ac$j!qkF@LX z@LVCkKOwl_Li-j1S&={23CCRp)Z`CUABq2UdnmYYC*)ep`#;yY3g5!J2_bYNru*0J zX~Bi_cUS~){uB%1_UNiGgdCGj{O@83#|eN7TNRY-2>uicg8AX5D})tW{L|mXauv1* z7ltOKZ;|~|BLWc+S>b)6{HNk>JLn5#Rj2R#QzNqXpx#$0?_>UR`+4+*F}XDg|Ekgd z{|0mG0EvA47GBC6HNZ}}7VR|E{O5HE5&hf8BbH_XnOpb*ZRJYS3f2f<+feN$?}~+E zB#Es(Si8?tiJ0{Aa|*Bb>Mp6_az5vWbsUIT6o0IWW8&S4S&X#UVz6tp{@qi+AiRpl zo=EKMh=i@VMHOhaHXd_79VC6^D!`{;evk-pYPCFz%iQYZo^|9uZ73Lt7`!_#^Yf4r zmmo+;FLBlg^5g_}OaKwSG}>S`xm@doNM2soggI}z)5Nx$(P93aQb$%FCPK>ir%E#e zlwyqp4@QTJ96H>K*XvnY+;^C9aHW1;%iplWI9i<2u{G_e-SD|Nq4RKCLgey z!*y)!6D)j;aDPcEuOVC|b8WI&VUe27Hmfp-VqT`04~0%12iknDSUO}u?U(qc9Uni1g_u5vh3<;L19e88oS_Pk;niLS$gZg` zgh;&E?&??rPua!VZ zP1p7z(wAzj5oe=bTreYI*ZrC3P}$;5-c4V-;%w-^yv~$^%&_!nWBg*PY$^V8#->N@)H ziTHCZrwNu*Z3M$0Ka&%uP#S)f_!jr5s!=I<5Ml(SPEx_WQrnTt7ixpp1FI^$md zxxA~Q@P*|=8|AOo=O=uyOQ&)9qo>*i99yH!`TZA?;TipJL?4}C!#olU9Tj(n8*ztY zTXFHnx?*NlhQbj`PPMwJ-F-RRNIM=2<6@Lh4wMg(0Cm}(z7C^*u(_@C5N2h38K${? zD}U6mto@=GF_}@~)TPFO$M@v;E^U+0hg~Gzd9O_j#Q4(YYs56l)~TZNWa}-gjin3@M7gjoHS4}J#GHL+ROq;?5truF9XgUE7ho3ZxsRH~CD+El700+jMt{~O z)kr7|=SZ<>rnOV+oOO?kquq@UHMmFr9du8Fu&rqdSP;c%x%1=_g1N)SdzO*X%J>Sb zLgGf4U_b3jaZMp2*@m@E6#CYigGPwaLQ1+tNujV{QYP_BG!{~BgzFahLU3WZnevGD z`H4L&$b!Blm-dK+MDjGQjACB|^+gjd${5+XIzlm0-ms})xnhN&$BCJF_OxxqeJy4~ zG`z6i&gW=r>yl;oXE3L-;nYgeIU5x@5LzgFXXjMmTZI2ly#Tn0Xx!O5S<-EGD8F`pBLsAu%z?5+FL+zG~IBQU2jjJStrKj4M?X*&AvPr8 zd7YgGoxQ8HNE=xLP$%b{R`vWWbpG{3gQzVF>xms{_!9tJoc3h$l32H}2r%a8a!aKT z|4fe|5t523Do>MTsZ^Z3-e3g!JaRr-Kx=ni(#7~4Y;M*YG31<)hpkO)=XLzuM441o z>^NI;@TX**%ci?WnWnH64Prx-uHwfJ9WB1lDNJ_rxYswBpB_bk`EV=lvmJlCS3Od$ zH=edlC%h8{n-bmmCht_Q&OWa~c^Hvt=i{h*m51!I;R-?T(7{6u1BN(bt#{?J%3t4* zScI;PR2sZ;d2mjyv8`AeE)cqpn#knhOA>jwJV7u+B;#$XGq}BduGT)0%T#@m0#&tF z9(B$N|k4k+!@hp~Mz&ewpY&wS(LxpTYN3(gowA3j`i;mR!j;TDN>A)Dl z9J`KGDKk11u9P`>jY>P#+g5q2i^r{vg)7m5pn)(#?5em_;$hEJ1l`z?f5a>h3KBrp@VBx2)R2CCZMnAh zqO3M713yCze-vBq6l0x+1IofkqsgV9LbvEXG`)gX+ll*0e4B z?M$P}?L5AXe6S~57%*PBM_0n%vFQ6j(s!!xIfB@nUOEmrU;7^Q-3WzIU2!kkBu!5g z`Stbe_nW3HIB`4NsJ?v1Cw?L|-De%@vFo$TP7Md~vCx7cm(fPaJp0^9vm*&bp-5s` z12g=Yj+vsvT@kwQ{`?E{TBTj{N~e-$VbHKl^i);)WTA6=f+sr9@UuxQ(7$CrEvr4N zSvS0$_7uit_Y4Wi7&|>#7ua~Q%O(IVWO;}~JB5KO(c$*qBQ|1LALFRpWvFcQnqkUz z$wNE26rorRsa>meExMt%jWzpeA}1{F#qrul>_f0b!6cS-uIr80Y%4Q)C7EWzU7DTs z;?Kp4%$8adpj(5a#{;?wLr)(|+*DV{_J}sr>RoGFJ7np6=yU|9>!{GMAeXseh8~g@ zjO{L?MfPCtvw+56MKj4W6RX3`4J%b3RB!I`L(*&pBGT z^wpwjr$cg)f%Fu`$+|<2+L+6U72(Ovmx{h82~fr@n}bpE&Vkx9MEwh1q50x^^<)+q zGXi02ntLumM)-rOrA`7|#2k_kayQ$afH{=h>l9CR`!Z%&<|f}En0Ps1^k<5Rv!`*p zvI}XbekV!E+6pVyY8(&%HS@{^ZgFzbut69Kx!Qec`3R5VsH)QmXVhJcWng5sjIfJY z_j+WmQKkPnC3*@pnp^!2mVyTek47~%2yC-O*&g<#Y4j{`X{5?a%qg&|;JhIH^yDa4 z&>gzc7#1oH*U2p}hHBBzJUwGBe;j)zcfybCLVR!p{~;v#1fnb5MV!<1;sK~Fjq=wC zGS`*fa6T1-Iq!SF-QoD3>*hl4?aF)u<~#-?6^RO zYBx6AofL+;aVzDCCsz3qXE_-B;qJB%V)IcX+Y6(q&ZozZFC==?p{rK&IU!oBeD{Sk zw?}ntX!zknW{pPM(iY0gx%V@*n6!A?$X8K~G^|yaS3>@plX|x?<-QBmdgYYRQXWhN zPeqO5k}{15#Xtv702t{wV@0yP^bSNG3 z`tDM27M6U!n!&NA<#GJ5R`urT2yWhC@MKIaF3lt>C;~%x+XA=uZ09kG#6?fNra*Sf z1zw3%8bpDb$~wRpFP{b7DF-;_zAk!sfTF5WqrEPZ}$zTb)Y zvoI5U!C^cT!_%tF*}J_WcN)`<5AtM5cS^K;{9ebLZE9Z8#$+^)Yv)C;?r_ZP)#*6g z{ci~R4{@~bNjO_iw!T5_DLf+6Wp;JQVKrV!kEb@B>?XYO_XHUrsQF!?0T8s~ok#Vd z!d%>uPj|BhkR)%6PVbdK^|TfdVbH~+s{?yYiTDf8&JGsA^lMo$X;v77`S>Dp#=WI+ zMrx`kU`s^0Ikb=mXUcXWV9-gW6?a$Os9)})+KU6Zg_e2Wrs~%WONv|2ewL`_F6McdyHYYEN4TC23Z`~nplabBL!!Ebm@`1WL$*sSY zNA&yHCLEtnA*HD=lZ>SG<9_+_)fs+cQQ0u|WP%V#`( z2t)6RDfhvC+uz|$%k}*S;P0C3kleqnNcI8S>AQ~~L)=cTE=^WeqH*4D_g>X~JRu>a z{=GMMfB+By>MBM44;IiR19thNDO_7P|LouY_x&v75d?uc^W7+#ycm@!o+kVUWe6d` zFt}@w_LmIIL{iysGQG`{uL=iUNg!y}Pb}hxf zPzVOh9>pFdG3B9anpn)ZxL0n>RUFN}m06AJnPGy}hH&O*yG3^)z zj0Qq>NY^N9pS`Qpzo9HN9F~Cwxu)!`ZyK#O z5fo|@{=w5Ie*tG~%P(7S)Y@I%!2Qkj@`aFN0v zNN#=x{lg}8*xxW$mkz+gY*gHKJ(V(fxLSO7-v26`o02&M+;A=f`ggIG?t!QCr&pH26H)UCZay@b37cc{u~;V_@G;9 zt^{X-sll;83f;frXjo}K(qWhAv}L2LN#OGxVOZREwx zcjTXkp*(+n)7OEqj~`NK=!lWrT|s8Njzg%Vjq^8{I%gp~LV(c}M}W=!PtOrS_Z&H$ z#d3V}Pds9ON)uiC3kK%-?=bMTU^f(m5oxY?l3Vr^oaPa+8Tfq`*3HQ)@6gVY_%o>$JxW+*98$+p`Hi6M8;%@Jq$ zuxlF=odUxmEu&CPPsOZ!e{7=^)eTaixL5+)Vq}*0Hxc(sKfA@L*$8~u3RP;IjSKpf za-xBeF#5z>nz|+e+sa0UmByvej_^!&g>z$;?h?D$|nG_$mw?L&M+AXuBPXe zfK#bbWe@o@oVZ9N+Ts?E5Fb4)t^&rn`6=e4Z(XF+P^LBlh4E$SG`GHzMER4tVpya+BZ3r&9a@u_h zzX(7E$ko2Jw8S1@XiZ1{KChiS>h$82SnzI;!z0MMoPZGu{&~sczgpE591y68L8#;a z$u%)b`#t_EV!K)*o&|zmbW$Q}ZUG+uVVO)XC@N8XL>znSZ7k6`_cxw2sCJK+!-dPq z@>|ookFXWQVE%48lh({Tx<6Qb7aG%t69^LHU#pmwa_5iRi7ZNMv z>49~C;DKF;OAG{UeUd<2MTL_t-xwc|8-I>YotKXS6e3GtQ(~Dfi)3uP{`N*u6(-?h z_ct|G%_eY8m_;42X~XrmpE?zgECrjZSzcmTCLsYej8VpF)1p1(DC*LsYND~l)7b~-J9UkD z;uu1J@N1f$)8I49u>KO9BeKgv*z>y{S)hGRvTBsQxrV7hLWA)qFysyI-tWlMEI0V{ z@o-^eyRw?W4_>IRnUVJ!eA&}V;3u9qa^Erir`w;?7=858!G{g@r8lnn1_NFqJ2_J- zK4AFQ z8KoN~8^H0~GL|$*2fh-h^pz`@2Jo*S>LU z=3El`YyN2h3taXUjACHq(m3$76cqK_ zfDy%nNaS7oYAI81F;7e&RsW3C6>xrD8b85O>g%H-FNri}iq!wc>%RsL$-l_VYyuid zayAOA3U%$(K9+!{`r=0A@q+r@or_g1l$yoM3JJWs893NCc`^fQjcakyr4qIP0}(Jk z0hc;NB|Q0Hg-D3`yVC80Ra?ieO0Vuo*#i6c`bO?aCtn|3a@pIKpT)?%XBlwfPC8O5 z<2`~;W>S6*^?0tXW|p!S#uxh$Q~`?co&E~O0PgKjfiPfG%#TQntm^uQ^d<@+w~eQ6 zNU#2VJXQz7#+wkdF}ZE8G*6?*`(?oGwE}10POK92=3LtGF@#GXwPZlA;(oFRQs`={yi=m)}IxJ6Q?tFcvUCt3-qC9xc}}M;uySugDO75PV}^Y zD+AD1bIk9@2Nzz!nF`Z#zLs>|cFclP?DGz=IVzedeulwZZD3F1a)$rYrVw;|Ueg53 zdy-WEC5aam3fS!v4&l0N5?k@;)#7`|T*I3(Z6bFt&1dOT1Z(^fVZRVg)mI9(-PUP}4VPW*jKMhIaqOO}PNb#hN~FqN zY}E#Qw?-0eWfJe&YpU@lv{~@vD8yQyH9QlSRLYa+Jghitq37Kzn#pwLG z-9XK8AYY@5yxIPQ$W;~1^_*?N#b_dGIjW{&|5Ym=z;Xq(O4d{NzJ`Ou5Y?(L25W0{ z;^Xc-z_7gL&P#CLY@J#bM6I5INrr6M2TS}!eBo)=NSB9xjB-uTOzUWu2bO z#09V#Y4$}gFVZMRM(9P}IpN-J`Yfb`mpyUSbw|G73!uC!b6NXe@=6|1l&<6Rgs>i9 zQY2#E`|DKQjUJaz6T*mLa8P+N@@$H}vR*w+qyJLHUQeqGo!35ov0CqkZThEh>voVr zcHZ;yaojEH`0|)B=e_R6SMj4oW|Pm4CxUrDQ}9^+)oA*jfSq9Y)Zy`K!TrA8Zf$ZR z{qC`ks^0}yk`r_>l8?#qW^!Vw|Lk_$8Xlrq0tX+Po|7JeC5FbEpUChhNH6*|^85PC zi;N$ayn&j6HwU7)`;+GF_>tHZ8|~l6#Ls>OmV%7AAXP<}%2TrKbEHBfGu&72zI)cRgpD1WU$Md?D(tpqEB_+Ukabv{A5vlE{$@y1ALJ_cjdMHhRY-R{6c^ga9wN*ut*ItrmrXM0S z4@JMwWIr@JLpy*_n7w0!UB(=f>36$a`$e3p&-BGkM8F$gR)&FDB{N0ED@3LtAFZVDL6(x{Ns9;n#KyVDKe|>?r0My7Cwd$1~2MUhO zisOYSPvgL361Rz}e4d?j0i#8rb%^=s3pkT6cdnwau&L^oSF#q_?#asX# z5VeH?D3%QEjEk#q0&n@@gyVL>$WkqzdBTqj zNB>R>5Vcu@EIF}bz$H^1E=WuzIt3J3W}gnxW|@JXSrJeeLV&#!RBi0pSY8MPXnwah zMW7IM6ft$mg43NY7nW()p2Q+9TBVjBd>iSLtW>8&Gr+^P5+E7mg;sUa0{TbQchd?i z4Zwzywh>xnt@YKS;d-=Tv8vCLxG$JnAOU2+YHyOPVrDCAp44`SZq5^8z!<|Tnkbav zTmEjUv)j%SVCLa<~%K1GbhTaSKCRj3XcyDT%fjxl>`YM%6;<8X&Oq zks9C-30#D%*{-Vq;yyiIj2#D&%@|0WG{p#ZSxe!DUkYM>s9>wzfy^%-PP%LYeVoi8 z$m^S+(wH+a3!rXC$PQW&w@tJMK(?$%U1H2^Lq@ib_fiR~$b|FMlS`FxaaMH4N?on1Bp7Xt4emF}mnHLByd0C%WOM?3`PwU}Kfg!Nr&pU%x zR71d0?9CK2#0K{6rbXj6tv6mAg8p0rq(p24RByry$3V_7`Q8oy4lOZ;YrkKTb^!uO z8vs$LsO_~OVNP2jU&EYw+qDX?LQx>I_t!`z>50^3MWR|Dq@>u#?}1S5!%skrSn@-@ z_xKXE@m1?borVsST>5fkPqt~DkEWYE#j{!{9K)L{f$o#xU=wuRwNT{|f3cCtg?m2*2NT%(8WH-FIZy%_RsVpzRp8u&|@K}nG_?xR&hOTZ}5vAC0 zm=K3qIjy85bcR}eX1Gd{p79JS4|?A0PV7?G(w?y?y1mbM58fu9U^XH{NAe$w35vRk?+ zUr9|XK?^*W9l8sWoaa_1U;09fJv&P%R!0P9KXKkYlbBKHgws&<5LSad_@YNhAg@Ry9t7P-WYstg*<8UG!eZ4Ihe%+1L}#rhrtAX+dBlmU6TmBH zqKtMh(y2X69pabdY39A&)6%DUMWjMBvd}k@EJ%ho`b_N+tx`#pS`VMqVkXQ zy(^U`K?Wn<<|#!|)cf5#te8xBUtTf+AXBy1ybB??6_mivKxQq)q2aLgmJO}TA(MUc zVl{}{H9ZpY^7Uu2Z%*_wJLLOpWQ}uw&>~L$gj6SfYryziQwT#GDMNBMT)bX zto%52cMm9DW?~#xQj+!RO=DJU!_x1!l3oFFRTZmg^p;|yPeIn&9T)14T?6!~l8*@Hu-w#F7pzb((*o|(P=tk^QRQiVrjx0AOaOP+uoT5t7=x0)?(C4#RP^^ z5}al=cK{mPH*n zb4J;RS+GP?&_sdlvQef<7yjHl*ycgi@O5=Eqv9VYn$}gGj&IKF3IbG7SHO4{pkqEC zqVDy&?*X@GOVEGH_`w6CY3Xy*BFU#ixrsj2eKh2^e#vp?E(~9%zefM$RzJydxZ!S% z8vU_0lyE!SY_fv5Qx@>blV2(Zqg_85I1s=xBA)QHV?ZIX{fJq}x9XWqZm1k2m0Qtn zxg>C@zaYU{CA2w=ZX6mSJ`Gx5vR#}5Nh0dgyOu9!FI`0vcMudxhHK#Ot*~?F`e1Rq zks(0aeLTJm0QX`Ot8vskhl@okN2Qa~#A2+A^9Oq(Zu$1l#%Rs^wMNC5hE}1oY3Q}a z)N_LYj$!5YgtO;?%*sR+8!jcW%O~9h;R{8_2St_VY%*CDp(T1&J&zR(RSXk0@oD*D2d*sy&I0Ao`Ui&$^Eqz6v!YP5^)iAhw{6F6xl3x&JeH zfn!y~7^*O=bOS$r?)K-*Spo;uXY2(b2AqhymAB0$PJlQOC$582GGuA`t;*Bn(c9f{ zfL)0-_82x?lP!2Dk!B<@P8O-U1Jn-4wkPmjWp%EI>=`C8wI(7OA%OUnMD&zb8D3)G zV|ZUv-=Vr(Tk)~x=_x(tyqTb6o^wk2-t#OyW9gpQ!f;4W`Qt@Oc8Bfm0#?+E-bn8E zBbpx9p4_?<=rd&r$4GXf{+YNxqt9`5Wg}#Oj8?|)i;eRwO=D$nz^+1*kf_T=2g%dx z9IQ8^Xa$0EwQ1c@b2+w8WZrm<-rQL^}-F+ebpkLZ4Z@wb$o%VcC4G z3=#COl1kvqBi~O6(U$`NT}W5KJG{kgsSy&MFPfNwtWjG!sZ`PFZ_o&M50jBMS*2P8 z_iDn9J~`8HllmioF>R$kylY*q?lQ<37zkNoNWl9A zjPybkza$UsVvn)F&Rb?Rb|iT#o2h3#n)(^`FX3Ab@$!T|N9hmogE`vc$J5upowej< zojXLpFKgLNfAC38UGBT@Excdeq1GqVVGNKzVy8?o2=_bbv_e_u)ejG{VpBDPayvK( zNe`0fTp?18Kf1~Rwv6_X7=+Rceu&c>H*Y4rqGS2}AXioQ~n`C(g+Mig^XB3zC{K zj1X(i4mCyHo3Ugy)$A(})6?D)`ws_wUUC+}m|Ng5$Is*`vmRSy`tZ(kg)p}1TE)eP zg5+h{<=&H!7c9McNLI|G^xfR^_+N=3O>9?2P9_;nx0gAMJT1U-V0=*ykUoX=fjmxG zNNU628J^L2?poS{>~?=21^X?YzDl@RPV?bDN%%{y$)tY&)Q0vASp$vRK?c1S6!XfF zCZkO8W|XPwQpMq0Dcl%&C-5jgIS6_Eq8hd~-C+K{U*FC0GBK&_! z(u6pUb^(t~l$m7o`&tHBUKPt98p4JPy-k8}mSwh|5%s3os?zdQ*OQ$XH2b=FSip^zV%1)tPAuBF`K0@lJE4asL&>^Bxfel?24V6a|5J4sYtt@kE;YdPn*Xg51P5M zMs#i8$c z+Bm}lhcE#QW_4~kQJypYjpBsF!2ZV>4`Yr6lo6bAgS3ce=Ywl* z%v$hwIkdz>cQGja>C=@~jTA0{lcdCrdzpKygIS5WPN(ZdM2U7}*~VNu*@5wfZ${Ds z#HPq%%^Sp-A!**EyHCDK$gC%zxP_}C-Cjs0XA;+_Bz*8y0rUJCIAYjorD}VHSh{6O zrwO;!EB1IKIZnAlPI??^%V{Dn9b)bHS&Pad##;87By7WIfMc9GT{cZqvtJ^v!guh< zAjhh*A98>HG&mNtO|t#10wJTWuw$wNy306m+fTTu$~V3|NyCmSzp9VuEn`UYHk82q z&@d%9{GcCeI`!wip~lXRapEO8L^B1>{O6*fF&|I{T;JiYmx252)3y08fJ7SRTa`k^ z9uMi0l%9B{z-vJ7GV-c@f1t6QH;ZaXTuk;stRZICrLW)HQP=-J_TDnCs_%Oj-INm2 zrGSWZiXxp`KtftdNm1!e=}-ZY5JdrLBqapt2EhOk0qInbkVd+>V}X9ZzjN;Y|Kh&5 zpL0Iad63v{AJE)7`2X@pw}IIHN|Z(3Q9-Eu~vbKG26KJ*89q z`ijWWBjaMk{s|8~4tO{}2CWMcX-6_8Iti{0-X``nB(AE<+t!Wppf1%S_fKtZvHn)p z61L75J6?)8rH!FxlbXf%;Ho#JQ1DEE@6L~qA4ZY z=KMmi^nu-4QEG6)`{ZZ`tynqVOdgX%4uQ_z>WPp`;aZe$ELUG}oEx)P9b>8YjGUG? zN@~MJPjdJLrePZmvK!&y#%IbP4Nt-Dgv>i}W%53JT~s|kvbootNK_X{B$a6?{g0BQ zS?|XU9E8+E)c9zVm)bHmn*QvnRKeYOR>o->&aVUxGkrontQ6d{Wt0 zJuy^U^;O=-eZDrG773i;soS55rbxRbWL^!92SQUx4?9_(1%;GgvD7(}s@9ohddqpM zxmn^Np{RLMqLNTl_m7jb=_w(C0zR@8zpNR0jae5y(tT7JD&zF-IW4)+3 z%AfmK!%AtQ`7yHfDC3JYjEOpRjcguf&^L_xON2e!_iPNdOv5aU=Cl1M|2qXY;oH{T zUC5c7NR|Znx--9Y>S1x7k~ci(!D}YS*~{v!Ti?YP1H4m@7Gp28HHn(ANY&TA9naTY zek(M(JCU^G*$)#c(qnXLW3ve!Wqx@p{%n=;bC3#g8t>}EzO*)+>=GIZjrMPO#x$Ka zlGeAE;8Yu?&qk9R^)6~U3+aSE6!6hk1@}zlF>eS4hMe#={JBdudyus#)?3fVfeQWM z4B_glnz3ckYG3F>hi@LQYiv8x%&0HYMNPBOa+flp$sHDM2+$S7R8~a`U6;7)f-xiA zWnSg-^KH4?LZ6Hb@mEi3SN?LdE5*qP#ma*DmY*+-pD|CkbnrZGV`j>Adoo7%Zb7Gi zFP>;Vo-*-C^71$}PTRM%F_XC`)p=H5wCE(A?#jwqOSx3-dFyr170ssp2l^hSJ&Wnv zdOYm_;LYc@bYPcy_mvTLclxO)ov*V1i;>Sk^dEz&$6s3x$fh1}Ju)`-+b@0fNonh% ztrqI@4Ib0M>?cz;q{1)rC%|dPQ#d$TxR{2!Ndt>Ji1=I*zs7Il(n>00>lemPL-8W> zXwZ`^S8n@YOg{K3!)r)`GU_#v}ZgPwDD z;Z+G7;CXxlZ z5oY40n{C_l88|s@kR+SEu@t}=+U^$_)N3cIO&>fgSuI|e!1r~SGJ{`5r(R!vor3^Cx8yz;$9Ha-}`f-;p!Q|;kp6Sx1Z$V**B-rK-l z7yXK!sx;b?N%Ek*>u{ecK+~eVOa>#{S)=?!PxQ5Uyn8rfIf_wD_6GVpC8a&je`PS` zQ%Ulu+49Vh4@fAUw{VpiG{| z8<;xao$#{f9Pi7rGxgH?v#sXaL)*V_zOh=jllvE?#h})+bhh<89c4?CbaG?aP^M{T zB+KupywMUaoxIpER?j zy+FXKfbE;2mJ)M|`B;DRtJex^h0*P4w zGv{QwT*Jl&BgPIi0Ax$Q$2~MM`SjpDf9ZxVcrHHQL=AbjmOdDyC6n3>z(M2 zklYJKoaI2&+9~-Y>O9XR=pYLpC|k+bF)w2 ziIdTx)4dlp>fZTfB{yuB)Zdg_!21Mn!UM1|bI!cQptAg~sw!(gRKLJkGT2j4#?vf% zR+F&K^^7`?n_gFqTuJWtbnIKDmQk}`>X_1)P+~>>B9`!N4IB*DINfBUxqG>FCbLp{ zy%~mqI@LScy-upD`aT``C-gOaUei99;?(xLuHs_%;E`FJWo9>qq^00MOgJ!aXlWx5 z(KmXCDaBrWNJcXXn|ghqd{op?g)MzmJ-hty4wsLeZoQtz*IE<(wuY9@(U11|0!`9R z%WC#pBAgQ;C_2h(Pr-wc3f}Gux99FgcE49&o8e|L|1V|?U!=(uOUjh86Eb#5)e?omB{@c zn)@SMpLK_&br+yOH?R4(!PQ{2%qiX{-&Sfo2CReE!o4|C|3lBofeMZsQ=3?I{B*Xj zkdW+;G#`BirbzVLZqJr!+p+=Ho$&@36y33RfQeK4h5P^{B1gFQu~Zy$wI`ipIbUEj4HIUtk^Z^Y=ale>H=XDRfUaS1}ex4(g0qV?Y(LXo%oDQzpLQu#yV$X(g z;oqfaVB&|@cekULCX>zB^Zyl|$;PQf59x(7tc3crKZ5_=Lqg6Mf#pI8BE^+pyw<9%$ZvOEZdIS*FneR-qaXa4WgXXGa`K>c$L$daPX1$r;Go4wS(N7MSXwgE$Gj%az|M44GB29~ zq*3Vhdt4=*RlWOW&>d_m;d&Xf{0R^g2@=)G|#oIPCj&frR? z{JE?5TbJ?s?u1)41+Sf%tdX@Ywd9w+z`=6?YcDf1 zPoh7*4QMWydsJbI^#|*`zn`Y+X!c9;&x zt=gNsy~#NpoRBFrLij1w|`xB&I_=?{wWCo+LU_*?5TbW^|&vTBa; zyOvq1F|~oil|bViCKE{n#4d}`v*OrzX2{6uTdE$E^;&}BFE6`=D0>{*vhW{a(6Uy@HABB`9QO|6J{ek(foWSlKtrPfxe&G1st+QUG%j3iy3a zEWC}9NoblD!~>o7l{?r->Rf#eoll`bsV?QqrkMo_4M)->B(|F%gNW%1ZBcn*-;iJc zcG&xh@M58Bkj0pUhd$e`*Zn+OoFWO1TgpFYw91961ZXgRlYvtiG1yGB zTW@c%?4qoG1e-81xeeKJjRTiB<1Mi#X~!*+ zzi-ll4Y`TvkAc)ir=_-_b+u~HYBlmh*Ke11l9njaqb__BFYJ)8Y zknJ4V(UZ^+Mj1Z$x@6ZG_E3dO3v`nEwl%^_Q1AT~hN_v#jOW~`e@Wcp3Z%`%G%F=) zFv~hkym}Q&MzH@D)+UtOt`8WMP*w~f-}30s>_E{$1VAANVAjiAl$tqmgg=o)r`q(t8btS8%PE*9Q{o|tir6dhX|SYM9y7r@?J0u_61MPd z0Bbk%V4EwRQIrFY4kh3R&MeSD){L2*5~11XUzPiDAIO2t0lWlz6ZPbpJf9m zA~%WS`ff2z(nNE|McOt>_Axfn<=yXxlHwFTi88yPc9`^nHaECMzrs9vEZ!tVz*C}5 zQBaPPvYlQ@uEOmDVYY0@6c4>_-@PV$Eo$=xNe@xZVa7OsW-60ub>K7V^_GdyW^Zq` z{cT|nUEp7;Sw|PLSIQYAJ4R)zpDRJi#-1H;%B2jAn^5S{=|SblwP8Pz)QBk)2fwek z#)#G4rhUc>oyU?gF#@+_>hRSB@RWuJp0S`@4Fq4vO~)sgYkXpvMc6A_27uF$3vt!n zkDKkHQrS*B2nppbQYaTWRX%8y+Z+t#1q+X*3q7n}mAl3xC!V!J(lJf%G4V9|QTtt^ zKN7@W%E(KIskXxCsaGAp!lc*3oyY5-;9`NDty28zCxj~Z@?iiEUOWw<_X(PZA9iJu zj|f}QT}Y9;m|KuYsP_vGBYTfWN+m+#ZgV8QcsFlnW{8GgEp!F^cj6w^*>i{W4CnK8 zBs`$WPR;a)XCGv(RmDe7-boIL3jY})_SF&qg`8S#2HFi!Vi>Ko<#N!U_I;Ss`9bXeLzfwRDx?7i~q zJTFG-$tpauecg`f_ut~EVXA}8vIyI6b4i7oHOQI{3I>$~4Cma{aMACw)zVssCpq5n z_Zc`}HNN(ihHs(oRtN-;Jj`_n;g51|63VYy4V}2xJOz%$XD0I(_%YaN$JoA8s3o@- ztJTcZOJ2T*1aPYlj92p28aN{ER}>;$dCew;yVl9`>FbALpr;vkv5GMNW0n-41EJgo zCuejDNk}}_=dHo*#2V|(5uD#)EiU|`*KLp=C)2~H7oPO(+Nsa?elyu>@MOytzR#IbxcfidWq?Wu zXZRjctaT4l3!XgD>FKSBISEt;*EmlWrLc_>%^cEwpw0{{@zy@yAsmt0*C?*Bl3E|A zDbee*a_e!)E8%Rqt8%xrMDzmDuLP@on`G~9H0eK)oDvdno%5lF|0ewwn(#_(^)6Q6 z{43wgmxk1x^X^-MfB$5Qs9{wIPL%(LpOrSOIQ>9wxBtlIRUi*4vwZi1>ffZl1RwI= z+{h0X{^L&^a2tX=r-w2BEf;hkdfHGH_5X*3mf%&mjZB;e`u|aAaKhc@OH)<<$DcCc zHik-WIS~9?qUZ&}-D)@ArvCR&gA{NZ@l>bm0{$&-azXlAhJSPZKg_-28R0g%?!V*t zj}iJmgZBTiK~u-a*aF#B)py@r``n8S|1mRNP95ozndA?yTb$0fcz|`XZt*PLz$Kif zkpGw@xg?R9JIQ5M&KSaXn?Eh?Zw8m(pZw2R^ofB%g~e9eCD3q8z~2dxlP&`5X+E}b zO!hw(iv@OiM*8c=RDMN$$BNbLs_Qx0+A(W*+;L?6Sbx{XX-d*avuAG4g06QJ@N0ts zo=6U-l1RbVP?~qrD6C_8`4OA{t}`Noeofg{m)WkTgLT@h!R>9L;5%~hzslf-05g$} zXRJTW5*a1l9}6^(S=)1nfZ1bRK(S4r&f4JxfnIHR>l4y)m0F`sVeJ0`K|3Pyd z(dZdb|6ch29T&j=pD3pFI8ni;w)+X`wyL}iwy8&)+iTJP!<(IOI2O3)P&T&Pl*yuq z&Pg&l9l*S+0PEPV`;ZGQW+fk7`JcY?enMt%rDju;7TxH3uNpHrmOc5a+l+MG0Q-vJK&IG!!GbnerM z?|3YUF4UY*U+A^k$hc+Ab>knY1I$J6(zGIqF5@iP)-A)Q_Mfd$NS1n(aP{tgYNVaf zKA0K#gGMN;5?&mAuXpz;Z~PTJ`eS*}MV3jU__8qr2>*x}z(0}%@sHH%_pryL`>FCj zYmvkM@4EQ^Ct76Gu7}cJv3`fhf3KHV6rEm(D9X$`p81GpD0p%H7ZQx5b=HeHONVfn z$p~;-J`xhu9qETbkg*IGcRC-oLfr^#zMq*%o>oGDqg22@YRA3d02hIB5GBixRs4)7 z5Eje{z5Vq`=6Ph1qoO|*)mB7t1CpT& zc0jNSZG?i^c+C0mVE^YGL_hZ7l3iG$*PZlv4llTxoa;Y2W{g{m=OM)%4=qnra0jzd zRYv(S;6ht9O9?!kO1wAtcF1n7Pu)nuM`M4zz%RVr7KkQ!%V#i}RqC>~6?`3tK;`ZB z<48*g=e-2P1J3Ex1YAaq^9+NjB!>r^^`9`!fo*QnTo3ZFC`$ou;GT^Jt;`aB+1d2# zR>YkZZ`vdEAATewSx9&e2Ive82$}l64 zCq4nH<_On#>^{^XydSrazJcv8cTkFL8M$;`{pkYE2Dh(@7U!=6_;mV{bqSti$tOW# zx<67S0b~?#8-N^miRzZ+0~Y4%%w*s2R}o2MSCY%Omc@xEwU9$LTNQyGExY9(n|H+K z^2?3P3^HD@Uu(T=YYg7za4JQbrOq?S;6vRTCLg+KRLBdF!wP8mCLSoDgJx_1h0%4$ zp&W)t$JefZ`+Dj9F%bX=RUG%=(No87M5DAkL)2S$p{0QypEk}+ z!N<-5AhARQg6;qZej@h6tDTJ2AGMSe>EVA(^%eU)ET1`g@8x%PjEofi04d%zh|icY zix8Q*5kujTgU3&XXr}EB_cse36(e%--I7C~?S}u`dQh9H z9@v68fU1DIo3isFi_b+2VL%QmkpqJs*MkgIWWA;2PW0$<$HBm%Blf>)9o*DR@dB=C0C*NKz<_G@8GJHcxZcEFzSz<3k$|w1-Ahp6mF~g z{J$O7dvx!4ZJqP{mHPHkEbzS3XxAh(PB>zD5cupr zg^@FIyp`R+d>fdL-$2>n^41V^q!5zsZ3oOw$7&naXUkoG1Z&+=wPZ^ILhnS?~s5gfA0o)5kknfLx-}4(GlK%b;$K$0A{azLyn3^Iw-Zd5)A?as8siaTl%U}ot zY4|F%GK47Eb{%v}eIx!~C4$XO~lXM{83UpzksHBCRg6 zS4~wIP87(qwC5+&vs{-jZep$!3=5_3|16UhZmK_iIU!muN=ZK{hfsB=$kL2$S z>_;as3zI@pSg_~E3cenC;Os#Q;e#W~-Np)lnc3L$-$tfZt*5U4@GJ zF+k&dl9njX?oBNG!{6O+5S3iG*FSY0wkl*oFCZHC2OuzhKVWc=>|~3`PNTF=vH&^B ztUfh8EhR8Xum-m+nU|J)H^s8v@d5}MT@B3qv;Z;_a<>8OAMl!}`!=j7ie7xDbN+HB zaT8&7tEk=Cz3CkFHv%BS=PMZ5_X(|QR;>KLf-3z6Lw?D1Q>mgN0(4tz7Ax>0X~Le$ zd4@-p3Y(Jqi=GoOZS`x@&c=If?7RJ9%bQ5_S4y|DYEyuZIK|OjJEWXN_7rK9UD?3Y zTU_D(p%%^#Pyt9q+ylj{)_X2JloicOZmE?GAyMKVDOVnhJ9piRC=u_r=c8yfrSP}f z5x~gptc#oLJec-jVJ0Nra9sU!x1-?NQ3wDI1~DrpKN>bS`d_U6je}AGPwD`*rgQ`s z_%Q}@l`0!7?b-9Xh^AlaBOH8&d(wpAO6(V*?TqJq_zeJoa^~!7dH}W{m>=#_cfsT9 z-t<4S{R<2^Ii@;JZk!Z(K$J3{BLB{M)!ZBBoJ-ej6Xfz|D|QHsz?ov?y#^`fGDuKD zeAJD0CgND1M5FUxc*C+9(De-psGCTwS(o?@Nkgw~-8NO{+hwKm@MxlHxxWeJ{pMDE zN^dKR)1UY=eJ&hLpEpSw4JH^?WESM;n{!>NxqIR-GkB#@pQC*kdA`(V)#2>H-YL@d zfO_hzoqfevkR9}H!=J=x!$CrIqEaC{o1?U0sI|SzlEo(oj*=Y_q#{A1tW+C7*!INlJ=ws-J-1v!0K~veQBC$peP?zj2vQd@;QcR`e?G&$`zBuX6hT<1+uhpUXVNu>U2t{74_SGKHLZ>RDV)I&+{HsD$(<&9R7h3Q_2C~%zWMud0r;rVek21y7696x|Bowt_ERc zOCogP-Wb>WLQ?#0vCr5~MRDMA^}&R#$f?(uU~YoGsOx5U>p>}sg8 z>7qMZJ!+ctI;Y%fZ|k=i)MFPjuD#$Jsd8=2?x;W5X?6M4@y-BFV|7nG?kHHf5up)|$1R zuB#wglokA1>pBuD~j#C7Rqa=oH{O@yo;;T?ccSuvkZ`j zLoOhADWHbhKUXK84|GmZY?;u(ep3?v6MBgP@H%`3fB%fQL4k4lo?$cb-N7+}CR<#@je^cnoj(Do=cZ&y{g?73!N4;n z>>VvXs0bNLkze>TIY^rEkefyv$Ba=MGhJEDgk?^X*PNl<;-!@5vNSpZeKTStNxcM{ zMV;*gCP&>0un6`eqe%Zu43W|VtN}C{LW=rp? zdT@=LNC(whVEkPmj z-nR4!=Z}{QNwXa?A}3Fs{tVZ-G@$&dXBkKGunKfE8k4ntM8y z3_T*G+30!0I5@z>$)4zmYSM4NiE&!MWu)BRxFF#%C0AUw$uv`haHAJJIC(#_*V?cA zGp+p58>G$F7+a8Pct|T?7J95sU9~!!kC*Mu{N@=>{^e|8?HsM&Q+*ssQ{yv6oKJ4I z4e1x&y27B()%|J%v)4d!^0my+P~d}w^U5qJf++h6I!T%11;G%Rh`pkR%DJa}TUlDM z)&aDpJ|FY>t$VrCO0hxY=D?fWo3GE-CgXKd-^47~b|Km>?sBZ60t68!%4Bo|g$a&DBf<^xY<0*4E4O#8an%$OCkF_D(#WepA{G>g}q{g%Ar&+tmkJkXx@|v^(Vw3L~9e+Wa{)MqIZyt#tPx|2lKySrYH)9x%}O2`}e1F z5^4r`OlJ`~l?M=`!fISfFMNN_q4@<=^fdzeCH95Ub_0bbGAY_#8}l<6JvEI_BzM@C zmFF;Wf;C$6nv44g<7l%*9(~?~dH`44xW@f$CB)yFUBU48$ce18FETRB8?TrSZFb!M zI@Xb`!L+mu#W{t$R<}3S%ikD(S4JL-KguO;3S`cFhShEY0#@D2IL|4sZ{!)(6jnGF zU6ctXT7Uo26H7pr`%2#%L$S0}ll+--vo;!`D!=`AC(p$~-?x)X*RquR3sjsoar~CI zCHL1frIN5`z*J(QPtEJhcfbkEV81a+KpYq>-dXB@{}@h7%j1-vYL}tCl;)GUIX_Ze z-iM|4+?*t-wln7sQOTUZz=NVAgMgO~Ah%MC(?8;(1AWEwg7}Y9gsV07bsAx?i zWM@OgqxYOdDBcc<+nFH$odTAd0L0oD%aN*5%kJ!_H*4G--|9NUikq6rN*06!;x-kD0N}bLoyxi1{8jhE&H6(DWLhl@mR@d)6S&+IM5x3i@$}EeF`xkMYMq?U(_aOc zPI=o39_OW(hTos$~fgRo4>5qj7QVaRr8ea;;8Dd#kEv^WlL zKsb{N*rl?Qfxa}l%iw5Whm{=korfTI-YmUSE0M@r)LYJG#YuU)T*b3cgu5q_Ugvtws@g- zI@plwa3lRS?8h>3;a6Q#=wCvdl|ra#?;nBgvkFn(s(`a7YC3 zoOw_NwWKI!;qtr!-tmNf6p9`tXuu<9jdhy*ynXu@?8H2g`BR4r0J<2(y}WErb-G@d zkwP1l)2A76%4cWo5~Ng|5u9>UA*itTjVi}+5FJ7Wn^rd70kFJccn{o$9p&wXg%hb_ z`7NKtEW*C1%;q`o_?Q!Qr$9aK3?r%w`zrsRZ(c&a$-bm6c2d=xN9~znhZ6(5Mn_h~ z+o7STFLW%ay6+o-$m zw*mDxL6N1bL@R{KT@rc+Dp9N|VRYBy1Z}OrC5GF1@`Y~PnagHdrH{z`i_O|rKEKFX z0l&-f7v~mJ_rOn~4M}h(v%IwNfuP3B#x&R!_r%fMWj}Q=>FML2PA4;X< zaO#}oF!_VBh$?fL8z`%rvW>wlvVF&Q@xskF zN4W^Y(IXB+evHNViSk;Yr9#L>E)r&%;fwCew+>&*KIal-dCW}nVgsy%-J(4Dz;N@y z=9hJKA_DX}ja8yFj!0&6>WAK|`pJP!K--&>D!B3X_SRbs`)rkhRiO8onYAY^e4rJw zOX$07mVC~k0RwL)Y6O=69bzc-D75;=26VTi4&O!(zh%66e{kf$4k$rpu!*hC<&CyF zKoZsCr3Y!TRPFn6T7HR!x`MB`=oq5Dqpc^>8cCvzfNdGTyN=`!9Sd23&qop&!LWJ= zZA1f$zP`>li7T#TxrCCMSaRzYL!xA}ekIUmryxeGCkNu(a+i>{y<@%#wOMBJSEHJZ zLF)tOb+^E#_aWr_)1T!rTL=ef`=-vl7!98@3dTwCq;0w)GcC9T3C7pWFR;IN?eEgW z5uIFkYST4CN9Fh$cse@ydnJ#lDf#JaR^?H0q~r8Qo8kn1Kn{ep@OVk+JO@Veo zx(*x#kXx}#WEgSiC%qqEnQUzXTZ;MbUB!hCB`;5%zSuC7|K9h40_wBKhiJ;4CS5Iz zUv@K@V~Z{@p$=f-;3*2Uck~*Xuj5Y}uXD@TIt8(DA;ls$Tj9Ju+)Tj;S z%!4kM?*VQD_TKPu!AZx6)B!|fZ*FzaRecDhHXrsLRGfhR0`3GQiw)Rm9-!$6XFiWL z1u78BqGq{w`jM&zru;of&-U%#<@+^m0`_V%1_6vqy$%k+DwMiJ zgmL$NWp;hzpLqyB1n}m|!@9W5)0F(D7Wtk!e|*NGgt!bT#Gekp1l zn+atYXK<9Sqc4yn5j7}Y)HSD*_g7pqc^*u%tr1%zEE~WYm^g^NB;!c<0+YTl!}i)RjXlq<3@nv!S-}KC6|t@VD40U zsolt+KGoIg5O!G3d_N}67YsXe=(!5|-RpY_%-rGnf@wJ6bMxwx_~7V(w{y53IZ$a+ zxItbYpxkK{>#GZu)vY?u{k&<8g7aK;dguyx^v3V!d2KE(#Jo1Ap>lgLR9yiRbH}Jt zFrs=*1-9J<+oe3$!{JT5_7B}1rE`h%q7&GB<5Q~) zP@+3Z9>5TC)S+N;32emzG7O%#O|(SqyKYg)-~JS&ktVlo)R>jv^mu6?XFBdXHT~mW zLFd_b-^AZRmwpf$4VUDc2TM*D->;qso1J|_dU}00bCv9HRjt}>!TVj>8kw41M~xWQ zBNrmxr>g*I<0PpiOOB`{t$Fqrnn*HD=9=iOKOAHjW62_u=#uWziyb7?``O;B6e_3x z^o@}?SK(v_sZqCnsB`ry)`uZNz%PW5Tz$3I>GCX|jt@Uu=LM-dtZ>0-fc(Yaonn$n8a`6+s{zY8Q1 zuL$PZ5tk2#Y4qOP;I$tFztbeJp=H|?Q2&dI$xrmmOrE=N$ zZBJ4oR?Rr0t9nP;W_;z!XcJ_EiJe8fdVQ+S6eD~uf}@{w4s0a6uDh0% zVeXPYO{TW!+*S%YmG3p~WFceIkl3w@r@SzdzOg;0_in0S_p|0?|BANIWX9gQcvni5 zH)PaF!jyONvtqx}DfB237+H%%n#lKSo$?%Ea&DcdmfwqfkyyKq%a{5Z zM_{kM-#0}zjjvZEuhb@srzu4I_h|-HQ5dlcJhJs zQ$K$EjSE>27fAgT384vIzwWg?3J@8(2GFedC{@uGF#yqM-9MiEJK{)LM}iUCEv<>y zkRIax&kyyIBZjF_G?odN>Rd3i_FZQcUOS*?2WEOWG8-=^WWxTPw!@3IPXl=I9{&wfIe26;XP z38+qPLuL#+6x+@O3!Q88+uI)=Q{wSZu%MEm(vo@tq!ZTkw?b=Qq9Hc1dku-1>m@_6 zu;nozzEBBupivTzNWiacyXu8#{&OMkI@9D&&b}sIsz0n_qpAWJH`vc}wWKck#U?NQ9SHQ~|W& zzVTyykRw03PeU(6LL^ii2-~9)5{R;;?bX%Ly{fNJfobLHwD~;&)65=a03WmSMr*y| zf$Q?lE3*VD;MJ~wp$jvZZ-@8|e5RjcK^=E7KTRiJua3mA599eV;_6>(PO}oOXRrfq zjF)w=-IhirI`lL!)k%Q~!Oz^gAP6{ake z3?%ih-&+a&j^zo|nZVpxpXkevJUKt4sKg8U(ybE-+70(7xc1&Ws9g@EjDaCPB{hEe zZ}71sL!%D3Py$~(Av|WeHlKfoe^nQi1RdB>9}%B)e8f{S`2hCPl{8jz|F|VqbKDmk zSPl&itDi$n1+tbND+j$!*8C=`q@GHgm z2i$6erprg+lO1+k*@WL&Bzp8hRV}O3t}_a z81=GWZNMTdczfTig%~vzQPMO+&E$MV)pu+J^#WfBo zMC4VstZDxpGMqV&U8@^6Wj@ZHDZz{q@#oN3AvwkbBcB0=C5OSzdpjfVYj=q? z*HN6|XN~f2ynS`E*eqO#O?7f+3(#}2A|5Lrd?pkuVPE6-JO&jPQ&l&Dg5I#HCRq3$ zY@07di)XUXtY6SW=@ID4e6%JYxjjaF?Qd$=B^ocaV#4ag2Xf9Fvb z_TrVy7y+)8KJPZ_Va`i0)1XND`wxVt&Hx?4Fw73aH&>O4WpQk=%AtC8XPkm;j8K+C z0mbPAMNCZzaHAq%e)-hQK?xuf`D9(BJYvgq4ExY_=s ztH@NzK2&1&%|A_%qk%BPV4t6z>9V8J5w4t`YKv#XJvXE^gNy!9>b(2B;H-41hioE& z{<+Bv7V|umrUw9rtB;``ro7@zR_!t~zNuApYJzzc;6ShKibI8APCubHZ&(;uh#>8^ z=6`P!+_A2_%7Aw~!JsE72PwxbvkJaY3Furf$>Vw~Z7hxqSr83no(jx=A|CPS$vJyg z<=7t~h03E>Y6Iewvdd?*eB%+HFvn z>7xl&YYZ=OO)EkjG^cEV6a0`KE*2&tI?yu{hj(2J_N}|}aG&Jg&ZEd9?|Nfl#9rcq zO$a`UK7W+zS-uPp`aCjP3j((b=g(qZ#8CVwMB;yjiRn1up}2pP;zbXnGob|hR@#KV zuRVc`CF{jKLD}25!nAq;qQ_TLgk6TJ7-dj&Hw4@P)WQRcfKZw1Qfyk+>9RBcz}Hk3R>lUj4Z$cGqrPdlBnN?(@H8SB)fc5 z95s-=r=ZstP9uO&3b>w|yMYkyK|85Doe6@K*LqbtO^Or2sV%A%dI9Z7b_$_i;5NmZ zJ4o;cq&-HfkhM4fjdAF`1w=ySP%0kfKzzzQJ{mzA3qbv+Cl{ha$rWPhlaD|=*bIwN z&u=~3%-zMIbM*l^I@=B79Nt4nn;9aff$p9VX(Tk;n@{^l$Z=d&%E)AP1Mn}Ll~B(Z zNb9{!(=VS~hQ_G?btCyA;FTu(x*k*F>?CpXE_{PR9YT z0p?y1HsU5><+=9j>6$uk(r)0~1*}z2=f^`lW?MFJv?YEPui6I(SCuaONYwP%u7|J_ z;N4SQ4pj|$=l9P~C&w#V3n|L%9D(b(hfs?HM1x-Tx0CU~$|yVZg#qJ(hA&?F3pA3s zhK~=rY~<1RD@)%%4SHWsln*;i$}X++sXOoH<G1OAMv zar_)BK209g;3t9c-uoCe^MmCggW0h^t~@|I>S!yhWlWNWk3z$b)B}mc)tZ_9XbSE`N^{L zkbwUpJg;OSXg?~xya$IFEzf<2Ip1*kh5hvY>+&Ty6%9|^exN8LSuin_9mBm_L*7Fs z2fPXbDq+tj^E?+XU`^G$1GNfa_mu^fr`b3~uD?WwgMhAV$nZoQRGc*z>uIHqT(3Mt?c3=C;7n8}glOUOn9(52qh1zF#P8A_@>joRsVz;rMJ@`zFWx zx%++xL&I4q-KE%SELn}Y=m>HJPK*kuf6!{#o(mA3Bo0ShQ&aD5?sxxWV>=m$K=H;8 z)aOXAU97sYT`ds+?Hs3b)b3}g{K2-szjIhg2!UM#c3!^$Mrj81RSA!=BqPF;!4DQI zmu{5V-1H;L7|$#UfIfuCa>QqOB00N`#Y@%mMM^2Buv3&CSsw*e63A$jG1ZN07OAW2 zTt-GOS=+@8O?{k$4vx?Bl~&`Y{J+1ecma`P*RqGU40z{T?UTwTGIXw7Ibe3`I(H!} zIy=S0aeZT;X=CN;hn`wMhT;(>g>#j|YM;6@>v?X}WF;+Sqs*RDmAX5y-m#Y0rk~!u zvM|-#b9NRACxAoA6tc#avM+*I4Gl*CQLro`J=11;NQEO&r#7zzwlNLpIOsiY+P~hH zz}xm4{~X{!`0t&P;xdGcFyG^iEut!)Byf1hnU7yi`1?;*5%Z^Ju&qHx*o|@+m>UdfuR?w zn(K|<-o9#ldiLhgKy|Nh+tngXGHsqTlBDVBDYm6seb(jdnCeYM8nxv)HWeokqR!gr z7(~`nHOZqwH!FZ-j_C-@a84;JPTC6aTfv;+pXTMX=pQx>K!v?}FM+(iZ50S%QK-H7 z;&x2quaLoQ%D#MfGpC6X|8?D7{>z}i8vu1ku#pp<)VtyWHY)wUMnxj30$bZ$xP(I} z^`#Pfq98nN`f@yBRf#(-5?upyGCBGRvbwUcS73#g`XM<@y1!HAw(5BUDZIwJSDFsW zl0>VOKBpH207sl7@`Cuu?&vHNMr-TSTO<5H=XP{yOC)>PZ~#c1zoBv+rut%PU;hXsIM%hFOI=Y(aJ#{ys~ex|*UL zS|OP9RZh*M#SR@3eK+MjR9^CZcoO~j1hAi)&;u*a%AC>rrw%GR^rG#~lKNjbdkoK^ zA=$fxkG@BrROdgL{o}&gF6=wZHYQUWy%}(aZQA$Qxn<|6>*!9slGd1`qVji=!wc4G zZLr{Z58WDG2IZ3Ij{XI-EtGSG100*TGV_`0rAHIyIUbZ|N}Cqy@n!Ol$>xE-9fazMg=|*EHn`bbaji zk0@F797H)OO6|xD1_}D2(~75lw1j+E#7O`mohtOH3DR}xX9=x`D;#fa>1LD%~%!jo+V7DisT*?It*FM4*0Kxv5XI zu~C`Ph`!p6z4=6=(z|TQ&$_OsVr=Igqg?Qu36J1Q&{v0PpzyP!pK1`l*k4g`)3JY6 ztzP_%YHbqqZWhMF4x>)uijh8|RDHS4AZmuu_ z`zhiqmRJM>s_FUmsiWJ$ZHUE5QNAW|d-mnyoo71jz0jdOBcjHe$m?faM5#=V1_UBX_Qhitgs&krHad3ZHanZKNwGJIau@*7P= z>vU@y7#xfrY_6<#2wLl<=oytrc&=R>By1vL$-0(X>8{tO&ZtZzut?&W;}Yn@I<^g% z%jxwBRY1V>o!CZdqPcJ0o~TIOfFmkDN$5AH>lURrm1u=WZ#}(N=q7Ws+RgTgqC3&i zkdZ7yB5?`(-%`mOR*y&TkD3dAi&bF!+{XG_yrCJ|;q$9`?>r3u`HDa4{fU2Z@Fd8* zr*1x2t@`IHKw&5Rx26(@?D$LZiD}p4d=VKKOcL6oq~_>`JmjDZGbj8yCykT^M+F-; zgWz8<7lplo6mIP_34MY86mz&}n}0rwJAqJ6%|?Gfgj3M`g|ECju}d`1z;kzppP($gDRAxwH=%GQP zsB4(#`Zq#qBlpypH;}Hgc8xZ6P|#pI$t!#JRb@FbvOm?da{?UFs8iss@i|Kv;{Fk5B} zJby~!AOB3!^be7+C<e9TL)=BHXbE_j~T$@27J< zoO^!flY7Hrt-0o!bIcLX^9(@a>O*#vfW!@sYmqzIfLw(I&NT^+A1gpgBb31KYda4{ z@mM9wGJk}m_tv#@W?i3@M4D+X&`7eRTHR#Os2C`NqTnQe8QAfik;JY8q%|97I@8Kq zQlbR+c2}j5r5_IH(;-CKZgOWflRH$+HoO=#t(qX|tV#1AikOLMboEzTe7WO3fCY!x zJ1rW+SSJCf$Bo~Gl>b9N&jiskC}vecRMoLI*V{e-MFw?#&_>%2TNo^L+Wlb=`)GR= z=V&24+rNgCnomoG2#2vJwXDm7R9>{<^0t>QO{*~d3%1@Sij zd%_1vEtWLd7E>*;$Qx<_i&P|@W22%O=IAt)+hX}NY9#U z?R|XKT{4>xxT8;$Tt-5z2?(VXh+iJ)e6h8_yAL92(WVdg9p`$o-xv%y8ketkQPAE# zPjtLYHj5>Y^z^Zxx8!14Ha*$&cP&x#~MnK;3k74EBk5PvFDu7HT@y|K@J zD$>y6`TPce6$)V@e=nQxMysK10SP7?0X8iorHy!s`uG6e`o-QngCHz~k<%ri0Uxv- z@QBxh=q%D!fss5hRSr%$M!oH<*~t-b6trRKO(n@Lrmp0DP_lV*`cbCVO{A#i%8S(p z3CSJ+j`B=G&7K9(j@y@XSObK3R8-6Hn`jFnWhO;Vv!Q_t#P~w^mfx$8eoWuwG6!HU z5xlSkT#jSQxDuc9)>0+Ai(;Ps8>B!&q=)3k9JdCKY-WejQ&%eShBRUQ=}Nxy8QxG?Lq{WwFiWVSElbZz>;C&@=N% zF4RmM+HpY1cOb=tB@3sGx9dz&P&6iD8MQgV>C=q&+b}~TX9+S0zn6jD7%s@6fI@KV z2oUz!)acoCmBNjgc#6tLt7~KC=qU=BF$!IPO(D$i-t0Y7c>?cd(QUkKwf=dhHdIsXlW0m2`y*;!b_S)KugROzV`B(G znBji8oV>HxQn8TL@EU@#wK5Y`H#+^uVuE-SQvuZ+!{6@`Y|f~6MuiCL%cJ+;!}FT} zGulHTW`=^`6Y8SRqxYtRCF%l5W3g0yai}l#>g_p+;>OcT)d5TX(A=UUlQ4D@iV^%4 z?1;D%xoMC$lPK6d+XybH2EH%z#?i0!xdXPQ5 z$JmP9LnGf3%@;~NhR3%gXomMbO3avtSEBNsm-WdJ5Ph1MNYb1JPq|scdD&~aD?O5y z@0*J7!UEr&&Iw2gONE@=JU&b4;4oRz5M1aoN7eu;@CUvpK$h6%ziEuR%>8dN@p-(WQLWBxUOQ?zyr9Gy)c zAu`xvrsq*mT+W8(rI;wg=GeQU9bIOYnAtH!E5V&5cGKiw$?W3%Br)Q;W^>W6cdjtd zQ@%s(LMg{@zW0%9gcH(fIUG`Wz0QzIkBNWj9Xa8jHU+M47Z%NZ)O~A}fU!@G4Gl`a znT!lbc-j#7y_*@vlS=2UqZ6?11>gt1=uEAM&-syYH#>dc_b@rD0jE?{&;Gt8e6BT5 zaeKwh{aU&$`U_}15CLeMb^++eb#`fLRDMqm!CSQwYw;N+fD%qQF290yUD|y-VfY^{ zLtdU)!6;b2_YY3!pt>mN6Ev$GH^^}@kKKph(#jqGGq#NUSYN8V;T;Lx3T#M0r?CDi zR9vCPwO#e#4!07WDcVf{bML!AclT-SP8O)~>K_+l4@W;?ikmc)0a;1=>SBBqh&=C? ztVi0;WqC+?WV660`o*L^2>ATqZ`8o}Tq%&~M(7*YSK-FVntBb=)n(t&(OF1H7LHCc zHt;BLmMsgtgXBEcJ^lN3nrJ$67?n{mT; z`E^nz>#k$t5*ZCWu`e${d;Y}TxqQ%}jv;=l2-;7Z!Y0EfA59;=`gW_3qs$2^ z_`iRzDS!Epi_wInWlZ>qC}^6kPb;3hk6{Zi;LW&v9jLQ4>z8t-FY7ri1IT4XW>H0P ziT*O>yk%uTPkS3a%tPQTjRCg(&**Z4>`ma>0D!;|E*AgFmqQH45>2kOo}h zvHVCP;9OJ~G6ULrq`1|NZGdp-dmmwR?{V&d52a~He{;rG=G3r9u|jDJ%E3f(-{ zR9zkK*h4){1(`$|wo$ylPV@i1HQLQ@|rblzV1 z6o;=jnC1UT{~OzgSa565>l(Mhgy|5yZ84 zobr%bs19nrj5?8f;14E>_>*Eyt3zj=;OU&@D;g`|h4-Vb-dO!1m-GU8tYH@)5-tSJ zB2P^ng+^*)7*`6Rl96EC{$ALJ<|6{dPy!%$y>;(aAoF&k3iX3G?;NI6I{nnsSl@=M(d1?NJD(rN!c%iix-0wv=^_T~rDWjp4l)WmC=dFn97g ztcGW*wBU1^Ls+g0zKrxaYeel>yA**;0!kNBQl{WYKO#B6+Vigkwhep{#^d>#XWaV( zp#&dB$&U=^6-N+36jZggx-kyOvU5)Rxq|m0Hc!N zzDYV0>$+nw;M|D`Ud0NNNL5&uL~rmd;TWG7bq-Qj zUPbsk^Ue@*Mk125b=hJjfe*GICy!7W$~JF~`{9x@9YQP6#q@uZ@epJU>PIH647uAI$bH??L|b8J2z#=*>?`$rbL5wkVI};A}J3ElZ{dVEJsl$Q|EUn$O4cA~4(vI@N zSnt;8Dp$X;7I5&QWQd%u-T#Pi5hkGq?|ZSk{xeL4?%3CtT)ve&%_S$<9;{qR-NWC) zuQ6<3IqMQa92_Q1NXV>i+?Q{pcR!TrQuxqh%H^{;FSW0vnttaC{+Z*iZ8Iux7y)u4 zBu3e*5*kH-X;Zt?5DjM;mPYH0lgcxU1x@vmx>3O$Kl z7oC5+Pp9``$tl^TlZ+hiXYFflKzB1N{V{Pxsta$nUZ0V*@x^zy=o5Lwe^d|el}6n2 z2z@|1OKhQ6K$-4DdLhsSf!XKfX}^Ph)`wNAhU&#QqPt3GD@@}xN9V695<3}n6xMQbAM!% z#m{){n9K2z3{Undbre_c6zoUFC^abD<(p!Kiw=lAb}P5aQ5P(4hf*d*-7@f@UK!Im zgvUZ7z?jz85g%mIl{wkXhROuhcg{U7%tHC~bK%o}!98$Kf&U1+jffPzmKZE_5s#*5 zs{|ffO-=j>)=%4p2oC0JC(9CqRwOJh0E-!sW&ZGW^xbE;UQkOB*w&77?o_E7hw2Pm;f}Iuy5)t z;%A;=A^W{I!-?Z#efQN5vD3ZIb3C1;wX%igYViU|DsBnsYNfVSw;-GHtwEl@O4Bqa z#auc&U3hh}>B7nmH29p?T8w%y_^N>monZ73S*XnqNutkEAIqK7TeI|LNBfhcV?Fhh z6RGG`&A*()vM_O-jzS6&JH3P=sOE5X+V{>5zeT(xF-D*-?&abW_fzfYU!nYFgxXhl zWUpkD+?%*m5gJgJV}J+hDV_zy;F@f1fyZ&*KG7lk`<+L{P(Q@I`})<-jR%CGCK&Wz z4$EAJi!@SP*h;qiT0~G{Oj1^>c)>zUh%8oZ)A%ZMSe+qzpouX8&Pt3-g(GSF9bR-9 zEBwr&u~(ja^S8b)YeI$DUsXCA>K^?51vpN4*p)@Igx~0#Gb!Ip)F9BJ3qwK@HFWwh zaW2eGU4iB~ah&H(_?)`3O3BWostgp2hBR>=*r{|JKBFsk^>$TBKuYQ~$rhb&St_G+{zb>9UUk)Q??S{q}->ay1 zg-x|F)xwn)-A$I#HcVpL#Rh{mr1Q6uT`qFCR1W3pIk3`V=LnOv#8j()JK4!-+Ak)r zaOlkoZa{^B*JN$f=Q54+_daHoO#}_co8l2Fs~!T`voj+1SLFah<@l{i;!Sd>=@*Za zSP6;kC+s2ep<r@(!v-t{Rgr99U5+@wD#KgxCK^J|e$q*vP*pAcv7V#T zU`+VTs>4|}Klb0}VTIUVx#HR`HPU1C7Ce209Isa4wPq^gaPad2<@SK{_;|=v(5H88 zV|R~wlbL4q?&$HH_x$N)hu#+9HhNQeiiMoZ3*}d8I%@Z7M>VkSAt}#CegCg4g-iIi zWY=FS3*Jgi%7t1b7T&e#4#o%lFUG2m&OuzTTr#)rt(@+)F_R zf`(!tVGCs{B|J3c`!#BKx+~+~UFE@O$<8)RU&>RDj*^UV*-$e3+?VW?UVWANe%-G> z<0R=%Hg61pXg5BFw8dGpS~c#=&aZsw-Xz#|KI9@D3)S)_F5!wdTCei<$~6|+94x}O zozYZ7Xqb=>YZGXf^%ZKkaEtuI%p~tKI@hRz^Gvaai5)-!pL2g-@M@*m`g2_Vl#!5- z#*ngDpH%3A4LQ0w;0HuzPbR7)k})%&s0jzB7V@KXtI%s))CbU67D@;@G8`$Wa|Y}l z*fK6IC7zI6Fd_!n{<-_QJ`Jv%6ARApdO6?a5LtU;-zR#@N70ahZ*_kJr1powQ zk$L7j9s;#jP>(-D-)c9Ja`BY<_8rgBDNVHG(MHH&Qh&8-H{dU&TbvprbhqecjJEa1 zS7P!_o`w2&_b2c-*_=#Rk(S0E$7d%~yrKXJGF4ahVFt=V_lZMI?#g>a9$MZD@UG{Z zIshhE$2^W;1FqW6s3>m;`)+v`x>$Yg$R~*KWIT~G+0Lo28Z6Qx9L_39l=c>y6rF-03p2bD;^kFlcj`B0KO8byh+=Kd+xbCFLI+i zeqcd*F{T$Xbm$I6;85yHAwFC}lq;Ne0IJ>jszWwiMrLt{1pWin0)^Mtb{BFB2G1~ z4yo0v0CBiw7Nch$SztXZ?NIkd%nFNoD-SPW1Jiah;Q@E1_1HIfa_~L!!;_W**6W-B zwjugqK>^(K`~4*WVA?vv#0&J4WbMpQ(s3@|OBW*~0x4c^fr0 zTJv_Y^PEVKcYsj;jU~n|eoI`~;Fm%Ky>fdU6TFV+Seq;8WPAaI(;hQDl{v2mgqf zp7~&PhN%KpKAEoT8E*xJ`iTTR##5Xn!)sFjbD5`4?|Lowe3mpIh~r`>_9q;r{EjzCRT( z99Cv89#2ypBN;+?*zWW>zUz|{4!S2!SMnK|yS|_3V&>@c-KaX8JvzMqdhOEK7J*RA zF7LPFdA4l81jdG->$>LuXUd{9^o!TA{Wm_8AAQkR)tIjyqaMTxG(eWJ&F|9hd=mD_ z8+gP=uX#9!RhS>cKSqCi|4MkPm(TYe3M4zK(suI<+MD2jZi1waDI}#D&`umr7_w9z z_EgSv8a0l6lW2n43O^&Yl+HbssHvyt-GA0dv4P9CFS?Z;|3;33?L*k*lmGF-8Zm+Y zx%&EaR4^I3j9SRdw(zcI>vx=p-#wVe(;pav3nYSkMepZYi)bB1`Q9!DJ!_tewg46R~*l?AM#4fsEK)r>cru! zEDwU?XSm~j%t14_fkF9z;I#2SFIIOAzQd%fR?-f2CA;hOzl(DFVEs~l-uh>!P`1Fb zK`Nw~rMufUqAKlOM-Tq~-#Kv?_R4T0lmfR~F#7*aR89w6q14A>aVF=(IK;1p>~LDM zyX|@8?Y)3xgca0P8Rarmc@EI>?-J?OuQ68tGl7#_Amfu|x0oaaiR~W(8D%S}P3j$z zVJu%%LGf-f?l~SCWR1BHog@g}xFEubV!RZ)P?DG86%{CW5-r)U*sP z2z9T%|Frk#_iqE0LIK)Q2UTwgfnC}c$D8Zo5WH#t>Jwy;dI8`kM*-2Db=OPM^*W_d zM*u4mmAC>GPD3tHlH_(K2#gNq8Fe?4)t5tcv|Rn6Na~A!QP0!Q4i|9oeiMIxz#&M3Z~sf>`GA8_X(xfD(!zH? zfr-Nc89&bynfD&d0rUzP#z^eSZaH4}5nTtg(siLaz8L^1z(k01Iy85wE23 zL-^i2yWvBydOWC1xA& z=uNrZ$-|!aKt7z{_kOVTm}or-5(*lAin3!dg*{KPS3x=I-m4%W8Z=8gLAoaL_u}HD zo9$}rI+7~_r0(QY{7|7e`KA@rxps?A{;??kvmtXk6QbfUfLbR+cQyUa@5bEOMsz8j z@ihyS=I=MA>viOp1q?ddq}vUH6aH|rEq~SpYr1NCsd#)p{uxi>!LF=hLOzl#N?`qw znMR=4uS?G6*zLuu=28=Ic#IKnZ^T>t%=5=BYueH6mF zN`%V3_*nH!x3FB|9nf% z>}}1y=NpJEl+uJlJ-H1yuFVvkqyYW*c(= za#p?K{GB>9tTU|}BL?s+w62c0SkmDuRwE9N!UuldRy(p%&iN3(0%hW4T1@66pZ;q! z(n>di-!gvwu*IlMK341W>%9+p)mH*{{1=)QwAH~u)sUE6oMLs|^%SJA06I{#zS>>8 z>%_lZH_Cv#^370e-G zLwakFWjM8xWpQ&gmjBq&XLV7cE}`k)dytxY0|ix^S!_IqHX3%imjaPVQMU%{kxJ;x z-;L!00LuEq2h12nN_AEA))45MsMQFd=nLj~S?h&UQ0(sWyd)SbAcvM5Q-)C6+zLUd z;Cp51b!oe>KcM|9Wp6smcmScb!`bJ-1A#CLpu5?=2s^e2~dzKD;^$x`Me~OfUeDj|@BWRL2DPWb!?S-;#=+5sN4AOczcv*3g zIq3qoIt{w{(n$B8_k##9Z@TX}eocr?iQam1$@&=Yme1L<_J@wdFdR_~pt9o3v+k}W z^w#)6)L!Kfh-2N3=_T_&Z?W!nr6bfZfn)xhOf^H7!-MxUTmK<$6u3Y;| zN)(+1WuOsbuU@gTCS_9woNe({?5UQi-972Rjif)YM=39xKtn1qG&-#|zMD5BKZMw4 zW3F%gEZ?;sy%&;u4`rBb*z~@A^bGHByak7EuilBo6l@IAN=1zOrdwmg6+|P5?D94I zz?4bp)B!jnI+$lYu$h(`EN8!R?myEy_Nk`9FlC)aU;32Wyy5k-OfQIJ2(mGAwWYro zoY0pch*cJ$QR06%*nRF3fi=Er%9!hVXSb{Bx<`oz>m@Y%ooT(TX@G@D)aN`p%XnUE zHj&4Dl={iT&Ubp#`+BGwiU-bH;B92aJWw5XzRQQ{yHwZ>g&!&vdjWcJm1;v{G2N3O%zwi6uC1`?P^) zB3SMRq1D3G)=RwBr-Kb<6VoR<*i)_r-ODm@Y~EhIeAz@w1>RDy;_wA!YT{#V-_Qp< zrEXt=$?W`t<+b(}dtcsAs1Z74#NlJ8tXON?Ds&fKh4eJ}z?*yf~D}f?w zL`5-QDt6c4dKh4-zUV6vJNy=aVo4$x`)4;tNBbY4%iQTyyQ#wO|Mcw~V7H4k+_3aa zy!2+1F3INM_E3=}zi2|RgV?TDx48A{NW}iYu?vPq=z+I3LLiSal&S;<2pMj43A#wPrETk-n(uy$ zOlUXFhBAjJDs5&umb+<<0X_1=GN@Cu+%$#oSq7w<-vmk&bSeYopwj_l%%zl2T%>pKL%sbOb4hz~9`G z&V0zkana^u^nW<0$We9`b-wb*2*E$c;nM5b&=cEBH~tA#)DABF_fRE$Vj+{WFQB0M zFaUY+-@^~S3=O>T>P(rx9*-St)fcFLjh43aLrOn)>EG(ZJ9>@7(f->ImWo_?0?&TF zbNtPo4ZtA->bU?z03>)$$>@}mFljsM)45ER%w^G{&a{cnMlVDsrpfFpF6 zSN;u=kwf=GKm0;a_&C0Xvg8ZskHkXgr~Oa<#S)=U*!8`N_=}-@rU>aFtuJCU2g$61 zz}yagVwIGhj8rKPGdKVDM*m08QP30BLeprVblEjRTMA9!80jFwas|D*WVv9pB9NZ3 zQGnS=gqoS|#$2zs<%^0xPNGKBxr2*N?+*zW-pT5aS5&Osw0l7`sjM1TmXhXdd)xfpt2G(rbAke@Spdi}NJ z(E{v+#<|3X{(usRz`Mj728fl&hY9x+Y{Ud1iNF*rH&zQyb_AkM;$R9mO+*1t$}iZ* z4#|18r>k%yVBI|X%NAeH>(&Qf_qv*p^R*m+0S50L19ij-9JVm1Difvh;U5VI=Db0) zSl&Sqxt~aX`qgbRGemtC2@c;>iV*^ntib(OAn~KuPXv4rU9abOymXb{*raSSAk>@g zFEkVR1q!o98-N`4Yk0_y5aJT0V`F3;?jDg!wQnF*CdO;aN$SPgAL0Q}HzczJ7+M3W zjkn)QcUKyM3i2HZ2dzO>&qlpS_f7S&7QiOMA3y;jfPu3t+0F;zWk5n`FECNbh0598 zn(H9uOTwlt_Hbz7IRwC@`O!_o{ANHsn*`+v4n(=fI|dTf6eQB?G6F}~Zov$wtn9UW zAO&G4hDdMyxD9=In;Wj!A;Cb05{!` z9g6Pyvvp1Hb|=^ojF7n{LGBgI;~k3-Y`92JJQaiUQ;yJ@BhjXx{8+ z-zr2YWC6{Gf_m9FxCJJaE@oWphaP$>Xi>3bzAn<^ilk_eA^T#-B zF$ClfiVf&vg4J)mumF}TPKm%LlURDk??nJnkE1dbC<51`^{QmXQ!d41B8)uGc!yYS z(IAor85P+xBn>`>cYIDdiD_DzE_&Z!sJSzcIiumBu0@ z>;+!GAGe*%>M5H~YNcF(olsi#_hz1720Hhtn9|Fj13g!pyUflH{Oispw(0ec;z5nq zUh_SL$eY&+ig$392w_-0+w`T8 z18E^CL&)zQj!$(2k03+dYjlWiUO+bR+8s?Y+3Mhoo?s%woWO-U-%MRcXQ7J9tF$rn z2WY;LP!Q#nNiwHUHoRx`3z7E=c6hf|ZGQF%FSZ3yK>)%`c5j1qq~7yM>{#Ua3_@{6 z^rmLf|PoTe6cedfLkWodRsX50fb~Gq1crf4&`?SleaHXjd_Aiqrk0J z!loDX0;E0rIcW=o5E{?eTP5VH)?iT8q%fu!KoCiI`;;*AfSGpFM z7fNSEkM%jSc+SD*?0*GFe5H|wp+95Y`HmjrRLj7nySwn{O#th~P!u`4u3sBVa(b>K z4utyeWD-CarRhM&m+#wc00YZySQ`o%P3Wz56&E=U;M0>^T$|f%14sXb;`AUW*#siu zy1T*@qoS8=9zCg3SWHVFL%RE{u~8Eq6%CH`z?yCZ5w|i?X7q^LrVqVO%P6Uz<(IVE zQ?fWM*d%M^la)_r$>wu<{YmlSwe0vSOCD8?ZUqw9%-(#ORh}MizwPmrk^7SCa7e23 znActL!LTnfwjL~Vuv)FcW+paK5k0a8#t)D(W>?3L>nnauUxn^GKu0LhR+Eib6NI~p z$h9nVBn*57lMV&BU@0Ge1rJyNbBoJSqnY);}A2+1&Tn5>N+2$M18w$*4mX6d)^a zl`N)h$04*7wz2`ALz6L%^vEP_N+`BMz-3T7XM?lDxQd)rf$o=bOrGqO2WU5K=Xxs3 zZqKKeLLoZ&X}J>sTO0)k@=OPL4F-}=Syq@k-J`aZxT+scVMju^Y%*Nol6{dea}nTw zVW7Si4ksGYJej6al0OjAd>YxoQi+ES=Cij{5MW}M;GPN~=lP+}^A6G&yp;H#i2eEo zuQH(}JGk9iEX&o%aLl9%et2?Svae)%0Qd)1li_;0*7~mRBSr0#f*wr}O@`ajVL9#I zFVg*Cr4(jqLdx^Qv+zvEZwX5LBd4KQ5~A|2U2-iw&`<~e*QFq_WQdOtFcB8<2Y z6ALdz-dl15;P*V^Fx{zA--leyvrXUCYN#Jb0>|Tojlihq1+MR^eDi1L+1|D{f#31d zS#8DRa2kW@5cXve2m=tG!@|cops5x^!I^qPmGvrX*n=0!yS+_GEZxX?!h27TT(rs( z61u0$rhsCf{k_ZrWNP(5#4c3O1)%Kte#5@7*pNFvGrj^?-4tpL2J#_)VTzBYpz<1g z!Nc1rT@g;Ym^O2BUZGVYpl>i2ji8&oyufJnut(VH+D|;?E^3AX-)!x$7ds?YrgIflhop1v+M?q$mbQ+#r!C(l4mu0vfUUBMo5ypBG$me)U> z_zv7_Xoc-%8bt;8lqZK|RTjU0NlYGv&evGuw_JC(?&zdY$Q7Do0=f0hgz(iP z`^|L@5o8>SyZ?^T7S9|ryalCx6z(cc82|e=tnk8 z0g<|W6mOu|N^q|a`=;Dk>GceQeirV_>sel#r<)(43^nx_myB0C1E|7{hY7jrA?@7N zBHQb}7&z6;pPMOrmMQ9ue~A1$))fWMU&^Hpb=Tj=QOYV5nhv@P%IrX> zfAfk#;z7FU%y>T{=E}!jd_`KvWOTA3&9<~P!YSpBy=gq5XIISkdswLr;U z+iRn{6QBOXDLjrDsU0{K%XH)rPE|Xc4|UdkOb^g$$pNR2fbazEIgEQ+S9ktER$j8i z$J?Y@6F99jWrfQ?P||@2fY6Nld{e0kpj2p=zD|Jp)9DW3v6SRyHqwU#-C1<)cUmG; z6nd`pmeuiCO;UZjk(@*AJwe3=vPIGuX-zcJF~;f+69k#vE%Pq9q{^wJilmMJ zC+F&d5iZG7@IfDb49nHnosK!n`-?K(!9*5ek@y5#H%Jm@f>eiW=MsjQy-K0BL(yhF zQN~7HXO_NfRa$0+^0=MVtWKs}r$ki-6y&cr*!a9MiCJ&}jbiOzg><;m%7^#~QjkbV zx(+yWtq5+jn1@tF9+l-?146j(Qa2ft>h7WpW5OfdG&6#*1Usb{l|e&0uOV<%Tz2wu zi6p>XV{MDW%k1dUl2`KUtnC%~qjwvEuWOkWjbb|P4Ty{%GL|d>vCh)rOe#VS$8TGS z6ZrIuGRYhUKfdb64nk1nZFzq;4E&;el~UXEH(GUoe2iS!4N0)p9IH!(1FRKqLafs+-nFn`~Uol+(>^$npLnO3f>4E7$LVpkcP|A2D%oy zNRSAIv9R*b*dB}Pu6=u{o!Kg|StAif3&2F)7x_}T9m7Oc+!6jKV9UaRW)lH~h)7U! zi3A||@FPg|bAVGUtDNnQErf9X~i z*bA1GE#L$Eu`l`6o127i2zzxSO&WnFW)fTwhlnC%(yl;)0_QIOc%X12hz(pWs{N}V zNf~$@kwykx2~a{w9PPU2OGvG=iL6&dTD^rp!C>$w$f2-6R+e>vWf_Q%ziX2oo11V|EoA(2>@v9O}ZK$XRJ8YEY&ruLaQU(2lD z=hR@ma-RD*)#)zy0%4LcrZObq;%0h3{~GDp1+4|jMM3gWI9oZ=3>1Jz$A_j6Q6dLF zQcn6MXE4weSvY*=0^|^@#MEY4HIyPk_I!&^UWy;tL9jz~3<%>J-4>dtI+j~2pOvXH z2G?m4lxjC7hr~U5&k?%M@F0TEU`kCI8^hU8)WY5~VY7l_XauxN{UU||iXoYkurj$p zHi#9Jp4~6g&VWLY{$5;jpUYhj>Gf0)8-$j%Rv+FTNm?Us^-&78Nt`3vE$Au)RrtB} zu9WUf0 z0`wb;P=|V6;Nk{`f~)J$J6FbWY^ArsR}X7RZz(;WU>?8fSLL>BxSZu#xa?O=* z2J|?6dv)@L{M;pi^WTPMGvgEmAI-h+h*is$d-RBblJZ^zI#;Fo)TfZmM|< zAG|--wwQV!m27_;ML=Lp!l@{w->u5~51;}l_?uxr@CLoR`~G-{?t&2*<0<3mKTNYE z%1_FWkn>uHLE7$q!~`wl@r#0KMPGTi^2i|ac7nqB6E{uzq#sx%sHR0Qkz5G7Uj9(= z_`>^Clr2S>3tf4Ran%a@xzXD{ehUBNaTMkHU>Z<8a5U;zTZd^wLyg zwuQb6{TDylV*8~$ENS}>$ZuOwaOs3$+*P&83Efve&vX69U(zSRx2>O@q3o)ENl=h= z@936+0hlcA#Fejbm?p3znu#t3nBP74&9nRZs1q;HzM}rQF-bdoB`pH=m!+qFj4xa~ z98jyEjRA7uc*fbIAD~Fwz)2QfWQR!%{Op5xGnpEuX zomxe74V7|TN6%vZeHe=LMQdeacy41yN_*3b^VcphQ%mbesYGNFumZjbj~xz;7?WMs z__x>SN#q)({#ixm5}z&q{2XqA?(^6O?NLyI@*a!ZXn~xbh*;;x-Fpc*B zmiC{nnT>>}KOZwhjd=c@W={jb!7nTF2Dbb3=^eOnn9OXGXRr8Rh0p7sI9?dexcZWD zWsl>z-6Q5DzSU$ZDtU<)}`cA{!>-G}2o2dnAdzi~C(v03f^eaC-Wvi}ozB-VtKtF8wLpZyCG9?M`v z&SrLE;TL#8tiKoC+*i938Yb2)A5<*$Zdb{5cW@rQpBOBnSTtwgnUb&OLy0H?B(#d$ zfTWv=^f&_ETm=EA4x&He)C_2^_zzQKS1a$Kj^~(*(;aQM1u&<3h zhC))KtNTjht1xz)CtROjsJf@v9nNyHH0&ciGNffoBw*+!!#_g;=?AN)UX(?mti%Am z1jCy`MBjr8(winTG_VOz#tAT^qOi*kHe5~$8qSFE3Hu?3sfqAXkiV#9_1a_p2AT~f zkn&~XHjU&urG;`)`{kE=E6o%gN>wxzdSa1s}By%tH4?(?i6Z;+nggIWmZRj`_>8fk+W0T9V9f28Ah z1OSZ&p+ge^RLn*eeimT@>T*aI5?Cy7QhbiApvgc$J(CcV;WY+Ti~!gvKF9}rli`=~ ztNAAVUC9k9-Wwl$na=QsVBg(fI@iHt6M$@tWGP(jAyj=}uQ&xX;*?`pWq(o`ISF_d z^F2_Gf99bj@_MiD6QpNMOSoJXXXRD$&&=rtXrX}GR9~0ZDU}{lAIF^D)QyhK@I+vH z{6cQsRp0RhFSJih%#MMCJtAuHXz&$t(w<3@3EDU~O7#MFo>)KPt+NoU8Dmf$Z6ajFzd__u zU=>hR1i`hWf|p9`>C;D{ zmvoMlhD69e;f6vPB>PJv6HAmht9v3RlV#%v7v!VmE<7mv9gi~t_UjEdRszt79ct;L z5zasVJ|v`#J4mOchDimZouIEhQiPNkay3&OQfMIxFZqyhcx+I8$#;$KN)(|TaeF1l@AcWm7(0NSwiuoCV{=D{c225D!mhoGDgctOHU4%# z{kbQMwe6aGE0D%mi1v4*-ZA?HRJlI`1CWa|zoGc6LgcLEp|-l9@nD zHC4@@>t$9BMq7J8_vU3@?Ushlj`p2(M96y_?pO(Ya89$>+m{5oH$r1~5?l`!d~c^< zBJK#(IOj>JZF~UhlFlI9ks?RS&7a?O&n24!>uW?Ff;jOf(?xaWBq@E}AZ}vAllbhm zKQ(9%p{=btUnW{dZb0>qCr-A^XFB+8ULUM57i6?}mj$Xg@3YCXc}~0lrTd`4H4Zs$ z`gEi*qrVf7<4P^6aYnY5hl`duzg(lA2k)oKe|E8NgA{3)C6ai-25+Nt@7pup#DIgb z<{vDm{8S(qKh02@>6%~2!FgkcUL#JM|5{SQXsfrY3|NmPaML)#H}W?U_-PEQpfpl8 zR@2VLJ;cm{nPvOAamaC!f8Fo!c#tKn%R{?J%-Hr+>YZdSNcpbf$erWk$A9p1dChJn zC8>DXtbARbI~~Bv&4U!dH4h~iCu-K2y76^U@4RXJddeJMFDJSEp0_Jn-rcT5Sqd%9 zdbQ}IBQ`IPAK7A11+&UfdRtsF{y^)4l)A1WYSgrqz_h>X;@fcawT^_Iba7Dm~CV!^{Sz9~*$eOYT>6&UW4| zRVyjGVE}F$SN!4H53iKPl$lPOXqgmB_nWD51@Nbz^40Z^Z=eX!-J8hVD^Zdapp zXR(`4M(>CmdOMWJc@Rnetj)>-8s|atRiz+;wN%mM>FZa81oKUnMy@yveibtKrRsPw z`nLa5Oqu2U)7CN(LnffEARY@jU<5b70g5tt^=T=e;XWwUtx|MO zaz2h&1Cdw$#cqlV8%XjK!9CM1wwc_QkUlL-s^QAR$KrnzQzkc*x%88-5;V@k_8Woz z#ae4+BU#RxsM(oYe&_o&k6e%Z3^bg$T2x;>;2$pg#WXKNW2^|IW9r)UDy%eJUGv#i?4OM*DpquW-N_Uya?dS~EfjMJ!Cl);XUvSQkT}h*DQ|}y$ z!h^#A`Ed;5TMI7i96u-SnIAaIVcBPWR@cFZ)pR9;Xlgzc>sC)*o9;b(n=f<`G#(tOmXAa3WE2?A z#|jgTFZ~{8fA;6*nk-$Um%(KX`iiRg+nEuC@!|9nR61Ie5fkXvvFSjth+#YSr~b~tPzq(O?sVGK)aZ<}_DxYTCXUaOh6AuPX}E73qsOJ1!r zjLXE2gqMTp8t#dk+AmlmdOl8GUSuj(-DdTWc=#Gf7OV@IC!?ZL2UJ1!CD{oQs@1@z|`Kc^Li`TT7$A7x3Da;agCeuY7}T63!_So*!X)F|44qG8<63+PwR7&7g}xi)(;| zNHpEB_Oe-HyEGZQejsb8MvPHHq?4&u!5|k=Qn1dG;Li?IO_wsQ)U5nj4RM37^R3Bf z5vsBjntdbi2c^DUzP)815UYOMpJ_jH#%)DhOJIwV+d!m7b|OUfvBRG$^{9}@0#0|M z^mh%6&3pv}wF zQoA6j8OcCh45#PH)7pX^6LjnsFLD@Y_v%v5jmRr}WPm<1ij}?hx6jb<@J%^RwgMZDo{$=-oS^gmR-@>+ z`qk+$GbQMah3uu^FKukhd$&zC_tY%K->Y&B^ASzOJwLPQP^fR|@q>5lMM-+ZmS(%# z^0$(Cp~WsWZX)g!v;ph(0Sh(>apBLdHrr0y6Tjl^204io2D69G>7v@j`bjIjl_P3Z z9t<5N8&f?|n5{;r^z+z`@4mNF1;)kcXj=O<)}V8D^+muZK_6piMZKjitGA# zGp9MI17#@kDWJWl{Nrdw>C6hZ!Naw-si+{|wBB#W&k$^iIWD}`;4q=4K43wKPim}A{LxzVS18I8%>3~ z5oNKG6kcD@IP{WA6O+Y1kJVk=D0u7W6nc)9hsiQ0PN}T^H6o(I{}yQ%-yN6llr@`ToNyKAm{4$)s6H`VN{Mj)oQ zvIrs-yk%=%I*%UYKL8?_%d0@0DJ~kDz&#qY`j4`sbne%y?r03UD6eeM*Sr@#(rRu! zSF8UREc*4&y22nse=?JDKAxd*v~tf|h?`!wTNtMJ8R~RUoz1T|z!fIrSZJ}m@>`F& z|E6Q7qiYx4Wt(6-X?tu~Mp~#0PqBt;g<@kD_0Ry<*8v99js*w|mbNw2FZlNN5rl|9t|otjtvwbASlf9Qkj zm@;~K($})L+p0Q;teDEOSX%^C!njSgS0tdKp2_YwLs*d5nV7V4DxXP&q!O7F%x)r; zqoefv!66kF;+3sCl~sKvJ2hXL@fo9X$2U1=lJxS;=KM7RipPZs(y=8Ox=s`}Jj1ps zrYkQS;|oF!QJwG7Eu3$p2glx?D6}!s>cAx@$h#XrTpbtWs|#jhfBY?w{I42_WXcbxHI@VKsgE-OgFUd(Zg?W>W&hSP2_4J5BS0(% zK02h)%ALq^`%OpPL@5j!o4CnVcV=sLcZ}@QFS!=6g8V+T0UovJ36dU3%d~9#I{*Ca z%I5OllcfH9T^U;0Oe*h%tJm<6UN-OprZ9Fw1N{d%7~=hZ4|WUKKbQ&7A@TzQA)TLGL+=bzp_oYgos_zwFdl@60w zr*;=V*Fc0CjTJ1rb_yphR&2S2xN^+z#i3x*xnvBOOPmw>U;0BT%QtdVX4F~TZ5YNX zs!=u6_xO&^pAxto7S4#Q=!7yF_dr$_eihD0ZVPGdYI6;_x!@@45F>1@F*UnrJEOhd zu%tw$l>WofQa^IEZkzs)X4fONnu@N;Gt>bQxEc;4-A1NT;&|t8;c=|yajdoET8$A# zr0sbrtP+emjUg(NG_8PbGdCS0t$g@{f{m)S{XspX(bTgM7Vyl(!h#O-%+@(Uq6ff6^3JC(2slGoojWidSTjX|8teeBJKLHi*rK5>` zxDF_99IOLDl9M*sj{Dkz+Qc0$X-ZWygf2VNPYfQ_qXI~@8bA0>N+MIX}(ug5aa5&pcvk8>N0~L^>cldQwqx0_jlRev&r+ytEGMZBX1AoeKPi1^5UDy za&2TEaGn%{d*)Yxpu{>TI*BelzYoH)Nb9kDgJ)87d+-#^4$T4}J_ev1Wn z7|AsXS;=Xb95ZN}Dbnovr0Sbk?^1;|DvC>{>!-ZLAz=QiwZuO9)>LzfX;(6>gZ^A} z^Od0a`7;5Cn>NqsUO22CsyB4Rs-TREsrUl2n!^wO7`?UisMk*Lu)Cr!mAbUYSZ=M> zordG5T-q_Qv)bZSoDz)os4%tJrB%plYR!~qJW#dlTELR2zw2KkU6{P*h#lHrR-w2#AUj6*DS1 zM+q&8l5=VVL2@^sh=6271qB+AB$<|+gJc9$6i{+#a+I7D$&zOs^||l)X5Oc2rl#i4 z)cmll((cnI?6ddU*Sdl|O5mNt=ndnX_d^jiv<(cArycnx*N2xU)UT43jt7_7WgJ){ zs(;$cQYAj~D@7Y`n(VHm^0H9PVmkAI*5)=IDA^Tz%MaIo)D+dA*pEYfGCSAr`txt; z@r98DgW8+hcZAQ=09~=;F!=1?9(%hSy_EfT?C47YOIw4JdkgO?%Z_;5fA^a14)-;s z9_ERrfbZ{SQu1`{`-|B9mpncmuLPB=F&CD`dMaY=ly)8VE-M~s+kY}vo+C%_8H3b! zE+K15LUJQGOCWdx0hzAfkP!V186xewn|v6|P}V|o`zXfi);-=TGc4wkmUdyvmQOz> z?7di$#Ff$Ez|>yc$yxCJyB~~h^L1ysV{a8?SpTlW@g#+zPJi9@PaOY%V&V66KJ23q z(iOVw%}qKjaNa1}DhiL&`?5`z=e9Ml!B5L=(-0?gS9Kv(DO+s8^!4*PViKMBo{mSN zOlM7psK>oGi_U2I4?Pis<(&*4+7iEO8UG%-E@gaVc>y8|f6EnQjWk3F{AekT5Z|<@ z@`U*=^s0T`GjYYS+041oUsNNWB=%dJWf%8i)S^#XNDKEn1tiedK)jML?&s$Lu{V?XopX+1PyJLEwPcc@pni06Q0SgIm%RRbo+au`kM`!)+?lG;Q~c*y(^}IbOxnA3c?*l7C#S6 zoh40MsSI>g7sceZZn^5=c`DWoY804>9Jtrfs(n$iR(jv9;ySD83wPf%rYC98NWq1k4ukcu&I3!No4C@0E@}dOx5yeBUW5Z?!g>iP5TBX6k{x z1-@*pZ+g)O;~>+5GO(@LuK2p2_5M?`15@V%NZ19eDGj;p{;V^o{Ws1oljT*J622Zk z;~F$~L{rft<{DY1CH6{R1Uf@64C?v^liRKOwc#pW!n*A$ERu zS1#qWB;Dt~#RQQI)?aJlh2(#!NBK}Q87H1U|DOu!Xc`qgR&W_TX)g}_Ee=upv9K-46P$ge_Ajj11DBDndh9Qb1M|uMt2apHB-w*j z!nsLs$#Jo>C{DBElJP#jE}mom+&<5-$nn_mH^fyoWlaIHRx=I7@cIfeE-V>^ z2lv0!lvb%yvT^tzYuk6+j&2PGRe5>Dt^BFrH*)2FfO5heDvczH(g6kAYt?@m5J*R} zRcZp-1`1C4r$1vv@~df!|I>=r{ootbyF|J_ZFr6A|BcL{J<93DUnce+!i zw0N7=hxZKK0WJXdJ+AGK@Y&zb6ZzsX#t0F+@JLbnat5AzNn^?5=~9hQlovyqyBfil513yXC&U9 zAN-hJg31`i3|47aRro%qiTU?@xvA2`bcR@)e%wtCD<>h2+^pR`H_m;o;I#FB&hJGo z37$N(1iJ!Lxm$YAuagvPI{%IlRmPx_Y7}q!zNh$q?t%#rH9k;kIuK(~TczrMNK(*` zJpE^YE&luE{|vA}eTN@E(r~kke{M?ke|yG{dty=jW%B>WBmNIV_W#Bar39?ch;QN& z>v}ZQJHW9mxVoG)JctQfBnhv_RD$B zgUNI(^-8gvwqp=)8+}bcg{~765;BktRb^OYT&Uvd;X11g+AzxFZ#PIUS!6=1rVZu4V2|ca!Sa?m6hfM zC}J=38C8FldOC4ZpAoRto^Wta|6m8y67`()g6!u&%5XOvaQQLwqZT2ClaBT9x~>mu zBrdw~nKkZjV;6}PC7CnN}WN}U(Lh;>1+`Mjr* z;329%RsaO1<~YUj_f7!5OXHh>`}D2RqBE=O-H+MX&j5DnHF3V1zZWH_-ztj(hoj%Q ztGwX`B(d(B3}%UVL0;e$yme`YfXK$)l<%S?LhkwNY}tju(aj(f(t0ote$un^-M`*} zD^$Omq*-H+SLv*8G0P&fm9O?ly8b$pxSiQBSQ`yln+l*7R19PmKRnuB0m7fYiPhC^ z<9%b5Kdb%Bpn1*-^iDyA`5A42Au`Jc)Po=b+2o7XCA}NV#DFMDil381-e-r!j8w zU$@UGo8$#Sg3bu_9-Q_RvrDI@Hj`rbPv$wd+#Di^Lds@f07<;DwI9IXvL|Zs7c#~I z#F`aBXX8QAg+zox{W-!{;9Z@5m&mkV?3fkhD)iKSgv}%RG)dcIhWTe z?<1K_`2`tQ&7-LZnc%TY$5PdMU|BQ*1z_rj2XM)pEMW%$&;1*t?0r#ZNw6amJ;ko4 z7`Irr=z%Z>mYU52C&DNs|IGZvR9L}G89zW?eVODYFLO4=+PeHv*#P1ft&|xkfQsVT zLRdrFzg(zBfJ5|y-R^v1@`M=#8}N<^Ibq2Q_o)ia!5k4wXAYtTyJE{NU>MBR7S-LT zMB)r>bhkrfO-8MBIm@TdkKtTN|KkN^TWCm*m zfAdDtZYtGICx!Gy1EX7Hi&#%@!k$P;VDV-zpH8sp17d~H!85KeKB;neWsnx}+JN7K zO$_W1oK^fXFjuKX)9@hyUFQlXv>1q+qHde(N(`n}HToW4iC5}!q^Y&IA53jS>pnGj zuix4JO_H%7RKe8A{t1;~|E0h01koNz_9~Z=()VGUo6NqGOA`8~bwA~vj_|^Ms@Mgf z_B6_0!1H+4cL)tDa05{;HRNv5h|}`S>5kNgxM8qanEb477HPUPno-ojc+H;4rDKs1 zQzVRyiF4co!OMh$TSL}{-Ubj#%5}dxLGITluS-~yqm>PVS8PH_i0;XWk#$4Yjxb;Q z%oDP9M_GLJ(U5zMDdkx@+g!89fy}TLT3G#_RtOk>;=PlrQ~DP-K#gEe<@3I#QLAti z7&wA96%cH})589kia?n#JaF|iLp20}H7iORH(6~uD>k55IkN36@Oa0@Z{XoJX+?LT zL8_sqrxfAwMW^z$Tx%H2d3ixF7o-mkbPo-To}WDIpMy`mnP^>(4J+(lWi&&rY8-X( zuT{d@;udVzb|B$wrdECX9@)f>?8-gL#^~MiLF3C z_H2Sd_J*n{%olHSB402LaCMk>5XX`mEnF}yPJbv?g^ek{R+G&E?l-rqeHzZb8kh3_u- zeVPKQpO$(-NwgfW$ejE3i$#AaaA{aNU9#3IOO)W|7J5CVm*V_oQ2CQt9684x7z=QY zJ0lIxZtnE{&}BgP>$CEGi;ek~Yr-Ii6Yc`p>$QRr0nhLK@i8SW(E+uDUjA)Au2f4@ zrHmYhQ~f6b`stt@+xsEc?Bc%JW(o1@O8p>mo6I?xwiq;23c}@w9lAhAi&+fz9ot(D zXbV|fO*sZ!vBTyY`x$ueGm6IJnM_fMv^!li+E$F{Rd155mLIWd{3ZY0~U0ZH>|6mL&OLree>q_A3<=RXx(qFLNH!?r%hRA9Eh$X|OFcvcl zFCU@1yn4LXXB{+Qg_bgSC_7bA$}88!U*o39mbva~MAkYfJ%bf2TBqN0$(FZhIb({- zPG3Ef+XDA!5?yY{R1WnV0fW3RZ7A$3GluiHixp!N+hMsylUCQV*QW-DdngG@W|tk) zD75|f`&-a0Xf0e4N3@wp!%A<9!`l}exn?r`ZWwLl0$0BsaVS-sDgX#M?YJEu?a=dB zA)0!@hbH%LzvN;!!v9B3lExJhKuL-ulCVX5v&(O zbVJZ@IlK_7i-vbgxtCPt-J1{|Yi#UWY;m?@MbhXHP)0cq?zQt6u&6EogAQTurBuRF zbYi?CWdj1br=u32fl@wC+1KA9X}A?hs8toPm*Em8fGCKbJut zbOS}IjGQR?a!i%1+`m6N;Y-D`~4Xk4!9YU=1vJ^`%P^(MB|(b=yIg8F!p6)qCv z4nJoqK2P2RY`(@OV|4nmFHKE$&qw zI3)Vs@z^v>PnWry8O&p5*n6_QOdDnryFMdd$S1<+K_b{Y^}iB3%V)uptAP%E<|R!JC6|&T7x%uy3Y@GX#_ZDMH#> zAAf`h@nM0B#laoio|w#LMy^UocPf_gyLFI5#i~VbUQ_whVoLf;8lyUkCh_}sD%Y9x zU9yTBVtRjxDnph^Ol0k7qN&-uM5Ia+YjNGIKs^dukw9xxTsNl~a+}Cut;f>2G_C(S zA28mu#DIs(Z;EIHKHi$x1|i#W{TK(+LfNn1^x0M^H{f9Dq>yObbfP=37Dc__g3qML zAo5cZ+E*ovKE-M4zeP{^7c@n4CDWN0RL(q(-+2d%xlEkUdST#zf^oF=US?ywN2PQu z7o5Z1&u765Mb5v8x@F(w=#QPDzte^a%*ZK#?)83q z+fW_>{Nkz)k1fQ7IXq8keKbhaoaN<~(^IZ)T{Z&^qGd_69ZZf?;`epj=N-h0K1ICDM*7W+;1!BE}4g%~ok@ z0n7;uUjVR+FWD5nm!KpxCo;6p9_~6W60W!~R7u)!vi9Zof2x;D{6S8n5iA<`N_EGq z#wLi7esSlNXw&j$NBd(T@oph}zUOXX$1Z!~I#gUDjiFP89n^Bl%EtNL3ic;YT>fqi zMw$-cL|HNY_AwulKRX{e*u_6^kXO7qBAl{l`wo;|vEe#JwcbTK^)JBqv{AqlP+0HH zDY3s>&PdRi9Bu3NpH>$BcB8w;`rUU28M77~@%<(?X|Z_sJ18lgwkmC%hJR5?*k6zR zU3ax3-yzlEW4X=e|J~}Y{UX-&OB)9t0OI^R_LoUroRyiXLxk?P`LI(Gi?um z5RGe=+;dH=Yt{#A-sXfB@UYbnnV3k37`k~Z93~=*vlPES&vWC?z6-%P{%S+azvX!I zK3xBYBZ&ELxP#rT6K=QmpZWE-uB83FbNio^F0?WCqo!}~fC%H=2KXSzac+%&4QT=&C3%UeF6tP5%V0!} zn^_!zzq)6UjWxYdYkU-rdJV(?O(52$Bh|E2U6C&Ou#X}FF=#8?&-<7Na^glLDoo43 z$+VyggNqdC()r|nMpEMGMQp(rfMLse0g9LB95_IC#}G*`4Gzp*C2bLzI@JMt+zbvg zjoou$Z?R!rra$s1HsC{p2mlpt6NfVrg4$&Vgj`5`)Ej2ip41G9T0IB8=M zQ-WnUi_c;&bTn_m%F{dR%c~M5ZYP?4YvMhKt<8W*tvGdqN9`l3*7HVa25=-}tWox8 z5!n8y=YEz1245Cr-ynO|gah0xgRpxW0yk|=v-w(@??C?M2g47!v9Br@n#sxX-iFbb z5;D-KsvFwMQf?0Swd+w@(&8Fg$w@=>0KuDsaO8E?+j>?RW94>AWbba>SI7eJ3sm`&j{sm_;Y97RAk{1s245f=Bb{^}$wRZ7VYVAyP!$Z2?h($F;t`TYz5 z7PwymbfyGu&#yhksF20;4)(`>BQZa}eQH7&=)2$!@D^(eQN?D-VOqRV`xAmbqX0`M zBH_)5WtVHZ!vS{`(ns|g%}#vYAjQrvCi|KR+=ljP;{Dtsam zGU3F8NB{#V4rvCgfT>(5NoW`m+=xIuxxAFUdZy#hMED}$3w(gxd}*kM6Ep`;IC4P0 zy6M9@yCxt;Er^cm>%mUx?i~FlsC&&hD}G+T+ywXo?M2nAq*qQ$g4#faZ$UE!3g1qE zJ18#YUeLW->GH&4ROM>Hpl1C2s*Mz(tLv4+sPF{!_hvGI%+?TzH)(Oleha+0TEye` z6w91fr-q|<;Y7`9@k~>LCw>`pKhTd(!ntvQnb5RrE@DdN^$TvDz`YYEyeJ8?@)NJC zlK8T92sk3tE?&V8O2X8re|)TXB6R=;mN=P;>pDO)U;Ol9M1w@y1B0k+DG8icAldF= z*F}(0u{A*q{QP#rAQbOV{{+~wq~Edc)O;gJ3w!WVW3PFUkcv3)E|Zxer-0lSyYd2o zXx#~CFym^3$kGY=BqV;ArwJ72Qa#^pmf)72aVBl*Vbhai7<$(V3|61goG>{e)MH3$ zH}d2lBagaYW_UmFoBet{_I6??OaMy@AxJM5?|^bF1H3$?0uOf17t9 z6``x|#Qn}EHZjg?^E0lF8i9xdWt-yjSzep8!lBBIR?KVOG1;fHc7S72Uu(QikZVit z^si##Rmr&9`5npN8rbiRf2|~)ySwc|!BEsv+fgLj{TzHRyDcx!%q5-ddlH zT^u@E3C7V#Ok%OmRHZW&L1&um7JHJ=AmtpHs!$dfGdezUsAVu8PyVi$73%zxxy1!^ z`zX?BKF{(CT;{Rqh`*(2xGu~6bT2>#V7_;ttvwA!j}|+#oSHJ$;P25Q-_J~Nef^eD z6jy(?v zuKQ-vaz(oDpq}CPh=I=)(m1!VmnaX1O=ILU{nzU5F!os_;!iz2p+RP?&K6~sgSdZ$ z`mF0%YFo-!YE!JwikV(sPqIXHR+qx1ig~L`wxZG5+SoVZkb9)aW2`sqoJ&nQZF*cg zRg14&H;BZ)gDp7RAW^}9C=sSEgazG@>A3K{qApqL*>u$x#;9bD!52uP-`y zKdR%qe@<{wL*1bGikrwJ7--f6IqexRz4{gD4U~= zv6kwd1nJb+LD*d6C1lqbD1nV*Am485yQVE>(&^-nTi(F?poE5(ZZMDh(pbu2V$V4S zR*yq`o=DpLOlRh6N$0kf*s%)>?6eIoFsd7Z>_Yhzj4(9?_I%t2b1-yUvJX!*57S&s63!NlB&> zS}f-T8pme_jJEiP7Qm&3s@`B+uxNMATT(&3y$`nC%ngTJl#`e)<0FqySQ>CuH-B_E zbmGGA>-0)F6Ty~Knn3@)VrR4ZVA1XU3{sJ$mq4NLNbQzEHOU#J_}KeR^~(qGr2hT; zQc2nwhsUUA+dKG#bie*aITd_kPv^x!frWThxfo19me8~myLtCmYkE~ zaUzz9|J$V|3g;+Ojb0Pfn1h{*ZW>gIU(WE~K}-5#Rpl9zu2Qvfb)z^zcbadOb8tdA zr9n*k-MQ7F2r5GDUJd#03%tsO-qP?$o>lGkgm#r!J8E_-gg@rvf)d3JfH z_tn5kB~3X3MQZHxH)FeBEQ6nwOFq3GM1th2;>}{h8TmhH7$4k0D+`D~BJ6fFspMRB zYQE7fK}%L~`ij684eZ8qwd*{jI&x8>GAW<767P4YzP4d(`Dsl_x01&@dr+aEK7`Ee zpcmy^vtL*T>vVJh9&i*{J$`F<)ANNIK~z-f$ndkrXP6x7zy*CR*f`X8+4^Ql$FpDf{oH%S+xW%{TUQO&%Or?7(ngt=@>tsGM{>9 zR8q2aJvsiH7qgZOgH-m*aQ?I+oBSGDHsQt`65YHDlVtW~VK`JnnN$1QvqNJ{Y76*Y z6qeTQl5~W@Q-!#uTdfkEchiMpNn zNKtN^v={6LLt)GZsGny0O=>_vNBdwa9g;Ms)V_oI2hHaSM75>)uZApd|{5h2HH z#QQn4oX$)TdS4h>?zh%nH*ICFgkXvWD`=gdeT4f94Z>=FJr`d^JL!QEGKmbi-#jz4J#_Z5|r+0 z%b~TXMPaHd%w7WQ_<}^kPpwtzG28K?;4eQdDl~Ks@p?v)WTDq4_BZ{C6|}~nk25k| zQa@q#xUfo_7{M@+9m@I1%Re;l9H;^Mo-;T_oZ(7i7hsz zjJb6-ohNIRf3~g*`at%3sG{P#p^@$MAMb^5LY>*gK#VmPK@Ub5k$x+>lA)DMeR%c< zvEb<^uO+=75v6&Be%4$7uX9}bbh`Uj@A4%9&o$w#j2b^!U~d(G8Nz{_gW)M83h$7U zDk==;P5=CsNM8Y}s7UiT%Mkf()`GJghSJirm9&(Gea=+8PQ^K1Yhf-Noq5!hgiDRM zaF`KfCdHH`QBA;U8H7BN8s+dAg$TXbz!w`|v*ywjd`?W|)o zog(Vx>{{_6>mn2^P%-jrM@&)2{*AxWbUDPKGf zbTU>9#suJ@QgD_M+H|_qyqL*TjgAV!m|Jz7ft^aL*`>8Pq*rr=((uv>yin{B1UGCO z$ArkVoVt)bM&k^r1^IH+C7^ZDlc{*M_Brg*irF8;*5dMynxIyHUF7IK&hMS8E2!H{u(=gqJ}o<3{Ci(7aXD&veUPRo)zq-oKq5^kH%Vp$%& zQ%IzxTH_2M203>N+z_&p{REhL+dr2OPjFjPeFTtyES`2tlOw(TIFQ?T&v!w&XQ)7$ z=Hr8Ff6gg*7&9zuOuD0=h3)E74xq{J8aER06)O^ARgajb5O`&i~nZlgd^3VHQf^kmN&C5S8u zcK@<7lcX<`9A8YL5#_9=w6*qqRZ#V4DnH8;3(F(+b^Qy*0}9hK5@^Xas$@rdpN7Uu zp^k<=9DSN|?Qt z8U+s}0ptNZ^~1l=2TzYXoVGk#9v8-V8MwQVml#CELj-M9C_>Beh2fYO0tMd9EVH)U z0$(AF<_K|SejBbLdwk_f{=@L;7rdUE`Q1zGPzsvPvs-Sbgg;mH3mHabu&JBnM7&yy zQwVW~=QK7rUhz8r5F?Y$(flvog$-#PH9I`(=8AW`x=1vx4c^JhuVs|skg|OmN0UAA zgm_rThQe_D$6&0pA}^Cp!~3)eUW-P3=^6bgeUn!=@8yc8GqGjk(sg^1LG~$%&y19t zhKfhl+z8&A&YsDO-D>y)Veb4_)2pZq2b^DQ4W4J-FNesL4WaBTfmW(02P9@6FYyEJ zY({lqEx|t=bJO=gk;F`Oj0ss1=L-(KVt%ZE3eIrg8XMQ_kO6F5n*e~pu;U;TjAK#u z;SrB&XhhoDw{iJW@Kc9^e{OW+4-Lhh0%%k zV;BoLR*g17HadFlaCjuGO3L$i+S*6m;QL(#y_6?P;2pc{MFPk*O5W)-M+s!2DdD0I zb?oau7lbfL_mN&1DWA@`q(YZa3bIO8D*e2bv7{egz`6V6#Y`bcY!}UYWb3pp*)W#2rP{R zd`>-l(Qz~VU=15W{_c2qjkg@x)BC?Ic6v%yj+@MEKcv@t*Gx8s$QqM$v(1HhVT->Z zV!Uo3+6T&S+wTwdbBLVakJEGxH+r@9h$bN@oJ0e&X_Ka@s_%qWe$Yl;QLfwh@Kg$2 zvaz(=++dtG4MP%I@yDUV;M$qb=b$E}%UhMq2xCDpBa(lW(R3+c?PWA()pVc04WrGK znFCikUCwf_#sY5H-#dJi!_#&Swh~sJQogX*lT#5It7Gh%E%{lvZJU)uY=4WCqUnGWky^d$7j0>*2DC zVrVsrSZJf|SryZU3afpYWOXRk`l{RJuVDJ9D}9P*yXa zU=<)!netVqMmybO+TVU2X+_a~;qOqDuMavW?O&^48JK3GiLEMUMMs>G$$0kbM5brH!_H%mUBYdJ?Wd&@Je=^RRCZ>_?0 zlU_dCDMM@4n=&lJ$D5sI%4QoLEB<}Jmvg^K%^EK}F_@x9CrS3{!X~E?gI6~|IvfHr zQrXRn-a-5pUJ>QqMOk$J=l_?niM8+g%5<3_^+i-gAvj`wekphA5D^quhE1AR4UZ&foBoItjFFE!&A#_P@I-X%`5+BbW^N z0#5;T(JNohVzu(j(s9*C;kN-^Zp1dJ+x$Ma+foez`rx=>7AU^P4X|HPfkr1JGtAR} zLTEJ^_vw|#AXB*&3b#vV6k04y`T5=1gD;&jpfMe0=Hx$&Ws$4rX4u!+yw~;?V z^9ZLp%?)9W=NilX%eh{H5@`9s&wmXdh!Svx-@AD({mb2Uf**1c{)MPH;2=OZ$Hqgk zxi%MZ{9g|EH8}FMQ?CEg){B$@R^PH$Apeh1fTt8Q9GUru#NUH}X+$6BO|o`GQ=a|P zn>rf^dm!qAXa4O>eW!sY0@3a~aQ0~UzzW~Da}7pBBN+T>=C9zyzriffmKKMA!Wb^> zWWD)&kL0fJNHhe(P2(G2QHtqFt5?Ul;$*Iz*uU>8(vp}5s1R`wof#;zJ1k5Q@)*3e zVph80R#(Sbkze9=+k9jPz4~a_`c{8S6`gH;BW>a8pmCXGYiA4UA34?!;CX3GYw-A6 zaDcV{LD^-a2_#4WA#|A|&bQ7D&e@CELJwjN?bC#21Yq8G9)7*V_RvTiU_%~H^7n_3 z?3!L+!Zd;A=|05Bm>~Age2676;1?_kFQ*a6o%_9a0_6yRl;7{juehbN1PEHV(3P~eH$cXeGo@p$UO)>lQ!b!&c{8D=idI>*3AlQsO6=^wM27^Ic z1*$55?q_yUX&rU%Wbw$g;9G1~VM z+#oA~Ki3em0*!z_{RiC_xSX;Skr7W)wKr~H059gP#^=xD`8CJ}0%y#S7(@q^3%+;~ z|GS`_bk%}C%&zdBvflcAzfOz-jNj1+kIt+yg2$9**zhS;BZ8hKJta}_rXh{+*A}Ql zRLaa`-0=rNsr;lK-XCY!rR+mOG-H!#>(RT=+7Zt7K$1#A6x2wCLAspy@+i<(_~FgZ zD1#1_Kg*46c&M*>+nt61aQ-4}BnDo&xQ>$hclnHK{qwFguR$N;cU}S1*&kwTYZ)d} zqHTDQ_;X-unvdJoI3TGh%^P7pMO~PNEco^hbL)=bUyEbXA#EF)y8u3Q-+BD)`D9^- z5+B$DY05fv1YgW}3RI4k7_g?BeA~du2Th_E8*r1ax9mZ{Vfn@&!l~i$7aVpznaF>= zYyv5*V;DMzDy}p^o~)StRh!p$-OHQ+&_rAdE86b8*T!ukZq7FEcN~1;XTO0v8x`?> zG9}^BHt-^UoBM1WfkyjDrPElaH)_(!g$qr}p(NW-1vkN5xPWKg+yy+82MNwW0#aia zW&o*~bCvY!65D|r)P$JtM`-oXOEuLm^c7{=WfO}=V3y-QO}q{4#!y-v0Zk-@2;DMJh!4c+dn<$}Au%x@c2t@A3oVTc8*lU+xFdOu@pWo% zJHk=~6Zv#x*^CyNScK*$wKyQ}eW@?cuqN(4Im_G2cePj%iVOp54R|~wQZr^8ohizyrw$@t)2mapan|B4&?SX<~ zA8@~~FkPLl-M318v=v~+F##h>rVmJT5|21WQjPCtGDVoIeLAl!4dfT*Aijsb;WaX8 zg=^oPR$y0{xaQQ+x^99O=z36}iSuSDnNeO4_@;=71>b0w7nB3wySw1NR<+0^m5pPi zN>9B(6HCN!?WEb%I0AZaN87cYVl=G1DR!^r6A1l|!nECLj_TaW^ouTkDo>7;?N~(8 zt6UyK0VDQE|AuJ>@t#RjqT&r@g;Gd+RfM)nBiM19c~hUUaV*P4x^H&JwC0S0&wdgH z{;M}nDRMQwt49M&Ta?E6p?A&qcp@!tT0M3 zyh#qn)LY0N$vvm?(RA}Ox;*HKmY;I|1E4_*Z-#sewmj}}Uxks;nC+8chkOSrW5NLz zc{Uc^|v-5TdvM`+5 zGWLT_`Xh%r0Z*)ISbFy?8B7m~2JP*ERcFeNg)VB%IccPQcDy+2I{y@$#>ov)Ze%Ji zRxTuW9o?hWIagK9fkhKzi%Xuri69Bx=(wqetJ}cG?@{vVVf8iGngHe8c^6Ad7y0EP zTEATMeYw{*THm5C)#l^9Yb%MlZ^1P1$F9k7w*VYGq^t_CWgEQNp)K!CiH(~)T^ z8h&=W6xuc<4~d_OV6%@Xw*$-Yt&?A80<`3RyM+<&(bFq(?NJU@y*nr`bV&o&SlvjH=KlqjTREZudC#KxOj`N+{?-3|^YM zo{?-6ykE>)g${ckww})A&;5PE{a!Nh(<z?*eq_~fRpH_nfv_(~5~ zL3)mbhtuKn&Vp$trKY&L_Kk=njab8=TnySoL$-9t;Q;DBf~gbnVa8?uUr!Z0>&pOF z+HgGJ-c?}Uc|POEC?RMPxe*!$rYO@^?K`$Nm!We_X8PVx4 z(nmxtKJaLjDGCBI?zeQ<_Mes>thDv9=`oErk$QSv+ETK9{O0!%w0c7{#&^sc=E>n{ zE*u%~LR^FE03QS3vbDtdFk2 zcvT;NX^iR&PIbk-l^J*d5o=;~zw}s$^~r_Ml4KCN3JUXRrZB!MNgHF~W+GwQ3{sXF z+0C+EwHg@)US9ka;C;Ej`1Zk?Zb7_2r=kx(%i4qlh0b7=}^2lk&9di-9J`fc#*}t(YPV|_}X?)r4220rakRZ!W z&uv1E7>7#&znt#j8K~jUrPs|1ip6qhL=qLhQ)6d{zw*;;ZFY^TC4^Q2 z^)y6GQ38t>ELC1-_bA2)^DML?ewMvC6Q;prZgu=-8Z+S?`_jfLLvn)0rE70xn-8@H z^-=RV)!*%ra5>#ZIhX|So3^|@59xIL3C;Oyu%{6 zC6o0(H+xO|nUbiRJNvd{+$WFl@-o$LZN5sXh}l(N5t zJ!e%kl7^G#Qx~|f1TA-m+PSa401S!Uf>qbyb$)9EZ!%bv%X)0H?u=?-lvK~U2B^i&5x`GcIgv4_2K}O0i#Jv^p!C9iq34oz@|2@U}GqMWb$ zuK_gr1UwhV80$`$B|TDsCgQVWO@f>PX+`o*6wy0rkRP__l8)_Jgf;PuXWE<0=mh^G$ zH|yf_tGpnjpAiE^(?fwQa?bV#B4jFlj<*I0&pShk{j!@E^gHr@pLJ+Aa@HRqbL|Dm z3B!H+d1YW{`xzxiJzKAVQ&VXzcflC;yyvYFvVn7^7tfBli)}S7Ss6PixGO7PbLBpo zLT2tIxoUP`u}dkjBFyg2DN+lnthi35?rRqXJa>65+U~sbe9LT2TfAQ}3J`7NCI(9G zK2ELaY+?N|l^7tJ0mh^YQbDz2*R$CcGPJxM%$<|LU&U%*2WbVR4dgTYN;cUioz#waQvHseH42n`6#y+ls+}>`C zhNy+BA%-mP_=G|~O70W($#OBF#>ir9dNN~xR_gTKdUlfuG)`nzY#v%ee_u^?q4KJh zWa5*R%yTsKQn~vcQ$MkSIUjl($bQ)F$x80q``z!@)^0rKCjAAJ6H!TbOmT83;f$Sl z2Op~iOU~X59dAICK-$;+MjxAf-M~J$IzhtQ((2 zr^R`0m~J)7M~PAVJ+`0eKO~L6pnft7XoWw#Z%xiuDli>YJ8OC+T>>sj%FnLQ!u#f* zj0xs%y9iV7>mQq|{=m^7Kfh`F>(^M|pao-p>b08(#F-TfUMRybOtW~h#sBJhZ2_>6 zo^1J9gWK2l^94`Is93`_hIaF0&q5ZQU7S%gUD=m|IM>46M9CymR0n73QY5qnDDuNk zv6_B8BaTtnguc>jzOl1INtLp!SLL~%l1qO^tVT|r8*2&6n=rM5&SVZyYg>>goIf>s zogf2qpE1mwd+j>saHae|lqBy^i?67tUWM7}becVpcz6l+U?&von9#{hRb` zx0#~K+`w~Pv<_LNy4djj>J1J9gk{U{@};AXet5ULM|@Q;OIWiEf435mbcCNop^|jA zH*JCTLt)hg+qvk+u;QKrj7fp?%A>V}fDLoG4}Euwd!~) ziz&W=>E0@&BpiPaSVintG@~99t%=0<(vO5G3ztCLp+ALVeM$J!c6(WlXjSEcwsk4_ z8(*KX@joL`SQZ;S;pG93_#PBh`^i)u2`p=5i_N;@Av)X`IpJ4M?ZMm_qLw}{{Dy-d-o67gV+V%lO_4M+|^@^d# zkbY&~9$dzH>B~H}?T$TP@3mfSj?Y<_O}|Vh9UBFEczGEGiuJy)`vsMwA_&)<=*ofF z6&BZ+&ti*cUYi5c6qQr1*Q#u7w-|KU?w;*9m&hsTkb(8Qdin{11>gQSUeYGk65$eHBnL4S-Lq8p8VEW zE+KA4FWyuo^9kobeRO#I3%<$Bs-@JNTNCNTn@@H&G_>01Vsf43p%4={Sybpl%i^KyWPmo{aeFApzqS;PS+hEL)NbA_0bgHSR zOTirSqM(gI|6#sUwC~&jC2R!X5zq1}-9@K`tGmOe@Pxlv zy${DT{lv#tAR~7KI;$%mMmV6^@&tRCaQW~I!+XrUu1w3j6aGV){UyeA0nNeUod#M< zU;q}X1cj5RSO9VhTGPlaKAL7fPk%m9L|=>{{TA$T8V`ytYAdWA^ zKYa~uPm4bd4&*0H{NYtGKB;8;PXhyFNgyux>-X}+A93xA5wS}Fwz2ZSdq^}(WqksT ztWwLlYe-N>#*8^fK9Z9LAw~5Sz(P;CKU_5l07(m@S7Z1(=!tFL%ePBiJ%{I)6XB|p zI{N~^=7j3vO{B$!ls|t$M-Wv0m8JZJZNNm$fH(fAqss}T-0l3q&371`({}cDhW8?Y z(9R#2DnauWJ%a2%=G>#Li?61)0wf+2Edw~Hyxh~LXM<=-Rw8I++pj+V4c3{qBPw1s z9okcf%)U%gu*>8gih{eQ?*W*`(dC^`r!-`D6*xvtszcLx``k6SS{8gDg=!81I`e$%!u@w1Jf6wt#K-*k?u5@SAtZ2l z`LtK3o|CX=pXc^WwjE2Wm52B3@f-_<$R|J?J|Jz~&_3~0atbH`VsLOd6K-KgV3~eB zf#44Y_wXYYl!lgJz+l2N-4ZZ>TTrVfr2B;d!92mhw2`z#*DZgv~Q{BWw1LVR}YQ%sqhme!jZJY}vv9dqmcOG0l@82;GIH9^*p?ZkgNUG-h;r2zQ_rPu! zI%A-o^Yx6NhjXXGTpG7=E#)$z9nigwG>;xG^}dll*inS@&05&}j~9S8A7tC6NlUL= zMiKyDZiZCen(2KxU#|c>8Uc>~3e!B$REvwgf8S|kNG}f9L)`rMi(>6pka0gVX$|U) zA2XfR)(sG>P{(BZ9pV{P8H!d^+X-^5Yi5o$BKgG z%ZysJ5TPe#&q4(XjF-&(7`SNnygITR^O??WDIw+TyWc*eo@C)>0 z+_c#9nlJvmF25k@_#0y}OrtEYT~?5I(DQ0Xwot%7YdjiRlmWOuqUf(bN0=QWy%r&3pOcAv6!IC3yNqJ zk@;d!I3$epTx4ozFX>K0f*`+o7oHTXK%4g1)}6+8v(q+g#X1gIBD`&t6j)jXFznih z^&<3WY!#67L#7C7yjUenQ%yifH^>tHvAg*zpeLmBmUyzQ{^5pP$~EwqiK#OXavnOW zAv5?{z`BorL3m4Ct)aXzj;j1?Q2HH73er=xYOwv z{%`EPbyU=A`!_l>f|Al9-AJc&Nhm0x(#_Ba64H&7bV`YeAfa@pbV^8fcZbx_zW2EI zexCiV^Lx+v_pGzd+JCs$%rM`%`@XJETu@|=_M$8XQ3GlSDT~>ix6Ji8UFec*w?eY@ zZGT7aEi?y2`rL2repSWx6IfEjboT##IM25qohB}@Q31-!{B)ZEc8cDb${<8*hQB_$Gywep1WfwxF-EKHw0c)=oHE0%erF&Z$}_*aj>HMaG<^aBhcS zSowB-pNA4NMbq^+JOP0&$YWOsZG_UCc7jb>BCP!etlu8%hpJVdr9noTnAlU|vKFlP z6r^J7tFF$|^smlccDSuN5hAX8JK4q);gmjB^R5%f zW=4@jDtCu>hT;+W%<*RQA{hu`VcU|hYI)9Kml}G|lnVB;Y+s&*b0TMm? zH^WMkUmoLhE?gdcOY8^mn0x%|d20n4PoMf+RK?j}-Cvk6eynsyc#gAO8;`UA5VuOGR&CO3=zE0Ia;8`iDt6>S$GB(T z_oTVeT4cz+c5PV%Jafzefa@Bqu&qD?hCMrV4GE$+t#4lea&4aQPI2pD;jQj34e`&@ zB^v1ks1x#Y%8Q4 z(<@kfIXs+a%aFxb_X^-;4|LQQ00zQ`tUeFKdJT0d4yLec85|o4)?bvZ5S`lZ0!Zsy zKcGN&^R;nm4khq7*;+MF9Er3^Vq*a$RMgGg?tuxJl^Lo{}jpawClqKima>N0lk zUJq8Rj^kA7>|eo`+Cu-Jox&^)wix~`KofB!wE1WWRNKM{+bZumv-5c80_=sR{TW(G z2>BzL$qajt@G4f=l+k?blTlU1!l$tH{-OpxG8r=GNHh_qjms0@rXVb1X``lUf(`&TDO>Yy>?0nMa=tf`k1oP~IV%sl$JU@11>g}J5> zT$2)SOQ;%X0H6e+SG$c}>*jIfIP(1Q)LfIaLxluj{qhOS!=XItma zYA2?Sk9B^wOetW+BVrw1u43}C38dAY#xH@1fYK2tmK!2c z&llR22d%hoJ@Z+Tf5bKO#mUO(>-Xb~zCPijjY5~vHH*RIS7)>RWS8sIxt~jF;1Ay; z>3{l>Rv+yCFI_M?vrl7`cUea z4T`y@Tq>SNldHd)8y-WWPib?oqgTzP&U8fL?2bZU{Kh@`s@)@D#;JIqea#cN zAieg@{WzRFF)z%k!uvz~Y$4#}%%uK_`(Zp`(xvX?Ig?G}pf^Y`%-#=J2bW51%Ay$g zTPjuS*s-zg*DK7D-`+kI4s7{}A2q#zf7e|xmqb9()quPIoJ}c(eBztP3pru+bA#8z zJ#}2+2{6Px3Em-%UEYs=uS6`l>4(WuGY@Nr}%#Pyp{b9nd>~^%cvWtPXdF#NrK-S{D?)MF@mI6^etu? zTA`!Ta!d!jHMmCdasMW?%zZgrY~<-Z?}_ttjAqjS*Q%5+P#j@b%May&9=_83?R)Ae zX<8p{uG!CB$o0=+`E&Y%qtS_U*Vu!9QHp;(b&Uc>8#()oZhdr=h?-Iq8pqDk>JpPq zfwt&xWaG}IQEJbX)f44Ie*|j?0nG!K36<9H&IkIqVLkQhr_VYJ!T=}9 zS^R3kAFsD|6K7X7I199N(#`y{j*{=C#aZ?$eT+6$9#~==Gzu2itoa0YTY48%A_m1l)JQgB-=l+6LTk<+urwDdu zMc6<_mI*U%3`7yvk1#~{p*9ie>%DRMjNW|~1$@6iE4dezXuO1J_3J-{TM~7;O1PVY zRc>`WF`KVhd%zvFB^qq^iWF;-23B^}2mHQI*4-MqUK$O(Py_Vn=$go061r&qsSrUA zN9`Zs6V7sSijYHEDIbp8r(I8Ed+Unb0%@D`#Xra$EhjzQsm=GQi?sdvR+zAHdZQ#` z$aN3n6|v@u13-ec>an_U{jeB=w`ACrY{gIIjH+hdEiB{>mx+>SD7ztcsplnQ( zmAIeTC{LC5Ag=vaQ>UUQC=3u)6dG}q)Apv9rO&t$t)KW&;m+3p*Cv84ph?%oNpoj& zp8-4@1K-5*APO$taneKT-)Eh-?T(FkWQ~tVr?hWfTAU&@qSD>NutP)jR)`eyhs^HM zh(B{5A}8=;2>+z5sKyX<=O^+Sxdlu4ejeI1<@4T*PX? zuJHKakqNn&hu8+kp?(}BQ?pwl%~>J>d!EuILy&cCCg|>sG1eOD)EUnQviEGu%3sYT zWOW6 zszH$aj3@<2ZH4^$?jtD}cL2oc?H%sMr7#9pXXD|15br0-Cv=QSuCIu+GT`=ZG;huqcAe@<`2b?`$sUWZb(SI6a6?`)D~h&B;K$;Ygr1 zlSc_s+8Utyi09||Ii;kJSF58LdQ<)|J}zYJGxw%Nk@bH!s<2GKeLgeHrrfP$l+U{1 zPIIQ0lI!C69LD=Jq zjhG7$<`HzaKJ&P)we2jrAXqu9F=4(GY(hQEWZN-khr^4BN^G!!;O%`l#S{mlwU14* zRcG$u$Ercbk5;e&eTTbA6LehRM`>(NAuryR2@!Ko*0%ft<_0g_^8dH_%%Tg?PzUpw zJU5neDgqn~kDwqz;TqG77{V0rIJQI<;~XJJ4GuN=Np#Prh)~8T|E41HsgBC0$W}o` z(bp^Tm#POLHQ3gEN$38@FKgMZnTQ5&1!$r<>=eK?CgG8W7pDz=X$tF7=tl?7b zg{fV=Mfq&k6Z0vS;cW~P`y~QAj^EwlVbC=t&%3OgQWo6xM?~jLXWt_^`!m7AtMjay z-?R%Uv`k$;E2&OkgrM7j5QiI-FJ`cM=n6au$9gb-@3>RE{+LUzo}j9}pGCLXcd0lD zE6x>Rf|BMc)Q)q4spW_!<(u3o@aU!x;Cd?3P))FPeXfWddxP*F?MrSbc39A@mlV_R&qpZ2OnFxIl z!0#$EezA=KiXYKiqb=8fE@Ahjhff=YhMFAwz2~jlNa6}yxnO(YL!JL@dnFdM%b#=l z)^{N5=XZGLp)grpNvFL?Ijxbe>YSPTI(O@@o%f%aI!jjc*Ul>g;br&VMAI}K5aJg5 zuma{vKd+MzaB~n0jHGE6+5q9I3AgT25r5V%GJeZvFGjE%X?bTB1yiGuu1L*>JN~cg zL&W=Xo2Ubz#}!Rn)T13oCVFl zL3*MD(3+Fnkuc{T>Dzk{VlgcfNnIV({A#-qbixzOO8>IeM>RubDp&7vrUPCrE2Uab zhl;!~6ITCa@Xyp^gJBChGGNDx@9ccJpMHIcZH(uu-);1Td)-3pM<7$X;+-Uy7! z7pMnqaA!|)M65IFk=2OF#2ovy@9dm!>H#HXAF%sy%;H)Rj)s^vBwijOhE0ojHk-LC z>T0=|APU2Plbzbuh}|PeXKdhoGWtwo3n4J)wrnI!|Kz`|LZ$Ip~DO8#cQe( zU3Ogn)~AS`s+54&?+|%YQtohTSITd-AG&?Gh!pJREM{D#v_;>jJqKG(*~tC#Zx~SY zrVp@~(W*k>5I_oLsjw-^BmOgL4 zbvu!!%?2LB{Bb_rlPIynu8~)nXyJza{`nC2V=O(e8Qrm+WVJwk)8BuNMn?lB4U`iM`sWEyT5fx=BU4nH<$XZ^&oiWH zkP!(k@hlB0gL$a>uJ7oFD5*MBASq% zb~hK}jqkz#Onm^gV%LD*0}nE5cMi7Q7Mu-RLt1bzFkrw#byh9yV)G& z2E3Yz)b@u7V!!!-t7TiW`d+9Mu(*j}YsiU@5ng+Jz32bhxCXiY%yM|-cisi;>5 zWO;tz%Y~vCL8@U@#^MF>$|B#i-B%O(?0k;Mk)ntc;G$A5wK03tg|zlw8AfUs#6x%9 zyn8okR3&5Ngg*qjR&>aaDNRIsEUZov%v(h~zhOnbNTjLL>yqUV`Y1GkF_*KXFDOQw z@?Smy8eSmHSk6Zmo#PaPtB0`S4=>otnr+`U-De(em)<g6^+tp-ULez+{dzc3Tl>LnsnFNEvKsP5vzC;+&Z^8B-IVCm(T$#p; z-Bw~B_X4QF>IO`bbqv0DD%EPExb{R^fxNvh&w)3^kE=};U*7x`AH=My%pC7*fT3ce z8yH;dwU5$;y|+c9o07TV(gk--GB&_0?9spRF_?PZDUu@D)2K1$?mo1?+~Zt#PWU8X z5B&`*@)}12v9bg-_CdwfVj$IfM+d<}LyJL1f#$j2vN3{%f&Kb>O4pf^G5ZeuDjLAMD?$3K|AoI_+BQIiv+I98xvQ9iMEvA)fS=-{HnS84Eoa9eXjQhcd#}TA>7#W*X zr}WW4YI786=S5Gp2JZM48}+hSZ4^f&uO{1txWSwmz3v5$W+k6_XSoQ%fiuj=u-Q@5 zFA)C~WCh)(;tW(|1Xl{ZHBh;pAJn{-%XTse-(8pdU6U?RZT8q}q!Tc}$6KwcAYK6J z!oqAxj^E1eOO#v^%(J$jq*u~LQA;^z+x}?rt2fSPdtBTlOvRSWi4$e&&7TW>HAr`7 zC*G+S$C9k&x|nc(fkR`6kUVR~;SDlr1<=T@QkVS+05}P;-cn^TxB{PU)HD;HFZ-mn z`oJ&Q|K`=j%ra8rviSg{1E5Xp4U`5C`ejHDj+m-IcmMzh2EivneddcW0q!r z`u>0qkPTAMH9X0uV3+wm*3y+6EJoslUgnm!<`;0k7 zU-Ce^21bp;If%VFaHbox9gg0jxR(TbMB_>**n$;|kquwzip7o|tcx4*T+10W7=G&d zQ+S;}FySNv+|**0->E9!>;0l+vUApBc*C1K0`R{vS*@L#%uD7^ZpNy~yZC{y#3jk}OBD4iCq(QkNX@eF}X}>qP=sicTzmkE)(0->^O+`gINbJ)R0SNv1fC=*EguiGh`-_@b=0o@0c zN^gB-ulS+|8utxw?(t@_6y)WXJ~_DOA%-XZE>cp_s#O;E5?(0-(Fg*WA=~f2Ivz%_ z-%Y2NxoI%jcsDm3^Ls*^*doZoqGt|0&?BycS~Bu@j@N&oPI;7P2#?^I*?Li!tHFy4 z8PN)-TWMFN;}y7H$-veZ0x_kl`5o6$s0X&5Rz%}Zk?j%1t}{fW< zU|5HgeFw(|F~B#HB;EJaDCzf-A?$p<>h(u)L)7?wvrWuH?93=rpRw;)?4JhR~6y8$DE0fZ2of zk$=6%6iVfU<)X_zLofa#pSUs#Rh$;u$A@M%&ef0WGW2O)9UW9Xoa$k!@maYQb+NhD z|EY|-P5*3YQzVfIqT6SfurCIQ&YCCjn{CMvQE;L|nF<6w;14l%{^~6}O)u`yu#CFY z&n!c8z}wFX*_hL+M>Bb{LcN@Y_71gx5m$&RVW! zCuXKtQD}ytH#dmJOZ)Lc9*&iMp2``AbI?j+f@hf(5m)NhKg0iSC5<+?a03yl;y4NB_=JNw8<-1c`?_zKe!kOaJZ!sl-PYV6II zG_Jx;JR}7m)gx=>pzK2xeVX=AEGlM8D7sXzY`k8+W-1HuSc$j^+V+4n*(KIvMe3kW zdD4)ZRW4tLFSa5$qql}`H;g&gMzy05ZnD$+sy7}PZz52Qst$f6)<027+CcU5-z7?p59nBd?az_vF@&{ENp4o_O?WrOCg|b4e@$5@BOR=EW!DOv!odP zA}&1Zn+;Un`^(*R{`+>$^NX;eZ!fqSXKE3P7e>DgolniRswWRM!dhq|}v-lk`WqUL^Rh$9!X# z0qJP}aqMO-5xlLK>y%)a7`^Rq8AA%+6KID7;Uu1k>WxTEE*$>~P=4axk82#Jkez8# zb$8G)RRS7OTH8unZ+JB<=A*lG^#wJHk1U%1vwfFISWNmFe`geTx|k9F)c;dkFkrDO zjrnhJs14ZYHKHyWOSZ;p^T9XpNK!EMJMk7mqpmyAnKKzmv{bt1U`vSi==dUt z+i}0-@Extbhp2S&q96lAfy_AZT$eW0(U#)o901(gEBU|5NiQUZVSgvQ)?_mbmF7G=MF`GHfr ziIlHlq)Cb-3oC6hQKPvQ*8sKd_9^BogHlef;+tK(=3k)jMGCn6&km^e z>OBuW@t)av(AbV;vfh`YBr{a)AZ|=wwtMb&i~%W#kyyvJ^GJn2aripJ`AaytssMmz50P-YYk|~wU{8g zr!o$OxB~6l=4n8u<2a*`=2}5xPa0`vTTdmP1i~dOT*h{1I zzuO+~!d1kLF_~gQ62?ICo?iAGEWOdz%XwurhcZIE_Nh7Y96@q=DP79ety>C8@hY3wjw-j3CblF69`28X6M>n}X|IBj& zu>=Cxt}F<)zd$mdN#~8_KU?m?oOablr4hH-xwjo`(QhJ74z4tI0XHCkS^R3r;Ekm^ zUAzkjNv<}v>y7tkzYl&6CgWMV!;{3lGO^8Hz9hi%>6y@8eKL0#I+V;a)xwiO>1Gd4 z;BMtX>CM#_Hi%5NF`8gy@h#e&x1A@?A5)rru@wTW!%q)?TUG9p!G3Y(w)k6uiF2IM z5j=EH0Na~8$m4+HMjcJ6#pTt7_J+0-fsR_RuSdqLaO0nqYvy46;O{+jUU0UBxd)Fj zNU9FNnZ2|SuIdGUBl=#sfM1Lcw^uhJ9< zP<#2xeBz^e(G_2(p9cn3wP3K3t}*H8TJ9t_kNf0T#Tk@ka27!#`VjCO!rqE#eawgQu4@`A*W)6e~q-3ob}>1DV}08xd2_YGcZ*!QpDwclX} z;QAGn9aKIjbs6c@B>Bo4^8){^M5XSLOLI<*G(>y*ckCm*Qz`mKdgv#5)0AN1Bcb#d;ihkB>=9!ySbN3d}_5YNcq#+$JuMy-ayn6~!J? zILKyvmY*(p!)<^3KFEc%#OjI25WUbTo6J~2^>GOI}d8&z7 zS^@rh9&`1AAR{vF;bx*W@GN+3rv|=4vrVH+z1S8yujQj{0ehk##S&Z9v7cYX(PjSELBS zAht#YM-zD`fS~duj0W0tq`Aby#s&z3O>o)dX&*N8?guw5(|2oBAWhL$e1svjl!p=S zf+jUYO-|;@lOq^KX=@Kc!v(TsP}pq?R+pApqdWpSTN;x1v5^(|yE{>6%mx%BvK*uu zG2fIT(;h4k7KksWZk!e?9VGOYLmP#d263lH0{2h^M**^sk%*JL7Eh-wt*wb^|2@_( zoh;FBk|JM3W|%ZU4WDcw7Qxfrs7deg{<=;VMo&A;EHP=rW9O0;QZ$xco@lq>9QkUM^O|r15D}tKBVEKZNs@avJwFark2VHB@E<-8ws|NW<{?}4#6JH9DEKkYO8n4=BaVB z;kU8)^`;WiShu{Z1E*Z8iclAT(RwdKykgu%6(}XQ!Ws**qP@NR!;0S)Icq@4@Ro%2 zE3^no(Xl__dGI}RdG=_4oeKIccw}(lon6lV{?wKAgE>u1kQ4Aa9~vhE^{(z7_vJMd zPG;UD)taS${w-tf?bEN`u8c^?Uv>#>DSS!YAZSTAmy`28lHQB*`4m@%zK60sS!U|1( z4!KzqZ2Y08F@L@1$`=X}CcQChr)T}XH^WHsa!NP!p~L_RP5q}+8G0u%poxENl6&VS zK#BcRUQ&S!Yew8ziOBe32HKj9~%CK^i<53oG)p6C&k+{K(r&A1JeCesh@ANEnqz zPED~9sm07wltF8$Nk67AGezn8T=9;_EKAtax*jfTuib7Hq7w;gs=PyHaPyB>C4oX21Z9U@*u;v4@aaL|)C7N&4pc*D_d*W;J4VkUY3 zH`8S+Bqu9j<#~yks*zUk=Yfe2_IJO2(H?#=V)$IKE`87RhvVRdI$;vK73)&x+80aD zvBE30=lkIc>T7)Xe!?gVfCTtT0&wK+-ykUj85;+va1AI@lbUMy`(oT23F#w2Z}BKV z;~ioL_nkEmDMkrz=a=;Yz=1%Cd~>Zm@fd{g2-LJrHRT~k5bmeJf9iKV|3>Y$06i*8 zyY6K#>*X~ER`U5dX^wll0LXbDDQ5@~m;-mdW<3x9R5Sv%>{qJjXwh-Ni?6N$6KUI5 zA)M~!SF~?3xRQ<>K%2g|0OO)gMZmVMIJmc$28>;LZj$>h57)dF-L+}^H*zveSq(50aBZMpc^ko6n{)OnTuDJ zMa5+UjG$}Px$Jb+$LLKIu$bHYR)rJ4ulj#82-Mo%>UDn)X|tUj2WgaEIB$Lp zNS#0O94FRy0_V94K#gc{KuybywsmBwy9GxeFl^KYE?xv_&OEffexb7}j>Z*wQ zo!P-mm{hMx^yo2_yD1%~@6|H3wL&$pb?*aKRH+-T;9k!UoKMn~ULTx+JjYnzyM9d1 z$N>vl(xsw!7%q7L($Lx12RKNp9sywu>e1%BjVmRikC2T6HYMmPN{@~7zq$%f#BB5< z`}cN5Ez37kpeorYq-clrZ ztfg2edp$hos$+n<4Jj}`IKF+}&!kUZJ41z;ItQvs(C~PBg$B<6#(M18%(t9RQwOAm zYNXnauo$!Wj>)k(>Ky}P$14u;5vVkgV&Zw}{N^=}`*)BUR&66UB=*2TAyD6xUab4W z7Z0k%_(+@V1(w^#e zmQLN2VWW2@L&O01#aq8JTYPmiX`b2#42TM8KLQg@C9EWP9~kGhc{P%Cyr}e*ovuyRIpcp}+ z@+$B5k&WXLj-rLi3ku747dB?B_l6qpg*bm#8)~C4lq)p3&&P5D?roDNw#bm^#gGd9 z1%NmO0zbM8hCyDVE(DPnBqy&kh+WNV!FNQ~c+P#o41O<>G};FU6s$-VLGtnGc@vl* z<9d#LGeRH_{9z5G9bPp>un@TaV*Ze6k&Els%cm5^cbY2671irn8insGiP;3CCoDQq zg^>JGpDgrj-Wm-v&)Z4%R_Exu8N(bWH6e6`JU71`%`xqY2YSP6? z^PXCUXDzoJ)gXqPsn8;$ANehc zkz{9u_ZF*&jgl=vCE02w{Wy=pv*H6vHdGFubow>Fd~3$vH}<92d`|gf^h>>TkY-As zG9eRiGzsPp;lNksOiuEhN%Wnb=lT+FULEI1K0r#Zl&VcPDZjmdl-8z3mlG%pH8Y$r zO^OAeAH^4JJ5e%H&fbUg|en{t>R>b zF>LRDKhwIY&*h`#nXE!@O+5Je3a zFSjdP+7uPye8&S7hCV#>kk?Oo=M&5e4$z$i!y!i`{f%61?MSO;(yJ52NC&0&iz)mL zrlA(g!UpK5+kt*zntPh;(Z?wEw@F`zSB8CbTl}+0cbws#gS6qO3As!@)J?xpBW*5{0gT@yiH9% zfHiJ<&;0mk1w#r;{j$-b<`E$smG+zWX4RGXR~F3;HW49wN)Tg5zLgCgf;|~5MZZ&6oHob8{8cd&L~7ts-uJhOVVGF z2}~Pt_w$SmaFh>7+s0HJi9L!mS-e0rSA|%sLtBENSsI{hi4PFo%A#h&;$U?h-G{|p2F2WF*V znvcD%6@}zmmXerK!PI57xm#e)v4&gkzU&_YutSq=9zwh3S%M^b6BewvE6z)iV*y|q zvMI9$>|@nur>E>J$tcvG!I#G`E^Gm)6DrZF3=^ts3JU`FzDofVg$olO-5Ql>UA*xy zh_Syno7HKWGb)XHv&1sES&qG?NahWx(Kw{W9IiKf@JJoAiQUWWu6@^F*?v-qr+yG5 z6Ct<;s#fK+9Z$>+vAeq*#h!@SQSMqmyTD2-{Iik%)7{lD?x&QN7WMrtL9Ew*a?*<3 zW`<+=T(TM}+DYn=CCLKoi}bftrOg5q!x6;ORN{#A%sFxE+CZ*mtxqZT`*oQHa!fzV z{CW4O9dW~}GhiVc9YY3sJc`B$Z>YSF8y;=(uuXS+OF6=>dNG(rOzwyptG90QZbUAz zpDD|jr(KD&(yba?Zo!EQbjmzjKgI57;T`YbA^85UHBZK_VuG4T@SEM$1jo@cB zXEe8cnswG5;c5Z7@8}5|c2a5eSm7xQg~O?91VSQS7YfH3JQCdq--x^Cf))ihO;9k$^^J zhD*J|P9;bEC5>HT62Z$Q%yM?mbZ`{qAv)|$vBDBNm=P%-GH*|*V2+p2W@VgLZ9WmH zy!9mm+iHx~=rBp(@ejds6CR}1D!%XwFeZb>XWgy`%moik#&Nc5)1$J{rF^@?lsu>O z*5A-U@(K;D{J*gmR^*94{rgzcwRPRPj|^0YuN=NQp0<|F7e_>YZ<68s))_+-Ogl)5krUx5hcW;{cl=iu z9Hm`!*ychuBJqdVE((DDzDR|an17SiN&mwX2VMpfTNyfxet1Avs80$?;V~72pz3;X z&k+4uX#Xj) zNPr}rf^*J&yI1DZ&l`tORJHZ2HIchi`#N-mW!-1vtJWS64I8afNuN6)WH z9g4hFr3L)TulNXmgOrNyeoC~ui7CO0a@xM(TU{e)Bs~MdOg=j=5lAmQ(@E)ER%n-= zs7G2#TnqIHM^CPk>z+NBq3jt%m%%&1GS{`hwO{f5=H2c>eHiyQ*BHl4iD*H)9h&Z=}B z%Wy4aT7F_DZgG#xrgf=n+YZ1TgxT)PN79L&W`wDdd1h>gTjWMN&SAlTuF`WK-B*0D`2#cz|FM&Ckh$m)3iQR1*USxtL;5wX*uzaA=3W*qUN@% zilP>aa=lIwj1;%u4!1b?&I90O_e-sr=slEa93{X`}rAMoK2B}w?D9>kC1M?ELe!!x=D;m{D{`4wH<`g&y&Wwf>3B2;JoxKN^(Aq zs5FLWR`r$I%To7C-wUmDL{q1|T>lx#oCmSF^Qi4Pn3?pD(Dk)cyPx`VJIc$(>uH*_ zkj*Tm)Rzl60jP32I?HvoU%yz@;hnp~J8&EX#utD5E)jZM;CZ0`7^ZhiYYBBsnFC!ltQ~Wg+c}~sq zFOO0{>?HWhY&U1T(Y!FBZr@7h!_B@NDve{*5Yu^`mD~=KQhsL<8$^NGg;AI24f`{r zr1uO-W`zlTPpP02cO#Hf3zg=qq$j+cc2~ZC6a=pL*PtanH)HMN-ovW3bv{m^j-w_YqwOntL9x#CW#^z=6%S6@#P}@>yT8spf zJ6cK+M`%qhMr!4>9CVOPIi<2JbY;aGi-)lATz1=Z6LnaOleuJ0&eoeu(nubNRw_({FY9Hb4BoPDQ~;WJuZy>BVNeH)&an^_ZYq!3N3 zI|YYjVS&p8gHNDD-s|R3E^7&hGH`gS{T4`mi$_FC`#%7LHru+ zvF|4qIHPbcK3p&9b(1CcnvGUIA0X3?*mS{NBZ4^G^%F>mUde}}NgZNmk1P&UMx#k~ zCqKd(XMt*kU*-9Zv?6&Xpw57K-Pv^I13(s zH1;v$J0s`3x_aXw8VF$ldTZGa#Ce_7!zXhpDs@GdI*>~89gQUu)J0`*&qEqG*Vd#hfy16?hh3%7gQCDu<#U|E@xomw6@Z{S`@zNI;-x7~4? zues%&@;w2;Q$ft#I2xA z1`Ozb5R%V|05s{5RfYeH`TzM2K!SJPNWZ}Umqy?j6JT+gWqd3C&x4_~1Gm6aPNisB zLjMJ^+$R83Lf%0&t$)3?0R>O-{2cR6_CF7nLVJg#(WO|jvj6L~V+eSP_%rz@8UIo? zbOW@#SdpJ7@n5fbK)_R|?lUkx|BtW%7iI=1>{?9kF`oYGHE}=i6dc01xcmR=GG2h; z{lBUkj{_kTBF8+S4#Mv}s8GVcyU9rqX31JU3hqY+Tk{NNcfe8H+VEt7c{Vcp1@ph! zL?s1LI-!0wx(c&D-q7rQ$`!c>mH!{UNqv&iB?|$GYs&dVW(&yUeS448z7hOunvl@@ zB}%I%aNM93;X}{%>ZnI+*`60T>AzGqA}M>S@ZXQt-iGoMOrc}94{*KDwLtl-bYDM_ z;nR=se51iMZrnR` zJ}-3Wh^|tI=5ENXCBHxaj5>h9H?0$)vvxKms%+8t>l>vg?!Uc-?}zV~pvb9?%8}!b z@p$q6Uw`xr^$r7s5&YNwpXYz>7XmZi0@a{hGq7c3{M$d@KcGty19=A-(M`=3|*ga$0Y&)O-2 zjg#oud8dE-u4eG}d+PT8$Ilimu}QoW~^%U0JOYD*m2($icw(`=92M+s;!d#7V;6 zb017!oIkVwWR&^8OUSze?3EI1_TIB6{o^0Ib<8;adJh*&$M+hKdbP%6^br}-qcpqpdyiCgp{8kcMe(KT^}n7j}5qaIERncCAox`n`TzQtk(U8 z8+UkKzWNv#-e<&jE({=maprCg(5n8cDgZp*bu0M=lA*~!$J>gu?=c7LF+m`X3Qchu zQs@KTsOFV(9^{U|6V-(x0EkA45;=!XLGs&KOx#ReKIltQ-QWEpDuk3)fn;zICVHFf z)I5;)&Nv${15W}TBo4f5H}E-J=gIs+voAkiAHOQ=UC+I9%p>qN>M|>zc*zqQ=vNZc z2=ad>O3Y8t%Eu680M(cSkB}!<)1X*QKt@iy>6gbpF~&c-OntMz_$hY8&NpcqKiaAT za@c)9r(_caY>SV4e}EorNO1b6_3} zyb}u2mS>v5+#}up9c}fT$M!2e06&hkQ@8AcC1TmK3{rkJ8?>OBJLdbVcd?)NXBZ)u zm+c81IM?GSfYvh(@*4ck4*UQ$^R0N|j0x~}gsfaA5C~Zi188?@9xz^2k6gFD<-ErhnE2cP zF+s{Q09N?%p;m3eep2IA!g+^a0~}d8$m0WGLh0^OAws85(wu%8lZt-t8L*8r9C82| zrtur3H(%|1{wDnE~80 zk@RsCg*pxwVbvb?2a=E7FU(kw^IM7@tc0hyevc_n>T0Wt>AJ-MuDY@Y90t+DA~CtH zWUeQHty2euV{gfcwIJ3{JWj5LvlrqN9`jz3dnZVs5|R4o3gkvAsKx-;Yupj#&3IHM zu#>-ekH=V6oO4YdjG$+8HSksYQQHU{h~^cO53FVliJ@*?v~S1KTpdc*F*(Yg6=)7* z8+LXi1svc~{n_rY^uTsoc^}d*ygpOgCACpdvsTrM_n5*8c<=e?sC*zIM@j>b%CK!% zhX$)Aq!4)hJaA+~6YTAyaG6-_AW=U?nX*XntpYkU!82{35qycL_T4FIEV``dZ;Rq; z6st^6vO#7sdJ&i$hao|+%;JDN;6W+q@lXct|D_$NMYBGLXM*&L?q6M$9fui@t$~b1 z5xjIv$9mjX7u2_Tz|O9lj6H+l@Emd5mi}w0`s67a=ucf-KbhbeJ6vy#Ok|-XCF~!- zA6)CVHvq!<0X@s=0I;N6CSUgyU>%L>N%PLUT&8IN>e}K(MClqRJ9TN}6_SIj4bLqm zZroOe{j1i>slP0lKyj^zJ$~yv}{FhV0H?_lq}gy8bL%I^vD+4W<98wc(|XcmybJm`xkO?$3tluI=QnFFQ^c(U&G(SlogEw2i(J8RR~R z$KNlutj)Vwa`IQvV>g$cXkj^!WyHFxdNP^MvgMn*A;5`)O4E3w9m>){r-Hn$6Qil2f9Y6Nua|dS%9OFmd%?28TSHn7m!{r1Ilce)Od<;Vm1=;E! z`4P*V7Qy3L4;mkoR^&DFt9o7QueHeZ&A&Sa?3@)dMBcL>HsD8)mw$*7Tnc=qoo2c+ zaoWz8$ijYob8tN{^Ay2Pr3|MwOY^FIOL|zFEMl>URnS}8y`paDTwe@h8pH}RLI=g+ zTz1FtTB4R#nPAhNY<$3bfq%5iHP1{E+Q0VNoH{HqZs+DYQ zPMty;klW7!DMwleo_EAAfn{)HnTn=}W5ygfBwbzqE-Mu23l#G#p1*xDS%9iv3rY;k zC3?<)K zB=HyR7^u={7ge?+J(O1zud-_GKxK)ldJ%E4Tjzn`SL(!#`QLM0r`KWA3i$CEa$wMm zZB%!KuE=wW@-`D*sn{K$!)Bh*QpPTxzu-lqdl~}0(T*lYQJgHE7x^W!OE%nVqM=&9 zsXnUNN3W?-|JE~EmwwpQ$2XZ}{MHVdSG~Ykf&#IcI7m!jkd0ramx!6Kqv5pUkU>=&7lsd* zlW2vqyUH&8NK65TUQp^ilqOm#P-p_$?K%K5_U%YQMf#)9p+9W=kmdI5R#KS(CX}+|Jb1Wh#2ZUZsJ(;v-?q1!&9?LEexb&4!Nlx>$q5gD+Auj1(d4r54jN3_7in&ZD$#o}wGJum+ z<{D?qug)YKrgH*k5_16f2MmZo1A>>sMgCSf~1kGnab!nGs_zBWCxub0cN z+yqlv#c-`Y`n_Hq+~C^b^~6j}57>VFq=sS(q91v)DM)2uySJ1(M|0G*CHYlB$i6k7 z)!F_HCr^`MdBI7kRZ#Q+4PiC(r3_F^ZU?42^w1#C-|8IaP2##wNooCtRpZIp3-*;J zVGCr9tWMhrJ@JxKp2+tUZNDOfXN#r7fsE^vcim%6nrqv-RlUdXHy%l(1_J~sX`P|_ zvd#9&xuwZNFVJ%A_50Qmtj6`k2ugLoCrxv&(}ZCCeXYdtgB7rk4A! z#BNH7s{r>L72<$YMQzQ1d)O&2OBSYQHUrNzsBwsPR)~tB0saXuabLnxXsz}xu<)6b zR7XuAD#H=*Pg)3Tgu2k$AoP^rm$n+RLR5tY#Bzz`ifk8Jn}Jv^BM(}NFw3=wl!Yr2r;GbxW0*ufOJB=Wg%ic+YCd6nRM1T!Cx}Q}QTH`81 oELVO}ilY#tl>*K~6`5UyTlpXR_^znSGBN7Bu6h%bh0Fo62$tW2lNglG~3?iUJ34#o1kT3)Z3PVm3 zL?q{&1j#vPUJoF8?m4I4t$Od?dR6aQ8wPv!-o3he_3E|0{#L)0mJ}w!C&!0CAVeZh z9zBCVPPjrK#OPCSP=d@!YX=`ti)X?QA?XcQCc%GfbreN(B_tqsz~84J|3JwhCvmrc zA3i9>@!vww+Ys16`3VTb%K-Av(LIvj6Zh{O_`yAM_z6QpkM0I#=o7#1KH-Xn{r;O6 z4eo|y2#CH0AE(WpC|N)tBsXzCP?2Xh7C_+@gGW-b;1g7c`-j&Ae%(I&1b?3(5EN#A z#Rq{1KtvurkhO)*MB(N2RpxsddqdqP>n+_4Vr^O-I6kNe4z(CQoToe=^zQZRGpA3x zQJlXT>p{ZxPo@D}{PSl&a~K7MJM$Sy8jHqTbNu1$fon5!&8YTpg~lvlWdk;Hr{%e3 z4!QnBiHPA1G?cIma&%Qz2yn1)N7vD2)EJVwLJu!yS7 z&9A?o)POL%hHPm-;D^_BEeMQM$x~)3t_=^y1Ua}|p_PzlQ|?D^C4J)yCDhO+lS~eH zMtv*+{4DHAGV#$%G_JD1nOp;PI1~6posM1tUMoO&HG%KngxR{i`hSG^|6|Vxv=R=D z$GA-L?b&)$aF`TPAduM(`@2san|>=JP|261@6=m_2Slhu)l!sni|OEIQ*Dzbbsx;N z%_QMko^;0wNN8EEF^qFWwdc)0Ua*{9kPh!4(;N@qYdBPpg^nH6T9Cfq!)vnhg|*1Gb12!oIjz1|f-~`TSSk8-Suv z+SDhve~$(P|01q`NGac*{38Xf%b4EF?eC12_6_dut+x$umhLUb>|4?Zm&7Wp`TrZ4GN{Sg!N-tW6XWuBF1{`uP{UuQ&uYHDiDs>(S5`Hjh={|kee(qOLJCty8LYV4&QvqOs3kBYi=x{IinmHfC0+_c(w1)Bae#QUNE#^Y z;InF$KjJXza(Em2K3RehxzwQ%#xdwff0|XlskUY_rM-?~D3INikOCppN{AMy} z8D06c;s0Ann#%DX8A5dOWMQ{y;wL4!vK)67Zw!h@BHn4YB@wg4g~bMi|KO@#tI;sX z6txcwlp#gvs2C?k#W~<#4(DerBB6a=YnhVFT^vt@PJDg3ks#NLm^z#v- zT~W?YS$HpRN+L_~_p8dYXdy1I^|Ryx;iZjy5h%X?Wb3EvXv3n_j^0`SEZFZUf?mA{ zYQICTt+s?h=oDyA$)>*VB$mQjvhcCE*=cGgsX1@9-{{*|r0#g^I#8lHCV{XXegT&r zqh~YLB<+uBm;7;Kj3K3-f@O3z-em|_Q>V-(h$yD03dv#>^T#ZuWeBvvo4yDOi8)Pv zqOB7TOOulcW7pv7M4oMr$?W;~mCRer^Goz&?7L7ng3il_OrR<%SO1pb+K;-!MGE1dYm_ayejz(iDxCQOi=na5 zQ;9kyA9(C{bh4*(+)KG$TCK}x=DxGK&X?{#kPoThGkhrDLtz(Yst?H`%v4px#wP|N zDV2_w0%aBGGJR`ey?*NGow?Su@82(m-L%yGk=&eHkRBeS`zSfy_CcscfMEf+6MwbgS6C`w(Tq_Q zbGuE1My_d_tS}48GpHbpy~&a@$+{9XCXz4Z^e~tH08Hrf` z@Y4}YnlHE?%Vp_SW7BG4u}Sh$p0(nUgdZqd&52Snm$l2-F2|5WVe&WF7-Q;(F=l?` zWld!%IZx~BQ^-QdWXO%q@T=1BDrlU8GqKeu(S&k4@SOAGKQuGCUPt0SmefKTnOcue}bj3xU>hH6m%P{0WmJ5Uoj2*{!xuhKpUi zM4}Sraj5dlHL3ASnh-(vPn``3VGUGL)zvn?*JC&TOK*B0qEvo4?f*2zYO)5$JE2B0 zdM@7f7Q|Y!uqe@reG?VBWBOFaOtCh}(9kloC86r)j4xD{Cq=VO<5D3D$+gI}_$txW$+%T>Cw#Zb2Vwo&>xOmluPt%SA9cJCmIM4(5ba_yt! za0Q9dRmq}Hx=K+P+Fspz$gz&%#2v3LBn%d-b@7Z#TUMPg*DRjjH|iC>*#p zh&PYU{_Z2_#R*aHWZ^TDmyCZNm39Xn1o@-ur+%vm1mE%|cv6*)BmeTBN0S}^--hV= zxqp7!LdeO2An;^*NJQUXE>Ig9cop!#Q-3)!sv_V?g&z`g$3`4-5-AOw8}}#w{MGjK zc(hf9ul{QL|8%!Wlf%F=ppU6^UTs%U6><5ydfk*0OV5^Mm*jz| zy1mkxHgT%jk0R!V_14NHtK5xyp1&7Z*AqZ^J32A}yVQ@n%ER!5kpRq%x0Kx0&lP^a z{_TYOOLtl%V)i)r^bgUGgWqzb8$W#}ODdYA2-W zx(MU6T{z3(yd!M<%@iK~{AMt7)kR>jjx=eBloYs+5vQ*_I|EC)Bi6p7xd-7Q)?cfD zA4RQg-^!X|DrAY2$SwB4x~)z4wVz3xfol? z=<*vK0Y3t>gh^6|F{aAspW9h%#)<}OkGv?X#qaLcP07jO8w5(IzrGkhwQ+O$V;-e2;74}JV z$^PE$7)DIwOHs{D7V8<#^%gP4!r=2toU4Q9E6&V>|QmR;g@T^-vnho5h6Jr0KM+;ak{sfforc0QA6Lijhey?YHa ziVa`L-j#}2dn~i@`g4c&r@;Nok%DUF5JKF5X+Rv-=VrH7r^orHGfGP$EE?|j@;a98 z?^3h9rhk6ocZDt z!D;?t*s)yEkfmc{pRj?39}EVQs~fa#3WG3c(Y9Idcd?8xEy;Ijx|dbQ;=!-My{t7l z+=t>HZ6Gg`k>YJ<#gI=1OYwErTufBTpZQYT|0%0ss$#Bqoo}{0zA<^7+ZRi#wK_&K zTq6wh5P*qYZcw&ZTxi{ys=&Da&S}JtgUj)|KN)LBjezo%)%4ZO{UP^e%4qe`icKHJ z#6t6tZ#K5|%JYx0PcP8QW&}QC#lYDd*Sg!v(^U+&T87!mJ_fp7`jKj>X7deFvNdIB zlGClbT$HRUWfv@&;Z!=}Ke(OA;?u~#|IkE{8$;Dkp=q=-!ECa#LCh`gm2k^2&7s3| z2tk^TNhOy~^0y&N8E!7-Mnv z^gyx0l9F||PJjM*bi{|R4WwnQlHB#vAIZm+eM44qN>axoEhMXWReC7ei%Gs&`VH>R z*_hNa^@FYnw3E%B?byGSq)tD>(2{0I(X`ElO1gh zy4Q-d>{qDDJv-85-La8?TXH<_WFtN{SFS-Clxr3HUe;#NHxOt#%@+@wBqxNXkb7-8 zB^b7G*>mo%VE9+ff0z~Tu5n*7$Xg%SE_zxkx-O@n`m22G`^p;`GG=b6`at0;=JER` z+k!C8m!sPa+1VqL*g9)@3yiOy$1Vuno|{w0hDMkagcEa^4WYfwtc}A}+waw6D@9IX z;qtE+dvfOVdX01Id8Oblo6uo9i}u3MTC}oqdePF4IyOaRqurI(#v3#p2;{CpX+c8& z{ix<*nr|VVV)ydfFx@Rw>FwfaC{Z!fyfe#>u+z&8+@_D8la}@DCwmoq@iPH-)($uy zhHS0?i}Z83N@>%#I7{^+<-r%PDCCSk*Oa~um=@S}c+@!ChewD<*3T{S5?CMAr>B1U z;!T_dOkRO0@Z2R4rYWC;?Xs8US}#Pa&kj4bN^oo&(l=Ndf1t`)uIGpeaBw?GVzxb# zl~FkKiXfQ$fuCcv(^_{w(7W*pSytDSSy?WfARYTNd>cdBsPhz2DT$WhG=-N9tiE6K z;%uLp%^z30WYBFl9@UGeCNY38`0+Y4%vz=qFcy7}GAn<32^)mZYP&Ff$zIH1wK~h8 zNg4Y#1uIjMDkQ!Auzrf!l_f#5PYGMEx!3unU#UNpIdNLurhk>Mp2eQRwCHVXWC%-~ zVH!4+pEjDxX{FiP9tCa7ciOre^IBnc(4=rSwCx}75#_mHCY~AGB8p}|uuW}|E~xoN zzLf4~X`b!0HI)XU{+86A>16mMe0}^=V}@!OOIzkN6Y^$b(-ZsH(3-|Ub&m?x3@hIR zn(S?kubc0zW;AYdE>Sfg{jfRwES~^?S zDXqJ{4hjx9DQCs}3~I(7p=*KMaSrEikM!t#r-W}f)Pj{F=2_5lA@&wT#1C)woFVuJ zUnT%bXn4jdeXAv5BxBt{&#F;NeA0HQ2E(H#I-lXvUlO`q$J)4pn&b!?s~|)-bk0A) zcB~H23>$7^0wgE?fiYb@Y-z=<`M61qy%mfDx%2JG=RPXBOgqq$?Kx=|aVNZXo4Y(F zy&QdJalwJD!U*~t{^?=IL8tX?WkCeS!?U?Trj$i2*tbc=w0L$Tn@M@lZd{cwvRr}H zwS_LDv?o(@ezWHZqO@dlEF!#I5!Y1vObrd%+-D$I2c!Jv%F0mig%8hJyP^F#p(Dyz4*Vl`6;f77+fHu!P2QP~R{ zm7@8D=`lswiYrN>WK!}LO^e#Ln9b`9&w1g}t!KLJoVHey^Q=i-(t00H zP)!9o_lk4A6CUGbRAq6pR!>oAgP(o{s`tueBY|kBTQ6odfYND&*@}Os z+$(D<#zU7O)vg7S_tTqx$0}`~LwZ`o4pouYi>6&>>5agZc1=3!g?1Q;v3p7lQP=lP) z>QOFU6jzE@wOqyJwX82@O4HfUkjX4F79GtZtdSS7o=fs}p_?Mr7pqRWk;?lRZ z*}{2eJ|hIocII>SuWuIyFkAAi4N8|vF3A^Rj$31>=zezxb&BHDI zE6^F>Et5Z}56~m#A*yR4e&94b$?FDqqOVCPMX}1v-NWtNaZr)6;`jE1DxNTK5=W zMlVPP2dJQkI3<-S>icKsPU@w^4JvQ`15ZJ35IvJJDP;@rBNVUHPcXYtQk2I zRhRL$rfVuaWq#_v(h~C-6RB$v*-|1+V~DwH#Gp$fZdgD(v{)T8G@_s`<-_qj^_!fj z{AbHHLx@~nrUkYmLJl`)sGZniUz~aDN1DqtT+Ei@K&4gSIq*`;pgw|AWq50Se!e1s z;0AW|Z9nmJhjY?9{!wDW5O?5A`@yAkAJgc}KENoGIM^6(^xRuj6|2bLQ>Fj3Fv!6T zwie23uPXMXP>OV3M_v`^s=MOIo zPZuK6*y7W9*Md-)(z=XHcpG1_;;Abn(-}V=EQ8VsnvKTZ>wyed_Zss#BV3SeCLe^1 z)w|e}EkAhL6QO^enisUwKr~DmCTGM7$@Q+vZiiEGo?mKzGuKW^Ak1JmP$Nubu#c() zfTD;0%0&UvvX?weEi;Qzj_z(tEUr*OLNwJ!a%M7T+1|L^b1Oy>F^yE2_O2em{hqDK z6CVa>W6uTH>m%=+E$-wndRWimit_EEHSVxlDeK@iN4TH~b-OT9Fz$yVva`c?1>?!@ ziWTP6=S_K~D)bnf(C1Fa*3GgTXJE5vwIv>(UrV0$g*t-W6#4;+y9|~w-ZB;xDW`i| zzO3~a<~rzop5vZzzh!K-mzFy)#fDODUHN|3BcqKTfStKboIZX~*xHi;&sdQXoy-u= zrZ%=05IM7^2qkgiaEW3WgP`GI2Aj8p?1 zHK$dqwkU;|LXXC4*z*>1ycY8J=c$SR6-gt6oRgn(?WN!n}NK&5qaCU?+9n1Q1L zlHzIXhv@j;CT{Ri~FgZdP(yT=1dsh?1!-y}}L#8l$o(w$HJK6K%$2kI>% z)5ui}5*4}6Zp_03vvSlKe>Jlx89VZ#VCrv0^_YAC=qD@Vk8p8id>;{Arq3uswPl8D-eYn05i_4oyUjAszttQNGzX0na%wuO71iF~5`vXy zEha4DeCn3iGuosyo@F|=vn;G<>FJgS40uj^X5|izbPS@sXCj#6jsl!*#wLtI^u8`- z{(7E^@F@Q#F^owX=amLh2uLUz*IOdfB|F(u!dXA90cDKTaV-5(iq)dv^A5PdK|C#=T4}-VUW!_!U6F+XOp!04;ZT|H;HHLl3N@JPm0& zqT7n|nnmgfiGmG1f+PHtk`>3s*`ie~CYLm2X)banm$R?A8AfaIBjJ|Hm{4AbkN(PYK8|VL$A^;REjb5Vri)Zl=?75I!rwKfk3oT#=ib8K?JfZs|?EjN4 z`-pILP-PofJha2W6uY{yFiB@)DL|+{okNf(sP-!+NY#{$qwj0#wrRTikk6M$$k!UkmgF~r~^K*yD{Rcsb zQIb?`ECyfBE7DKt7|>TJ+ua#h<8+a&{bfwHLgUv42UNQ3J4eE2!eM#i9$I}VD$%G- zC7X5ne)ejfp0%>wtIKYMZBsBD)Y-=_%pYX869F;az7QkP(&msbt3oT0D0ujK`?qq| zqD$6=BQePQA_jNo_&_gy5F@3s3`MCtpa9!&gy^~`@#k2n3=erTZs&CmYvO)+Ha4)! zwoQBn)@8MvBS$S7PcWvTF~%hQZhpBLY)&(|@{XYfjh)&A_p+)qT||*5$5kA$l~>j# z@-+$*IS4hJ_) z`3rfQHglg&wR(Gcl7qUX{=wB9>cwwI05fMjs+fSub?a&Rmra`su)L0jFe`mXF5l9F z+#R@AzC`J6p?Bumi2N0b1Et^b2&Uae7T@Edp)ol zEg)o)l^7F^pc*6@ls9QllN3X8t{3P(*L5t|<0@1e);7AVWTKVZSAds~wb^y+-R&C= zAGR_ka_ydZ$KCfMB5H_4RZ}dt+;e}VV{mz@&NOD4iSkwcW#io5Zo%M%>AAgN?*+p-Tk|jK=0@gS)cxKR)UzaNx^e83^J%AY zD@0tZrdRf3Rgl>J;D8(~V^NMVM-WDnt1UowJy$V;Pb{OvOT{LaK6PvojD26|y50@@ zdxae(Cav!K93p_tFo*Yg@jLk$4fHhg(J;Rv1gzDWaMH3ge_M3iUM=`8Ac^ zNTqWf&Y3_`x#ir+&_zxAI;`uUJkdltrnGtP3YlOkrJS!Ee-Q;%PW{5&x+dVI>B((?5Bmv*Mts>$XeOL+?ofayDnPY z{j0tE3YQiQ+A`A_FOaCYOd{46wkxJ<@)$~fvez(^jm}Eh7BG~U*SyhZtxH+NZxoqM z*p?@H{<7ciOvWkhp}uniXV;bHdyTPxEnJ<;yS7+)s^*`mA|BZ7R_v5KCMRJ!JV*IQ zV9EZNuGh{$eT(iJs}k{#;-C0>I`}AMJ}~uzjvy<$Z+~x;4fPzZjt!kA+DMKt92gMk zX|+SMegAN0URyE2tszkJy<4YqKWm)phy&+qo-Y!66#|`FN5<0%_^Cnlxm_uHtm`{s zw-8KO^#fUH$qT{=4g>ZVB<#E!YolN9jfCuJ*80}-2{VRu3Nup<5Tbn_7TC#Zwm+v2 zZZ;ggM4z5OJ1udhAWgM39tqcR9apt{|6^f4MwhH@h3!5HBk8WE8|8E_w{;!9wfqqF z;X~`@+v4jNEY(`rS(okXg_PjM1ouPQ&KUn z4qR&m!kd`x8K<6B+-%Jq47^l5rfT_1yL9QAQ-eLsIrK^e#JbpJXR>IF+l~;n$b4iv zdZ}_Kci$P2lOmc83NCNgWevSF$+LS2)P(&^MOO})03s~0)lhRxDO2jjlx&6ec1qef%I0l6J2PS2-fPh;Uy;1ho}9^q z<_`I+59|-D_e3MEgjF)q=x>)}k-Ap9z`;kAGZp2m>!)I6vr=#sh-pcuRqe&}=w5ngpL2=FNd1?6`E{dUiL+LEc_gX2WV9d!N4iUP+6!2ntblZJuj# zH!-YzphnSCh@P-iKc+qiKrRg=`^%V7+i0-ul$GT8j8AlaL3ua_;o-I3{v;X&?OR>x z>{S)3?-mvAB9>0%6j6D9y6Cd9z55OEXxd??%>JJJnHuUPJg{-2eYA>_Xh7aSNTF** zpCTeXrM|7}nV1Ea77`=g_Xt%hE#L5LC95*DycINO?W0&-XYm@f$-s9pshIjYI`}(0 zug^8)BpPT#rX#zWgJ&NQ2I;@5J`V*=-{{O@`!4-GB)MDBf-=$Y*I1-pvo+kzBj*7{LF0;m zXOSVYbTWa@Y`2m0r+q`N?0I2%)|Z3M!Z)kgd)B|zZ7Vv2&EKk?W_B$|Y>Av3xtwUX zH(*GsX>`@s-{7i5u^qBVyZw>ktUU>y2)whDq1f zIx1l;3Zqsfp8;A@vNe&PxZDQcH08{CH#5;Z-(!%?`f5^aDT6FPiVzxoZ8z`N;EW4IuqK27uEIoDwu|?^&#Wxj;q@E zA^TL+jDO&z-tRCc)Tk~s)bd9t0|zj~?Z_Eb^n%Ln^ZDgq1Gbtb zW4ToVGK5bUj_PlHjnL8m2POWNsx5_CR@kLIsK(cT&3xcdQ-sqvu?RH}qT*iu)IE{e zaM~w(_9caLHL`420V6QXlx>l8%SpK+N#Wh7vsnI_+NArtGanL7n&)r??~SFk;x!!y1o^#2A3*PXsZmT4*vN1nYkEoPu}$t zwK+s;-OM6ds0vHv%?8*(?#Yj;KVG8!28Ms?a^A#}imZ6UmA#}TLO-ODWnE(6(<1VT z&;9078_s5$MChvI2UINRwQmGuPsmsh50pRncL4j)B$yEq9G-1?LpQTtdV+{z(zZ=O z!kth1b!kVe!;5rT`dczVI*?0Vv=SXjFCyX<$LSsAQOheqP*v@GiJ<8pE3XZLCGF$h zre6zA4(t*QPPBW<1@zKe#ofNGTH1ob8SFaoc6XE%C7VwjG_WPH=qb^-%b;ruFLMI7 z^ZaA=3x3eMo&0O>^m1wd<;d;s@99PaXQHR^?!oBt6xY+FmMUQllSstJYb<366sDQm z^$onkitL~jww4mbyn?3br`Bz<(+nq63y{y|ZyTMfMkqdpGi4CJNb77WJL`lb8q|;O zAm4YX@Dp44#6i91z_+j6d;%AZ|0qA|%2G|3BFTa>b5zP=OX_HwBPBb5in8&Y2<0)M zYzxI@CR~&U%)#R$`L4n<$53hVI}f_b@K)p6p6Jx?=5DQx-#1iizk05?I`>kmB+B;t zA%CUq$59>3t_keIQ(;MbzUu2DpJw8czmj8pz0+5#g*o@0Rve@%Im#Tza2m-(=-smj ziH1bHeNz_FM^5`+#%i)MKW*ZjIY3DOLQ`ZxuMY#k*vxr&rV+n(OKk;MEpS_kRL5eT zg`GOWRG9vb(~6>7pqg|NfO&zFQK0kp3iB_NmOpXYA|d8RCqnGyDE%h>VdcdCx1l3% z0<8QQ>Nj5|y++_cNu#j)zb0Afn;*5I>nE9{NV;L@=y!#sOaEgV-u=nI67XR?T2)9I z7wkpxUMH}fK5Cz8@PR#`RfbJm(m3XZLrz|oImq?0DExyYxI$ka=Vd@Iz7Yqwg*I8k z>>u0$pgr(Eki}INfRcbbuiV4@hl4B?QUTJxl4QOEfB~eO_1*geFla!)KFRSr{`UxR z+XH%qZ9-?gU19(2UBf)pzkm`oD2~}^(5icJYf|3wHAtlB4lOgNq8IS}(=BJiPb|r* zJEW3uxY7vwTLV76?_G!g@RpDCGx!-$*%NrgR6qH)^dBzXIZN}W;g3EZWGFR{Ni8A{ zS!c=VA%=48H=Rz4F64I zd)Mg76I>+2igK!tL8QT%iXgpJ);*7;R*qB)N;+{DCSh=5&gdg2b>=akqJhSd5eT9c z@DwBP=zBgg{D$(te(hOUS4cy`j)2dm+eaF%!%4sfc1^B=Z;q$S5h1dOEaBA8c*{ez zhroWl_%GPqdF6aj{n5*thZN8z!UOp6-wBZsPra{7ieir79O--i-n&&$a%4M7aNXCL$@nPZr2-TN+Ik`6=v6I+-ZG+2*wQE6ikTrSva64N96+UUpes z+$NaT>8B?VMYJuQ-5plr$LSF-AULi27O+OIsO~I|0z(LM+OurmKgAB&zB35jLxFH2{jh zt5vzwy_1@U&*3^%^dyE~paB-Xn+ZKKG+0(NpW6Ya7||2vo5rivjGu5`&5cU0?7&Ht<)ku9n`3EWGlqC;xr_x}Ps^JLs8a~6Gjq?9wYT*n{Q-#dA+8k z{X~>ppJZu~-``zJSIIT00j$CfI=LPn*9gvyTfgmfH|}{r|FSd1Om3tCdta;ei2b+6ISy#7-Js84un+B0fXP}j zH&?hn!9M6{Vfs&)k}etH)!j+auaNzXFZ+wJ1O;IAtHi;yFqpopv;KUx5b1XqzwKh6vZ(0ei!jro8qm3kHB0>CykWnktNY z;TN$>9;-;|+;op&hDD6?Ryg;3(Q>~hg~^027^NH0NYD4wMq2!emVz9I+Yr|Qg%#}i zhpCw4S9aC0_ZrRNh;1L3b-sNMoaZJ0DK3v_pJA<(!u7@*5S`B@5x#&JmcgOz&B*4; zqR?wnXk4|pfJ#lvK~bm)sl=EzK#gD+Py3TkIK>@Na(~eg3j0VSq3>+$y7Zt%1#y zdnVJJL!3oxQn}BUbgPSLW`NyM>)|u} zI}6@S2CxmlvEm|Qk18!YL68@wW}kokOn7eb`apGcEO`l2aV%8!N`YRxtEXnySPaq8 znwL!rW^@_k$M;buHp;q~Jxi&?uVm~q#g&MKyb3bpOs1l{FU77FDCWWe47tT4*bkMFf#!^P?xY%)kf83f0tPH10~U`%n_7uW={YT z$79osaa>CF&WweEq{(V}e-Cq$+L0{9nZEw5cd75Ylq*UMW_ZTKowS4Nr+s@}%U2aS!C#Ike zL2wFsN>;ZK-VF|0|9tK{e(KX25*K|)!2L1B(n0?$lU-_lyGK;GJb!^A(9%@WvK3-M zccwaNgLj^kokOR4Gx*$d_zj(!9^h?eDyXh5;~IK}!^E+Q*+*=7x*Mzg#Mq@{Yc_Xq zQ4@zG8=ALe$xC2VZ?Um;*~qhOyBzOE`DzzOzuRWR z&+Q@B0QA)rO_$|}LD|=7RggP#nPf^A9*wKcHw#m*cH#r&5G__xD3WbJh#-$nrPoT*MzIg@6e z9l{l#x+L_T=|iMP>qR!*m4~n-E!0|-fAMld;ibt_ts%L7(9xJDR1`B_Lalw)2R3W&+-~-3%U;!g1LW}nUBQY!ythP#0 zGNJ&l^^Nsaus^T8+OMMNQNrg-D<-+$ghaTaK6R(x6toAVaHGqe9+%ZdD{dPB8jE@L z{H}SsXbCRa^k-A=6MH~T*9Fr-o3ez46h_*}|CSBocxxW#aH4k(R-7cd=WHK2c9L== zOn*wN-)B`NzrQ`LzF$zzluTx|Sao?_lf6sBeYC$6mG}!s%LnwRApW)02n4NsWCpcN z8eCelLIm}my?w%fuM|hI7O9UB+VosZz>#MR&#(UAAkwhgn$+tPB<78b=Z(BG2AJAO zPZ;5uJN(XjZoyu-aXZU+FxOFEQ*$~XzIfD*N#%sy#7|6HPpNN)UTR#b%@|sOo4oc+ zQ>GSBH3bW#2_SMTB(gX$NU)`yPBwN4g~~D{3>dx8T&=}?NiEo2>upqZ-dtym5Ea~raoIbGQTQ?GR1zE8(&vU;b6W3@ zy(DypCl`?9mIoY6^SBqvV7v7Fmb|J8Sof5`wrx)aA|<%A`S-45PnO7esqvMG=8ClZ zG1OcG_xulW(7Z_gjdvV5HG(+xc@yR~L8Os2q!3g3z+LSnc|z)g>nWcNJFpkmany*S zMh;aOg=vHi$)No-117LWG^3=`{@(D`&lAXGLxPT32cB}aqOo2 zC)ZBq{EvI54}BAyds6wIsRy>=2^4ehTX>F4y!HWO;@|6(6uDh^h>ks04fHZ$$TtYrUk4uuxc#r+e*Zs=h2Ox! zk2u^p02w~txc_2^NW)J zJVhG)(9Ir6O)q(OhyVobiV&ekZokt*r8592#DKLg`wn$}+s82F$BbJAm0rKUbv^M6 zEzkJT>@i~-oV<#6G(_$m3o?EQCkVIHIp$-sOo-@#ys~9MipPR9(BlNLj=uil81lOP{y^Sj z*PEY@1&LC?2{Oa;xbn|AF8?od9OAwwII*Gt8>SkEuD# zVo|MZMqQbsk^R=aX=4_;LS^z23LV9zAaUTW=k{EoX@}-o?7{gAA&MXZeGOk2_M(=g znqiT%ivf{9j!xz`h%>8_8+1q4ay$js3rwsy7*HSLvYM)X^V|Fn`V33PqJ@WJdf=oE zR`*g=x*PP9NMbom6G9LcatfzOXr03+7(v!rB_!t=t0`9fA9yB;tDf5vY80JQ>5Eg_ z!EB(=r-+8kt0}`s%RuTFIQ9pZ86?R${QAbuXiacG$YmJ^H04`1qk+N&z;CK{0`A5o zbKZ?1_qps=NsImM(tVZB>gs!IxuyB6jXbSUAYleUGy`55LMPKl#L+jj2EzSyKyU8t z2h~V!w}`2!7lQDDEvcu_iMQOiKzMd`fW%2YIen7#)j%0=f}E% zFe8$@tFpPE+Y7-tNhQ}eFfq|Nn|B=NHVIR;HV2t~njZ~>;bxU@&dqI2XV`$z z3j;A!MIUgL=V&D(70>0C6s-?9yiFwLU6DSYQE+(%Gp09C&-ivUe-n+f~i81}mKG{G;F zatCy0L?o`SdegmELF62KrBfi>EbyzUO}|yJR*T87$7RVJtNB||md{ADr>sBR3+Jdp z^crR5-ye@`t;RsPlxpXl*9&hHrPHadHs}0o`n>YOZmkSPoTsE4URCV^-11E{i;)-u zHiTc-E~TgtbV2a0lDmNRjFqaY3of2AP|}a}=pk#l730Wq`c_40w{FCyVOsH848S#_-Q*lu9y9ZrhV58cDh^TnF>ba&r;S%~R!D&UMy{fkiy~xUN z5%uc);9&6{AjMnBE+>#bQPqm`V}FS|NN9I5wt0!Wmz|v1RdgJ1aZ%5Ou~r}w6gi)O z%mEppVKe(xjLzrOXl;61Znm;@KDWpRz(T!56jwVq5(b;d63QZC>6k^hPN+Ey?~M48JhlKF{A2NgZF_BY8u84&4)S9(9pqw43aPC}Rw;dO&N*BR zP?!T-bNj+A876?G6o3%8iqgFDoCydP7O~1KXYA2lKH;a+_E$4pJiLN30TiPA;zmoo z&;Bz1e(;P!R*Y{OQ0kcHDr3nVRfK3HS*t|7w*|OOG~FC9(6?^a>nC8`3@RZ#Nt5ox zd|lP16fEvIv_r+R`LVG=J2pY=+f=BEiNWPHfbobCqUR9LwR?03b)s8*PzhEC?Z2BL z1QG;yv_3|Nqub%Vn=Bs&w>olzMhw8Q8tLR!pLlrocb0=K+SrW1u{Ggp2#%~n?Qp~` zB{U$Z?yXF49N`<(gEU>q+do#6E<|me_VfvVi#w2N*raqfj(Yd@TUK5tU!)z7O}S6If(2}}6qd}zK?4oOK?UQG48XZW=AKBW`~g`Nl2 zGC3LXiGiphg;pM3E1p-^eZ`_~I20UK#iUqe9mD4o#1tEt#UrC$@~Nt>2VgcRtFB#; zJ1H?o&*mCRLbmzoG0Z341F35aPN8vjIXWaHEf$Or3oHpQk82teK}saNdRoRf2(?&V zRaXf{pJHyUS6(c!r*h?^+nEkLV*nP_BKRhk0sW+`$c=(s@qzm@Bjz}{*HBrDBym5~ z7rEXKdy3Rth-&L>#ez1=$lUL@C+*$gM53?sPZ&8Va4nJaW6G1>_LJ1Iu2$D6e^TN$ zePxWGqi+BwDLK!oI4)N8PF_|01c}`X%J~2lzkFwg^XLSxaNtz{NfilRAW1p|_u>Nh zmcG`DkJb|dgCPGg?f9rrMOUnOA&D&QI^Z0| z{8W%J=-KfY1haYX)2Q4`mZiZ(^MQ}ep9`Xe>XA>gGD}ip)CN9k;m2j>C`SJx6DZ7h z8Yk3Ecgc`78X!m)veV;s2ED6W5_CkVDYQC1#Z-w!lT25Y-D~$m37go##YP-?E8+)1E&A#$I5M+}_ zOVE4Cs)R%dO5zBM0RFuV?Lmu1Ud+`f<-4jNXV=n%hrH>0;)B+?2?w>T)a%No#j8O~ z>;jLs?=~(G4l!3>362cz%r@S=2~uGVTH;5q_=ToheT8(STpY$Z02*V!ck-=+q~u^w z;nFd@h|cuv7ST%=QQ_ZHzjCiM2?pC%&($bL(P;x(y?k|G%qXOQ+<4DqN%{IXD-)f0ix69#rJ3Yj2e{L za%23x;L^j|YVSjVbE6&AVL}bhjJh#{bF|z{pW`+r;nI~##?4^Kkb|P(udmn+xzz}& zV+Ds_=srZ);_!3Z@7?;(!b3CRqQP{jE|FuNG7O<46t?Jmh@mR5S-$ajvEY27M1jC- z&6Sm4-icBOkln3{o0M;{zyqtxpoIUVts;!meq};CKEqdOYnHB{;e`)FXeB0Df(wjC z!8c&egT?n>jO$CkS*_*Xnus&D`O@0nho065b1{2a?(hxy{* zo-%-4FowHJaSd3uN_ZDkRJ9~PDOrB91f=lFv1SP^-BIm{Nmp&Pp5Uw9j#hh%Qe#i(W=##K0$>C=iXlW7p+s1sRzT5r-(u+zFOt{M1R!Y^k^p#{Xmi z-!BCJz#KIxqF__UF0*h@XNf}tAY8=@eN7{C0$xJrqNdf_ZEVMBmOV;-a0I* zt$hO?Bm`+eKtezSln|6|6cuRvd6Y1)`ED;fV;7R|A4s zC?ZGk+#dYm=x9|aO&Bvudumr!>E- zop8Vx0Qx(8w#e-^HQf zZ$r?2)+QiIb1GewY-L`A0>4kVu9{Cy^6!0zsObkV;b{$0eX%3d5gpLpxR z?=$IAxVZki(8m8L8os(Xl=U(_*2CXtl5=tWHdu7_|2LSrJa1fWp(wH8Z9LrHx~lIC z6O9g#`hpg!m(MaMe@v_hC8cah>h)qE2%C;z3Y%IWKw>`H*KmAs%wECR9pxi4)HYji_QOE@Stk!FIH>uYagD9M-NUuss4g16Zfv)ZaqL4 zfsHAeDBQozQU3oi#FhW;>>1DJWVHYfwg+WsLTiD~*l%P-)N}UQ2cTaY&29c9DZ%2g zI1n?6F~^Ekti06d_a9K`;~g5gy>BHZ)<|g$BOaZ`*46^we~!XbUZ1l?E=q5;HBGyb z63jrHd+FY9tS3?Q)|FPNwinmT&xo~N;7rf8y$D^AEK^j_=woER`n*i$_d=1qLj$|D zc?&-+UCZ%nADO7s=dUbbukAFyW0L$0$%CLGa9TOq1h`U0hE7!aO&|@}c^YOJGP{rD zew$tQ{hm(@)7=d3;3&UM6oL^A_N(PhJKA}CbIeO-9sP@Qa1RIR0c4id+wqGcsc&CM z0U(=I9H5u7L_QYSY;%WXMb?wo>}^C!}Z{Oiet11bbt9^*bni{ZQ( ze;~hnzh7~#9Pnm<)d7j0;L-O}IQPpW8Fb&>0nz0bZaa66-Jo-rn}|1+5<^}g{41j2 z1jY77&#$f<82EFbXOfsNPa0n-u;6cMnInL_!m8Vg755v^-yxH?$*WZO*j4i`6R1IV z2katH=LA2D;8Xl+49E+ht`Oa}9N58-PeC$gI7qU4uKWg>$x(L{$wV;}wEx4xx(Vn~ zWX}wgn6a$hhx}dc3J9tD|5Hf4;M!3%bK`%a zP)#(wD5v{NDc)1?fA|<&@=~$;TibG%@9b%Mg=i?L|0x-eki9s_hgsk>p zih3RcXP6EV`>Op8E=3XOH1)N>hiZhi2w}9ol(Xdyn;S;}B>=pnyjkUEwb!U%pe4V! zX}Ht_O?zt7OKwZ7bshdK#d($&{{eFCE>R-40|S|>I`hIV?y>}s-Va>x4FJ640QxK= zJO=DOIM-(ZRvGRx2*5O-{`~W^73Qu7Qdzl>1#}YS zTGul~(XFl*8E%>%6BdE0(ZoTrAkST7|F#@vd9ABGIyXC+dUat1(oxeGP|@0<;&*>tPB%>qj`SA`Q>DRwX} z91{>8xlhEL)idNCuIXgVvzk??80immr<$vdH+rHhFr&>Odvr(vYgw*j%gXI$>6)4+ zZgX;i+o`aa7|XLXIh#>PJI)zWP3i}g#%d#x+|KsO_SEpqyB?JSDPh&Zq}#KXxj1mN372D|tYZNhDiQy=`4!M-c5&0Y zE_(e~6{Eyur;RvcVJ;6Ne+|RRU;%6B-QvsxBr!|g0@xDRxQ==P00?^_=l$L0=^(&n z#`X2a8Up+?JD@?DL(YIhZ6OzbB2i&OanIvNbD*W6)6NmZXDHV}tt)fIL21)bM_ z64aL#A=JylA3+P$X9MQ$me;`fmEj(z``&kmJp*jLno%}(i9tFtGDbE^c|OzIa-qD} z#oQp;uVNgZawquYttTMoTu_RNkQ?54E;Ghj=`@KcV=VF1AOgpXQUWWV#r~!0#VJ3t z-9nvUjnd=tdRKDePsqgwyJCc z1Kf6HAmVZA`qeUR-}PiWRWC6xCj|zi*~<&jppV4C<1b;Q6F<>_J%Fu+_&b?9RZUM>0AK2;WcOu zIHQ)f+;Bef&5Fk5(&5ywA$E&+P(B~7b!=0Q)7#*7A(*ArY;qx(Wg8gLwAV@(Tncd1 zE??~2+;y$99i^OT6m{J|u9LC`pDLw~icy?Rw5T`X^fu8!Q`M&0foXTtGe=wiU@5-4IZOaYZp z!yUma{mQ>MQn{uF#N?tfcDl_yLB6Y*IpytfPAgw7C^99pH)7&)jj6y!feRwIY68e$ zsW7(YLgn`HN088=h+dcWQc@)l9x6)-;vWTIyo~ubhef_9vVnyW)Z?@W&Hcp@{9Esp zX7p5L1=fph-59_$0iE>h#UHKrJ;)=INAFh1=4w`jAhz$8PS>X{JjHk^GYn4RD?X7d zYD&>}9b&y?Ti1cF>y_~Cje2ahS6^{8bo}XEDzAicy*mUmw*yV}pXGyhauA{F`4ni? zxCu*hp_Xn|AJflpS}}4;l?NB0fbi!jEIUvTy|Mi5`n{;^gGma_0pw}`q?rCpK@N?k zFq5@(nd6%h85nb|9;($}-IJdPs#SLbV8{Y=A9ANtfPVFm#Y-6$KldtPW|?bHdIxgC+VxeHy9hTb4DZz)w&-x0NRrKw5P~1K*vU7ckwwm zDXxU-Lyq^xhFellm`zM@e>@A#j>cuBQsvQs*u_iN19k5ggy%qoZZ78SHHHZmX8_tN zs2>liS!VNU8FQf;7g(+59hoR= zX7KXR5f*+7*w~B$#4smjB(W?0HbPBKiLLS8+Mv>2$N;)(<#9R*hL_k z+(rdqiX3-(KEi!UL{EQz(u9Kexhcl^vfRO;jXp*Lygt3c>TU)5dmM2iv_1@Z*TwHs z^7z&RyI;z91*eKFE7rLa@Vw2xLo|V!U(~kgj!{#l+>vIG$QhcuG?!<1x>YvAEa(r^ z`T~gOeu8}*(3mUJP*(xM(#TeZLxqjo8C>g-ce7&i47uSAr$4qtgB8|LWE50iS(0N^ zGm+7$a>K^hW&(7ZZ)w3d5>5pHJsxzBk%B^iCTHm)f7$i8m0bhS{>((P+6U_5Hog{zvW6PnEf}0U_4)K9jOc0g2%#B)Y9< zd$)nF^Yihhdu}%5XN!oz?{i(KZgEz z>4~xQ4VNuiYVmlK?`{(ffV{b$3mxj??|_(`JJcLk%?S>K`&imy;TD-VvEJ>7$$CIT zlKv4~2NEn@%{8zc@p>lAs;PuAGz6124oZtg}ZPC70km=(mAngVugRH_76eT(} zNant-k3fB?Dy{Fm4f}=%$YRcg>?@rK*Gkr%!2=;&hKo>erqr#sn<8EYE+)Rk+u7zc zfxvOp<59BA+SgRLTvz%HqQRcP-jtTZ1q)o7d#?3%Kz>U2%b@(WFI^bd*2CjZmy@u* z8bBzzY|=P5J%IaFUl6(-E1h7R)LTCzlwM*k|Gu8b1hU#SWJ`XiS$!Ge_$0pWf>ei! z`WXcsbos2B7NZQ~?T`-*a6N1v|2)!js}ExfG-h{Oc8-QrDrY!ZI6A*rxa_32@qJM~UHo*5coDRajawi4u<4LnicFaGsV%vtm@$?pCtONxjGDtvr7R)S5?vE^XYbhFd>liL7LO9<&w`Rw-2Njxvd z(2^Hx560mU*9BJvYbvL6kUJx}FT*Whh5C9rthfQI{Tc~stBAAiTP_x0h;x94wU&zV z-K)z$`FqV>)?J_+T-hdH3M?+e;MsXm(VZ7A(KbCfNp_vLK97(as- zT&E6TcFk5558&=ok`BG6_98Qf?FU6QToF~9dqnSrJN}hWu-*bA8AkCo*~W7WAlGDx zY-2Er2SuaV@yr*m*LE*B0ur9FdNWCVw+i2fGZoiATeMg&jjV+ zumtLD!U6G3V72xgEQQidVosnWav*=4HA?TyYX}~qk@PViq_*0RyFN`yWR5=QQeo_e zTF-$uQr!GzD&O)O0xea^NtrBR+a#1@2Assc&!gbc1j%1)IC&p^O9u~S$QMNA1>(t5 z-yOjQ1zQk%H)@c$Kf>sUTtna#$oX9viW1Bnf~+_(-BKUej}}c+34It4mT#vnGO}Byr_royAS^7&XwMszo!;q5NfR(ssF=w(Fy3x*WZ7DbnoRoH=FtT2+ zjWYQBGSp#jVCYse3`fH$n-I3lle~0VxdQtfoc`E6Ao@Gj~CY?6&PstTqGv=Y&|zFZMvzlRorerokrQ`kK9-mckKvbzM7f zXYkSYXtwPTsk<_hN6(5qh40N>JBU2*c|cL*={b0@|0;GF;{&z3>B(W+M?tv z_tXgag|9(y{t^K%BDFLQuKY<3hG2jv$r)CEFPTcG;4arupz zgNx#ai5lZ1>i$Rm>HphePyZLNO~KQns5b|@{sX;5Y*C@?SfOk&k)QfgpOt_fsNT=;AaKEZ;bMuPG>kZGJ;=vd5Q=Eu0zB@fe1gGT)Jy3Cu z=(xuqbKm0#%97WpY7wqt=%9APjg3FUc44Nj;evbH4g-}eI_`9Ng;o?<4Og*9O_#@b z1Y%^qXy_ip9o^?IaTCw-zmVhsfu$5{N!_#Mi1UQA^L&RJ)AldtkK{H3cRy%KJiPkw z>Qj8$)DJhD!X^ch99WcdZZheh5H|Us=e&7?ehuZ$8ydfxkDpB^D`kymPVOA!oFlTg z*0Y2R4HATovs_>8Pi_jr_&A&m1{|tPvmL4xp6GwRPkgx%g_j0p7!Q4Vw~B4+l6*rY zg2`AKiv4D*Z!!p9=!5ulpi2wzL%`(D^n^V>dqUw`f7;=*=3_L!#~J2-5Sv4 zD!xd;UNtbVI{a9mTp*#`!75n}S$tQoYI~S5G3U)#A+%ppy(E0?H9U>2^iF`BO$7_z zME=v{G|4!g4faY`*|YE%-gDlBLBbb`TwTtBLu!IzJZ-Dj7$?>V+Qb+)=9@R{Kd8Ah z8oH88Vbunbo_4M~PK%F6PT<)#Fy?M;YtKlFtG7A9miB3AoTr1Dy`MXF{c)I?UzS8 z>^Ax)&Nqhh3&&g=oS*-Qub!=clOP*cQ5F2tG_aXM_phb+OLuy4v=k`Hulwb2N`2N&2w^3!Aq2z|M}NF4~vgjYyd zjBogIt9%}Ge&(kvYDLTP@J%GOm`2z? zW~Q6{D;6y12E`O~?+3{d>wp&bVX~oGc?PGOAX|4uxZ*B^f?YC_OB!IS!}Aje{DGRy=zBh7DnzchP9o zESy=Boe_QdyT0LZ-hxHh-GQmj0i~lw2^2*W%*Zm|CTmO6SRXl+<%arlBUlCt|G-oS z6KNhp7dXS3Zj-~N|31U~=Uro)Vr~|ys-7GPfiu0rs4dqXVQffyW%HjNKR#f^8B-%z zjh-mvfDiK9ug!U5hJUq+93KC~uSCwH$iZUE!VBfKZ7qFlQM+|L$9c0(m^BHa_n7mc z@ff?klWuLE*>gz2^c!a!zKnTjn_BgB0wcQe9TZ--Nwwz<?EH*rYQz@qnd^&Lhph@KPS-eGZoQpH&%UI|%_2JH)&pIXLHq&>1FvOy^ z)?;tvuggT&II0Q%oG)zc8z@E%D{%ZHWs? qg93{CP&%^j>3 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 hzg#)BVDKYQH~Qb5J^qD~8Ug;hs;r@ueaYm>{{h *obj = @{@"foo": string}; -// NSString *json = @"{\"foo\":null}"; -// XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL)); -// } +- (void)testNotUTF8Convertible +{ + //see https://gist.github.com/0xced/56035d2f57254cf518b5 + NSString *string = [[NSString alloc] initWithBytes:"\xd8\x00" length:2 encoding:NSUTF16StringEncoding]; + NSDictionary *obj = @{@"foo": string}; + NSString *json = @"{\"foo\":null}"; + XCTAssertEqualObjects(json, RCTJSONStringify(obj, NULL)); +} - (void)testErrorPointer { diff --git a/scripts/.tests.env b/scripts/.tests.env index 4b51b7246a4007..1495605b04d074 100644 --- a/scripts/.tests.env +++ b/scripts/.tests.env @@ -17,7 +17,7 @@ export AVD_NAME="testAVD" export AVD_ABI=x86 ## IOS ## -export IOS_TARGET_OS="13.3" +export IOS_TARGET_OS="13.2.2" export IOS_DEVICE="iPhone 8" export TVOS_DEVICE="Apple TV" diff --git a/scripts/objc-test.sh b/scripts/objc-test.sh index cc81e1f24d31ff..f729d8dea53b76 100755 --- a/scripts/objc-test.sh +++ b/scripts/objc-test.sh @@ -14,6 +14,11 @@ SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT=$(dirname "$SCRIPTS") +SKIPPED_TESTS=() +# TODO: T60408036 This test crashes iOS 13 for bad access, please investigate +# and re-enable. See https://gist.github.com/0xced/56035d2f57254cf518b5. +SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/testNotUTF8Convertible") + # Create cleanup handler cleanup() { EXIT=$? @@ -56,7 +61,8 @@ runTests() { -workspace RNTester/RNTesterPods.xcworkspace \ -scheme RNTester \ -sdk iphonesimulator \ - -destination "platform=iOS Simulator,name=$IOS_DEVICE,OS=$IOS_TARGET_OS" + -destination "platform=iOS Simulator,name=$IOS_DEVICE,OS=$IOS_TARGET_OS" \ + "${SKIPPED_TESTS[@]}" } buildProject() { diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index fabe50b206ba10..d2e59662819d86 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -210,14 +210,15 @@ try { describe('Test: ' + iosTestType + ' end-to-end test'); if ( + // TODO: Get target OS and simulator from .tests.env tryExecNTimes( () => { - let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.3'; + let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2'; let sdk = 'iphonesimulator'; let scheme = 'HelloWorld'; if (argv.tvos) { - destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.3'; + destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.2.2'; sdk = 'appletvsimulator'; scheme = 'HelloWorld-tvOS'; } From 89823c944b64ff5ba6a1d4b02587e13b629ab42f Mon Sep 17 00:00:00 2001 From: Shubho Sadhu Date: Tue, 14 Jan 2020 14:43:31 -0800 Subject: [PATCH 0029/1126] Revert D19377037: Add extension API parameters to libraries Differential Revision: D19377037 Original commit changeset: 3026a3400570 fbshipit-source-id: 57deddfd6006c6d171a005f4dd35e1d1df30de64 --- Libraries/FBLazyVector/BUCK | 1 - Libraries/FBReactNativeSpec/BUCK | 1 - Libraries/RCTRequired/BUCK | 1 - React/CoreModules/BUCK | 1 - 4 files changed, 4 deletions(-) diff --git a/Libraries/FBLazyVector/BUCK b/Libraries/FBLazyVector/BUCK index afefaac8f86f46..6c3c798d9ca06b 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -5,7 +5,6 @@ fb_apple_library( autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = False, - extension_api_only = True, frameworks = [], labels = ["supermodule:ios/isolation/infra.react_native"], link_whole = False, diff --git a/Libraries/FBReactNativeSpec/BUCK b/Libraries/FBReactNativeSpec/BUCK index 8d9b6b2126cea0..72cb95bac5beb6 100644 --- a/Libraries/FBReactNativeSpec/BUCK +++ b/Libraries/FBReactNativeSpec/BUCK @@ -10,7 +10,6 @@ fb_apple_library( prefix = "FBReactNativeSpec", ), contacts = ["oncall+react_native@xmail.facebook.com"], - extension_api_only = True, frameworks = [ "Foundation", "UIKit", diff --git a/Libraries/RCTRequired/BUCK b/Libraries/RCTRequired/BUCK index f3459e05bb749a..d061b9e31e92aa 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -4,7 +4,6 @@ fb_apple_library( name = "RCTRequired", autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], - extension_api_only = True, frameworks = ["Foundation"], labels = ["supermodule:ios/isolation/infra.react_native"], ) diff --git a/React/CoreModules/BUCK b/React/CoreModules/BUCK index f856c64f8ea546..f42fcca46f2485 100644 --- a/React/CoreModules/BUCK +++ b/React/CoreModules/BUCK @@ -26,7 +26,6 @@ rn_apple_library( "WebKit", ], exported_preprocessor_flags = rn_extra_build_flags(), - extension_api_only = True, frameworks = [ "Foundation", "UIKit", From 644eb0a9610f6465f9b44005f4b5b9bf722196da Mon Sep 17 00:00:00 2001 From: Nate Stedman Date: Tue, 14 Jan 2020 15:22:35 -0800 Subject: [PATCH 0030/1126] Revert D19400656: Revert D19377037: [fb_apple_library][codemod][12/12] Add extension API parameters to libraries Differential Revision: D19400656 Original commit changeset: 57deddfd6006 fbshipit-source-id: 5271e9faa002ff64508d8e52d0c60bf7a362ff02 --- Libraries/FBLazyVector/BUCK | 1 + Libraries/FBReactNativeSpec/BUCK | 1 + Libraries/RCTRequired/BUCK | 1 + React/CoreModules/BUCK | 1 + 4 files changed, 4 insertions(+) diff --git a/Libraries/FBLazyVector/BUCK b/Libraries/FBLazyVector/BUCK index 6c3c798d9ca06b..afefaac8f86f46 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -5,6 +5,7 @@ fb_apple_library( autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = False, + extension_api_only = True, frameworks = [], labels = ["supermodule:ios/isolation/infra.react_native"], link_whole = False, diff --git a/Libraries/FBReactNativeSpec/BUCK b/Libraries/FBReactNativeSpec/BUCK index 72cb95bac5beb6..8d9b6b2126cea0 100644 --- a/Libraries/FBReactNativeSpec/BUCK +++ b/Libraries/FBReactNativeSpec/BUCK @@ -10,6 +10,7 @@ fb_apple_library( prefix = "FBReactNativeSpec", ), contacts = ["oncall+react_native@xmail.facebook.com"], + extension_api_only = True, frameworks = [ "Foundation", "UIKit", diff --git a/Libraries/RCTRequired/BUCK b/Libraries/RCTRequired/BUCK index d061b9e31e92aa..f3459e05bb749a 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -4,6 +4,7 @@ fb_apple_library( name = "RCTRequired", autoglob = True, contacts = ["oncall+react_native@xmail.facebook.com"], + extension_api_only = True, frameworks = ["Foundation"], labels = ["supermodule:ios/isolation/infra.react_native"], ) diff --git a/React/CoreModules/BUCK b/React/CoreModules/BUCK index f42fcca46f2485..f856c64f8ea546 100644 --- a/React/CoreModules/BUCK +++ b/React/CoreModules/BUCK @@ -26,6 +26,7 @@ rn_apple_library( "WebKit", ], exported_preprocessor_flags = rn_extra_build_flags(), + extension_api_only = True, frameworks = [ "Foundation", "UIKit", From 05f1bb3dd4e5591419398c103a1a1b5bb3b32989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 14 Jan 2020 16:34:18 -0800 Subject: [PATCH 0031/1126] Bump Homebrew cache key (#27764) Summary: Trivial: bump Circle CI Homebrew cache key to move past cache error in CI builds. Changelog: [Internal] - Bump Homebrew cache key on Circle CI Pull Request resolved: https://github.com/facebook/react-native/pull/27764 Differential Revision: D19401723 Pulled By: hramos fbshipit-source-id: cec18ea68ac141ab85ad694ac261d98cbf0e4440 --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index aa6abb99688433..e2fe5f5ab6efb9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,13 +109,13 @@ commands: steps: - restore_cache: keys: - - v2-brew + - v3-brew - steps: << parameters.steps >> - save_cache: paths: - /usr/local/Homebrew - ~/Library/Caches/Homebrew - key: v2-brew + key: v3-brew with_pods_cache_span: parameters: From 4eb389d0696df22c75a6594912190331ffedaa1d Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 14 Jan 2020 16:34:41 -0800 Subject: [PATCH 0032/1126] Ensure NativeModules depend on their spec's owners Summary: For every untyped NativeModule Java file, we ensure that its owner depends on the owner of its JS spec. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D19382937 fbshipit-source-id: 0a1d840bff2f9e8db0f06c910448e9b25415d18c --- ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK index 39f69cba1f1318..ba1e76099c4e46 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK @@ -36,7 +36,9 @@ rn_android_library( react_native_target("java/com/facebook/react/packagerconnection:packagerconnection"), react_native_target("res:devsupport"), ], - exported_deps = [react_native_target("java/com/facebook/fbreact/specs:FBReactNativeSpec")], + exported_deps = [ + react_native_target("java/com/facebook/fbreact/specs:FBReactNativeSpec"), + ], ) rn_android_library( From cd833c3bb065000bc76858393b63fc373bad97d6 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 14 Jan 2020 16:34:41 -0800 Subject: [PATCH 0033/1126] Make remaining NativeModules TurboModule-compatible Summary: This converts all NativeModules excluding the following into TurboModules: ``` // Deleted "fbsource/fbandroid/java/com/facebook/catalyst/modules/relaynativecache/RelayNativeCacheReaderModule.java" // Owners of FBC will migrate these by themselves "fbsource/xplat/fbc-mobile-app/android/app/src/main/java/com/fbc/i18n/FBCi18nAssetsModule.java" "fbsource/xplat/fbc-mobile-app/android/app/src/main/java/com/fbc/react/CellScanResultsModule.java" "fbsource/xplat/fbc-mobile-app/android/app/src/main/java/com/fbc/react/WiFiScanResultsModule.java" // Don't have Buck owners "fbsource/xplat/js/react-native-fbsdk/android/src/main/java/com/facebook/reactnative/androidsdk/FBAccessTokenModule.java" "fbsource/xplat/js/react-native-fbsdk/android/src/main/java/com/facebook/reactnative/androidsdk/FBGraphRequestModule.java" "fbsource/xplat/js/react-native-fbsdk/android/src/main/java/com/facebook/reactnative/androidsdk/FBLoginManagerModule.java" "fbsource/xplat/js/react-native-fbsdk/android/src/main/java/com/facebook/reactnative/androidsdk/FBShareAPIModule.java" "fbsource/xplat/intl/oss-fbt/__github__/react-native-fbt-android-native-module/android/src/main/java/com/reactlibrary/FbtAndroidNativeModule.java" ``` This should conclude the Android TurboModule migration. Changelog: [Android][Added] - Make remaining NativeModules TurboModule-compatible Reviewed By: PeteTheHeat Differential Revision: D19383442 fbshipit-source-id: 71beaee087f6436b197a65f0d68527d9964bb6ce --- .../com/facebook/react/devsupport/JSCHeapCapture.java | 7 +++---- .../java/com/facebook/react/devsupport/LogBoxModule.java | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java index 142c961ade47d4..2880da778455aa 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java @@ -8,17 +8,16 @@ package com.facebook.react.devsupport; import androidx.annotation.Nullable; +import com.facebook.fbreact.specs.NativeJSCHeapCaptureSpec; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; import com.facebook.react.module.annotations.ReactModule; import java.io.File; // This module is being called only by Java via the static method "captureHeap" that // requires it to already be initialized, thus we eagerly initialize this module @ReactModule(name = JSCHeapCapture.TAG, needsEagerInit = true) -public class JSCHeapCapture extends ReactContextBaseJavaModule { +public class JSCHeapCapture extends NativeJSCHeapCaptureSpec { public static final String TAG = "JSCHeapCapture"; public interface HeapCapture extends JavaScriptModule { @@ -69,7 +68,7 @@ public synchronized void captureHeap(String path, final CaptureCallback callback } } - @ReactMethod + @Override public synchronized void captureComplete(String path, String error) { if (mCaptureInProgress != null) { if (error == null) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java index 05e70b069d33fc..9050a421fb4772 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java @@ -12,16 +12,15 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; +import com.facebook.fbreact.specs.NativeLogBoxSpec; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.common.ReactConstants; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.module.annotations.ReactModule; @ReactModule(name = LogBoxModule.NAME) -public class LogBoxModule extends ReactContextBaseJavaModule { +public class LogBoxModule extends NativeLogBoxSpec { public static final String NAME = "LogBox"; @@ -54,7 +53,7 @@ public String getName() { return NAME; } - @ReactMethod + @Override public void show() { UiThreadUtil.runOnUiThread( new Runnable() { @@ -77,7 +76,7 @@ public void run() { }); } - @ReactMethod + @Override public void hide() { UiThreadUtil.runOnUiThread( new Runnable() { From ace68f03e859c10c7db42c2bb19099ad6d1a6e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 14 Jan 2020 17:32:48 -0800 Subject: [PATCH 0034/1126] Use correct location for buck_to_junit (#27766) Summary: `test_android`'s Test Collection step fails when it attempts to convert buck's output to the junit-compatible format that Circle CI expects. Executing the script from the `okbuck` location should help here. ## Changelog [Internal] - Use correct location for buck_to_junit in test_android CI step Pull Request resolved: https://github.com/facebook/react-native/pull/27766 Test Plan: Circle CI Differential Revision: D19403837 Pulled By: hramos fbshipit-source-id: 44e599ab653e7412340c3dcfdc45c5d37bcea1ee --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e2fe5f5ab6efb9..e571eb7296cc64 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -519,6 +519,7 @@ jobs: find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \; find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \; if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then + cd ~/okbuck ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml fi when: always From 9d36375b668875f77ff79732a1f7d916b6a33f9e Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 14 Jan 2020 17:40:16 -0800 Subject: [PATCH 0035/1126] iOS: mark apple_library()'s to target SDK 10 Summary: This forces individual rn libraries to target SDK 10+ Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D19382542 fbshipit-source-id: f4cdebc82a03578134d1de4c9d8a7923fa128e65 --- tools/build_defs/oss/rn_defs.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/build_defs/oss/rn_defs.bzl b/tools/build_defs/oss/rn_defs.bzl index 7f661fc6c24ec0..e3e961ae600477 100644 --- a/tools/build_defs/oss/rn_defs.bzl +++ b/tools/build_defs/oss/rn_defs.bzl @@ -167,10 +167,12 @@ def rn_android_prebuilt_aar(*args, **kwargs): def rn_apple_library(*args, **kwargs): kwargs.setdefault("link_whole", True) kwargs.setdefault("enable_exceptions", True) + kwargs.setdefault("target_sdk_version", "10.0") native.apple_library(*args, **kwargs) def rn_plugin_apple_library(**kwargs): kwargs.setdefault("link_whole", True) + kwargs.setdefault("target_sdk_version", "10.0") # This just an alias to apple_library for now. native.apple_library(**kwargs) From d3e81d583290d88ee67dca84c8d5dc7e56b2b942 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 14 Jan 2020 17:40:16 -0800 Subject: [PATCH 0036/1126] iOS - deprecate iOS 9 support by removing runtime checks for 10.0+ Summary: This removes all callsites that rely on runtime checks to detect the target deployment version. We no longer need to check for iOS 10+ in a few places. Note: for this to compile, the hosting app needs to target iOS 10.0+. Changelog: [iOS] [Deprecated] - Deprecate iOS 9 Reviewed By: hramos Differential Revision: D19271321 fbshipit-source-id: 424ad7e2161261d148cb436cc20b4c531a4ba5b7 --- Libraries/LinkingIOS/RCTLinkingManager.mm | 56 ++------ .../RCTPushNotificationManager.mm | 33 ++--- .../Text/TextInput/RCTBaseTextInputView.m | 121 +++++++++--------- React/Base/RCTConvert.m | 11 +- .../RCTPullToRefreshViewComponentView.mm | 4 +- 5 files changed, 87 insertions(+), 138 deletions(-) diff --git a/Libraries/LinkingIOS/RCTLinkingManager.mm b/Libraries/LinkingIOS/RCTLinkingManager.mm index 85b9aa7a0bd0ec..2ad1c627e991db 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -99,30 +99,8 @@ - (void)handleOpenURLNotification:(NSNotification *)notification resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - if (@available(iOS 10.0, *)) { - [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(@YES); - } else { - #if TARGET_OS_SIMULATOR - // Simulator-specific code - if([URL.absoluteString hasPrefix:@"tel:"]){ - RCTLogWarn(@"Unable to open the Phone app in the simulator for telephone URLs. URL: %@", URL); - resolve(@NO); - } else { - reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); - } - #else - // Device-specific code - reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); - #endif - } - }]; - } else { -#if !TARGET_OS_UIKITFORMAC - // Note: this branch will never be taken on UIKitForMac - BOOL opened = [RCTSharedApplication() openURL:URL]; - if (opened) { + [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { + if (success) { resolve(@YES); } else { #if TARGET_OS_SIMULATOR @@ -138,9 +116,7 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); #endif } -#endif - } - + }]; } RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL @@ -193,25 +169,13 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject:(__unused RCTPromiseRejectBlock)reject) { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - if (@available(iOS 10.0, *)) { - [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } - }]; - } else { -#if !TARGET_OS_UIKITFORMAC - // Note: This branch will never be taken on UIKitForMac - BOOL opened = [RCTSharedApplication() openURL:url]; - if (opened) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } -#endif - } + [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } + }]; } RCT_EXPORT_METHOD(sendIntent:(NSString *)action diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index c6465bd7189f64..b2ba94d497bef0 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -472,36 +472,27 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; - } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; } RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; - } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:identifiers]; } RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { - NSMutableArray *formattedNotifications = [NSMutableArray new]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { + NSMutableArray *formattedNotifications = [NSMutableArray new]; - for (UNNotification *notification in notifications) { - [formattedNotifications addObject:RCTFormatUNNotification(notification)]; - } - callback(@[formattedNotifications]); - }]; - } + for (UNNotification *notification in notifications) { + [formattedNotifications addObject:RCTFormatUNNotification(notification)]; + } + callback(@[formattedNotifications]); + }]; } #else //TARGET_OS_TV / TARGET_OS_UIKITFORMAC diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 5a15e8fe641e1a..c61279893f0ad0 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -194,68 +194,65 @@ - (void)setSelection:(RCTTextSelection *)selection - (void)setTextContentType:(NSString *)type { - #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - if (@available(iOS 10.0, *)) { - - static dispatch_once_t onceToken; - static NSDictionary *contentTypeMap; - - dispatch_once(&onceToken, ^{ - contentTypeMap = @{@"none": @"", - @"URL": UITextContentTypeURL, - @"addressCity": UITextContentTypeAddressCity, - @"addressCityAndState":UITextContentTypeAddressCityAndState, - @"addressState": UITextContentTypeAddressState, - @"countryName": UITextContentTypeCountryName, - @"creditCardNumber": UITextContentTypeCreditCardNumber, - @"emailAddress": UITextContentTypeEmailAddress, - @"familyName": UITextContentTypeFamilyName, - @"fullStreetAddress": UITextContentTypeFullStreetAddress, - @"givenName": UITextContentTypeGivenName, - @"jobTitle": UITextContentTypeJobTitle, - @"location": UITextContentTypeLocation, - @"middleName": UITextContentTypeMiddleName, - @"name": UITextContentTypeName, - @"namePrefix": UITextContentTypeNamePrefix, - @"nameSuffix": UITextContentTypeNameSuffix, - @"nickname": UITextContentTypeNickname, - @"organizationName": UITextContentTypeOrganizationName, - @"postalCode": UITextContentTypePostalCode, - @"streetAddressLine1": UITextContentTypeStreetAddressLine1, - @"streetAddressLine2": UITextContentTypeStreetAddressLine2, - @"sublocality": UITextContentTypeSublocality, - @"telephoneNumber": UITextContentTypeTelephoneNumber, - }; - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - if (@available(iOS 11.0, tvOS 11.0, *)) { - NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, - @"password": UITextContentTypePassword}; - - NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; - [iOS11baseMap addEntriesFromDictionary:iOS11extras]; - - contentTypeMap = [iOS11baseMap copy]; - } - #endif - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ - if (@available(iOS 12.0, tvOS 12.0, *)) { - NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, - @"oneTimeCode": UITextContentTypeOneTimeCode}; - - NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; - [iOS12baseMap addEntriesFromDictionary:iOS12extras]; - - contentTypeMap = [iOS12baseMap copy]; - } - #endif - }); - - // Setting textContentType to an empty string will disable any - // default behaviour, like the autofill bar for password inputs - self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; - } + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) + static dispatch_once_t onceToken; + static NSDictionary *contentTypeMap; + + dispatch_once(&onceToken, ^{ + contentTypeMap = @{@"none": @"", + @"URL": UITextContentTypeURL, + @"addressCity": UITextContentTypeAddressCity, + @"addressCityAndState":UITextContentTypeAddressCityAndState, + @"addressState": UITextContentTypeAddressState, + @"countryName": UITextContentTypeCountryName, + @"creditCardNumber": UITextContentTypeCreditCardNumber, + @"emailAddress": UITextContentTypeEmailAddress, + @"familyName": UITextContentTypeFamilyName, + @"fullStreetAddress": UITextContentTypeFullStreetAddress, + @"givenName": UITextContentTypeGivenName, + @"jobTitle": UITextContentTypeJobTitle, + @"location": UITextContentTypeLocation, + @"middleName": UITextContentTypeMiddleName, + @"name": UITextContentTypeName, + @"namePrefix": UITextContentTypeNamePrefix, + @"nameSuffix": UITextContentTypeNameSuffix, + @"nickname": UITextContentTypeNickname, + @"organizationName": UITextContentTypeOrganizationName, + @"postalCode": UITextContentTypePostalCode, + @"streetAddressLine1": UITextContentTypeStreetAddressLine1, + @"streetAddressLine2": UITextContentTypeStreetAddressLine2, + @"sublocality": UITextContentTypeSublocality, + @"telephoneNumber": UITextContentTypeTelephoneNumber, + }; + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + if (@available(iOS 11.0, tvOS 11.0, *)) { + NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, + @"password": UITextContentTypePassword}; + + NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; + [iOS11baseMap addEntriesFromDictionary:iOS11extras]; + + contentTypeMap = [iOS11baseMap copy]; + } + #endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ + if (@available(iOS 12.0, tvOS 12.0, *)) { + NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, + @"oneTimeCode": UITextContentTypeOneTimeCode}; + + NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; + [iOS12baseMap addEntriesFromDictionary:iOS12extras]; + + contentTypeMap = [iOS12baseMap copy]; + } + #endif + }); + + // Setting textContentType to an empty string will disable any + // default behaviour, like the autofill bar for password inputs + self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; #endif } diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index b728ed23820822..25ec3266b7eb05 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -363,13 +363,10 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC // Added for Android compatibility @"numeric": @(UIKeyboardTypeDecimalPad), }]; - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); - } + temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); mapping = temporaryMapping; }); - + UIKeyboardType type = RCTConvertEnumValue("UIKeyboardType", mapping, @(UIKeyboardTypeDefault), json).integerValue; return type; } @@ -445,7 +442,7 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC @"default": @(UIBarStyleDefault), @"black": @(UIBarStyleBlack), @"blackOpaque": @(UIBarStyleBlackOpaque), - @"blackTranslucent": @(UIBarStyleBlackTranslucent), + @"blackTranslucent": @(UIBarStyleBlackTranslucent), }), UIBarStyleDefault, integerValue) #endif @@ -788,7 +785,7 @@ + (UIImage *)UIImage:(id)json // This check is added here instead of being inside RCTImageFromLocalAssetURL, since // we don't want breaking changes to RCTImageFromLocalAssetURL, which is called in a lot of places // This is a deprecated method, and hence has the least impact on existing code. Basically, - // instead of crashing the app, it tries one more location for the image. + // instead of crashing the app, it tries one more location for the image. if (!image) { image = RCTImageFromLocalBundleAssetURL(URL); } diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm index d0c1da31f25c3d..f8db5e3da23777 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm @@ -132,7 +132,7 @@ - (void)_attach return; } - if (@available(iOS 10.0, macOS 13.0, *)) { + if (@available(macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = _refreshControl; } } @@ -146,7 +146,7 @@ - (void)_detach // iOS requires to end refreshing before unmounting. [_refreshControl endRefreshing]; - if (@available(iOS 10.0, macOS 13.0, *)) { + if (@available(macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = nil; } _scrollViewComponentView = nil; From 8b735a2c1e912ecf61feb0d96eb962d81a59ebd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 14 Jan 2020 17:53:04 -0800 Subject: [PATCH 0037/1126] Skip testNotUTF8Convertible (correct path) (#27767) Summary: Use correct path to testNotUTF8Convertible which is being skipped. ## Changelog [Internal] - Use correct path to testNotUTF8Convertible which is being skipped. Pull Request resolved: https://github.com/facebook/react-native/pull/27767 Test Plan: Circle CI Differential Revision: D19404469 Pulled By: hramos fbshipit-source-id: 70cf06c90dac74ac7963b9a35a543e11b21ba471 --- scripts/objc-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/objc-test.sh b/scripts/objc-test.sh index f729d8dea53b76..930113e5dd1b55 100755 --- a/scripts/objc-test.sh +++ b/scripts/objc-test.sh @@ -17,7 +17,7 @@ ROOT=$(dirname "$SCRIPTS") SKIPPED_TESTS=() # TODO: T60408036 This test crashes iOS 13 for bad access, please investigate # and re-enable. See https://gist.github.com/0xced/56035d2f57254cf518b5. -SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/testNotUTF8Convertible") +SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/RCTJSONTests/testNotUTF8Convertible") # Create cleanup handler cleanup() { From f11937ef6545962ff0bc6dc0a536306f592b3125 Mon Sep 17 00:00:00 2001 From: Jiawei Lv Date: Tue, 14 Jan 2020 21:41:25 -0800 Subject: [PATCH 0038/1126] Revert D19271321: iOS - deprecate iOS 9 support by removing runtime checks for 10.0+ Differential Revision: D19271321 Original commit changeset: 424ad7e21612 fbshipit-source-id: 2bd9599e8fb31914dbcbc03f732379d6c8103028 --- Libraries/LinkingIOS/RCTLinkingManager.mm | 56 ++++++-- .../RCTPushNotificationManager.mm | 33 +++-- .../Text/TextInput/RCTBaseTextInputView.m | 121 +++++++++--------- React/Base/RCTConvert.m | 11 +- .../RCTPullToRefreshViewComponentView.mm | 4 +- 5 files changed, 138 insertions(+), 87 deletions(-) diff --git a/Libraries/LinkingIOS/RCTLinkingManager.mm b/Libraries/LinkingIOS/RCTLinkingManager.mm index 2ad1c627e991db..85b9aa7a0bd0ec 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -99,8 +99,30 @@ - (void)handleOpenURLNotification:(NSNotification *)notification resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { - if (success) { + if (@available(iOS 10.0, *)) { + [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(@YES); + } else { + #if TARGET_OS_SIMULATOR + // Simulator-specific code + if([URL.absoluteString hasPrefix:@"tel:"]){ + RCTLogWarn(@"Unable to open the Phone app in the simulator for telephone URLs. URL: %@", URL); + resolve(@NO); + } else { + reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); + } + #else + // Device-specific code + reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); + #endif + } + }]; + } else { +#if !TARGET_OS_UIKITFORMAC + // Note: this branch will never be taken on UIKitForMac + BOOL opened = [RCTSharedApplication() openURL:URL]; + if (opened) { resolve(@YES); } else { #if TARGET_OS_SIMULATOR @@ -116,7 +138,9 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); #endif } - }]; +#endif + } + } RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL @@ -169,13 +193,25 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject:(__unused RCTPromiseRejectBlock)reject) { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } - }]; + if (@available(iOS 10.0, *)) { + [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } + }]; + } else { +#if !TARGET_OS_UIKITFORMAC + // Note: This branch will never be taken on UIKitForMac + BOOL opened = [RCTSharedApplication() openURL:url]; + if (opened) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } +#endif + } } RCT_EXPORT_METHOD(sendIntent:(NSString *)action diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index b2ba94d497bef0..c6465bd7189f64 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -472,27 +472,36 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; + } } RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:identifiers]; + } } RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { - NSMutableArray *formattedNotifications = [NSMutableArray new]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { + NSMutableArray *formattedNotifications = [NSMutableArray new]; - for (UNNotification *notification in notifications) { - [formattedNotifications addObject:RCTFormatUNNotification(notification)]; - } - callback(@[formattedNotifications]); - }]; + for (UNNotification *notification in notifications) { + [formattedNotifications addObject:RCTFormatUNNotification(notification)]; + } + callback(@[formattedNotifications]); + }]; + } } #else //TARGET_OS_TV / TARGET_OS_UIKITFORMAC diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index c61279893f0ad0..5a15e8fe641e1a 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -194,65 +194,68 @@ - (void)setSelection:(RCTTextSelection *)selection - (void)setTextContentType:(NSString *)type { - #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) - static dispatch_once_t onceToken; - static NSDictionary *contentTypeMap; - - dispatch_once(&onceToken, ^{ - contentTypeMap = @{@"none": @"", - @"URL": UITextContentTypeURL, - @"addressCity": UITextContentTypeAddressCity, - @"addressCityAndState":UITextContentTypeAddressCityAndState, - @"addressState": UITextContentTypeAddressState, - @"countryName": UITextContentTypeCountryName, - @"creditCardNumber": UITextContentTypeCreditCardNumber, - @"emailAddress": UITextContentTypeEmailAddress, - @"familyName": UITextContentTypeFamilyName, - @"fullStreetAddress": UITextContentTypeFullStreetAddress, - @"givenName": UITextContentTypeGivenName, - @"jobTitle": UITextContentTypeJobTitle, - @"location": UITextContentTypeLocation, - @"middleName": UITextContentTypeMiddleName, - @"name": UITextContentTypeName, - @"namePrefix": UITextContentTypeNamePrefix, - @"nameSuffix": UITextContentTypeNameSuffix, - @"nickname": UITextContentTypeNickname, - @"organizationName": UITextContentTypeOrganizationName, - @"postalCode": UITextContentTypePostalCode, - @"streetAddressLine1": UITextContentTypeStreetAddressLine1, - @"streetAddressLine2": UITextContentTypeStreetAddressLine2, - @"sublocality": UITextContentTypeSublocality, - @"telephoneNumber": UITextContentTypeTelephoneNumber, - }; - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - if (@available(iOS 11.0, tvOS 11.0, *)) { - NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, - @"password": UITextContentTypePassword}; - - NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; - [iOS11baseMap addEntriesFromDictionary:iOS11extras]; - - contentTypeMap = [iOS11baseMap copy]; - } - #endif - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ - if (@available(iOS 12.0, tvOS 12.0, *)) { - NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, - @"oneTimeCode": UITextContentTypeOneTimeCode}; - - NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; - [iOS12baseMap addEntriesFromDictionary:iOS12extras]; - - contentTypeMap = [iOS12baseMap copy]; - } - #endif - }); - - // Setting textContentType to an empty string will disable any - // default behaviour, like the autofill bar for password inputs - self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + if (@available(iOS 10.0, *)) { + + static dispatch_once_t onceToken; + static NSDictionary *contentTypeMap; + + dispatch_once(&onceToken, ^{ + contentTypeMap = @{@"none": @"", + @"URL": UITextContentTypeURL, + @"addressCity": UITextContentTypeAddressCity, + @"addressCityAndState":UITextContentTypeAddressCityAndState, + @"addressState": UITextContentTypeAddressState, + @"countryName": UITextContentTypeCountryName, + @"creditCardNumber": UITextContentTypeCreditCardNumber, + @"emailAddress": UITextContentTypeEmailAddress, + @"familyName": UITextContentTypeFamilyName, + @"fullStreetAddress": UITextContentTypeFullStreetAddress, + @"givenName": UITextContentTypeGivenName, + @"jobTitle": UITextContentTypeJobTitle, + @"location": UITextContentTypeLocation, + @"middleName": UITextContentTypeMiddleName, + @"name": UITextContentTypeName, + @"namePrefix": UITextContentTypeNamePrefix, + @"nameSuffix": UITextContentTypeNameSuffix, + @"nickname": UITextContentTypeNickname, + @"organizationName": UITextContentTypeOrganizationName, + @"postalCode": UITextContentTypePostalCode, + @"streetAddressLine1": UITextContentTypeStreetAddressLine1, + @"streetAddressLine2": UITextContentTypeStreetAddressLine2, + @"sublocality": UITextContentTypeSublocality, + @"telephoneNumber": UITextContentTypeTelephoneNumber, + }; + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + if (@available(iOS 11.0, tvOS 11.0, *)) { + NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, + @"password": UITextContentTypePassword}; + + NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; + [iOS11baseMap addEntriesFromDictionary:iOS11extras]; + + contentTypeMap = [iOS11baseMap copy]; + } + #endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ + if (@available(iOS 12.0, tvOS 12.0, *)) { + NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, + @"oneTimeCode": UITextContentTypeOneTimeCode}; + + NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; + [iOS12baseMap addEntriesFromDictionary:iOS12extras]; + + contentTypeMap = [iOS12baseMap copy]; + } + #endif + }); + + // Setting textContentType to an empty string will disable any + // default behaviour, like the autofill bar for password inputs + self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; + } #endif } diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 25ec3266b7eb05..b728ed23820822 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -363,10 +363,13 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC // Added for Android compatibility @"numeric": @(UIKeyboardTypeDecimalPad), }]; - temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); + } mapping = temporaryMapping; }); - + UIKeyboardType type = RCTConvertEnumValue("UIKeyboardType", mapping, @(UIKeyboardTypeDefault), json).integerValue; return type; } @@ -442,7 +445,7 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC @"default": @(UIBarStyleDefault), @"black": @(UIBarStyleBlack), @"blackOpaque": @(UIBarStyleBlackOpaque), - @"blackTranslucent": @(UIBarStyleBlackTranslucent), + @"blackTranslucent": @(UIBarStyleBlackTranslucent), }), UIBarStyleDefault, integerValue) #endif @@ -785,7 +788,7 @@ + (UIImage *)UIImage:(id)json // This check is added here instead of being inside RCTImageFromLocalAssetURL, since // we don't want breaking changes to RCTImageFromLocalAssetURL, which is called in a lot of places // This is a deprecated method, and hence has the least impact on existing code. Basically, - // instead of crashing the app, it tries one more location for the image. + // instead of crashing the app, it tries one more location for the image. if (!image) { image = RCTImageFromLocalBundleAssetURL(URL); } diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm index f8db5e3da23777..d0c1da31f25c3d 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm @@ -132,7 +132,7 @@ - (void)_attach return; } - if (@available(macOS 13.0, *)) { + if (@available(iOS 10.0, macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = _refreshControl; } } @@ -146,7 +146,7 @@ - (void)_detach // iOS requires to end refreshing before unmounting. [_refreshControl endRefreshing]; - if (@available(macOS 13.0, *)) { + if (@available(iOS 10.0, macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = nil; } _scrollViewComponentView = nil; From 58a6a40eac9afb5c4de78a63418cc48ea97da1a4 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Wed, 15 Jan 2020 09:21:20 -0800 Subject: [PATCH 0039/1126] Re-land [RN] iOS - deprecate iOS 9 support by removing runtime checks for 10.0+ Summary: Re-landing the reverted change: This removes all callsites that rely on runtime checks to detect the target deployment version. We no longer need to check for iOS 10+ in a few places. Note: for this to compile, the hosting app needs to target iOS 10.0+. Changelog: [iOS] [Deprecated] - Deprecate iOS 9 Reviewed By: sammy-SC Differential Revision: D19411136 fbshipit-source-id: ec0a957dc57819f0ee7d138c858209cabe3e5102 --- Libraries/LinkingIOS/RCTLinkingManager.mm | 56 ++------ .../RCTPushNotificationManager.mm | 33 ++--- .../Text/TextInput/RCTBaseTextInputView.m | 121 +++++++++--------- React/Base/RCTConvert.m | 11 +- .../RCTPullToRefreshViewComponentView.mm | 4 +- 5 files changed, 87 insertions(+), 138 deletions(-) diff --git a/Libraries/LinkingIOS/RCTLinkingManager.mm b/Libraries/LinkingIOS/RCTLinkingManager.mm index 85b9aa7a0bd0ec..2ad1c627e991db 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -99,30 +99,8 @@ - (void)handleOpenURLNotification:(NSNotification *)notification resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - if (@available(iOS 10.0, *)) { - [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(@YES); - } else { - #if TARGET_OS_SIMULATOR - // Simulator-specific code - if([URL.absoluteString hasPrefix:@"tel:"]){ - RCTLogWarn(@"Unable to open the Phone app in the simulator for telephone URLs. URL: %@", URL); - resolve(@NO); - } else { - reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); - } - #else - // Device-specific code - reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); - #endif - } - }]; - } else { -#if !TARGET_OS_UIKITFORMAC - // Note: this branch will never be taken on UIKitForMac - BOOL opened = [RCTSharedApplication() openURL:URL]; - if (opened) { + [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { + if (success) { resolve(@YES); } else { #if TARGET_OS_SIMULATOR @@ -138,9 +116,7 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); #endif } -#endif - } - + }]; } RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL @@ -193,25 +169,13 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject:(__unused RCTPromiseRejectBlock)reject) { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - if (@available(iOS 10.0, *)) { - [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } - }]; - } else { -#if !TARGET_OS_UIKITFORMAC - // Note: This branch will never be taken on UIKitForMac - BOOL opened = [RCTSharedApplication() openURL:url]; - if (opened) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } -#endif - } + [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } + }]; } RCT_EXPORT_METHOD(sendIntent:(NSString *)action diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index c6465bd7189f64..b2ba94d497bef0 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -472,36 +472,27 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; - } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; } RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; - } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:identifiers]; } RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { - NSMutableArray *formattedNotifications = [NSMutableArray new]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { + NSMutableArray *formattedNotifications = [NSMutableArray new]; - for (UNNotification *notification in notifications) { - [formattedNotifications addObject:RCTFormatUNNotification(notification)]; - } - callback(@[formattedNotifications]); - }]; - } + for (UNNotification *notification in notifications) { + [formattedNotifications addObject:RCTFormatUNNotification(notification)]; + } + callback(@[formattedNotifications]); + }]; } #else //TARGET_OS_TV / TARGET_OS_UIKITFORMAC diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 5a15e8fe641e1a..c61279893f0ad0 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -194,68 +194,65 @@ - (void)setSelection:(RCTTextSelection *)selection - (void)setTextContentType:(NSString *)type { - #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - if (@available(iOS 10.0, *)) { - - static dispatch_once_t onceToken; - static NSDictionary *contentTypeMap; - - dispatch_once(&onceToken, ^{ - contentTypeMap = @{@"none": @"", - @"URL": UITextContentTypeURL, - @"addressCity": UITextContentTypeAddressCity, - @"addressCityAndState":UITextContentTypeAddressCityAndState, - @"addressState": UITextContentTypeAddressState, - @"countryName": UITextContentTypeCountryName, - @"creditCardNumber": UITextContentTypeCreditCardNumber, - @"emailAddress": UITextContentTypeEmailAddress, - @"familyName": UITextContentTypeFamilyName, - @"fullStreetAddress": UITextContentTypeFullStreetAddress, - @"givenName": UITextContentTypeGivenName, - @"jobTitle": UITextContentTypeJobTitle, - @"location": UITextContentTypeLocation, - @"middleName": UITextContentTypeMiddleName, - @"name": UITextContentTypeName, - @"namePrefix": UITextContentTypeNamePrefix, - @"nameSuffix": UITextContentTypeNameSuffix, - @"nickname": UITextContentTypeNickname, - @"organizationName": UITextContentTypeOrganizationName, - @"postalCode": UITextContentTypePostalCode, - @"streetAddressLine1": UITextContentTypeStreetAddressLine1, - @"streetAddressLine2": UITextContentTypeStreetAddressLine2, - @"sublocality": UITextContentTypeSublocality, - @"telephoneNumber": UITextContentTypeTelephoneNumber, - }; - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - if (@available(iOS 11.0, tvOS 11.0, *)) { - NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, - @"password": UITextContentTypePassword}; - - NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; - [iOS11baseMap addEntriesFromDictionary:iOS11extras]; - - contentTypeMap = [iOS11baseMap copy]; - } - #endif - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ - if (@available(iOS 12.0, tvOS 12.0, *)) { - NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, - @"oneTimeCode": UITextContentTypeOneTimeCode}; - - NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; - [iOS12baseMap addEntriesFromDictionary:iOS12extras]; - - contentTypeMap = [iOS12baseMap copy]; - } - #endif - }); - - // Setting textContentType to an empty string will disable any - // default behaviour, like the autofill bar for password inputs - self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; - } + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) + static dispatch_once_t onceToken; + static NSDictionary *contentTypeMap; + + dispatch_once(&onceToken, ^{ + contentTypeMap = @{@"none": @"", + @"URL": UITextContentTypeURL, + @"addressCity": UITextContentTypeAddressCity, + @"addressCityAndState":UITextContentTypeAddressCityAndState, + @"addressState": UITextContentTypeAddressState, + @"countryName": UITextContentTypeCountryName, + @"creditCardNumber": UITextContentTypeCreditCardNumber, + @"emailAddress": UITextContentTypeEmailAddress, + @"familyName": UITextContentTypeFamilyName, + @"fullStreetAddress": UITextContentTypeFullStreetAddress, + @"givenName": UITextContentTypeGivenName, + @"jobTitle": UITextContentTypeJobTitle, + @"location": UITextContentTypeLocation, + @"middleName": UITextContentTypeMiddleName, + @"name": UITextContentTypeName, + @"namePrefix": UITextContentTypeNamePrefix, + @"nameSuffix": UITextContentTypeNameSuffix, + @"nickname": UITextContentTypeNickname, + @"organizationName": UITextContentTypeOrganizationName, + @"postalCode": UITextContentTypePostalCode, + @"streetAddressLine1": UITextContentTypeStreetAddressLine1, + @"streetAddressLine2": UITextContentTypeStreetAddressLine2, + @"sublocality": UITextContentTypeSublocality, + @"telephoneNumber": UITextContentTypeTelephoneNumber, + }; + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + if (@available(iOS 11.0, tvOS 11.0, *)) { + NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, + @"password": UITextContentTypePassword}; + + NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; + [iOS11baseMap addEntriesFromDictionary:iOS11extras]; + + contentTypeMap = [iOS11baseMap copy]; + } + #endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ + if (@available(iOS 12.0, tvOS 12.0, *)) { + NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, + @"oneTimeCode": UITextContentTypeOneTimeCode}; + + NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; + [iOS12baseMap addEntriesFromDictionary:iOS12extras]; + + contentTypeMap = [iOS12baseMap copy]; + } + #endif + }); + + // Setting textContentType to an empty string will disable any + // default behaviour, like the autofill bar for password inputs + self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; #endif } diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index b728ed23820822..25ec3266b7eb05 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -363,13 +363,10 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC // Added for Android compatibility @"numeric": @(UIKeyboardTypeDecimalPad), }]; - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); - } + temporaryMapping[@"ascii-capable-number-pad"] = @(UIKeyboardTypeASCIICapableNumberPad); mapping = temporaryMapping; }); - + UIKeyboardType type = RCTConvertEnumValue("UIKeyboardType", mapping, @(UIKeyboardTypeDefault), json).integerValue; return type; } @@ -445,7 +442,7 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC @"default": @(UIBarStyleDefault), @"black": @(UIBarStyleBlack), @"blackOpaque": @(UIBarStyleBlackOpaque), - @"blackTranslucent": @(UIBarStyleBlackTranslucent), + @"blackTranslucent": @(UIBarStyleBlackTranslucent), }), UIBarStyleDefault, integerValue) #endif @@ -788,7 +785,7 @@ + (UIImage *)UIImage:(id)json // This check is added here instead of being inside RCTImageFromLocalAssetURL, since // we don't want breaking changes to RCTImageFromLocalAssetURL, which is called in a lot of places // This is a deprecated method, and hence has the least impact on existing code. Basically, - // instead of crashing the app, it tries one more location for the image. + // instead of crashing the app, it tries one more location for the image. if (!image) { image = RCTImageFromLocalBundleAssetURL(URL); } diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm index d0c1da31f25c3d..f8db5e3da23777 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.mm @@ -132,7 +132,7 @@ - (void)_attach return; } - if (@available(iOS 10.0, macOS 13.0, *)) { + if (@available(macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = _refreshControl; } } @@ -146,7 +146,7 @@ - (void)_detach // iOS requires to end refreshing before unmounting. [_refreshControl endRefreshing]; - if (@available(iOS 10.0, macOS 13.0, *)) { + if (@available(macOS 13.0, *)) { _scrollViewComponentView.scrollView.refreshControl = nil; } _scrollViewComponentView = nil; From 4b703e3c1ffe11ef523ca13193285de670d9b2a4 Mon Sep 17 00:00:00 2001 From: Riley Dulin Date: Wed, 15 Jan 2020 16:50:06 -0800 Subject: [PATCH 0040/1126] Remove .flowconfig from hermes/inspector/tools/msggen Summary: Changelog: [Internal] This separate `.flowconfig` file was causing versioning issues. Delete it so that `msggen` can share the same flowconfig as the rest of React Native. Reviewed By: willholen Differential Revision: D19413710 fbshipit-source-id: 748cb50a3151df1c67ee7176e57e259e48f50be7 --- .../hermes/inspector/tools/msggen/.flowconfig | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 ReactCommon/hermes/inspector/tools/msggen/.flowconfig diff --git a/ReactCommon/hermes/inspector/tools/msggen/.flowconfig b/ReactCommon/hermes/inspector/tools/msggen/.flowconfig deleted file mode 100644 index 15700903b7d760..00000000000000 --- a/ReactCommon/hermes/inspector/tools/msggen/.flowconfig +++ /dev/null @@ -1,16 +0,0 @@ -[ignore] -.*/node_modules/* -.*/bin/.* - -[include] - -[libs] - -[options] -suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe -esproposal.class_static_fields=enable -esproposal.class_instance_fields=enable -unsafe.enable_getters_and_setters=true - -[version] -^0.56.0 From 46351cc2763c4afea0fda10d389b1a6c79fe3f57 Mon Sep 17 00:00:00 2001 From: Riley Dulin Date: Wed, 15 Jan 2020 16:50:06 -0800 Subject: [PATCH 0041/1126] Use the devtools-protocol npm package to generate code Summary: Changelog: [Internal] Before, we were relying on checking out the `devtools-protocol` Github repo at a specific commit and making special changes to the JSON file. In order to make it easier to update, use the officially published npm package. I found the closest package version that was published, but it had two differences: * `Runtime.getHeapUsage` was either missing (in earlier versions) or experimental (in later versions) * `isDefault` and `isPageContext` were removed. I'm not sure what these were used for anyway, the comment leads me to believe they're probably not necessary anymore There were some customizations made previously to annotate `recursive` on some properties. The npm package doesn't set these, so I wrote some checks to add it back in if it can be detected. This was mostly to handle one special case: `Runtime.StackTrace`. The workaround seems to be fine for that case. Reviewed By: willholen Differential Revision: D19386890 fbshipit-source-id: db0d85f6bc71cba77ee67d85efe2f38376d7cc87 --- .../hermes/inspector/chrome/Connection.cpp | 26 ---------- .../hermes/inspector/chrome/MessageTypes.cpp | 46 +---------------- .../hermes/inspector/chrome/MessageTypes.h | 25 +--------- .../chrome/tests/ConnectionTests.cpp | 49 ++----------------- .../hermes/inspector/tools/message_types.txt | 1 - .../inspector/tools/msggen/package.json | 1 + .../inspector/tools/msggen/src/Converters.js | 18 ++++--- .../inspector/tools/msggen/src/Property.js | 21 +++----- .../inspector/tools/msggen/src/index.js | 17 ++++--- .../hermes/inspector/tools/msggen/yarn.lock | 5 ++ ReactCommon/hermes/inspector/tools/run_msggen | 3 +- 11 files changed, 39 insertions(+), 173 deletions(-) diff --git a/ReactCommon/hermes/inspector/chrome/Connection.cpp b/ReactCommon/hermes/inspector/chrome/Connection.cpp index 1f8e109b6572b9..8fa7b3633edcb4 100644 --- a/ReactCommon/hermes/inspector/chrome/Connection.cpp +++ b/ReactCommon/hermes/inspector/chrome/Connection.cpp @@ -83,7 +83,6 @@ class Connection::Impl : public inspector::InspectorObserver, void handle(const m::debugger::StepOverRequest &req) override; void handle(const m::heapProfiler::TakeHeapSnapshotRequest &req) override; void handle(const m::runtime::EvaluateRequest &req) override; - void handle(const m::runtime::GetHeapUsageRequest &req) override; void handle(const m::runtime::GetPropertiesRequest &req) override; private: @@ -257,11 +256,6 @@ void Connection::Impl::onContextCreated(Inspector &inspector) { note.context.id = 1; note.context.name = "hermes"; - // isDefault and isPageContext are custom properties that the legacy RN to - // JSC adapter set for some unknown reason. - note.context.isDefault = true; - note.context.isPageContext = true; - sendNotificationToClientViaExecutor(note); } @@ -570,26 +564,6 @@ void Connection::Impl::handle(const m::debugger::StepOverRequest &req) { sendResponseToClientViaExecutor(inspector_->stepOver(), req.id); } -void Connection::Impl::handle(const m::runtime::GetHeapUsageRequest &req) { - auto resp = std::make_shared(); - resp->id = req.id; - - inspector_ - ->executeIfEnabled( - "Runtime.getHeapUsage", - [this, resp](const debugger::ProgramState &state) { - HermesRuntime &rt = getRuntime(); - jsi::Instrumentation &i = rt.instrumentation(); - auto info = i.getHeapInfo(/* includeExpensive */ false); - - resp->usedSize = info["hermes_allocatedBytes"]; - resp->totalSize = info["hermes_heapSize"]; - }) - .via(executor_.get()) - .thenValue([this, resp](auto &&) { sendResponseToClient(*resp); }) - .thenError(sendErrorToClient(req.id)); -} - std::vector Connection::Impl::makePropsFromScope( std::pair frameAndScopeIndex, diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp index e0134d1751e77a..80667c4fac7700 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<986a7615a1af0edce2bf49c00b4ef623>> +// @generated SignedSource<<138b9ba90e2b7ed52d87874ad422df4b>> #include "MessageTypes.h" @@ -43,7 +43,6 @@ std::unique_ptr Request::fromJsonThrowOnError(const std::string &str) { {"HeapProfiler.takeHeapSnapshot", makeUnique}, {"Runtime.evaluate", makeUnique}, - {"Runtime.getHeapUsage", makeUnique}, {"Runtime.getProperties", makeUnique}, }; @@ -212,8 +211,6 @@ runtime::ExecutionContextDescription::ExecutionContextDescription( assign(origin, obj, "origin"); assign(name, obj, "name"); assign(auxData, obj, "auxData"); - assign(isPageContext, obj, "isPageContext"); - assign(isDefault, obj, "isDefault"); } dynamic runtime::ExecutionContextDescription::toDynamic() const { @@ -223,8 +220,6 @@ dynamic runtime::ExecutionContextDescription::toDynamic() const { put(obj, "origin", origin); put(obj, "name", name); put(obj, "auxData", auxData); - put(obj, "isPageContext", isPageContext); - put(obj, "isDefault", isDefault); return obj; } @@ -653,26 +648,6 @@ void runtime::EvaluateRequest::accept(RequestHandler &handler) const { handler.handle(*this); } -runtime::GetHeapUsageRequest::GetHeapUsageRequest() - : Request("Runtime.getHeapUsage") {} - -runtime::GetHeapUsageRequest::GetHeapUsageRequest(const dynamic &obj) - : Request("Runtime.getHeapUsage") { - assign(id, obj, "id"); - assign(method, obj, "method"); -} - -dynamic runtime::GetHeapUsageRequest::toDynamic() const { - dynamic obj = dynamic::object; - put(obj, "id", id); - put(obj, "method", method); - return obj; -} - -void runtime::GetHeapUsageRequest::accept(RequestHandler &handler) const { - handler.handle(*this); -} - runtime::GetPropertiesRequest::GetPropertiesRequest() : Request("Runtime.getProperties") {} @@ -815,25 +790,6 @@ dynamic runtime::EvaluateResponse::toDynamic() const { return obj; } -runtime::GetHeapUsageResponse::GetHeapUsageResponse(const dynamic &obj) { - assign(id, obj, "id"); - - dynamic res = obj.at("result"); - assign(usedSize, res, "usedSize"); - assign(totalSize, res, "totalSize"); -} - -dynamic runtime::GetHeapUsageResponse::toDynamic() const { - dynamic res = dynamic::object; - put(res, "usedSize", usedSize); - put(res, "totalSize", totalSize); - - dynamic obj = dynamic::object; - put(obj, "id", id); - put(obj, "result", std::move(res)); - return obj; -} - runtime::GetPropertiesResponse::GetPropertiesResponse(const dynamic &obj) { assign(id, obj, "id"); diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.h b/ReactCommon/hermes/inspector/chrome/MessageTypes.h index ef169f982222f8..25fddb3c1b7bd3 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.h +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.h @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<551bd6eb5c18ce9019815c7a6ad564c9>> +// @generated SignedSource<> #pragma once @@ -53,8 +53,6 @@ struct ExceptionDetails; struct ExecutionContextCreatedNotification; struct ExecutionContextDescription; using ExecutionContextId = int; -struct GetHeapUsageRequest; -struct GetHeapUsageResponse; struct GetPropertiesRequest; struct GetPropertiesResponse; struct InternalPropertyDescriptor; @@ -92,7 +90,6 @@ struct RequestHandler { virtual void handle(const debugger::StepOverRequest &req) = 0; virtual void handle(const heapProfiler::TakeHeapSnapshotRequest &req) = 0; virtual void handle(const runtime::EvaluateRequest &req) = 0; - virtual void handle(const runtime::GetHeapUsageRequest &req) = 0; virtual void handle(const runtime::GetPropertiesRequest &req) = 0; }; @@ -113,7 +110,6 @@ struct NoopRequestHandler : public RequestHandler { void handle(const debugger::StepOverRequest &req) override {} void handle(const heapProfiler::TakeHeapSnapshotRequest &req) override {} void handle(const runtime::EvaluateRequest &req) override {} - void handle(const runtime::GetHeapUsageRequest &req) override {} void handle(const runtime::GetPropertiesRequest &req) override {} }; @@ -215,8 +211,6 @@ struct runtime::ExecutionContextDescription : public Serializable { std::string origin; std::string name; folly::Optional auxData; - folly::Optional isPageContext; - folly::Optional isDefault; }; struct runtime::PropertyDescriptor : public Serializable { @@ -398,14 +392,6 @@ struct runtime::EvaluateRequest : public Request { folly::Optional awaitPromise; }; -struct runtime::GetHeapUsageRequest : public Request { - GetHeapUsageRequest(); - explicit GetHeapUsageRequest(const folly::dynamic &obj); - - folly::dynamic toDynamic() const override; - void accept(RequestHandler &handler) const override; -}; - struct runtime::GetPropertiesRequest : public Request { GetPropertiesRequest(); explicit GetPropertiesRequest(const folly::dynamic &obj); @@ -470,15 +456,6 @@ struct runtime::EvaluateResponse : public Response { folly::Optional exceptionDetails; }; -struct runtime::GetHeapUsageResponse : public Response { - GetHeapUsageResponse() = default; - explicit GetHeapUsageResponse(const folly::dynamic &obj); - folly::dynamic toDynamic() const override; - - double usedSize{}; - double totalSize{}; -}; - struct runtime::GetPropertiesResponse : public Response { GetPropertiesResponse() = default; explicit GetPropertiesResponse(const folly::dynamic &obj); diff --git a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp index efdd72290ea86f..d78ca58f04f122 100644 --- a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp +++ b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp @@ -227,8 +227,6 @@ m::runtime::ExecutionContextCreatedNotification expectExecutionContextCreated( EXPECT_EQ(note.context.id, 1); EXPECT_EQ(note.context.origin, ""); EXPECT_EQ(note.context.name, "hermes"); - EXPECT_EQ(note.context.isDefault, true); - EXPECT_EQ(note.context.isPageContext, true); return note; } @@ -1285,49 +1283,6 @@ TEST(ConnectionTests, testLoadMultipleScripts) { expectNotification(conn); } -TEST(ConnectionTests, testGetHeapUsage) { - using HUReq = m::runtime::GetHeapUsageRequest; - using HUResp = m::runtime::GetHeapUsageResponse; - - TestContext context; - AsyncHermesRuntime &asyncRuntime = context.runtime(); - SyncConnection &conn = context.conn(); - - int msgId = 1; - - asyncRuntime.executeScriptAsync(R"( - debugger; // [1] - var a = []; - for (var i = 0; i < 100; ++i) { - a.push({b: i}); - } - debugger; // [2] - )"); - - send(conn, msgId++); - expectExecutionContextCreated(conn); - expectNotification(conn); - - // [1] (line 1) hit debugger statement, check heap usage, resume. - expectNotification(conn); - const auto before = send(conn, msgId++); - send(conn, msgId++); - expectNotification(conn); - - // [2] (line 6) hit debugger statement, check heap usage, resume; - expectNotification(conn); - const auto after = send(conn, msgId++); - send(conn, msgId++); - expectNotification(conn); - - // Sanity checks - EXPECT_LE(before.usedSize, before.totalSize); - EXPECT_LE(after.usedSize, after.totalSize); - - // Check for growth - EXPECT_LT(before.usedSize, after.usedSize); -} - TEST(ConnectionTests, testGetProperties) { TestContext context; AsyncHermesRuntime &asyncRuntime = context.runtime(); @@ -1459,7 +1414,9 @@ TEST(ConnectionTests, testGetPropertiesOnlyOwnProperties) { conn, msgId++, scopeObject.objectId.value(), - {{"this", PropInfo("undefined")}, {"obj", PropInfo("object")}, {"protoObject", PropInfo("object")}}); + {{"this", PropInfo("undefined")}, + {"obj", PropInfo("object")}, + {"protoObject", PropInfo("object")}}); EXPECT_EQ(scopeChildren.count("obj"), 1); std::string objId = scopeChildren.at("obj"); diff --git a/ReactCommon/hermes/inspector/tools/message_types.txt b/ReactCommon/hermes/inspector/tools/message_types.txt index df900b23d2452f..d42b189adda4fd 100644 --- a/ReactCommon/hermes/inspector/tools/message_types.txt +++ b/ReactCommon/hermes/inspector/tools/message_types.txt @@ -20,5 +20,4 @@ HeapProfiler.takeHeapSnapshot Runtime.consoleAPICalled Runtime.evaluate Runtime.executionContextCreated -Runtime.getHeapUsage Runtime.getProperties diff --git a/ReactCommon/hermes/inspector/tools/msggen/package.json b/ReactCommon/hermes/inspector/tools/msggen/package.json index 39c978a94dc438..52aec233035dab 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/package.json +++ b/ReactCommon/hermes/inspector/tools/msggen/package.json @@ -32,6 +32,7 @@ } }, "dependencies": { + "devtools-protocol": "0.0.511679", "idx": "^2.1.0", "yargs": "^14.2.0" } diff --git a/ReactCommon/hermes/inspector/tools/msggen/src/Converters.js b/ReactCommon/hermes/inspector/tools/msggen/src/Converters.js index ac23fc1e8a2dd0..277c9fd1631f25 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/src/Converters.js +++ b/ReactCommon/hermes/inspector/tools/msggen/src/Converters.js @@ -18,7 +18,15 @@ export function toCppType(type: string): string { return type.substr(0, 1).toUpperCase() + type.substr(1); } -const jsTypeMappings: {[key: string]: string, ...} = { +export type JsTypeString = + | 'any' + | 'boolean' + | 'integer' + | 'number' + | 'object' + | 'string'; + +const jsTypeMappings = { any: 'folly::dynamic', array: 'folly::dynamic', boolean: 'bool', @@ -28,10 +36,6 @@ const jsTypeMappings: {[key: string]: string, ...} = { string: 'std::string', }; -export function jsTypeToCppType(jsTypeStr: string): string { - const cppType = jsTypeMappings[jsTypeStr]; - if (!cppType) { - throw new TypeError(`${jsTypeStr} is not an expected JS type string`); - } - return cppType; +export function jsTypeToCppType(jsTypeStr: JsTypeString): string { + return jsTypeMappings[jsTypeStr]; } diff --git a/ReactCommon/hermes/inspector/tools/msggen/src/Property.js b/ReactCommon/hermes/inspector/tools/msggen/src/Property.js index 15ece449c714d8..ab93dd05baeaec 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/src/Property.js +++ b/ReactCommon/hermes/inspector/tools/msggen/src/Property.js @@ -10,7 +10,12 @@ 'use strict'; -import {jsTypeToCppType, toCppNamespace, toCppType} from './Converters'; +import { + jsTypeToCppType, + toCppNamespace, + toCppType, + type JsTypeString, +} from './Converters'; export class Property { domain: string; @@ -110,14 +115,6 @@ function toFullCppType(curDomain: string, absOrRelRef: string) { return `${toCppNamespace(domain)}::${toCppType(id)}`; } -type JsTypeString = - | 'any' - | 'boolean' - | 'integer' - | 'number' - | 'object' - | 'string'; - class PrimitiveProperty extends Property { type: JsTypeString; @@ -159,15 +156,9 @@ class RefProperty extends Property { constructor(domain: string, obj: any) { super(domain, obj); this.$ref = obj.$ref; - this.recursive = obj.recursive; } getRefDebuggerName(): ?string { - // recursive props cause cycles--just ignore them - if (this.recursive) { - return null; - } - const [domain, id] = toDomainAndId(this.domain, this.$ref); return `${domain}.${id}`; } diff --git a/ReactCommon/hermes/inspector/tools/msggen/src/index.js b/ReactCommon/hermes/inspector/tools/msggen/src/index.js index b8680605b37b75..fab6c6527d0114 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/src/index.js +++ b/ReactCommon/hermes/inspector/tools/msggen/src/index.js @@ -12,6 +12,7 @@ import fs from 'fs'; +// $FlowFixMe import yargs from 'yargs'; import {Command} from './Command'; @@ -23,6 +24,9 @@ import {PropsType, Type} from './Type'; import {HeaderWriter} from './HeaderWriter'; import {ImplementationWriter} from './ImplementationWriter'; +// $FlowFixMe: this isn't a module, just a JSON file. +const proto = require('devtools-protocol/json/js_protocol.json'); + type Descriptor = {| types: Array, commands: Array, @@ -78,7 +82,9 @@ function buildGraph(desc: Descriptor): Graph { if (props) { for (const prop of props) { const refId = prop.getRefDebuggerName(); - if (refId) { + (prop: Object).recursive = refId && refId === nodeId; + if (refId && refId !== nodeId) { + // Don't add edges for recursive properties. graph.addEdge(nodeId, refId); } } @@ -182,7 +188,7 @@ function filterReachableFromRoots( function main() { const args = yargs - .usage('Usage: msggen ') + .usage('Usage: msggen ') .alias('h', 'help') .help('h') .boolean('e') @@ -191,17 +197,14 @@ function main() { .alias('r', 'roots') .describe('r', 'path to a file listing root types, events, and commands') .nargs('r', 1) - .demandCommand(3, 3).argv; + .demandCommand(2, 2).argv; const ignoreExperimental = !!args.e; - const [protoJsonPath, headerPath, implPath] = args._; + const [headerPath, implPath] = args._; const headerStream = fs.createWriteStream(headerPath); const implStream = fs.createWriteStream(implPath); - const protoJsonBuf = fs.readFileSync(protoJsonPath); - const proto = JSON.parse(protoJsonBuf.toString()); - const desc = parseDomains(proto.domains, ignoreExperimental); const graph = buildGraph(desc); const roots = parseRoots(desc, String(args.roots)); diff --git a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock index 7d4c312b5ac81b..af476cd43da6ca 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +++ b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock @@ -1907,6 +1907,11 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +devtools-protocol@0.0.507347: + version "0.0.511679" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.511679.tgz#ed69e7138b0659a035c2d57d64d75aaa1e493352" + integrity sha512-6Gk8SbN5DgeazXWTwIS+peg9RJ9diIhqZKd80Q7Cz8cKAWpM0onp6ShhGwJozkxK/fDpWwC+gOYSY431UqkSTQ== + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" diff --git a/ReactCommon/hermes/inspector/tools/run_msggen b/ReactCommon/hermes/inspector/tools/run_msggen index 3dc0787197caa6..053cb3673727e5 100755 --- a/ReactCommon/hermes/inspector/tools/run_msggen +++ b/ReactCommon/hermes/inspector/tools/run_msggen @@ -10,14 +10,13 @@ yarn build FBSOURCE=$(hg root) MSGTYPES_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/tools/message_types.txt" -PROTO_PATH="${FBSOURCE}/third-party/chrome-devtools-protocol/json/js_protocol.json" HEADER_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/chrome/MessageTypes.h" CPP_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp" node bin/index.js \ --ignore-experimental \ --roots "$MSGTYPES_PATH" \ - "$PROTO_PATH" "$HEADER_PATH" "$CPP_PATH" + "$HEADER_PATH" "$CPP_PATH" clang-format -i --style=file "$HEADER_PATH" clang-format -i --style=file "$CPP_PATH" From 0ee7fb98cc9cae89196570de306e37eefdd3b434 Mon Sep 17 00:00:00 2001 From: Riley Dulin Date: Wed, 15 Jan 2020 16:50:06 -0800 Subject: [PATCH 0042/1126] Update the chrome devtools protocol for the inspector Summary: Changelog: [Internal] Upgrade Chrome devtools protocol for Hermes Update to the most recent version of the devtools protocol, r730699. This just adds a few parameters to the stable API. They have reasonable defaults that shouldn't break the existing functionality. Reviewed By: willholen Differential Revision: D19387559 fbshipit-source-id: 49d9ebf4a1a20f349ea6e46be6d5f36184ba8afb --- .../hermes/inspector/chrome/MessageTypes.cpp | 18 +++++++++++++++++- .../hermes/inspector/chrome/MessageTypes.h | 10 +++++++++- .../hermes/inspector/tools/msggen/package.json | 2 +- .../hermes/inspector/tools/msggen/yarn.lock | 8 ++++---- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp index 80667c4fac7700..6fe6b31f617163 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<138b9ba90e2b7ed52d87874ad422df4b>> +// @generated SignedSource<<633984dcfe87d2822ef0e80c1aab93ef>> #include "MessageTypes.h" @@ -185,6 +185,7 @@ dynamic debugger::Scope::toDynamic() const { debugger::CallFrame::CallFrame(const dynamic &obj) { assign(callFrameId, obj, "callFrameId"); assign(functionName, obj, "functionName"); + assign(functionLocation, obj, "functionLocation"); assign(location, obj, "location"); assign(url, obj, "url"); assign(scopeChain, obj, "scopeChain"); @@ -197,6 +198,7 @@ dynamic debugger::CallFrame::toDynamic() const { put(obj, "callFrameId", callFrameId); put(obj, "functionName", functionName); + put(obj, "functionLocation", functionLocation); put(obj, "location", location); put(obj, "url", url); put(obj, "scopeChain", scopeChain); @@ -341,6 +343,7 @@ debugger::EvaluateOnCallFrameRequest::EvaluateOnCallFrameRequest( assign(includeCommandLineAPI, params, "includeCommandLineAPI"); assign(silent, params, "silent"); assign(returnByValue, params, "returnByValue"); + assign(throwOnSideEffect, params, "throwOnSideEffect"); } dynamic debugger::EvaluateOnCallFrameRequest::toDynamic() const { @@ -351,6 +354,7 @@ dynamic debugger::EvaluateOnCallFrameRequest::toDynamic() const { put(params, "includeCommandLineAPI", includeCommandLineAPI); put(params, "silent", silent); put(params, "returnByValue", returnByValue); + put(params, "throwOnSideEffect", throwOnSideEffect); dynamic obj = dynamic::object; put(obj, "id", id); @@ -471,6 +475,7 @@ debugger::SetBreakpointByUrlRequest::SetBreakpointByUrlRequest( assign(lineNumber, params, "lineNumber"); assign(url, params, "url"); assign(urlRegex, params, "urlRegex"); + assign(scriptHash, params, "scriptHash"); assign(columnNumber, params, "columnNumber"); assign(condition, params, "condition"); } @@ -480,6 +485,7 @@ dynamic debugger::SetBreakpointByUrlRequest::toDynamic() const { put(params, "lineNumber", lineNumber); put(params, "url", url); put(params, "urlRegex", urlRegex); + put(params, "scriptHash", scriptHash); put(params, "columnNumber", columnNumber); put(params, "condition", condition); @@ -592,11 +598,13 @@ heapProfiler::TakeHeapSnapshotRequest::TakeHeapSnapshotRequest( dynamic params = obj.at("params"); assign(reportProgress, params, "reportProgress"); + assign(treatGlobalObjectsAsRoots, params, "treatGlobalObjectsAsRoots"); } dynamic heapProfiler::TakeHeapSnapshotRequest::toDynamic() const { dynamic params = dynamic::object; put(params, "reportProgress", reportProgress); + put(params, "treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots); dynamic obj = dynamic::object; put(obj, "id", id); @@ -624,6 +632,7 @@ runtime::EvaluateRequest::EvaluateRequest(const dynamic &obj) assign(silent, params, "silent"); assign(contextId, params, "contextId"); assign(returnByValue, params, "returnByValue"); + assign(userGesture, params, "userGesture"); assign(awaitPromise, params, "awaitPromise"); } @@ -635,6 +644,7 @@ dynamic runtime::EvaluateRequest::toDynamic() const { put(params, "silent", silent); put(params, "contextId", contextId); put(params, "returnByValue", returnByValue); + put(params, "userGesture", userGesture); put(params, "awaitPromise", awaitPromise); dynamic obj = dynamic::object; @@ -897,6 +907,9 @@ debugger::ScriptParsedNotification::ScriptParsedNotification(const dynamic &obj) assign(hash, params, "hash"); assign(executionContextAuxData, params, "executionContextAuxData"); assign(sourceMapURL, params, "sourceMapURL"); + assign(hasSourceURL, params, "hasSourceURL"); + assign(isModule, params, "isModule"); + assign(length, params, "length"); } dynamic debugger::ScriptParsedNotification::toDynamic() const { @@ -911,6 +924,9 @@ dynamic debugger::ScriptParsedNotification::toDynamic() const { put(params, "hash", hash); put(params, "executionContextAuxData", executionContextAuxData); put(params, "sourceMapURL", sourceMapURL); + put(params, "hasSourceURL", hasSourceURL); + put(params, "isModule", isModule); + put(params, "length", length); dynamic obj = dynamic::object; put(obj, "method", method); diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.h b/ReactCommon/hermes/inspector/chrome/MessageTypes.h index 25fddb3c1b7bd3..3910ed4faa665f 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.h +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.h @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<> +// @generated SignedSource<<16a6754d1896fef0cbab2a05800f6885>> #pragma once @@ -195,6 +195,7 @@ struct debugger::CallFrame : public Serializable { debugger::CallFrameId callFrameId{}; std::string functionName; + folly::Optional functionLocation; debugger::Location location{}; std::string url; std::vector scopeChain; @@ -279,6 +280,7 @@ struct debugger::EvaluateOnCallFrameRequest : public Request { folly::Optional includeCommandLineAPI; folly::Optional silent; folly::Optional returnByValue; + folly::Optional throwOnSideEffect; }; struct debugger::PauseRequest : public Request { @@ -328,6 +330,7 @@ struct debugger::SetBreakpointByUrlRequest : public Request { int lineNumber{}; folly::Optional url; folly::Optional urlRegex; + folly::Optional scriptHash; folly::Optional columnNumber; folly::Optional condition; }; @@ -374,6 +377,7 @@ struct heapProfiler::TakeHeapSnapshotRequest : public Request { void accept(RequestHandler &handler) const override; folly::Optional reportProgress; + folly::Optional treatGlobalObjectsAsRoots; }; struct runtime::EvaluateRequest : public Request { @@ -389,6 +393,7 @@ struct runtime::EvaluateRequest : public Request { folly::Optional silent; folly::Optional contextId; folly::Optional returnByValue; + folly::Optional userGesture; folly::Optional awaitPromise; }; @@ -510,6 +515,9 @@ struct debugger::ScriptParsedNotification : public Notification { std::string hash; folly::Optional executionContextAuxData; folly::Optional sourceMapURL; + folly::Optional hasSourceURL; + folly::Optional isModule; + folly::Optional length; }; struct heapProfiler::AddHeapSnapshotChunkNotification : public Notification { diff --git a/ReactCommon/hermes/inspector/tools/msggen/package.json b/ReactCommon/hermes/inspector/tools/msggen/package.json index 52aec233035dab..8ee113ea68d624 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/package.json +++ b/ReactCommon/hermes/inspector/tools/msggen/package.json @@ -32,7 +32,7 @@ } }, "dependencies": { - "devtools-protocol": "0.0.511679", + "devtools-protocol": "0.0.730699", "idx": "^2.1.0", "yargs": "^14.2.0" } diff --git a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock index af476cd43da6ca..2baa205fe1ec0c 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +++ b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock @@ -1907,10 +1907,10 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= -devtools-protocol@0.0.507347: - version "0.0.511679" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.511679.tgz#ed69e7138b0659a035c2d57d64d75aaa1e493352" - integrity sha512-6Gk8SbN5DgeazXWTwIS+peg9RJ9diIhqZKd80Q7Cz8cKAWpM0onp6ShhGwJozkxK/fDpWwC+gOYSY431UqkSTQ== +devtools-protocol@0.0.730699: + version "0.0.730699" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.730699.tgz#4d18f6a9b7fb7cf3f1ffe73bfe14aad66cf3b2ef" + integrity sha512-dprBpuPzVIIXXL6GevzhvWe2wg836h3d5hY+n6IzzHbKLsUh6QlVmcIy15za0J3MhDFbmEH60s6uYsrw/tgBbw== diff-sequences@^24.9.0: version "24.9.0" From 434526e13d9b61715c0ab00f19298e44790708a2 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 16 Jan 2020 12:44:10 -0800 Subject: [PATCH 0043/1126] Get rid of implicit exact object in PickerExample Summary: In order to be sure that 0.62 does not require an exact-by-default codebase, we should get rid of any `{}` occurrences inside of react-native-github. If all the object types in react-native-github are either explicitly exact `{||}` or explicitly inexact `{...}` then those object types will have consistent semantics regardless of the Flow settings in the client codebase. Changelog: [Internal] Reviewed By: rickhanlonii Differential Revision: D19347283 fbshipit-source-id: 4c199bd7f1684b70df1b1c717941d0d477f67117 --- RNTester/js/examples/Picker/PickerExample.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNTester/js/examples/Picker/PickerExample.js b/RNTester/js/examples/Picker/PickerExample.js index 150ae0794861e2..c4d1e2bfcf4902 100644 --- a/RNTester/js/examples/Picker/PickerExample.js +++ b/RNTester/js/examples/Picker/PickerExample.js @@ -125,7 +125,7 @@ class ColorPickerExample extends React.Component<{...}, ColorState> { ); } } -class AccessibilityLabelPickerExample extends React.Component<{}, State> { +class AccessibilityLabelPickerExample extends React.Component<{||}, State> { state: State = { value: '3', }; From ce18521c9ead89666be253679a98a6ea39dd571b Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Thu, 16 Jan 2020 13:35:59 -0800 Subject: [PATCH 0044/1126] Ensure TurboModuleManager.getModule also queries CxxModuleWrappers Summary: We should also call `TurboModuleManager.getLegacyCxxModule('foo')` when we call `TurboModuleManager.getModule('foo')` is called. This fixes a Marketplace crash. See: D19432594 Changelog: [Android][Fixed] - Ensure TMM.getModule also queries CxxModuleWrappers Reviewed By: ejanzer Differential Revision: D19434549 fbshipit-source-id: cff741cf1587d2a0dbcdc5eb95016c8aa283b727 --- .../turbomodule/core/TurboModuleManager.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index 467a7e394d6f8c..fab7cd0f11bd5b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -10,6 +10,7 @@ import androidx.annotation.Nullable; import com.facebook.jni.HybridData; import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.CxxModuleWrapper; import com.facebook.react.bridge.JSIModule; import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.NativeModule; @@ -55,9 +56,8 @@ public List getEagerInitModuleNames() { return mTurbomoduleManagerDelegate.getEagerInitModuleNames(); } - @DoNotStrip @Nullable - protected TurboModule getJavaModule(String name) { + private TurboModule getJavaModule(String name) { if (!mTurboModules.containsKey(name)) { final TurboModule turboModule = mTurbomoduleManagerDelegate.getModule(name); @@ -75,9 +75,33 @@ protected TurboModule getJavaModule(String name) { return mTurboModules.get(name); } + @DoNotStrip + @Nullable + private TurboModule getLegacyCxxModule(String name) { + if (!mTurboModules.containsKey(name)) { + final CxxModuleWrapper turboModule = mTurbomoduleManagerDelegate.getLegacyCxxModule(name); + + if (turboModule instanceof TurboModule) { + /** + * TurboModuleManager is initialized after ReactApplicationContext has been setup. + * Therefore, it's safe to call initialize on the TurboModule. + */ + ((NativeModule) turboModule).initialize(); + + mTurboModules.put(name, (TurboModule) turboModule); + } + } + + return mTurboModules.get(name); + } + @Nullable public TurboModule getModule(String name) { - return getJavaModule(name); + TurboModule javaModule = getJavaModule(name); + if (javaModule != null) { + return javaModule; + } + return getLegacyCxxModule(name); } public Collection getModules() { From c40988cc22b0ea4d5250580adbf8a67586edf7b2 Mon Sep 17 00:00:00 2001 From: Nat Mote Date: Thu, 16 Jan 2020 14:03:30 -0800 Subject: [PATCH 0045/1126] Deploy Flow v0.116 to xplat Summary: Changelog: [Internal] Reviewed By: gkz Differential Revision: D19416307 fbshipit-source-id: 32767f24e5bfeb1912f7dd5527eb8c4db7a08a1a --- .flowconfig | 2 +- .flowconfig.android | 2 +- Libraries/Image/ImageViewNativeComponent.js | 3 ++- Libraries/Image/ImageViewViewConfig.js | 3 ++- Libraries/StyleSheet/processTransform.js | 6 ------ package.json | 2 +- template/_flowconfig | 2 +- yarn.lock | 8 ++++---- 8 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.flowconfig b/.flowconfig index b23b074f14bf2d..4c413037a12004 100644 --- a/.flowconfig +++ b/.flowconfig @@ -84,4 +84,4 @@ untyped-import untyped-type-import [version] -^0.115.0 +^0.116.0 diff --git a/.flowconfig.android b/.flowconfig.android index 45caa62b699e81..cbe0fae787de96 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -84,4 +84,4 @@ untyped-import untyped-type-import [version] -^0.115.0 +^0.116.0 diff --git a/Libraries/Image/ImageViewNativeComponent.js b/Libraries/Image/ImageViewNativeComponent.js index 3d42a66a11c5e1..b5dea64e6f19f7 100644 --- a/Libraries/Image/ImageViewNativeComponent.js +++ b/Libraries/Image/ImageViewNativeComponent.js @@ -52,4 +52,5 @@ if (global.RN$Bridgeless) { ); } -export default ((ImageViewNativeComponent: any): HostComponent); // flowlint-line unclear-type:off +// flowlint-next-line unclear-type:off +export default ((ImageViewNativeComponent: any): HostComponent); diff --git a/Libraries/Image/ImageViewViewConfig.js b/Libraries/Image/ImageViewViewConfig.js index 7c6c1beda4e03b..5870038e97d584 100644 --- a/Libraries/Image/ImageViewViewConfig.js +++ b/Libraries/Image/ImageViewViewConfig.js @@ -39,7 +39,8 @@ const ImageViewViewConfig = { validAttributes: { ...ReactNativeViewViewConfig.validAttributes, blurRadius: true, - capInsets: {diff: (require('../Utilities/differ/insetsDiffer'): any)}, // flowlint-line unclear-type:off + // flowlint-next-line unclear-type:off + capInsets: {diff: (require('../Utilities/differ/insetsDiffer'): any)}, defaultSource: { process: require('./resolveAssetSource'), }, diff --git a/Libraries/StyleSheet/processTransform.js b/Libraries/StyleSheet/processTransform.js index 353d3de776e3c0..051c363f3a0553 100644 --- a/Libraries/StyleSheet/processTransform.js +++ b/Libraries/StyleSheet/processTransform.js @@ -170,9 +170,6 @@ function _validateTransform(key, value, transformation) { switch (key) { case 'matrix': invariant( - /* $FlowFixMe(>=0.88.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.88 was deployed. To see the error, delete - * this comment and run Flow. */ value.length === 9 || value.length === 16, 'Matrix transform must have a length of 9 (2d) or 16 (3d). ' + 'Provided matrix has a length of %s: %s', @@ -185,9 +182,6 @@ function _validateTransform(key, value, transformation) { break; case 'translate': invariant( - /* $FlowFixMe(>=0.88.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.88 was deployed. To see the error, delete - * this comment and run Flow. */ value.length === 2 || value.length === 3, 'Transform with key translate must be an array of length 2 or 3, found %s: %s', /* $FlowFixMe(>=0.84.0 site=react_native_fb) This comment suppresses an diff --git a/package.json b/package.json index 9ef9962e7be99b..c2686908f2b84a 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "eslint-plugin-react-hooks": "^2.0.1", "eslint-plugin-react-native": "3.8.1", "eslint-plugin-relay": "1.4.1", - "flow-bin": "^0.115.0", + "flow-bin": "^0.116.0", "flow-remove-types": "1.2.3", "jest": "^24.8.0", "jest-junit": "^6.3.0", diff --git a/template/_flowconfig b/template/_flowconfig index fed57808e52c98..e05f3b0b998226 100644 --- a/template/_flowconfig +++ b/template/_flowconfig @@ -73,4 +73,4 @@ untyped-import untyped-type-import [version] -^0.115.0 +^0.116.0 diff --git a/yarn.lock b/yarn.lock index facb8b1112f78d..570326f5afc6f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3382,10 +3382,10 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -flow-bin@^0.115.0: - version "0.115.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.115.0.tgz#22e3ad9e5c7198967de80138ba8a9154ff387960" - integrity sha512-xW+U2SrBaAr0EeLvKmXAmsdnrH6x0Io17P6yRJTNgrrV42G8KXhBAD00s6oGbTTqRyHD0nP47kyuU34zljZpaQ== +flow-bin@^0.116.0: + version "0.116.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.116.0.tgz#f2e5ef318838ceb760e3f588b66076bc8ee1dc87" + integrity sha512-6q1f84mhAzHlUp9eTpIIJqINFBXf2+HGQllYfrkdQ+DfOLkF2wEZNHpVlYX1DL0G3uS8D//XEfsN2seZAc7jiw== flow-parser@0.*: version "0.89.0" From dd476d0506573f66adcde1740c4187ab185fc008 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Fri, 17 Jan 2020 11:19:57 -0800 Subject: [PATCH 0046/1126] Run rn-native-modules/specs/update_oss to stop tests from failing Summary: Changelog: [Internal] Fix following test failure ``` Date: 2020-01-17 07:18:10.533721 Step JSON: {"name": "Test: Verify OSS NativeModules Specs for iOS are up-to-date.", "continue_after_user_failure": true, "timeout": 3600, "shell": "cd \"$(hg root)/xplat/js\" && NODE_ENV=test scripts/rn-native-modules/specs/update_oss ios", "env": {}} Command: cd "$(hg root)/xplat/js" && NODE_ENV=test scripts/rn-native-modules/specs/update_oss ios Exit code: 1 Stdout: Building OSS NativeModule Specs - platform: ios... Stderr: Starting new Buck daemon... Using additional configuration options from .buckconfig.local, /etc/buckconfig.d/sandcastle PARSING BUCK FILES: FINISHED IN 5.9s CREATING ACTION GRAPH: FINISHED IN 0.1s DOWNLOADED 0 ARTIFACTS, 0.00 BYTES, 0.0% CACHE MISS BUILDING: FINISHED IN 8.5s (100%) 1/1 JOBS, 1 UPDATED Top slow rules //xplat/js:FBReactNativeSpec-flow-types-ios: 0.1s BUILD SUCCEEDED More details at https://our.intern.facebook.com/intern/buck/build/d68bbc08-49cf-4ef5-8eba-51d79bea09ba Error: Spec files are not up-to-date, please re-run 'js1 build oss-native-modules-specs -p ios'! at main.then.updated (/data/sandcastle/boxes/trunk-hg-fbobjc-fbsource/xplat/js/scripts/rn-native-modules/specs/update-specs.js:96:15) ``` I ran `js1 build oss-native-modules-specs -p ios` to fix it. Reviewed By: PeteTheHeat Differential Revision: D19450371 fbshipit-source-id: 0957298ad70ad3e8feca96622cd29ed223438961 --- .../FBReactNativeSpec-generated.mm | 6 ----- .../FBReactNativeSpec/FBReactNativeSpec.h | 27 ------------------- 2 files changed, 33 deletions(-) diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index a9a9a4c4329de2..2b57778f7e6d88 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -1722,12 +1722,6 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } // namespace react } // namespace facebook -@implementation RCTCxxConvert (NativeNetworkingAndroid_Header) -+ (RCTManagedPointer *)JS_NativeNetworkingAndroid_Header:(id)json -{ - return facebook::react::managedPointer(json); -} -@end namespace facebook { namespace react { diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index c2d82d8f05f51c..690ed8bf468dbb 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -1808,23 +1808,6 @@ namespace facebook { }; } // namespace react } // namespace facebook - -namespace JS { - namespace NativeNetworkingAndroid { - struct Header { - NSString *first() const; - NSString *second() const; - - Header(NSArray *const v) : _v(v) {} - private: - NSArray *_v; - }; - } -} - -@interface RCTCxxConvert (NativeNetworkingAndroid_Header) -+ (RCTManagedPointer *)JS_NativeNetworkingAndroid_Header:(id)json; -@end @protocol NativeNetworkingAndroidSpec - (void)sendRequest:(NSString *)method @@ -3551,16 +3534,6 @@ inline id JS::NativeLinking::SpecSendIntentExtrasElement::value() cons id const p = _v[@"value"]; return p; } -inline NSString *JS::NativeNetworkingAndroid::Header::first() const -{ - id const p = _v[0]; - return RCTBridgingToString(p); -} -inline NSString *JS::NativeNetworkingAndroid::Header::second() const -{ - id const p = _v[1]; - return RCTBridgingToString(p); -} inline NSString *JS::NativeNetworkingIOS::SpecSendRequestQuery::method() const { id const p = _v[@"method"]; From 459c54c4079e1ca9c2d12bae89a935e5a4c6444e Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 17 Jan 2020 15:53:23 -0800 Subject: [PATCH 0047/1126] Refactor RCTTurboModuleManager to take in a CallInvoker Summary: In bridgeless mode, `RCTTurboModuleManager` is initialized with a nil bridge. This has mostly worked, since `RCTBridge` doesn't do too many things for TMM (some notifs and perf markers). The one important thing it provides is a `_jsInvoker`. In bridgeless mode, up until this point `_jsInvoker` has been nil, and turbo modules were not able to call functions on the JS thread. This diff fixes that. Reviewed By: RSNara Differential Revision: D19437174 fbshipit-source-id: 86bfc0a47bd9576e7d3203b860e86446eb0b63dd --- RNTester/RNTester/AppDelegate.mm | 5 +++- .../core/platform/ios/RCTTurboModuleManager.h | 4 ++- .../platform/ios/RCTTurboModuleManager.mm | 30 +++++++++---------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/RNTester/RNTester/AppDelegate.mm b/RNTester/RNTester/AppDelegate.mm index 2819b4a42f1355..49766f32de4617 100644 --- a/RNTester/RNTester/AppDelegate.mm +++ b/RNTester/RNTester/AppDelegate.mm @@ -21,6 +21,7 @@ #import #import #import +#import #import @@ -114,7 +115,9 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self]; + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge + delegate:self + jsInvoker:std::make_shared(bridge.reactInstance)]; __weak __typeof(self) weakSelf = self; return std::make_unique([weakSelf, bridge](facebook::jsi::Runtime &runtime) { if (!bridge) { diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.h b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.h index 87724c49a403ed..7fdb9fd017b6af 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.h +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.h @@ -38,7 +38,9 @@ @interface RCTTurboModuleManager : NSObject -- (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id)delegate; +- (instancetype)initWithBridge:(RCTBridge *)bridge + delegate:(id)delegate + jsInvoker:(std::shared_ptr)jsInvoker; - (void)installJSBindingWithRuntime:(facebook::jsi::Runtime *)runtime; diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index 841f9256807139..004aa7113cf9eb 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -17,7 +17,6 @@ #import #import #import -#import #import #import @@ -63,10 +62,12 @@ @implementation RCTTurboModuleManager { std::atomic _invalidating; } -- (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id)delegate +- (instancetype)initWithBridge:(RCTBridge *)bridge + delegate:(id)delegate + jsInvoker:(std::shared_ptr)jsInvoker { if (self = [super init]) { - _jsInvoker = std::make_shared(bridge.reactInstance); + _jsInvoker = jsInvoker; _delegate = delegate; _bridge = bridge; _invalidating = false; @@ -353,10 +354,7 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name [[NSNotificationCenter defaultCenter] postNotificationName:RCTDidInitializeModuleNotification object:strongBridge - userInfo:@{ - @"module" : module, - @"bridge" : RCTNullIfNil([strongBridge parentBridge]) - }]; + userInfo:@{@"module" : module, @"bridge" : RCTNullIfNil([strongBridge parentBridge])}]; }; if ([[module class] respondsToSelector:@selector(requiresMainQueueSetup)] && @@ -445,11 +443,11 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification if (methodQueue) { dispatch_group_enter(moduleInvalidationGroup); [bridge - dispatchBlock:^{ - [((id)module) invalidate]; - dispatch_group_leave(moduleInvalidationGroup); - } - queue:methodQueue]; + dispatchBlock:^{ + [((id)module) invalidate]; + dispatch_group_leave(moduleInvalidationGroup); + } + queue:methodQueue]; continue; } } @@ -481,10 +479,10 @@ - (void)invalidate // Backward-compatibility: RCTInvalidating handling, but not adhering to desired methodQueue. for (const auto &p : rctCacheCopy) { - id module = p.second; - if ([module respondsToSelector:@selector(invalidate)]) { - [((id)module) invalidate]; - } + id module = p.second; + if ([module respondsToSelector:@selector(invalidate)]) { + [((id)module) invalidate]; + } } { From 44678bbf766c2ede54dd8ccd9d4105b72f93f612 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 17 Jan 2020 15:57:50 -0800 Subject: [PATCH 0048/1126] Add @DoNotStrip annotation to getJavaModule Summary: For some reason, I think this method is being optimized away, which is really strange considering that it's being used in getModule. Changelog: [Internal] Reviewed By: ejanzer Differential Revision: D19454855 fbshipit-source-id: 414b4888f7aacf730dd22939e2e2140b94dff4e7 --- .../com/facebook/react/turbomodule/core/TurboModuleManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index fab7cd0f11bd5b..431a82512c8e23 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -56,6 +56,7 @@ public List getEagerInitModuleNames() { return mTurbomoduleManagerDelegate.getEagerInitModuleNames(); } + @DoNotStrip @Nullable private TurboModule getJavaModule(String name) { if (!mTurboModules.containsKey(name)) { From 9457efa84c872f029027cdcfc3bae4f403715e48 Mon Sep 17 00:00:00 2001 From: Rajat Gupta Date: Fri, 17 Jan 2020 16:12:41 -0800 Subject: [PATCH 0049/1126] Always update background color and bar style on Android status bar Summary: Changelog: [Fix] Fix status bar color not updating when navigating between two screens with the same status bar color. Reviewed By: RSNara Differential Revision: D19439424 fbshipit-source-id: 44388f1f94c87c12102471d72183bb6c152a46b6 --- Libraries/Components/StatusBar/StatusBar.js | 38 ++++++++------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 16137272440f31..b62c0dcb11a432 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -455,31 +455,21 @@ class StatusBar extends React.Component { ); } } else if (Platform.OS === 'android') { - if ( - !oldProps || - oldProps.barStyle.value !== mergedProps.barStyle.value - ) { - NativeStatusBarManagerAndroid.setStyle(mergedProps.barStyle.value); - } - if ( - !oldProps || - oldProps.backgroundColor.value !== mergedProps.backgroundColor.value - ) { - const processedColor = processColor( - mergedProps.backgroundColor.value, + //todo(T60684787): Add back optimization to only update bar style and + //background color if the new value is different from the old value. + NativeStatusBarManagerAndroid.setStyle(mergedProps.barStyle.value); + const processedColor = processColor(mergedProps.backgroundColor.value); + if (processedColor == null) { + console.warn( + `\`StatusBar._updatePropsStack\`: Color ${ + mergedProps.backgroundColor.value + } parsed to null or undefined`, + ); + } else { + NativeStatusBarManagerAndroid.setColor( + processedColor, + mergedProps.backgroundColor.animated, ); - if (processedColor == null) { - console.warn( - `\`StatusBar._updatePropsStack\`: Color ${ - mergedProps.backgroundColor.value - } parsed to null or undefined`, - ); - } else { - NativeStatusBarManagerAndroid.setColor( - processedColor, - mergedProps.backgroundColor.animated, - ); - } } if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) { NativeStatusBarManagerAndroid.setHidden(mergedProps.hidden.value); From e69ce88ef63b769f8f23c1ecafcac459d15d39c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 17 Jan 2020 16:40:43 -0800 Subject: [PATCH 0050/1126] Use Xcode 11.3.0 and iOS 13.3 in tests (#27783) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/27783 Use Xcode 11.3.0 to run tests, using an iPhone 8 simulator running iOS 13.3. Snapshot tests disabled as they're failing on Circle CI. Changelog: [iOS] [Changed] - Use Xcode 11.3 and iOS 13.3 simulator in iOS tests Reviewed By: PeteTheHeat Differential Revision: D19411972 fbshipit-source-id: 3ddef9e6fbdbd3c35271732fc6d6d74de099230e --- .circleci/config.yml | 2 +- scripts/.tests.env | 3 ++- scripts/objc-test.sh | 1 + scripts/run-ci-e2e-tests.js | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e571eb7296cc64..eec9cddbf1106c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ executors: reactnativeios: <<: *defaults macos: - xcode: "11.2.1" + xcode: "11.3.0" # ------------------------- # COMMANDS diff --git a/scripts/.tests.env b/scripts/.tests.env index 1495605b04d074..3a6f63061da411 100644 --- a/scripts/.tests.env +++ b/scripts/.tests.env @@ -17,9 +17,10 @@ export AVD_NAME="testAVD" export AVD_ABI=x86 ## IOS ## -export IOS_TARGET_OS="13.2.2" +export IOS_TARGET_OS="13.3" export IOS_DEVICE="iPhone 8" export TVOS_DEVICE="Apple TV" +export SDK_IOS="iphonesimulator" ## CI OVERRIDES ## # Values to override when running in CI diff --git a/scripts/objc-test.sh b/scripts/objc-test.sh index 930113e5dd1b55..4c8c66e1f73cf5 100755 --- a/scripts/objc-test.sh +++ b/scripts/objc-test.sh @@ -15,6 +15,7 @@ SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT=$(dirname "$SCRIPTS") SKIPPED_TESTS=() +SKIPPED_TESTS+=("-skip-testing:RNTesterIntegrationTests/RNTesterSnapshotTests") # TODO: T60408036 This test crashes iOS 13 for bad access, please investigate # and re-enable. See https://gist.github.com/0xced/56035d2f57254cf518b5. SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/RCTJSONTests/testNotUTF8Convertible") diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index d2e59662819d86..48de37be0c37c3 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -213,12 +213,12 @@ try { // TODO: Get target OS and simulator from .tests.env tryExecNTimes( () => { - let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.2.2'; + let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.3'; let sdk = 'iphonesimulator'; let scheme = 'HelloWorld'; if (argv.tvos) { - destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.2.2'; + destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.3'; sdk = 'appletvsimulator'; scheme = 'HelloWorld-tvOS'; } From 8fe04cfd7e54b4dc98b788823dcaf4afc415c697 Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 17 Jan 2020 17:20:13 -0800 Subject: [PATCH 0051/1126] Migrate RCTDevSettings to TM Summary: As titled. The work to write the spec and make this module compatible were done in D18148890. Reviewed By: RSNara Differential Revision: D19442016 fbshipit-source-id: 369bb4247d6590d41ec414f93c79d98d4a6bed88 --- React/CoreModules/RCTDevSettings.mm | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/React/CoreModules/RCTDevSettings.mm b/React/CoreModules/RCTDevSettings.mm index 08615d6131add8..8cb40a963a8907 100644 --- a/React/CoreModules/RCTDevSettings.mm +++ b/React/CoreModules/RCTDevSettings.mm @@ -113,7 +113,7 @@ - (void)_reloadWithDefaults:(NSDictionary *)defaultValues @end -@interface RCTDevSettings () { +@interface RCTDevSettings () { BOOL _isJSLoaded; #if ENABLE_PACKAGER_CONNECTION RCTHandlerToken _reloadToken; @@ -129,14 +129,9 @@ @implementation RCTDevSettings RCT_EXPORT_MODULE() -+ (BOOL)requiresMainQueueSetup -{ - return YES; // RCT_DEV-only -} - - (instancetype)init { - // default behavior is to use NSUserDefaults + // Default behavior is to use NSUserDefaults with shake and hot loading enabled. NSDictionary *defaultValues = @{ kRCTDevSettingShakeToShowDevMenu : @YES, kRCTDevSettingHotLoadingEnabled : @YES, @@ -177,11 +172,9 @@ - (void)setBridge:(RCTBridge *)bridge #endif #if RCT_ENABLE_INSPECTOR - // we need this dispatch back to the main thread because even though this - // is executed on the main thread, at this point the bridge is not yet - // finished with its initialisation. But it does finish by the time it - // relinquishes control of the main thread, so only queue on the JS thread - // after the current main thread operation is done. + // We need this dispatch to the main thread because the bridge is not yet + // finished with its initialisation. By the time it relinquishes control of + // the main thread, this operation can be performed. dispatch_async(dispatch_get_main_queue(), ^{ [bridge dispatchBlock:^{ @@ -439,10 +432,18 @@ - (void)jsLoaded:(NSNotification *)notification }); } +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} + @end #else // #if RCT_DEV +@interface RCTDevSettings () +@end + @implementation RCTDevSettings - (instancetype)initWithDataSource:(id)dataSource @@ -489,6 +490,11 @@ - (void)setIsShakeToShowDevMenuEnabled:(BOOL)enabled { } +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} + @end #endif From a89a553532dbde051cf49a2876060b52c400caa1 Mon Sep 17 00:00:00 2001 From: Frieder Bluemle Date: Fri, 17 Jan 2020 21:05:29 -0800 Subject: [PATCH 0052/1126] Update Gradle wrapper to 6.1 (#27800) Summary: ``` Welcome to Gradle 6.1! Here are the highlights of this release: - Dependency cache is relocatable - Configurable compilation order between Groovy, Java & Scala - New sample projects in Gradle's documentation For more details see https://docs.gradle.org/6.1/release-notes.html ``` ## Changelog [Android] [Changed] - Update Gradle wrapper to 6.1 Pull Request resolved: https://github.com/facebook/react-native/pull/27800 Test Plan: Build project Differential Revision: D19460735 Pulled By: mdvacca fbshipit-source-id: b5e71cf97c0208947d6e524a74907b74f6a71c8d --- gradle/wrapper/gradle-wrapper.jar | Bin 58702 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 58702 -> 58695 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 12333 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1ba7206f882daf..31a0802f364091 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/template/android/gradle/wrapper/gradle-wrapper.jar b/template/android/gradle/wrapper/gradle-wrapper.jar index cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 12333 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 diff --git a/template/android/gradle/wrapper/gradle-wrapper.properties b/template/android/gradle/wrapper/gradle-wrapper.properties index 1ba7206f882daf..31a0802f364091 100644 --- a/template/android/gradle/wrapper/gradle-wrapper.properties +++ b/template/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From cc3e27d484d3a412f632454b7f1c637b2c271af2 Mon Sep 17 00:00:00 2001 From: Emily Janzer Date: Fri, 17 Jan 2020 21:10:18 -0800 Subject: [PATCH 0053/1126] Don't update dimensions for a new ReactRootView if they haven't changed Summary: ReactRootView currently caches the last seen DisplayMetrics so we can compare them against the current values in DisplayMetricsHolder to determine if the screen dimensions have changed. (If they have changed, we emit an event to notify JS of the new dimensions). However, ReactRootView initializes these member variables with empty DisplayMetrics, which means that the first time we check against them in onGlobalLayout, we will *always* emit an event to JS. This seems reasonable if you only have one ReactRootView, but if you create a new RRV for each RN screen in your app, then you're going to get updated dimensions on each navigation event, even though the screen dimensions have probably not changed. In this diff, I'm no longer storing the DisplayMetrics in ReactRootView at all, but instead am using temporary variables to check the new DisplayMetrics values against the old. Changelog: [Android][Fixed] Only update dimensions in ReactRootView if they've changed Reviewed By: JoshuaGross, mdvacca Differential Revision: D19395326 fbshipit-source-id: c01aee73064764503c9b49208032c790b83a1d29 --- .../com/facebook/react/ReactRootView.java | 32 ++----------------- .../modules/deviceinfo/DeviceInfoModule.java | 15 +++++++-- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index cfb6b5031c15a6..f4f220e9a26546 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -15,10 +15,8 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; -import android.os.Build; import android.os.Bundle; import android.util.AttributeSet; -import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Surface; @@ -683,8 +681,6 @@ private class CustomGlobalLayoutListener implements ViewTreeObserver.OnGlobalLay private int mKeyboardHeight = 0; private int mDeviceRotation = 0; - private DisplayMetrics mWindowMetrics = new DisplayMetrics(); - private DisplayMetrics mScreenMetrics = new DisplayMetrics(); /* package */ CustomGlobalLayoutListener() { DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext().getApplicationContext()); @@ -749,32 +745,8 @@ private void checkForDeviceOrientationChanges() { } private void checkForDeviceDimensionsChanges() { - // Get current display metrics. - DisplayMetricsHolder.initDisplayMetrics(getContext()); - // Check changes to both window and screen display metrics since they may not update at the - // same time. - if (!areMetricsEqual(mWindowMetrics, DisplayMetricsHolder.getWindowDisplayMetrics()) - || !areMetricsEqual(mScreenMetrics, DisplayMetricsHolder.getScreenDisplayMetrics())) { - mWindowMetrics.setTo(DisplayMetricsHolder.getWindowDisplayMetrics()); - mScreenMetrics.setTo(DisplayMetricsHolder.getScreenDisplayMetrics()); - emitUpdateDimensionsEvent(); - } - } - - private boolean areMetricsEqual(DisplayMetrics displayMetrics, DisplayMetrics otherMetrics) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - return displayMetrics.equals(otherMetrics); - } else { - // DisplayMetrics didn't have an equals method before API 17. - // Check all public fields manually. - return displayMetrics.widthPixels == otherMetrics.widthPixels - && displayMetrics.heightPixels == otherMetrics.heightPixels - && displayMetrics.density == otherMetrics.density - && displayMetrics.densityDpi == otherMetrics.densityDpi - && displayMetrics.scaledDensity == otherMetrics.scaledDensity - && displayMetrics.xdpi == otherMetrics.xdpi - && displayMetrics.ydpi == otherMetrics.ydpi; - } + // DeviceInfoModule caches the last dimensions emitted to JS, so we don't need to check here. + emitUpdateDimensionsEvent(); } private void emitOrientationChanged(final int newRotation) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java index d997266426500f..a6a2e5c4a47278 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java @@ -14,6 +14,8 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftException; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.turbomodule.core.interfaces.TurboModule; @@ -30,6 +32,7 @@ public class DeviceInfoModule extends ReactContextBaseJavaModule private @Nullable ReactApplicationContext mReactApplicationContext; private float mFontScale; + private @Nullable ReadableMap mPreviousDisplayMetrics; public DeviceInfoModule(ReactApplicationContext reactContext) { super(reactContext); @@ -83,9 +86,15 @@ public void emitUpdateDimensionsEvent() { } if (mReactApplicationContext.hasActiveCatalystInstance()) { - mReactApplicationContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit("didUpdateDimensions", DisplayMetricsHolder.getDisplayMetricsNativeMap(mFontScale)); + // Don't emit an event to JS if the dimensions haven't changed + WritableNativeMap displayMetrics = + DisplayMetricsHolder.getDisplayMetricsNativeMap(mFontScale); + if (!displayMetrics.equals(mPreviousDisplayMetrics)) { + mReactApplicationContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("didUpdateDimensions", displayMetrics); + mPreviousDisplayMetrics = displayMetrics; + } } else { ReactSoftException.logSoftException( NAME, From bef845ffd521aa83d779de584ec370f9f88f27f3 Mon Sep 17 00:00:00 2001 From: Emily Janzer Date: Sat, 18 Jan 2020 11:57:48 -0800 Subject: [PATCH 0054/1126] Save a copy of DisplayMetrics native map in DeviceInfoModule Summary: After some more testing, I discovered a problem in D19395326 because the native map that DeviceInfoModule was storing in `mPreviousDisplayMetrics` had been consumed when the event was emitted to JS. This caused the comparison to fail, so it would emit the event again when the dimensions hadn't changed. In this diff, I'm storing a Java-only copy of the native map before emitting the event to JS so this shouldn't happen. Changelog: [Android][Fixed] Fix bug in updating dimensions in JS Reviewed By: mdvacca Differential Revision: D19462861 fbshipit-source-id: 2e47479df93377b85fe87f255972dd31e874e3a8 --- .../com/facebook/react/modules/deviceinfo/DeviceInfoModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java index a6a2e5c4a47278..f8deb0e2e4e073 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java @@ -90,10 +90,10 @@ public void emitUpdateDimensionsEvent() { WritableNativeMap displayMetrics = DisplayMetricsHolder.getDisplayMetricsNativeMap(mFontScale); if (!displayMetrics.equals(mPreviousDisplayMetrics)) { + mPreviousDisplayMetrics = displayMetrics.copy(); mReactApplicationContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("didUpdateDimensions", displayMetrics); - mPreviousDisplayMetrics = displayMetrics; } } else { ReactSoftException.logSoftException( From 475df0699d9aaa5b498a82fd378ed2a64edcc544 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Sat, 18 Jan 2020 18:45:45 -0800 Subject: [PATCH 0055/1126] Fix rendering of FB emoji in RN Android Summary: This diff ensures the measurement and rendering of FB emojis is correnct in RN Android. Before this commit we were customizing Spannable object with FB emojis right before rendering the text into the TextView, this diff ensures that the Spannable is "customized" as soon as it is created, ensuring the measurement of the Text. changelog: [internal] Reviewed By: JoshuaGross Differential Revision: D19354107 fbshipit-source-id: 92e07cf30503404f7820f25eaa9efdc02f6bddbd --- .../react/views/text/ReactTextShadowNode.java | 9 +++++++ .../text/ReactTextViewManagerCallback.java | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 28180b31f9d36f..1a6599e643370b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -57,6 +57,8 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode { private boolean mShouldNotifyOnTextLayout; + private @Nullable ReactTextViewManagerCallback mReactTextViewManagerCallback = null; + private final YogaMeasureFunction mTextMeasureFunction = new YogaMeasureFunction() { @Override @@ -196,6 +198,10 @@ private void initMeasureFunction() { } } + public void setReactTextViewManagerCallback(ReactTextViewManagerCallback callback) { + mReactTextViewManagerCallback = callback; + } + // Return text alignment according to LTR or RTL style private int getTextAlign() { int textAlign = mTextAlign; @@ -217,6 +223,9 @@ public void onBeforeLayout(NativeViewHierarchyOptimizer nativeViewHierarchyOptim /* text (e.g. from `value` prop): */ null, /* supportsInlineViews: */ true, nativeViewHierarchyOptimizer); + if (mReactTextViewManagerCallback != null) { + mReactTextViewManagerCallback.onPostProcessSpannable(mPreparedSpannableText); + } markUpdated(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java new file mode 100644 index 00000000000000..16eeab59d70ea5 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.views.text; + +import android.text.Spannable; + +/** + * This interface allows clients of {@link ReactTextViewManager} to customize or prepare {@link + * Spannable} object that represent text that will be rendered on the screen. + */ +public interface ReactTextViewManagerCallback { + + /** + * Callback executed right after the {@link Spannable} object is created by React. + * + *

NB: THREAD SAFETY (this comment also exists at Countable.cpp) - * - *

{@link #dispose} deletes the corresponding native object on whatever thread the method is - * called on. In the common case when this is called by Countable#finalize(), this will be called on - * the system finalizer thread. If you manually call dispose on the Java object, the native object - * will be deleted synchronously on that thread. - */ -@DoNotStrip -public class Countable { - - static { - SoLoader.loadLibrary("fb"); - } - - // Private C++ instance - @DoNotStrip private long mInstance = 0; - - public native void dispose(); - - protected void finalize() throws Throwable { - dispose(); - super.finalize(); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/CpuCapabilitiesJni.java b/ReactAndroid/src/main/java/com/facebook/jni/CpuCapabilitiesJni.java deleted file mode 100644 index c19086c9aaff89..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/CpuCapabilitiesJni.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.soloader.SoLoader; - -/** Utility class to determine CPU capabilities */ -@DoNotStrip -public class CpuCapabilitiesJni { - - static { - SoLoader.loadLibrary("fb"); - } - - @DoNotStrip - public static native boolean nativeDeviceSupportsNeon(); - - @DoNotStrip - public static native boolean nativeDeviceSupportsVFPFP16(); - - @DoNotStrip - public static native boolean nativeDeviceSupportsX86(); -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java b/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java deleted file mode 100644 index 862f900e76f2d4..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; -import java.util.concurrent.atomic.AtomicReference; - -/** - * A thread which invokes the "destruct" routine for objects after they have been garbage collected. - * - *

An object which needs to be destructed should create a static subclass of {@link Destructor}. - * Once the referent object is garbage collected, the DestructorThread will callback to the {@link - * Destructor#destruct()} method. - * - *

The underlying thread in DestructorThread starts when the first Destructor is constructed and - * then runs indefinitely. - */ -public class DestructorThread { - - /** - * N.B The Destructor SHOULD NOT refer back to its referent object either explicitly or - * implicitly (for example, as a non-static inner class). This will create a reference cycle where - * the referent object will never be garbage collected. - */ - public abstract static class Destructor extends PhantomReference { - - private Destructor next; - private Destructor previous; - - public Destructor(Object referent) { - super(referent, sReferenceQueue); - sDestructorStack.push(this); - } - - private Destructor() { - super(null, sReferenceQueue); - } - - /** Callback which is invoked when the original object has been garbage collected. */ - protected abstract void destruct(); - } - - /** A list to keep all active Destructors in memory confined to the Destructor thread. */ - private static DestructorList sDestructorList; - /** A thread safe stack where new Destructors are placed before being add to sDestructorList. */ - private static DestructorStack sDestructorStack; - - private static ReferenceQueue sReferenceQueue; - private static Thread sThread; - - static { - sDestructorStack = new DestructorStack(); - sReferenceQueue = new ReferenceQueue(); - sDestructorList = new DestructorList(); - sThread = - new Thread("HybridData DestructorThread") { - @Override - public void run() { - while (true) { - try { - Destructor current = (Destructor) sReferenceQueue.remove(); - current.destruct(); - - // If current is in the sDestructorStack, - // transfer all the Destructors in the stack to the list. - if (current.previous == null) { - sDestructorStack.transferAllToList(); - } - - DestructorList.drop(current); - } catch (InterruptedException e) { - // Continue. This thread should never be terminated. - } - } - } - }; - - sThread.start(); - } - - private static class Terminus extends Destructor { - @Override - protected void destruct() { - throw new IllegalStateException("Cannot destroy Terminus Destructor."); - } - } - - /** This is a thread safe, lock-free Treiber-like Stack of Destructors. */ - private static class DestructorStack { - private AtomicReference mHead = new AtomicReference<>(); - - public void push(Destructor newHead) { - Destructor oldHead; - do { - oldHead = mHead.get(); - newHead.next = oldHead; - } while (!mHead.compareAndSet(oldHead, newHead)); - } - - public void transferAllToList() { - Destructor current = mHead.getAndSet(null); - while (current != null) { - Destructor next = current.next; - sDestructorList.enqueue(current); - current = next; - } - } - } - - /** A doubly-linked list of Destructors. */ - private static class DestructorList { - private Destructor mHead; - - public DestructorList() { - mHead = new Terminus(); - mHead.next = new Terminus(); - mHead.next.previous = mHead; - } - - public void enqueue(Destructor current) { - current.next = mHead.next; - mHead.next = current; - - current.next.previous = current; - current.previous = mHead; - } - - private static void drop(Destructor current) { - current.next.previous = current.previous; - current.previous.next = current.next; - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/HybridClassBase.java b/ReactAndroid/src/main/java/com/facebook/jni/HybridClassBase.java deleted file mode 100644 index 1ef6bf94146430..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/HybridClassBase.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip -public abstract class HybridClassBase extends HybridData {} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/HybridData.java b/ReactAndroid/src/main/java/com/facebook/jni/HybridData.java deleted file mode 100644 index 00c329da572a86..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/HybridData.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.soloader.SoLoader; - -/** - * This object holds a native C++ member for hybrid Java/C++ objects. - * - *

NB: THREAD SAFETY - * - *

{@link #resetNative} deletes the corresponding native object synchronously on whatever thread - * the method is called on. Otherwise, deletion will occur on the {@link DestructorThread} thread. - */ -@DoNotStrip -public class HybridData { - - static { - SoLoader.loadLibrary("fb"); - } - - @DoNotStrip private Destructor mDestructor = new Destructor(this); - - /** - * To explicitly delete the instance, call resetNative(). If the C++ instance is referenced after - * this is called, a NullPointerException will be thrown. resetNative() may be called multiple - * times safely. Because the {@link DestructorThread} also calls resetNative, the instance will - * not leak if this is not called, but timing of deletion and the thread the C++ dtor is called on - * will be at the whim of the Java GC. If you want to control the thread and timing of the - * destructor, you should call resetNative() explicitly. - */ - public synchronized void resetNative() { - mDestructor.destruct(); - } - - /** - * N.B. Thread safety. If you call isValid from a different thread than {@link #resetNative()} - * then be sure to do so while synchronizing on the hybrid. For example: - * - *


-   * synchronized(hybrid) {
-   *   if (hybrid.isValid) {
-   *     // Do stuff.
-   *   }
-   * }
-   * 
- */ - public boolean isValid() { - return mDestructor.mNativePointer != 0; - } - - public static class Destructor extends DestructorThread.Destructor { - - // Private C++ instance - @DoNotStrip private long mNativePointer; - - Destructor(Object referent) { - super(referent); - } - - @Override - protected final void destruct() { - // When invoked from the DestructorThread instead of resetNative, - // the DestructorThread has exclusive ownership of the HybridData - // so synchronization is not necessary. - deleteNative(mNativePointer); - mNativePointer = 0; - } - - static native void deleteNative(long pointer); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/IteratorHelper.java b/ReactAndroid/src/main/java/com/facebook/jni/IteratorHelper.java deleted file mode 100644 index cee868f3195351..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/IteratorHelper.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import androidx.annotation.Nullable; -import com.facebook.proguard.annotations.DoNotStrip; -import java.util.Iterator; - -/** - * To iterate over an Iterator from C++ requires two calls per entry: hasNext() and next(). This - * helper reduces it to one call and one field get per entry. It does not use a generic argument, - * since in C++, the types will be erased, anyway. This is *not* a {@link java.util.Iterator}. - */ -@DoNotStrip -public class IteratorHelper { - private final Iterator mIterator; - - // This is private, but accessed via JNI. - @DoNotStrip private @Nullable Object mElement; - - @DoNotStrip - public IteratorHelper(Iterator iterator) { - mIterator = iterator; - } - - @DoNotStrip - public IteratorHelper(Iterable iterable) { - mIterator = iterable.iterator(); - } - - /** - * Moves the helper to the next entry in the map, if any. Returns true iff there is an entry to - * read. - */ - @DoNotStrip - boolean hasNext() { - if (mIterator.hasNext()) { - mElement = mIterator.next(); - return true; - } else { - mElement = null; - return false; - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/JniTerminateHandler.java b/ReactAndroid/src/main/java/com/facebook/jni/JniTerminateHandler.java deleted file mode 100644 index 8bcbddfd7b6a30..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/JniTerminateHandler.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -public class JniTerminateHandler { - public static void handleTerminate(Throwable t) throws Throwable { - Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler(); - if (h == null) { - // Odd. Let the default std::terminate_handler deal with it. - return; - } - h.uncaughtException(Thread.currentThread(), t); - // That should exit. If it doesn't, let the default handler deal with it. - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/MapIteratorHelper.java b/ReactAndroid/src/main/java/com/facebook/jni/MapIteratorHelper.java deleted file mode 100644 index a7f18ecf9df643..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/MapIteratorHelper.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import androidx.annotation.Nullable; -import com.facebook.proguard.annotations.DoNotStrip; -import java.util.Iterator; -import java.util.Map; - -/** - * To iterate over a Map from C++ requires four calls per entry: hasNext(), next(), getKey(), - * getValue(). This helper reduces it to one call and two field gets per entry. It does not use a - * generic argument, since in C++, the types will be erased, anyway. This is *not* a {@link - * java.util.Iterator}. - */ -@DoNotStrip -public class MapIteratorHelper { - @DoNotStrip private final Iterator mIterator; - @DoNotStrip private @Nullable Object mKey; - @DoNotStrip private @Nullable Object mValue; - - @DoNotStrip - public MapIteratorHelper(Map map) { - mIterator = map.entrySet().iterator(); - } - - /** - * Moves the helper to the next entry in the map, if any. Returns true iff there is an entry to - * read. - */ - @DoNotStrip - boolean hasNext() { - if (mIterator.hasNext()) { - Map.Entry entry = mIterator.next(); - mKey = entry.getKey(); - mValue = entry.getValue(); - return true; - } else { - mKey = null; - mValue = null; - return false; - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/NativeRunnable.java b/ReactAndroid/src/main/java/com/facebook/jni/NativeRunnable.java deleted file mode 100644 index 9711cf96d486d8..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/NativeRunnable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; - -/** A Runnable that has a native run implementation. */ -@DoNotStrip -public class NativeRunnable implements Runnable { - - @DoNotStrip private final HybridData mHybridData; - - @DoNotStrip - private NativeRunnable(HybridData hybridData) { - mHybridData = hybridData; - } - - public native void run(); -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/ThreadScopeSupport.java b/ReactAndroid/src/main/java/com/facebook/jni/ThreadScopeSupport.java deleted file mode 100644 index 58141dda4f2bf0..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/ThreadScopeSupport.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.soloader.SoLoader; - -@DoNotStrip -public class ThreadScopeSupport { - static { - SoLoader.loadLibrary("fb"); - } - - // This is just used for ThreadScope::withClassLoader to have a java function - // in the stack so that jni has access to the correct classloader. - @DoNotStrip - private static void runStdFunction(long ptr) { - runStdFunctionImpl(ptr); - } - - private static native void runStdFunctionImpl(long ptr); -} diff --git a/ReactAndroid/src/main/java/com/facebook/jni/fbjni.pro b/ReactAndroid/src/main/java/com/facebook/jni/fbjni.pro deleted file mode 100644 index 09fad6a9e4ad87..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/fbjni.pro +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -# For common use cases for the hybrid pattern, keep symbols which may -# be referenced only from C++. - --keepclassmembers class * { - com.facebook.jni.HybridData *; - (com.facebook.jni.HybridData); -} - --keepclasseswithmembers class * { - com.facebook.jni.HybridData *; -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK index 68c1e25fcd901a..759d28915d8acb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK @@ -51,7 +51,7 @@ rn_android_library( react_native_target("java/com/facebook/react/turbomodule/core:callinvokerholder"), ] + ([react_native_target("jni/react/jni:jni")] if not IS_OSS_BUILD else []), exported_deps = [ - react_native_dep("java/com/facebook/jni:jni"), + react_native_dep("libraries/fbjni:java"), react_native_dep("java/com/facebook/proguard/annotations:annotations"), react_native_dep("third-party/java/jsr-330:jsr-330"), react_native_target("java/com/facebook/react/bridge:interfaces"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index a83a714043a1b4..3bddb58f351b38 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -12,7 +12,7 @@ #include "StateWrapperImpl.h" #import -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h index a2c1f71a43e2bc..12bc5f05f21027 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.cpp index 6b7303e2144f34..4a722a75b9d649 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.cpp @@ -7,7 +7,7 @@ #include "ComponentFactoryDelegate.h" #include -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h index e9d091df5ad529..aea2b356b1c7a1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentFactoryDelegate.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp index fb825461a43e9c..fc613c01290ef6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.cpp @@ -6,7 +6,7 @@ */ #include "EventBeatManager.h" -#include +#include using namespace facebook::jni; namespace facebook { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h index 462e0704fb00f7..5a36037c7d3334 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp index cdcc13fc306ca2..fda61cd1c9a66e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp @@ -6,7 +6,7 @@ */ #include "EventEmitterWrapper.h" -#include +#include using namespace facebook::jni; @@ -33,4 +33,4 @@ void EventEmitterWrapper::registerNatives() { } } // namespace react -} // namespace facebook +} // namespace facebook \ No newline at end of file diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h index 353aa24171941d..08809945270877 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp index 7101bb7032aaad..40bf0c392d6758 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.cpp @@ -6,7 +6,7 @@ */ #include "NodeStateWrapper.h" -#include +#include #include using namespace facebook::jni; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h index d19cae44ad1199..da7266e56f8cbc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/NodeStateWrapper.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp index f8b87bddd2dae5..3f135bca68527e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp @@ -5,8 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -#include #include +#include #include "Binding.h" #include "EventBeatManager.h" diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp index e35531e9325dba..20cd8b92850614 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.cpp @@ -7,7 +7,7 @@ #import "ReactNativeConfigHolder.h" -#include +#include using namespace facebook::react; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h index 8b28ffb0a953d0..4fe200a5ad400a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ReactNativeConfigHolder.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp index 73898875e87d93..9a5b929e9af10f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.cpp @@ -6,7 +6,7 @@ */ #include "StateWrapperImpl.h" -#include +#include #include using namespace facebook::jni; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h index fc93083c3b534d..b2d15a350f5a80 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/StateWrapperImpl.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk index 8ec340a601c033..c521147677c16d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk @@ -16,6 +16,6 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_CFLAGS += -fvisibility=hidden -fexceptions -frtti LOCAL_STATIC_LIBRARIES := libjsi libjsireact jscruntime -LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni include $(BUILD_SHARED_LIBRARY) diff --git a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/OnLoad.cpp index af724e282d68f8..f4e1783fee6f51 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/OnLoad.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk index 9eb190ae8ab10c..53fb0c2bf557ef 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk @@ -16,6 +16,6 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_CFLAGS += -fvisibility=hidden -fexceptions -frtti LOCAL_STATIC_LIBRARIES := libjsi libjsireact -LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni include $(BUILD_SHARED_LIBRARY) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp index a4ede5d71e3946..8883a318d89629 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.cpp @@ -7,7 +7,7 @@ #include "BlobCollector.h" -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.h b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.h index f688cd18084ba1..6cb79c052a3de1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.h +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BlobCollector.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/OnLoad.cpp index c30fb26dd2777c..54bb91af292d72 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/OnLoad.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include "BlobCollector.h" diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK index 00c073456a8d6a..092745fd177118 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK @@ -11,7 +11,7 @@ rn_android_library( ], deps = [ react_native_dep("third-party/android/androidx:annotation"), - react_native_dep("java/com/facebook/jni:jni"), + react_native_dep("libraries/fbjni:java"), react_native_dep("java/com/facebook/proguard/annotations:annotations"), react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"), react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK index 14d0577e360cef..ab6fd1ad0ef562 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK @@ -43,6 +43,6 @@ rn_android_library( deps = [ react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), react_native_target("java/com/facebook/react/turbomodule/core/interfaces:interfaces"), - react_native_dep("java/com/facebook/jni:jni"), + react_native_dep("libraries/fbjni:java"), ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk index 16329ccf65cabd..1633f5ad878a53 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk @@ -17,7 +17,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES = libcallinvoker -LOCAL_SHARED_LIBRARIES = libfb +LOCAL_SHARED_LIBRARIES = libfb libfbjni # Name of this module. LOCAL_MODULE := callinvokerholder diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h index 148ff2538b4856..edb621ce6a0717 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CallInvokerHolder.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp index 3a9e269fe32008..65dc87dd688c10 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp @@ -5,8 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -#include #include +#include #include "TurboModuleManager.h" diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp index eae88b38143e1f..db8c26ad075ab1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h index 131d77095be9c1..4c5a89eb43c43e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h index 6577d915f416a1..8fd63d66682667 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManagerDelegate.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/ReactAndroid/src/main/jni/first-party/fb/Android.mk b/ReactAndroid/src/main/jni/first-party/fb/Android.mk index 90f2565152d1aa..63907ed47f29fc 100644 --- a/ReactAndroid/src/main/jni/first-party/fb/Android.mk +++ b/ReactAndroid/src/main/jni/first-party/fb/Android.mk @@ -9,21 +9,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ assert.cpp \ - jni/ByteBuffer.cpp \ - jni/Countable.cpp \ - jni/Environment.cpp \ - jni/Exceptions.cpp \ - jni/fbjni.cpp \ - jni/Hybrid.cpp \ - jni/jni_helpers.cpp \ - jni/LocalString.cpp \ - jni/OnLoad.cpp \ - jni/ReadableByteChannel.cpp \ - jni/References.cpp \ - jni/WeakReference.cpp \ log.cpp \ - lyra/lyra.cpp \ - onload.cpp \ LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include @@ -38,7 +24,6 @@ LOCAL_CFLAGS += -DHAVE_POSIX_CLOCKS LOCAL_LDLIBS := -llog -ldl -landroid LOCAL_EXPORT_LDLIBS := -llog - LOCAL_MODULE := libfb include $(BUILD_SHARED_LIBRARY) diff --git a/ReactAndroid/src/main/jni/first-party/fb/Doxyfile b/ReactAndroid/src/main/jni/first-party/fb/Doxyfile deleted file mode 100644 index b44118dd5dbc5f..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/Doxyfile +++ /dev/null @@ -1,15 +0,0 @@ -PROJECT_NAME = "Facebook Android Support" -JAVADOC_AUTOBRIEF = YES -EXTRACT_ALL = YES -RECURSIVE = YES -EXCLUDE = tests -EXCLUDE_PATTERNS = *.cpp -GENERATE_HTML = YES -GENERATE_LATEX = NO -ENABLE_PREPROCESSING = YES -HIDE_UNDOC_MEMBERS = YES -HIDE_SCOPE_NAMES = YES -HIDE_FRIEND_COMPOUNDS = YES -HIDE_UNDOC_CLASSES = YES -SHOW_INCLUDE_FILES = NO -#ENABLED_SECTIONS = INTERNAL diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h deleted file mode 100644 index 49e4f502a4a3f7..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h deleted file mode 100644 index 58f4c9346bc018..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -namespace detail { -template -struct JPrimitive : JavaClass { - using typename JavaClass::javaobject; - using JavaClass::javaClassStatic; - static local_ref valueOf(jprim val) { - static auto cls = javaClassStatic(); - static auto method = - cls->template getStaticMethod("valueOf"); - return method(cls, val); - } - jprim value() const { - static auto method = - javaClassStatic()->template getMethod(T::kValueMethod); - return method(this->self()); - } -}; - -} // namespace detail - - -#define DEFINE_BOXED_PRIMITIVE(LITTLE, BIG) \ - struct J ## BIG : detail::JPrimitive { \ - static auto constexpr kJavaDescriptor = "Ljava/lang/" #BIG ";"; \ - static auto constexpr kValueMethod = #LITTLE "Value"; \ - j ## LITTLE LITTLE ## Value() const { \ - return value(); \ - } \ - }; \ - inline local_ref autobox(j ## LITTLE val) { \ - return J ## BIG::valueOf(val); \ - } - -DEFINE_BOXED_PRIMITIVE(boolean, Boolean) -DEFINE_BOXED_PRIMITIVE(byte, Byte) -DEFINE_BOXED_PRIMITIVE(char, Character) -DEFINE_BOXED_PRIMITIVE(short, Short) -DEFINE_BOXED_PRIMITIVE(int, Integer) -DEFINE_BOXED_PRIMITIVE(long, Long) -DEFINE_BOXED_PRIMITIVE(float, Float) -DEFINE_BOXED_PRIMITIVE(double, Double) - -#undef DEFINE_BOXED_PRIMITIVE - -struct JVoid : public jni::JavaClass { - static auto constexpr kJavaDescriptor = "Ljava/lang/Void;"; -}; - -inline local_ref autobox(alias_ref val) { - return make_local(val); -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h deleted file mode 100644 index 3218de8b6ddf31..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include "CoreClasses.h" -#include "References-forward.h" - -namespace facebook { -namespace jni { - -class JBuffer : public JavaClass { -public: - static constexpr const char* kJavaDescriptor = "Ljava/nio/Buffer;"; - - void rewind() const; -}; - -// JNI's NIO support has some awkward preconditions and error reporting. This -// class provides much more user-friendly access. -class FBEXPORT JByteBuffer : public JavaClass { - public: - static constexpr const char* kJavaDescriptor = "Ljava/nio/ByteBuffer;"; - - static local_ref wrapBytes(uint8_t* data, size_t size); - - bool isDirect() const; - - uint8_t* getDirectBytes() const; - size_t getDirectSize() const; -}; - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h deleted file mode 100644 index 0a6e85217d7970..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** @file Common.h - * - * Defining the stuff that don't deserve headers of their own... - */ - -#pragma once - -#include - -#include - -#include -#include - -#ifdef FBJNI_DEBUG_REFS -# ifdef __ANDROID__ -# include -# else -# include -# endif -#endif - -// If a pending JNI Java exception is found, wraps it in a JniException object and throws it as -// a C++ exception. -#define FACEBOOK_JNI_THROW_PENDING_EXCEPTION() \ - ::facebook::jni::throwPendingJniExceptionAsCppException() - -// If the condition is true, throws a JniException object, which wraps the pending JNI Java -// exception if any. If no pending exception is found, throws a JniException object that wraps a -// RuntimeException throwable.  -#define FACEBOOK_JNI_THROW_EXCEPTION_IF(CONDITION) \ - ::facebook::jni::throwCppExceptionIf(CONDITION) - -/// @cond INTERNAL - -namespace facebook { -namespace jni { - -FBEXPORT void throwPendingJniExceptionAsCppException(); -FBEXPORT void throwCppExceptionIf(bool condition); - -[[noreturn]] FBEXPORT void throwNewJavaException(jthrowable); -[[noreturn]] FBEXPORT void throwNewJavaException(const char* throwableName, const char* msg); -template -[[noreturn]] void throwNewJavaException(const char* throwableName, const char* fmt, Args... args); - - -/** - * This needs to be called at library load time, typically in your JNI_OnLoad method. - * - * The intended use is to return the result of initialize() directly - * from JNI_OnLoad and to do nothing else there. Library specific - * initialization code should go in the function passed to initialize - * (which can be, and probably should be, a C++ lambda). This approach - * provides correct error handling and translation errors during - * initialization into Java exceptions when appropriate. - * - * Failure to call this will cause your code to crash in a remarkably - * unhelpful way (typically a segfault) while trying to handle an exception - * which occurs later. - */ -FBEXPORT jint initialize(JavaVM*, std::function&&) noexcept; - -namespace internal { - -/** - * Retrieve a pointer the JNI environment of the current thread. - * - * @pre The current thread must be attached to the VM - */ -inline JNIEnv* getEnv() noexcept { - // TODO(T6594868) Benchmark against raw JNI access - return Environment::current(); -} - -// Define to get extremely verbose logging of references and to enable reference stats -#ifdef FBJNI_DEBUG_REFS -template -inline void dbglog(const char* msg, Args... args) { -# ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_VERBOSE, "fbjni_dbg", msg, args...); -# else - std::fprintf(stderr, msg, args...); -# endif -} - -#else - -template -inline void dbglog(const char*, Args...) { -} - -#endif - -}}} - -/// @endcond diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h deleted file mode 100644 index 4505842c6c26b6..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" -#include "File.h" - -namespace facebook { -namespace jni { - -class AContext : public JavaClass { - public: - static constexpr const char* kJavaDescriptor = "Landroid/content/Context;"; - - // Define a method that calls into the represented Java class - local_ref getCacheDir() { - static auto method = getClass()->getMethod("getCacheDir"); - return method(self()); - } - - local_ref getFilesDir() { - static auto method = getClass()->getMethod("getFilesDir"); - return method(self()); - } -}; - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h deleted file mode 100644 index a3d19d6ea96395..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -#include "Common.h" -#include "Exceptions.h" -#include "Meta.h" -#include "MetaConvert.h" - -namespace facebook { -namespace jni { - -// jobject ///////////////////////////////////////////////////////////////////////////////////////// - -inline bool isSameObject(alias_ref lhs, alias_ref rhs) noexcept { - return internal::getEnv()->IsSameObject(lhs.get(), rhs.get()) != JNI_FALSE; -} - -inline local_ref JObject::getClass() const noexcept { - return adopt_local(internal::getEnv()->GetObjectClass(self())); -} - -inline bool JObject::isInstanceOf(alias_ref cls) const noexcept { - return internal::getEnv()->IsInstanceOf(self(), cls.get()) != JNI_FALSE; -} - -template -inline T JObject::getFieldValue(JField field) const noexcept { - return field.get(self()); -} - -template -inline local_ref JObject::getFieldValue(JField field) const noexcept { - return adopt_local(field.get(self())); -} - -template -inline void JObject::setFieldValue(JField field, T value) noexcept { - field.set(self(), value); -} - -inline std::string JObject::toString() const { - static auto method = findClassLocal("java/lang/Object")->getMethod("toString"); - - return method(self())->toStdString(); -} - - -// Class is here instead of CoreClasses.h because we need -// alias_ref to be complete. -class MonitorLock { - public: - inline MonitorLock() noexcept; - inline MonitorLock(alias_ref object) noexcept; - inline ~MonitorLock() noexcept; - - inline MonitorLock(MonitorLock&& other) noexcept; - inline MonitorLock& operator=(MonitorLock&& other) noexcept; - - inline MonitorLock(const MonitorLock&) = delete; - inline MonitorLock& operator=(const MonitorLock&) = delete; - - private: - inline void reset() noexcept; - alias_ref owned_; -}; - -MonitorLock::MonitorLock() noexcept : owned_(nullptr) {} - -MonitorLock::MonitorLock(alias_ref object) noexcept - : owned_(object) { - internal::getEnv()->MonitorEnter(object.get()); -} - -void MonitorLock::reset() noexcept { - if (owned_) { - internal::getEnv()->MonitorExit(owned_.get()); - if (internal::getEnv()->ExceptionCheck()) { - abort(); // Lock mismatch - } - owned_ = nullptr; - } -} - -MonitorLock::~MonitorLock() noexcept { - reset(); -} - -MonitorLock::MonitorLock(MonitorLock&& other) noexcept - : owned_(other.owned_) -{ - other.owned_ = nullptr; -} - -MonitorLock& MonitorLock::operator=(MonitorLock&& other) noexcept { - reset(); - owned_ = other.owned_; - other.owned_ = nullptr; - return *this; -} - -inline MonitorLock JObject::lock() const noexcept { - return MonitorLock(this_); -} - -inline jobject JObject::self() const noexcept { - return this_; -} - -inline void swap(JObject& a, JObject& b) noexcept { - using std::swap; - swap(a.this_, b.this_); -} - -// JavaClass /////////////////////////////////////////////////////////////////////////////////////// - -namespace detail { -template -static local_ref newInstance(Args... args) { - static auto cls = JC::javaClassStatic(); - static auto constructor = cls->template getConstructor(); - return cls->newObject(constructor, args...); -} -} - - -template -auto JavaClass::self() const noexcept -> javaobject { - return static_cast(JObject::self()); -} - -// jclass ////////////////////////////////////////////////////////////////////////////////////////// - -namespace detail { - -// This is not a real type. It is used so people won't accidentally -// use a void* to initialize a NativeMethod. -struct NativeMethodWrapper; - -} - -struct NativeMethod { - const char* name; - std::string descriptor; - detail::NativeMethodWrapper* wrapper; -}; - -inline local_ref JClass::getSuperclass() const noexcept { - return adopt_local(internal::getEnv()->GetSuperclass(self())); -} - -inline void JClass::registerNatives(std::initializer_list methods) { - const auto env = internal::getEnv(); - - JNINativeMethod jnimethods[methods.size()]; - size_t i = 0; - for (auto it = methods.begin(); it < methods.end(); ++it, ++i) { - jnimethods[i].name = it->name; - jnimethods[i].signature = it->descriptor.c_str(); - jnimethods[i].fnPtr = reinterpret_cast(it->wrapper); - } - - auto result = env->RegisterNatives(self(), jnimethods, methods.size()); - FACEBOOK_JNI_THROW_EXCEPTION_IF(result != JNI_OK); -} - -inline bool JClass::isAssignableFrom(alias_ref other) const noexcept { - const auto env = internal::getEnv(); - // Ths method has behavior compatible with the - // java.lang.Class#isAssignableFrom method. The order of the - // arguments to the JNI IsAssignableFrom C function is "opposite" - // from what some might expect, which makes this code look a little - // odd, but it is correct. - const auto result = env->IsAssignableFrom(other.get(), self()); - return result; -} - -template -inline JConstructor JClass::getConstructor() const { - return getConstructor(jmethod_traits_from_cxx::constructor_descriptor().c_str()); -} - -template -inline JConstructor JClass::getConstructor(const char* descriptor) const { - constexpr auto constructor_method_name = ""; - return getMethod(constructor_method_name, descriptor); -} - -template -inline JMethod JClass::getMethod(const char* name) const { - return getMethod(name, jmethod_traits_from_cxx::descriptor().c_str()); -} - -template -inline JMethod JClass::getMethod( - const char* name, - const char* descriptor) const { - const auto env = internal::getEnv(); - const auto method = env->GetMethodID(self(), name, descriptor); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!method); - return JMethod{method}; -} - -template -inline JStaticMethod JClass::getStaticMethod(const char* name) const { - return getStaticMethod(name, jmethod_traits_from_cxx::descriptor().c_str()); -} - -template -inline JStaticMethod JClass::getStaticMethod( - const char* name, - const char* descriptor) const { - const auto env = internal::getEnv(); - const auto method = env->GetStaticMethodID(self(), name, descriptor); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!method); - return JStaticMethod{method}; -} - -template -inline JNonvirtualMethod JClass::getNonvirtualMethod(const char* name) const { - return getNonvirtualMethod(name, jmethod_traits_from_cxx::descriptor().c_str()); -} - -template -inline JNonvirtualMethod JClass::getNonvirtualMethod( - const char* name, - const char* descriptor) const { - const auto env = internal::getEnv(); - const auto method = env->GetMethodID(self(), name, descriptor); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!method); - return JNonvirtualMethod{method}; -} - -template -inline JField(), T>> -JClass::getField(const char* name) const { - return getField(name, jtype_traits::descriptor().c_str()); -} - -template -inline JField(), T>> JClass::getField( - const char* name, - const char* descriptor) const { - const auto env = internal::getEnv(); - auto field = env->GetFieldID(self(), name, descriptor); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!field); - return JField{field}; -} - -template -inline JStaticField(), T>> JClass::getStaticField( - const char* name) const { - return getStaticField(name, jtype_traits::descriptor().c_str()); -} - -template -inline JStaticField(), T>> JClass::getStaticField( - const char* name, - const char* descriptor) const { - const auto env = internal::getEnv(); - auto field = env->GetStaticFieldID(self(), name, descriptor); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!field); - return JStaticField{field}; -} - -template -inline T JClass::getStaticFieldValue(JStaticField field) const noexcept { - return field.get(self()); -} - -template -inline local_ref JClass::getStaticFieldValue(JStaticField field) noexcept { - return adopt_local(field.get(self())); -} - -template -inline void JClass::setStaticFieldValue(JStaticField field, T value) noexcept { - field.set(self(), value); -} - -template -inline local_ref JClass::newObject( - JConstructor constructor, - Args... args) const { - const auto env = internal::getEnv(); - auto object = env->NewObject(self(), constructor.getId(), - detail::callToJni( - detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!object); - return adopt_local(static_cast(object)); -} - -inline jclass JClass::self() const noexcept { - return static_cast(JObject::self()); -} - -inline void registerNatives(const char* name, std::initializer_list methods) { - findClassLocal(name)->registerNatives(methods); -} - - -// jstring ///////////////////////////////////////////////////////////////////////////////////////// - -inline local_ref make_jstring(const std::string& modifiedUtf8) { - return make_jstring(modifiedUtf8.c_str()); -} - -namespace detail { -// convert to std::string from jstring -template <> -struct Convert { - typedef jstring jniType; - static std::string fromJni(jniType t) { - return wrap_alias(t)->toStdString(); - } - static jniType toJniRet(const std::string& t) { - return make_jstring(t).release(); - } - static local_ref toCall(const std::string& t) { - return make_jstring(t); - } -}; - -// convert return from const char* -template <> -struct Convert { - typedef jstring jniType; - // no automatic synthesis of const char*. (It can't be freed.) - static jniType toJniRet(const char* t) { - return make_jstring(t).release(); - } - static local_ref toCall(const char* t) { - return make_jstring(t); - } -}; -} - -// jtypeArray ////////////////////////////////////////////////////////////////////////////////////// - -namespace detail { -inline size_t JArray::size() const noexcept { - const auto env = internal::getEnv(); - return env->GetArrayLength(self()); -} -} - -namespace detail { -template -inline ElementProxy::ElementProxy( - Target* target, - size_t idx) - : target_{target}, idx_{idx} {} - -template -inline ElementProxy& ElementProxy::operator=(const T& o) { - target_->setElement(idx_, o); - return *this; -} - -template -inline ElementProxy& ElementProxy::operator=(alias_ref& o) { - target_->setElement(idx_, o.get()); - return *this; -} - -template -inline ElementProxy& ElementProxy::operator=(alias_ref&& o) { - target_->setElement(idx_, o.get()); - return *this; -} - -template -inline ElementProxy& ElementProxy::operator=(const ElementProxy& o) { - auto src = o.target_->getElement(o.idx_); - target_->setElement(idx_, src.get()); - return *this; -} - -template -inline ElementProxy::ElementProxy::operator const local_ref () const { - return target_->getElement(idx_); -} - -template -inline ElementProxy::ElementProxy::operator local_ref () { - return target_->getElement(idx_); -} -} - -template -std::string JArrayClass::get_instantiated_java_descriptor() { - return "[" + jtype_traits::descriptor(); -}; - -template -std::string JArrayClass::get_instantiated_base_name() { - return get_instantiated_java_descriptor(); -}; - -template -auto JArrayClass::newArray(size_t size) -> local_ref { - static auto elementClass = findClassStatic(jtype_traits::base_name().c_str()); - const auto env = internal::getEnv(); - auto rawArray = env->NewObjectArray(size, elementClass.get(), nullptr); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!rawArray); - return adopt_local(static_cast(rawArray)); -} - -template -inline void JArrayClass::setElement(size_t idx, const T& value) { - const auto env = internal::getEnv(); - env->SetObjectArrayElement(this->self(), idx, value); -} - -template -inline local_ref JArrayClass::getElement(size_t idx) { - const auto env = internal::getEnv(); - auto rawElement = env->GetObjectArrayElement(this->self(), idx); - return adopt_local(static_cast(rawElement)); -} - -template -inline detail::ElementProxy> JArrayClass::operator[](size_t index) { - return detail::ElementProxy>(this, index); -} - -// jarray ///////////////////////////////////////////////////////////////////////////////////////// - -template -auto JPrimitiveArray::getRegion(jsize start, jsize length) - -> std::unique_ptr { - using T = typename jtype_traits::entry_type; - auto buf = std::unique_ptr{new T[length]}; - getRegion(start, length, buf.get()); - return buf; -} - -template -std::string JPrimitiveArray::get_instantiated_java_descriptor() { - return jtype_traits::descriptor(); -} -template -std::string JPrimitiveArray::get_instantiated_base_name() { - return JPrimitiveArray::get_instantiated_java_descriptor(); -} - -template -auto JPrimitiveArray::pin() -> PinnedPrimitiveArray> { - return PinnedPrimitiveArray>{this->self(), 0, 0}; -} - -template -auto JPrimitiveArray::pinRegion(jsize start, jsize length) - -> PinnedPrimitiveArray> { - return PinnedPrimitiveArray>{this->self(), start, length}; -} - -template -auto JPrimitiveArray::pinCritical() - -> PinnedPrimitiveArray> { - return PinnedPrimitiveArray>{this->self(), 0, 0}; -} - -template -class PinnedArrayAlloc { - public: - static void allocate( - alias_ref::array_type> array, - jsize start, - jsize length, - T** elements, - size_t* size, - jboolean* isCopy) { - (void) start; - (void) length; - *elements = array->getElements(isCopy); - *size = array->size(); - } - static void release( - alias_ref::array_type> array, - T* elements, - jint start, - jint size, - jint mode) { - (void) start; - (void) size; - array->releaseElements(elements, mode); - } -}; - -template -class PinnedCriticalAlloc { - public: - static void allocate( - alias_ref::array_type> array, - jsize start, - jsize length, - T** elements, - size_t* size, - jboolean* isCopy) { - const auto env = internal::getEnv(); - *elements = static_cast(env->GetPrimitiveArrayCritical(array.get(), isCopy)); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!elements); - *size = array->size(); - } - static void release( - alias_ref::array_type> array, - T* elements, - jint start, - jint size, - jint mode) { - const auto env = internal::getEnv(); - env->ReleasePrimitiveArrayCritical(array.get(), elements, mode); - } -}; - -template -class PinnedRegionAlloc { - public: - static void allocate( - alias_ref::array_type> array, - jsize start, - jsize length, - T** elements, - size_t* size, - jboolean* isCopy) { - auto buf = array->getRegion(start, length); - FACEBOOK_JNI_THROW_EXCEPTION_IF(!buf); - *elements = buf.release(); - *size = length; - *isCopy = true; - } - static void release( - alias_ref::array_type> array, - T* elements, - jint start, - jint size, - jint mode) { - std::unique_ptr holder; - if (mode == 0 || mode == JNI_ABORT) { - holder.reset(elements); - } - if (mode == 0 || mode == JNI_COMMIT) { - array->setRegion(start, size, elements); - } - } -}; - -// PinnedPrimitiveArray /////////////////////////////////////////////////////////////////////////// - -template -PinnedPrimitiveArray::PinnedPrimitiveArray(PinnedPrimitiveArray&& o) { - *this = std::move(o); -} - -template -PinnedPrimitiveArray& -PinnedPrimitiveArray::operator=(PinnedPrimitiveArray&& o) { - if (array_) { - release(); - } - array_ = std::move(o.array_); - elements_ = o.elements_; - isCopy_ = o.isCopy_; - size_ = o.size_; - start_ = o.start_; - o.clear(); - return *this; -} - -template -T* PinnedPrimitiveArray::get() { - return elements_; -} - -template -inline void PinnedPrimitiveArray::release() { - releaseImpl(0); - clear(); -} - -template -inline void PinnedPrimitiveArray::commit() { - releaseImpl(JNI_COMMIT); -} - -template -inline void PinnedPrimitiveArray::abort() { - releaseImpl(JNI_ABORT); - clear(); -} - -template -inline void PinnedPrimitiveArray::releaseImpl(jint mode) { - FACEBOOK_JNI_THROW_EXCEPTION_IF(array_.get() == nullptr); - Alloc::release(array_, elements_, start_, size_, mode); -} - -template -inline void PinnedPrimitiveArray::clear() noexcept { - array_ = nullptr; - elements_ = nullptr; - isCopy_ = false; - start_ = 0; - size_ = 0; -} - -template -inline T& PinnedPrimitiveArray::operator[](size_t index) { - FACEBOOK_JNI_THROW_EXCEPTION_IF(elements_ == nullptr); - return elements_[index]; -} - -template -inline bool PinnedPrimitiveArray::isCopy() const noexcept { - return isCopy_ == JNI_TRUE; -} - -template -inline size_t PinnedPrimitiveArray::size() const noexcept { - return size_; -} - -template -inline PinnedPrimitiveArray::~PinnedPrimitiveArray() noexcept { - if (elements_) { - release(); - } -} - -template -inline PinnedPrimitiveArray::PinnedPrimitiveArray(alias_ref::array_type> array, jint start, jint length) { - array_ = array; - start_ = start; - Alloc::allocate(array, start, length, &elements_, &size_, &isCopy_); -} - -template -inline alias_ref JavaClass::javaClassStatic() { - static auto cls = findClassStatic(jtype_traits::base_name().c_str()); - return cls; -} - -template -inline local_ref JavaClass::javaClassLocal() { - std::string className(jtype_traits::base_name().c_str()); - return findClassLocal(className.c_str()); -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h deleted file mode 100644 index 7ff8bceb482800..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -/** @file CoreClasses.h - * - * In CoreClasses.h wrappers for the core classes (jobject, jclass, and jstring) is defined - * to provide access to corresponding JNI functions + some convenience. - */ - -#include "References-forward.h" -#include "Meta-forward.h" -#include "TypeTraits.h" - -#include - -#include - -#include - -namespace facebook { -namespace jni { - -class JClass; -class JObject; - -/// Lookup a class by name. Note this functions returns an alias_ref that -/// points to a leaked global reference. This is appropriate for classes -/// that are never unloaded (which is any class in an Android app and most -/// Java programs). -/// -/// The most common use case for this is storing the result -/// in a "static auto" variable, or a static global. -/// -/// @return Returns a leaked global reference to the class -FBEXPORT alias_ref findClassStatic(const char* name); - -/// Lookup a class by name. Note this functions returns a local reference, -/// which means that it must not be stored in a static variable. -/// -/// The most common use case for this is one-time initialization -/// (like caching method ids). -/// -/// @return Returns a global reference to the class -FBEXPORT local_ref findClassLocal(const char* name); - -/// Check to see if two references refer to the same object. Comparison with nullptr -/// returns true if and only if compared to another nullptr. A weak reference that -/// refers to a reclaimed object count as nullptr. -FBEXPORT bool isSameObject(alias_ref lhs, alias_ref rhs) noexcept; - -// Together, these classes allow convenient use of any class with the fbjni -// helpers. To use: -// -// struct MyClass : public JavaClass { -// constexpr static auto kJavaDescriptor = "Lcom/example/package/MyClass;"; -// }; -// -// Then, an alias_ref will be backed by an instance of -// MyClass. JavaClass provides a convenient way to add functionality to these -// smart references. -// -// For example: -// -// struct MyClass : public JavaClass { -// constexpr static auto kJavaDescriptor = "Lcom/example/package/MyClass;"; -// -// void foo() { -// static auto method = javaClassStatic()->getMethod("foo"); -// method(self()); -// } -// -// static local_ref create(int i) { -// return newInstance(i); -// } -// }; -// -// auto obj = MyClass::create(10); -// obj->foo(); -// -// While users of a JavaClass-type can lookup methods and fields through the -// underlying JClass, those calls can only be checked at runtime. It is recommended -// that the JavaClass-type instead explicitly expose it's methods as in the example -// above. - -namespace detail { -template -static local_ref newInstance(Args... args); -} - -class MonitorLock; - -class FBEXPORT JObject : detail::JObjectBase { -public: - static constexpr auto kJavaDescriptor = "Ljava/lang/Object;"; - - static constexpr const char* get_instantiated_java_descriptor() { return nullptr; } - static constexpr const char* get_instantiated_base_name() { return nullptr; } - - /// Get a @ref local_ref of the object's class - local_ref getClass() const noexcept; - - /// Checks if the object is an instance of a class - bool isInstanceOf(alias_ref cls) const noexcept; - - /// Get the primitive value of a field - template - T getFieldValue(JField field) const noexcept; - - /// Get and wrap the value of a field in a @ref local_ref - template - local_ref getFieldValue(JField field) const noexcept; - - /// Set the value of field. Any Java type is accepted, including the primitive types - /// and raw reference types. - template - void setFieldValue(JField field, T value) noexcept; - - /// Convenience method to create a std::string representing the object - std::string toString() const; - - // Take this object's monitor lock - MonitorLock lock() const noexcept; - - typedef _jobject _javaobject; - typedef _javaobject* javaobject; - -protected: - jobject self() const noexcept; -private: - friend void swap(JObject& a, JObject& b) noexcept; - template - friend struct detail::ReprAccess; - template - friend class JavaClass; - - template - friend class JObjectWrapper; -}; - -// This is only to maintain backwards compatibility with things that are -// already providing a specialization of JObjectWrapper. Any such instances -// should be updated to use a JavaClass. -template<> -class JObjectWrapper : public JObject { -}; - - -namespace detail { -template -struct JTypeFor { - static_assert( - std::is_base_of< - std::remove_pointer::type, - typename std::remove_pointer::type - >::value, ""); - using _javaobject = typename std::remove_pointer::type; - using javaobject = JType; -}; - -template -struct JTypeFor { - // JNI pattern for jobject assignable pointer - struct _javaobject : Base::_javaobject { - // This allows us to map back to the defining type (in ReprType, for - // example). - typedef T JniRefRepr; - }; - using javaobject = _javaobject*; -}; -} - -// JavaClass provides a method to inform fbjni about user-defined Java types. -// Given a class: -// struct Foo : JavaClass { -// static constexpr auto kJavaDescriptor = "Lcom/example/package/Foo;"; -// }; -// fbjni can determine the java type/method signatures for Foo::javaobject and -// smart refs (like alias_ref) will hold an instance of Foo -// and provide access to it through the -> and * operators. -// -// The "Base" template argument can be used to specify the JavaClass superclass -// of this type (for instance, JString's Base is JObject). -// -// The "JType" template argument is used to provide a jni type (like jstring, -// jthrowable) to be used as javaobject. This should only be necessary for -// built-in jni types and not user-defined ones. -template -class FBEXPORT JavaClass : public Base { - using JObjType = typename detail::JTypeFor; -public: - using _javaobject = typename JObjType::_javaobject; - using javaobject = typename JObjType::javaobject; - - using JavaBase = JavaClass; - - static alias_ref javaClassStatic(); - static local_ref javaClassLocal(); -protected: - /// Allocates a new object and invokes the specified constructor - /// Like JClass's getConstructor, this function can only check at runtime if - /// the class actually has a constructor that accepts the corresponding types. - /// While a JavaClass-type can expose this function directly, it is recommended - /// to instead to use this to explicitly only expose those constructors that - /// the Java class actually has (i.e. with static create() functions). - template - static local_ref newInstance(Args... args) { - return detail::newInstance(args...); - } - - javaobject self() const noexcept; -}; - -/// Wrapper to provide functionality to jclass references -struct NativeMethod; - -class FBEXPORT JClass : public JavaClass { - public: - /// Java type descriptor - static constexpr const char* kJavaDescriptor = "Ljava/lang/Class;"; - - /// Get a @local_ref to the super class of this class - local_ref getSuperclass() const noexcept; - - /// Register native methods for the class. Usage looks like this: - /// - /// classRef->registerNatives({ - /// makeNativeMethod("nativeMethodWithAutomaticDescriptor", - /// methodWithAutomaticDescriptor), - /// makeNativeMethod("nativeMethodWithExplicitDescriptor", - /// "(Lcom/facebook/example/MyClass;)V", - /// methodWithExplicitDescriptor), - /// makeCriticalNativeMethod_DO_NOT_USE_OR_YOU_WILL_BE_FIRED("criticalNativeMethodWithAutomaticDescriptor", - /// criticalNativeMethodWithAutomaticDescriptor), - /// makeCriticalNativeMethod_DO_NOT_USE_OR_YOU_WILL_BE_FIRED("criticalNativeMethodWithExplicitDescriptor", - /// "(IIF)Z", - /// criticalNativeMethodWithExplicitDescriptor), - /// }); - /// - /// By default, C++ exceptions raised will be converted to Java exceptions. - /// To avoid this and get the "standard" JNI behavior of a crash when a C++ - /// exception is crashing out of the JNI method, declare the method noexcept. - /// This does NOT apply to critical native methods, where exceptions causes - /// a crash. - void registerNatives(std::initializer_list methods); - - /// Check to see if the class is assignable from another class - /// @pre cls != nullptr - bool isAssignableFrom(alias_ref cls) const noexcept; - - /// Convenience method to lookup the constructor with descriptor as specified by the - /// type arguments - template - JConstructor getConstructor() const; - - /// Convenience method to lookup the constructor with specified descriptor - template - JConstructor getConstructor(const char* descriptor) const; - - /// Look up the method with given name and descriptor as specified with the type arguments - template - JMethod getMethod(const char* name) const; - - /// Look up the method with given name and descriptor - template - JMethod getMethod(const char* name, const char* descriptor) const; - - /// Lookup the field with the given name and deduced descriptor - template - JField(), T>> getField(const char* name) const; - - /// Lookup the field with the given name and descriptor - template - JField(), T>> getField(const char* name, const char* descriptor) const; - - /// Lookup the static field with the given name and deduced descriptor - template - JStaticField(), T>> getStaticField(const char* name) const; - - /// Lookup the static field with the given name and descriptor - template - JStaticField(), T>> getStaticField( - const char* name, - const char* descriptor) const; - - /// Get the primitive value of a static field - template - T getStaticFieldValue(JStaticField field) const noexcept; - - /// Get and wrap the value of a field in a @ref local_ref - template - local_ref getStaticFieldValue(JStaticField field) noexcept; - - /// Set the value of field. Any Java type is accepted, including the primitive types - /// and raw reference types. - template - void setStaticFieldValue(JStaticField field, T value) noexcept; - - /// Allocates a new object and invokes the specified constructor - template - local_ref newObject(JConstructor constructor, Args... args) const; - - /// Look up the static method with given name and descriptor as specified with the type arguments - template - JStaticMethod getStaticMethod(const char* name) const; - - /// Look up the static method with given name and descriptor - template - JStaticMethod getStaticMethod(const char* name, const char* descriptor) const; - - /// Look up the non virtual method with given name and descriptor as specified with the - /// type arguments - template - JNonvirtualMethod getNonvirtualMethod(const char* name) const; - - /// Look up the non virtual method with given name and descriptor - template - JNonvirtualMethod getNonvirtualMethod(const char* name, const char* descriptor) const; - -private: - jclass self() const noexcept; -}; - -// Convenience method to register methods on a class without holding -// onto the class object. -void registerNatives(const char* name, std::initializer_list methods); - -/// Wrapper to provide functionality to jstring references -class FBEXPORT JString : public JavaClass { - public: - /// Java type descriptor - static constexpr const char* kJavaDescriptor = "Ljava/lang/String;"; - - /// Convenience method to convert a jstring object to a std::string - std::string toStdString() const; -}; - -/// Convenience functions to convert a std::string or const char* into a @ref local_ref to a -/// jstring -FBEXPORT local_ref make_jstring(const char* modifiedUtf8); -FBEXPORT local_ref make_jstring(const std::string& modifiedUtf8); - -namespace detail { -template -class ElementProxy { - private: - Target* target_; - size_t idx_; - - public: - using T = typename Target::javaentry; - ElementProxy(Target* target, size_t idx); - - ElementProxy& operator=(const T& o); - - ElementProxy& operator=(alias_ref& o); - - ElementProxy& operator=(alias_ref&& o); - - ElementProxy& operator=(const ElementProxy& o); - - operator const local_ref () const; - - operator local_ref (); -}; -} - -namespace detail { -class FBEXPORT JArray : public JavaClass { - public: - // This cannot be used in a scope that derives a descriptor (like in a method - // signature). Use a more derived type instead (like JArrayInt or - // JArrayClass). - static constexpr const char* kJavaDescriptor = nullptr; - size_t size() const noexcept; -}; - -// This is used so that the JArrayClass javaobject extends jni's -// jobjectArray. This class should not be used directly. A general Object[] -// should use JArrayClass. -class FBEXPORT JTypeArray : public JavaClass { - // This cannot be used in a scope that derives a descriptor (like in a method - // signature). - static constexpr const char* kJavaDescriptor = nullptr; -}; -} - -template -class JArrayClass : public JavaClass, detail::JTypeArray> { - public: - static_assert(is_plain_jni_reference(), ""); - // javaentry is the jni type of an entry in the array (i.e. jint). - using javaentry = T; - // javaobject is the jni type of the array. - using javaobject = typename JavaClass, detail::JTypeArray>::javaobject; - static constexpr const char* kJavaDescriptor = nullptr; - static std::string get_instantiated_java_descriptor(); - static std::string get_instantiated_base_name(); - - /// Allocate a new array from Java heap, for passing as a JNI parameter or return value. - /// NOTE: if using as a return value, you want to call release() instead of get() on the - /// smart pointer. - static local_ref newArray(size_t count); - - /// Assign an object to the array. - /// Typically you will use the shorthand (*ref)[idx]=value; - void setElement(size_t idx, const T& value); - - /// Read an object from the array. - /// Typically you will use the shorthand - /// T value = (*ref)[idx]; - /// If you use auto, you'll get an ElementProxy, which may need to be cast. - local_ref getElement(size_t idx); - - /// EXPERIMENTAL SUBSCRIPT SUPPORT - /// This implementation of [] returns a proxy object which then has a bunch of specializations - /// (adopt_local free function, operator= and casting overloads on the ElementProxy) that can - /// make code look like it is dealing with a T rather than an obvious proxy. In particular, the - /// proxy in this iteration does not read a value and therefore does not create a LocalRef - /// until one of these other operators is used. There are certainly holes that you may find - /// by using idioms that haven't been tried yet. Consider yourself warned. On the other hand, - /// it does make for some idiomatic assignment code; see TestBuildStringArray in fbjni_tests - /// for some examples. - detail::ElementProxy operator[](size_t idx); -}; - -template -using jtypeArray = typename JArrayClass::javaobject; - -template -local_ref::javaobject> adopt_local_array(jobjectArray ref) { - return adopt_local(static_cast::javaobject>(ref)); -} - -template -local_ref adopt_local(detail::ElementProxy elementProxy) { - return static_cast>(elementProxy); -} - -template -class PinnedPrimitiveArray; - -template class PinnedArrayAlloc; -template class PinnedRegionAlloc; -template class PinnedCriticalAlloc; - -/// Wrapper to provide functionality to jarray references. -/// This is an empty holder by itself. Construct a PinnedPrimitiveArray to actually interact with -/// the elements of the array. -template -class FBEXPORT JPrimitiveArray : - public JavaClass, detail::JArray, JArrayType> { - static_assert(is_jni_primitive_array(), ""); - public: - static constexpr const char* kJavaDescriptor = nullptr; - static std::string get_instantiated_java_descriptor(); - static std::string get_instantiated_base_name(); - - using T = typename jtype_traits::entry_type; - - static local_ref newArray(size_t count); - - void getRegion(jsize start, jsize length, T* buf); - std::unique_ptr getRegion(jsize start, jsize length); - void setRegion(jsize start, jsize length, const T* buf); - - /// Returns a view of the underlying array. This will either be a "pinned" - /// version of the array (in which case changes to one immediately affect the - /// other) or a copy of the array (in which cases changes to the view will take - /// affect when destroyed or on calls to release()/commit()). - PinnedPrimitiveArray> pin(); - - /// Returns a view of part of the underlying array. A pinned region is always - /// backed by a copy of the region. - PinnedPrimitiveArray> pinRegion(jsize start, jsize length); - - /// Returns a view of the underlying array like pin(). However, while the pin - /// is held, the code is considered within a "critical region". In a critical - /// region, native code must not call JNI functions or make any calls that may - /// block on other Java threads. These restrictions make it more likely that - /// the view will be "pinned" rather than copied (for example, the VM may - /// suspend garbage collection within a critical region). - PinnedPrimitiveArray> pinCritical(); - -private: - friend class PinnedArrayAlloc; - T* getElements(jboolean* isCopy); - void releaseElements(T* elements, jint mode); -}; - -FBEXPORT local_ref make_boolean_array(jsize size); -FBEXPORT local_ref make_byte_array(jsize size); -FBEXPORT local_ref make_char_array(jsize size); -FBEXPORT local_ref make_short_array(jsize size); -FBEXPORT local_ref make_int_array(jsize size); -FBEXPORT local_ref make_long_array(jsize size); -FBEXPORT local_ref make_float_array(jsize size); -FBEXPORT local_ref make_double_array(jsize size); - -using JArrayBoolean = JPrimitiveArray; -using JArrayByte = JPrimitiveArray; -using JArrayChar = JPrimitiveArray; -using JArrayShort = JPrimitiveArray; -using JArrayInt = JPrimitiveArray; -using JArrayLong = JPrimitiveArray; -using JArrayFloat = JPrimitiveArray; -using JArrayDouble = JPrimitiveArray; - -/// RAII class for pinned primitive arrays -/// This currently only supports read/write access to existing java arrays. You can't create a -/// primitive array this way yet. This class also pins the entire array into memory during the -/// lifetime of the PinnedPrimitiveArray. If you need to unpin the array manually, call the -/// release() or abort() functions. During a long-running block of code, you -/// should unpin the array as soon as you're done with it, to avoid holding up -/// the Java garbage collector. -template -class PinnedPrimitiveArray { - public: - static_assert(is_jni_primitive::value, - "PinnedPrimitiveArray requires primitive jni type."); - - using ArrayType = typename jtype_traits::array_type; - - PinnedPrimitiveArray(PinnedPrimitiveArray&&); - PinnedPrimitiveArray(const PinnedPrimitiveArray&) = delete; - ~PinnedPrimitiveArray() noexcept; - - PinnedPrimitiveArray& operator=(PinnedPrimitiveArray&&); - PinnedPrimitiveArray& operator=(const PinnedPrimitiveArray&) = delete; - - T* get(); - void release(); - /// Unpins the array. If the array is a copy, pending changes are discarded. - void abort(); - /// If the array is a copy, copies pending changes to the underlying java array. - void commit(); - - bool isCopy() const noexcept; - - const T& operator[](size_t index) const; - T& operator[](size_t index); - size_t size() const noexcept; - - private: - alias_ref array_; - size_t start_; - T* elements_; - jboolean isCopy_; - size_t size_; - - void allocate(alias_ref, jint start, jint length); - void releaseImpl(jint mode); - void clear() noexcept; - - PinnedPrimitiveArray(alias_ref, jint start, jint length); - - friend class JPrimitiveArray::array_type>; -}; - -struct FBEXPORT JStackTraceElement : JavaClass { - static auto constexpr kJavaDescriptor = "Ljava/lang/StackTraceElement;"; - - static local_ref create(const std::string& declaringClass, const std::string& methodName, const std::string& file, int line); - - std::string getClassName() const; - std::string getMethodName() const; - std::string getFileName() const; - int getLineNumber() const; -}; - -/// Wrapper to provide functionality to jthrowable references -class FBEXPORT JThrowable : public JavaClass { - public: - static constexpr const char* kJavaDescriptor = "Ljava/lang/Throwable;"; - - using JStackTrace = JArrayClass; - - local_ref initCause(alias_ref cause); - local_ref getStackTrace(); - void setStackTrace(alias_ref>); -}; - -#pragma push_macro("PlainJniRefMap") -#undef PlainJniRefMap -#define PlainJniRefMap(rtype, jtype) \ -namespace detail { \ -template<> \ -struct RefReprType { \ - using type = rtype; \ -}; \ -} - -PlainJniRefMap(JArrayBoolean, jbooleanArray); -PlainJniRefMap(JArrayByte, jbyteArray); -PlainJniRefMap(JArrayChar, jcharArray); -PlainJniRefMap(JArrayShort, jshortArray); -PlainJniRefMap(JArrayInt, jintArray); -PlainJniRefMap(JArrayLong, jlongArray); -PlainJniRefMap(JArrayFloat, jfloatArray); -PlainJniRefMap(JArrayDouble, jdoubleArray); -PlainJniRefMap(JObject, jobject); -PlainJniRefMap(JClass, jclass); -PlainJniRefMap(JString, jstring); -PlainJniRefMap(JThrowable, jthrowable); - -#pragma pop_macro("PlainJniRefMap") - -}} - -#include "CoreClasses-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h deleted file mode 100644 index 213ec5c7125775..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * @file Exceptions.h - * - * After invoking a JNI function that can throw a Java exception, the macro - * @ref FACEBOOK_JNI_THROW_PENDING_EXCEPTION() or @ref FACEBOOK_JNI_THROW_EXCEPTION_IF() - * should be invoked. - * - * IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! - * To use these methods you MUST call initExceptionHelpers() when your library is loaded. - */ - -#pragma once - -#include -#include -#include - -#include - -#include - -#include "Common.h" -#include "References.h" -#include "CoreClasses.h" - -#if defined(__ANDROID__) && defined(__ARM_ARCH_5TE__) && !defined(FBJNI_NO_EXCEPTION_PTR) -// ARMv5 NDK does not support exception_ptr so we cannot use that when building for it. -#define FBJNI_NO_EXCEPTION_PTR -#endif - -namespace facebook { -namespace jni { - -class JThrowable; - -class JCppException : public JavaClass { - public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/CppException;"; - - static local_ref create(const char* str) { - return newInstance(make_jstring(str)); - } - - static local_ref create(const std::exception& ex) { - return newInstance(make_jstring(ex.what())); - } -}; - -// JniException //////////////////////////////////////////////////////////////////////////////////// - -/** - * This class wraps a Java exception into a C++ exception; if the exception is routed back - * to the Java side, it can be unwrapped and just look like a pure Java interaction. The class - * is resilient to errors while creating the exception, falling back to some pre-allocated - * exceptions if a new one cannot be allocated or populated. - * - * Note: the what() method of this class is not thread-safe (t6900503). - */ -class FBEXPORT JniException : public std::exception { - public: - JniException(); - ~JniException(); - - explicit JniException(alias_ref throwable); - - JniException(JniException &&rhs); - - JniException(const JniException &other); - - local_ref getThrowable() const noexcept; - - virtual const char* what() const noexcept; - - void setJavaException() const noexcept; - - private: - global_ref throwable_; - mutable std::string what_; - mutable bool isMessageExtracted_; - const static std::string kExceptionMessageFailure_; - - void populateWhat() const noexcept; -}; - -// Exception throwing & translating functions ////////////////////////////////////////////////////// - -// Functions that throw C++ exceptions - -static const int kMaxExceptionMessageBufferSize = 512; - -// These methods are the preferred way to throw a Java exception from -// a C++ function. They create and throw a C++ exception which wraps -// a Java exception, so the C++ flow is interrupted. Then, when -// translatePendingCppExceptionToJavaException is called at the -// topmost level of the native stack, the wrapped Java exception is -// thrown to the java caller. -template -[[noreturn]] void throwNewJavaException(const char* throwableName, const char* fmt, Args... args) { - int msgSize = snprintf(nullptr, 0, fmt, args...); - - char *msg = (char*) alloca(msgSize + 1); - snprintf(msg, kMaxExceptionMessageBufferSize, fmt, args...); - throwNewJavaException(throwableName, msg); -} - -// Identifies any pending C++ exception and throws it as a Java exception. If the exception can't -// be thrown, it aborts the program. -FBEXPORT void translatePendingCppExceptionToJavaException(); - -#ifndef FBJNI_NO_EXCEPTION_PTR -FBEXPORT local_ref getJavaExceptionForCppException(std::exception_ptr ptr); -#endif - -FBEXPORT local_ref getJavaExceptionForCppBackTrace(); - -FBEXPORT local_ref getJavaExceptionForCppBackTrace(const char* msg); -// For convenience, some exception names in java.lang are available here. - -const char* const gJavaLangIllegalArgumentException = "java/lang/IllegalArgumentException"; - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h deleted file mode 100644 index 9b52183a9e2186..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -class JFile : public JavaClass { - public: - static constexpr const char* kJavaDescriptor = "Ljava/io/File;"; - - // Define a method that calls into the represented Java class - std::string getAbsolutePath() { - static auto method = getClass()->getMethod("getAbsolutePath"); - return method(self())->toStdString(); - } - -}; - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h deleted file mode 100644 index fba774b675c3d3..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -#include -#include - -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -namespace detail { - -class BaseHybridClass { -public: - virtual ~BaseHybridClass() {} -}; - -struct FBEXPORT HybridData : public JavaClass { - constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridData;"; - static local_ref create(); -}; - -class HybridDestructor : public JavaClass { - public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/HybridData$Destructor;"; - - template - T* getNativePointer() { - static auto pointerField = javaClassStatic()->getField("mNativePointer"); - auto* value = reinterpret_cast(getFieldValue(pointerField)); - if (!value) { - throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException"); - } - return value; - } - - template - void setNativePointer(std::unique_ptr new_value) { - static auto pointerField = javaClassStatic()->getField("mNativePointer"); - auto old_value = std::unique_ptr(reinterpret_cast(getFieldValue(pointerField))); - if (new_value && old_value) { - FBCRASH("Attempt to set C++ native pointer twice"); - } - setFieldValue(pointerField, reinterpret_cast(new_value.release())); - } -}; - -template -detail::BaseHybridClass* getNativePointer(T t) { - return getHolder(t)->getNativePointer(); -} - -template -void setNativePointer(T t, std::unique_ptr new_value) { - getHolder(t)->setNativePointer(std::move(new_value)); -} - -template -local_ref getHolder(T t) { - static auto holderField = t->getClass()->template getField("mDestructor"); - return t->getFieldValue(holderField); -} - -// JavaClass for HybridClassBase -struct FBEXPORT HybridClassBase : public JavaClass { - constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridClassBase;"; - - static bool isHybridClassBase(alias_ref jclass) { - return HybridClassBase::javaClassStatic()->isAssignableFrom(jclass); - } -}; - -template -struct HybridTraits { - // This static assert should actually always fail if we don't use one of the - // specializations below. - static_assert( - std::is_base_of::value || - std::is_base_of::value, - "The base of a HybridClass must be either another HybridClass or derived from JObject."); -}; - -template <> -struct HybridTraits { - using CxxBase = BaseHybridClass; - using JavaBase = JObject; -}; - -template -struct HybridTraits< - Base, - typename std::enable_if::value>::type> { - using CxxBase = Base; - using JavaBase = typename Base::JavaPart; -}; - -template -struct HybridTraits< - Base, - typename std::enable_if::value>::type> { - using CxxBase = BaseHybridClass; - using JavaBase = Base; -}; - -// convert to HybridClass* from jhybridobject -template -struct FBEXPORT Convert< - T, typename std::enable_if< - std::is_base_of::type>::value>::type> { - typedef typename std::remove_pointer::type::jhybridobject jniType; - static T fromJni(jniType t) { - if (t == nullptr) { - return nullptr; - } - return wrap_alias(t)->cthis(); - } - // There is no automatic return conversion for objects. -}; - -template -struct RefReprType::value, void>::type> { - static_assert(std::is_same::value, - "HybridFoo (where HybridFoo derives from HybridClass) is not supported in this context. " - "For an xxx_ref, you may want: xxx_ref or HybridFoo*."); - using Repr = T; -}; - - -} - -template -class FBEXPORT HybridClass : public detail::HybridTraits::CxxBase { -public: - struct JavaPart : JavaClass::JavaBase> { - // At this point, T is incomplete, and so we cannot access - // T::kJavaDescriptor directly. jtype_traits support this escape hatch for - // such a case. - static constexpr const char* kJavaDescriptor = nullptr; - static std::string get_instantiated_java_descriptor(); - static std::string get_instantiated_base_name(); - - using HybridType = T; - - // This will reach into the java object and extract the C++ instance from - // the mHybridData and return it. - T* cthis(); - - friend class HybridClass; - }; - - using jhybridobject = typename JavaPart::javaobject; - using javaobject = typename JavaPart::javaobject; - typedef detail::HybridData::javaobject jhybriddata; - - static alias_ref javaClassStatic() { - return JavaPart::javaClassStatic(); - } - - static local_ref javaClassLocal() { - std::string className(T::kJavaDescriptor + 1, strlen(T::kJavaDescriptor) - 2); - return findClassLocal(className.c_str()); - } - -protected: - typedef HybridClass HybridBase; - - // This ensures that a C++ hybrid part cannot be created on its own - // by default. If a hybrid wants to enable this, it can provide its - // own public ctor, or change the accessibility of this to public. - using detail::HybridTraits::CxxBase::CxxBase; - - static void registerHybrid(std::initializer_list methods) { - javaClassStatic()->registerNatives(methods); - } - - static local_ref makeHybridData(std::unique_ptr cxxPart) { - auto hybridData = detail::HybridData::create(); - setNativePointer(hybridData, std::move(cxxPart)); - return hybridData; - } - - template - static local_ref makeCxxInstance(Args&&... args) { - return makeHybridData(std::unique_ptr(new T(std::forward(args)...))); - } - - template - static void setCxxInstance(alias_ref o, Args&&... args) { - setNativePointer(o, std::unique_ptr(new T(std::forward(args)...))); - } - -public: - // Factory method for creating a hybrid object where the arguments - // are used to initialize the C++ part directly without passing them - // through java. This method requires the Java part to have a ctor - // which takes a HybridData, and for the C++ part to have a ctor - // compatible with the arguments passed here. For safety, the ctor - // can be private, and the hybrid declared a friend of its base, so - // the hybrid can only be created from here. - // - // Exception behavior: This can throw an exception if creating the - // C++ object fails, or any JNI methods throw. - template - static local_ref newObjectCxxArgs(Args&&... args) { - static bool isHybrid = detail::HybridClassBase::isHybridClassBase(javaClassStatic()); - auto cxxPart = std::unique_ptr(new T(std::forward(args)...)); - - local_ref result; - if (isHybrid) { - result = JavaPart::newInstance(); - setNativePointer(result, std::move(cxxPart)); - } - else { - auto hybridData = makeHybridData(std::move(cxxPart)); - result = JavaPart::newInstance(hybridData); - } - - return result; - } - - // TODO? Create reusable interface for Allocatable classes and use it to - // strengthen type-checking (and possibly provide a default - // implementation of allocate().) - template - static local_ref allocateWithCxxArgs(Args&&... args) { - auto hybridData = makeCxxInstance(std::forward(args)...); - static auto allocateMethod = - javaClassStatic()->template getStaticMethod("allocate"); - return allocateMethod(javaClassStatic(), hybridData.get()); - } - - // Factory method for creating a hybrid object where the arguments - // are passed to the java ctor. - template - static local_ref newObjectJavaArgs(Args&&... args) { - return JavaPart::newInstance(std::move(args)...); - } - - // If a hybrid class throws an exception which derives from - // std::exception, it will be passed to mapException on the hybrid - // class, or nearest ancestor. This allows boilerplate exception - // translation code (for example, calling throwNewJavaException on a - // particular java class) to be hoisted to a common function. If - // mapException returns, then the std::exception will be translated - // to Java. - static void mapException(const std::exception& ex) {} -}; - -template -inline T* HybridClass::JavaPart::cthis() { - detail::BaseHybridClass* result = 0; - static bool isHybrid = detail::HybridClassBase::isHybridClassBase(this->getClass()); - if (isHybrid) { - result = getNativePointer(this); - } else { - static auto field = - HybridClass::JavaPart::javaClassStatic()->template getField("mHybridData"); - auto hybridData = this->getFieldValue(field); - if (!hybridData) { - throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException"); - } - - result = getNativePointer(hybridData); - } - - // This would require some serious programmer error. - FBASSERTMSGF(result != 0, "Incorrect C++ type in hybrid field"); - // I'd like to use dynamic_cast here, but -fno-rtti is the default. - return static_cast(result); -}; - -template -/* static */ inline std::string HybridClass::JavaPart::get_instantiated_java_descriptor() { - return T::kJavaDescriptor; -} - -template -/* static */ inline std::string HybridClass::JavaPart::get_instantiated_base_name() { - auto name = get_instantiated_java_descriptor(); - return name.substr(1, name.size() - 2); -} - -// Given a *_ref object which refers to a hybrid class, this will reach inside -// of it, find the mHybridData, extract the C++ instance pointer, cast it to -// the appropriate type, and return it. -template -inline auto cthis(T jthis) -> decltype(jthis->cthis()) { - return jthis->cthis(); -} - -void HybridDataOnLoad(); - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h deleted file mode 100644 index 8e7083c8f92ce9..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -namespace facebook { -namespace jni { - -namespace detail { - -template -struct IteratorHelper : public JavaClass> { - constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/IteratorHelper;"; - - typedef local_ref value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::forward_iterator_tag iterator_category; - - typedef JavaClass> JavaBase_; - - bool hasNext() const { - static auto hasNextMethod = - JavaBase_::javaClassStatic()->template getMethod("hasNext"); - return hasNextMethod(JavaBase_::self()); - } - - value_type next() { - static auto elementField = - JavaBase_::javaClassStatic()->template getField("mElement"); - return dynamic_ref_cast(JavaBase_::getFieldValue(elementField)); - } - - static void reset(value_type& v) { - v.reset(); - } -}; - -template -struct MapIteratorHelper : public JavaClass> { - constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/MapIteratorHelper;"; - - typedef std::pair, local_ref> value_type; - - typedef JavaClass> JavaBase_; - - bool hasNext() const { - static auto hasNextMethod = - JavaBase_::javaClassStatic()->template getMethod("hasNext"); - return hasNextMethod(JavaBase_::self()); - } - - value_type next() { - static auto keyField = JavaBase_::javaClassStatic()->template getField("mKey"); - static auto valueField = JavaBase_::javaClassStatic()->template getField("mValue"); - return std::make_pair(dynamic_ref_cast(JavaBase_::getFieldValue(keyField)), - dynamic_ref_cast(JavaBase_::getFieldValue(valueField))); - } - - static void reset(value_type& v) { - v.first.reset(); - v.second.reset(); - } -}; - -template -class Iterator { - public: - typedef typename T::value_type value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::input_iterator_tag iterator_category; - - // begin ctor - Iterator(global_ref&& helper) - : helper_(std::move(helper)) - , i_(-1) { - ++(*this); - } - - // end ctor - Iterator() - : i_(-1) {} - - bool operator==(const Iterator& it) const { return i_ == it.i_; } - bool operator!=(const Iterator& it) const { return !(*this == it); } - const value_type& operator*() const { assert(i_ != -1); return entry_; } - const value_type* operator->() const { assert(i_ != -1); return &entry_; } - Iterator& operator++() { // preincrement - bool hasNext = helper_->hasNext(); - if (hasNext) { - ++i_; - entry_ = helper_->next(); - } else { - i_ = -1; - helper_->reset(entry_); - } - return *this; - } - Iterator operator++(int) { // postincrement - Iterator ret; - ret.i_ = i_; - ret.entry_ = std::move(entry_); - ++(*this); - return ret; - } - - global_ref helper_; - // set to -1 at end - std::ptrdiff_t i_; - value_type entry_; -}; - -} - -template -struct JIterator::Iterator : public detail::Iterator> { - using detail::Iterator>::Iterator; -}; - -template -typename JIterator::Iterator JIterator::begin() const { - static auto ctor = detail::IteratorHelper::javaClassStatic()-> - template getConstructor::javaobject( - typename JIterator::javaobject)>(); - return Iterator( - make_global( - detail::IteratorHelper::javaClassStatic()->newObject(ctor, this->self()))); -} - -template -typename JIterator::Iterator JIterator::end() const { - return Iterator(); -} - -template -struct JIterable::Iterator : public detail::Iterator> { - using detail::Iterator>::Iterator; -}; - -template -typename JIterable::Iterator JIterable::begin() const { - static auto ctor = detail::IteratorHelper::javaClassStatic()-> - template getConstructor::javaobject( - typename JIterable::javaobject)>(); - return Iterator( - make_global( - detail::IteratorHelper::javaClassStatic()->newObject(ctor, this->self()))); -} - -template -typename JIterable::Iterator JIterable::end() const { - return Iterator(); -} - -template -size_t JCollection::size() const { - static auto sizeMethod = - JCollection::javaClassStatic()->template getMethod("size"); - return sizeMethod(this->self()); -} - -template -struct JMap::Iterator : public detail::Iterator> { - using detail::Iterator>::Iterator; -}; - -template -size_t JMap::size() const { - static auto sizeMethod = - JMap::javaClassStatic()->template getMethod("size"); - return sizeMethod(this->self()); -} - -template -typename JMap::Iterator JMap::begin() const { - static auto ctor = detail::MapIteratorHelper::javaClassStatic()-> - template getConstructor::javaobject( - typename JMap::javaobject)>(); - return Iterator( - make_global( - detail::MapIteratorHelper::javaClassStatic()->newObject(ctor, this->self()))); -} - -template -typename JMap::Iterator JMap::end() const { - return Iterator(); -} - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h deleted file mode 100644 index 606e6a5ed3a7f0..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -/** - * JavaClass which represents a reference to a java.util.Iterator instance. It - * provides begin()/end() methods to provide C++-style iteration over the - * underlying collection. The class has a template parameter for the element - * type, which defaults to jobject. For example: - * - * alias_ref::javaobject> my_iter = ...; - * - * In the simplest case, it can be used just as alias_ref::javaobject>, - * for example in a method declaration. - */ -template -struct JIterator : JavaClass> { - constexpr static auto kJavaDescriptor = "Ljava/util/Iterator;"; - - struct Iterator; - - /** - * To iterate: - * - * for (const auto& element : *jiter) { ... } - * - * The JIterator iterator value_type is local_ref, containing a reference - * to an element instance. - * - * If the Iterator returns objects whch are not convertible to the given - * element type, iteration will throw a java ClassCastException. - * - * For example, to convert an iterator over a collection of java strings to - * an std::vector of std::strings: - * - * std::vector vs; - * for (const auto& elem : *jiter) { - * vs.push_back(elem->toStdString()); - * } - * - * Or if you prefer using std algorithms: - * - * std::vector vs; - * std::transform(jiter->begin(), jiter->end(), std::back_inserter(vs), - * [](const local_ref& elem) { return elem->toStdString(); }); - * - * The iterator is a InputIterator. - */ - Iterator begin() const; - Iterator end() const; -}; - -/** - * Similar to JIterator, except this represents any object which implements the - * java.lang.Iterable interface. It will create the Java Iterator as a part of - * begin(). - */ -template -struct JIterable : JavaClass> { - constexpr static auto kJavaDescriptor = "Ljava/lang/Iterable;"; - - struct Iterator; - - Iterator begin() const; - Iterator end() const; -}; - -/** - * JavaClass types which represent Collection, List, and Set are also provided. - * These preserve the Java class hierarchy. - */ -template -struct JCollection : JavaClass, JIterable> { - constexpr static auto kJavaDescriptor = "Ljava/util/Collection;"; - - /** - * Returns the number of elements in the collection. - */ - size_t size() const; -}; - -template -struct JList : JavaClass, JCollection> { - constexpr static auto kJavaDescriptor = "Ljava/util/List;"; -}; - -template -struct JSet : JavaClass, JCollection> { - constexpr static auto kJavaDescriptor = "Ljava/util/Set;"; -}; - -/** - * JavaClass which represents a reference to a java.util.Map instance. It adds - * wrappers around Java methods, including begin()/end() methods to provide - * C++-style iteration over the Java Map. The class has template parameters - * for the key and value types, which default to jobject. For example: - * - * alias_ref::javaobject> my_map = ...; - * - * In the simplest case, it can be used just as alias_ref::javaobject>, - * for example in a method declaration. - */ -template -struct JMap : JavaClass> { - constexpr static auto kJavaDescriptor = "Ljava/util/Map;"; - - struct Iterator; - - /** - * Returns the number of pairs in the map. - */ - size_t size() const; - - /** - * To iterate over the Map: - * - * for (const auto& entry : *jmap) { ... } - * - * The JMap iterator value_type is std::pair, local_ref> - * containing references to key and value instances. - * - * If the Map contains objects whch are not convertible to the given key and - * value types, iteration will throw a java ClassCastException. - * - * The iterator is a InputIterator. - */ - Iterator begin() const; - Iterator end() const; -}; - -} -} - -#include "Iterator-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JThread.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JThread.h deleted file mode 100644 index 6bcf9641207214..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JThread.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" -#include "NativeRunnable.h" - -namespace facebook { -namespace jni { - -class JThread : public JavaClass { - public: - static constexpr const char* kJavaDescriptor = "Ljava/lang/Thread;"; - - void start() { - static auto method = javaClassStatic()->getMethod("start"); - method(self()); - } - - void join() { - static auto method = javaClassStatic()->getMethod("join"); - method(self()); - } - - static local_ref create(std::function&& runnable) { - auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable)); - return newInstance(static_ref_cast(jrunnable)); - } -}; - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JWeakReference.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JWeakReference.h deleted file mode 100644 index 30396b5fe3a9d2..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JWeakReference.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -/** - * Wrap Java's WeakReference instead of using JNI WeakGlobalRefs. - * A WeakGlobalRef can yield a strong reference even after the object has been - * finalized. See comment in the djinni library. - * https://github.com/dropbox/djinni/blob/master/support-lib/jni/djinni_support.hpp - */ -template -class JWeakReference : public JavaClass> { - - typedef JavaClass> JavaBase_; - - public: - static constexpr const char* kJavaDescriptor = "Ljava/lang/ref/WeakReference;"; - - static local_ref> newInstance(alias_ref object) { - return JavaBase_::newInstance(static_ref_cast(object)); - } - - local_ref get() const { - static auto method = JavaBase_::javaClassStatic()->template getMethod("get"); - return static_ref_cast(method(JavaBase_::self())); - } -}; - -} -} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h deleted file mode 100644 index 833acc04b022c8..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -namespace facebook { -namespace jni { - -template -class JMethod; -template -class JStaticMethod; -template -class JNonvirtualMethod; -template -struct JConstructor; -template -class JField; -template -class JStaticField; - -/// Type traits for Java types (currently providing Java type descriptors) -template -struct jtype_traits; - -/// Type traits for Java methods (currently providing Java type descriptors) -template -struct jmethod_traits; - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h deleted file mode 100644 index e3c33921ce4e65..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include "Common.h" -#include "Exceptions.h" -#include "MetaConvert.h" -#include "References.h" -#include "Boxed.h" - -#if defined(__ANDROID__) -# include -#endif - -namespace facebook { -namespace jni { - -// JMethod ///////////////////////////////////////////////////////////////////////////////////////// - -inline JMethodBase::JMethodBase(jmethodID method_id) noexcept - : method_id_{method_id} -{} - -inline JMethodBase::operator bool() const noexcept { - return method_id_ != nullptr; -} - -inline jmethodID JMethodBase::getId() const noexcept { - return method_id_; -} - -namespace { - -template -struct ArgsArraySetter; - -template -struct ArgsArraySetter { - static void set(alias_ref::javaobject> array, Arg arg0, Args... args) { - // TODO(xxxxxxxx): Use Convert... to do conversions like the fast path. - (*array)[idx] = autobox(arg0); - ArgsArraySetter::set(array, args...); - } -}; - -template -struct ArgsArraySetter { - static void set(alias_ref::javaobject> array) { - (void)array; - } -}; - -template -local_ref::javaobject> makeArgsArray(Args... args) { - auto arr = JArrayClass::newArray(sizeof...(args)); - ArgsArraySetter<0, Args...>::set(arr, args...); - return arr; -} - - -inline bool needsSlowPath(alias_ref obj) { -#if defined(__ANDROID__) - // On Android 6.0, art crashes when attempting to call a function on a Proxy. - // So, when we detect that case we must use the safe, slow workaround. That is, - // we resolve the method id to the corresponding java.lang.reflect.Method object - // and make the call via it's invoke() method. - static auto is_bad_android = build::Build::getAndroidSdk() == 23; - - if (!is_bad_android) return false; - static auto proxy_class = findClassStatic("java/lang/reflect/Proxy"); - return obj->isInstanceOf(proxy_class); -#else - return false; -#endif -} - -} - -template -inline void JMethod::operator()(alias_ref self, Args... args) { - const auto env = Environment::current(); - env->CallVoidMethod( - self.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); -} - -#pragma push_macro("DEFINE_PRIMITIVE_CALL") -#undef DEFINE_PRIMITIVE_CALL -#define DEFINE_PRIMITIVE_CALL(TYPE, METHOD) \ -template \ -inline TYPE JMethod::operator()(alias_ref self, Args... args) { \ - const auto env = internal::getEnv(); \ - auto result = env->Call ## METHOD ## Method( \ - self.get(), \ - getId(), \ - detail::callToJni(detail::Convert::type>::toCall(args))...); \ - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ - return result; \ -} - -DEFINE_PRIMITIVE_CALL(jboolean, Boolean) -DEFINE_PRIMITIVE_CALL(jbyte, Byte) -DEFINE_PRIMITIVE_CALL(jchar, Char) -DEFINE_PRIMITIVE_CALL(jshort, Short) -DEFINE_PRIMITIVE_CALL(jint, Int) -DEFINE_PRIMITIVE_CALL(jlong, Long) -DEFINE_PRIMITIVE_CALL(jfloat, Float) -DEFINE_PRIMITIVE_CALL(jdouble, Double) -#pragma pop_macro("DEFINE_PRIMITIVE_CALL") - -/// JMethod specialization for references that wraps the return value in a @ref local_ref -template -class JMethod : public JMethodBase { - public: - // TODO: static_assert is jobject-derived or local_ref jobject - using JniRet = typename detail::Convert::type>::jniType; - static_assert(IsPlainJniReference(), "JniRet must be a JNI reference"); - using JMethodBase::JMethodBase; - JMethod() noexcept {}; - JMethod(const JMethod& other) noexcept = default; - - /// Invoke a method and return a local reference wrapping the result - local_ref operator()(alias_ref self, Args... args); - - friend class JClass; -}; - -template -inline auto JMethod::operator()(alias_ref self, Args... args) -> local_ref { - const auto env = Environment::current(); - auto result = env->CallObjectMethod( - self.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return adopt_local(static_cast(result)); -} - -template -inline void JStaticMethod::operator()(alias_ref cls, Args... args) { - const auto env = internal::getEnv(); - env->CallStaticVoidMethod( - cls.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); -} - -#pragma push_macro("DEFINE_PRIMITIVE_STATIC_CALL") -#undef DEFINE_PRIMITIVE_STATIC_CALL -#define DEFINE_PRIMITIVE_STATIC_CALL(TYPE, METHOD) \ -template \ -inline TYPE JStaticMethod::operator()(alias_ref cls, Args... args) { \ - const auto env = internal::getEnv(); \ - auto result = env->CallStatic ## METHOD ## Method( \ - cls.get(), \ - getId(), \ - detail::callToJni(detail::Convert::type>::toCall(args))...); \ - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ - return result; \ -} - -DEFINE_PRIMITIVE_STATIC_CALL(jboolean, Boolean) -DEFINE_PRIMITIVE_STATIC_CALL(jbyte, Byte) -DEFINE_PRIMITIVE_STATIC_CALL(jchar, Char) -DEFINE_PRIMITIVE_STATIC_CALL(jshort, Short) -DEFINE_PRIMITIVE_STATIC_CALL(jint, Int) -DEFINE_PRIMITIVE_STATIC_CALL(jlong, Long) -DEFINE_PRIMITIVE_STATIC_CALL(jfloat, Float) -DEFINE_PRIMITIVE_STATIC_CALL(jdouble, Double) -#pragma pop_macro("DEFINE_PRIMITIVE_STATIC_CALL") - -/// JStaticMethod specialization for references that wraps the return value in a @ref local_ref -template -class JStaticMethod : public JMethodBase { - - public: - using JniRet = typename detail::Convert::type>::jniType; - static_assert(IsPlainJniReference(), "T* must be a JNI reference"); - using JMethodBase::JMethodBase; - JStaticMethod() noexcept {}; - JStaticMethod(const JStaticMethod& other) noexcept = default; - - /// Invoke a method and return a local reference wrapping the result - local_ref operator()(alias_ref cls, Args... args) { - const auto env = internal::getEnv(); - auto result = env->CallStaticObjectMethod( - cls.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return adopt_local(static_cast(result)); - } - - friend class JClass; -}; - -template -inline void -JNonvirtualMethod::operator()(alias_ref self, alias_ref cls, Args... args) { - const auto env = internal::getEnv(); - env->CallNonvirtualVoidMethod( - self.get(), - cls.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); -} - -#pragma push_macro("DEFINE_PRIMITIVE_NON_VIRTUAL_CALL") -#undef DEFINE_PRIMITIVE_NON_VIRTUAL_CALL -#define DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(TYPE, METHOD) \ -template \ -inline TYPE \ -JNonvirtualMethod::operator()(alias_ref self, alias_ref cls, Args... args) { \ - const auto env = internal::getEnv(); \ - auto result = env->CallNonvirtual ## METHOD ## Method( \ - self.get(), \ - cls.get(), \ - getId(), \ - detail::callToJni(detail::Convert::type>::toCall(args))...); \ - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ - return result; \ -} - -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jboolean, Boolean) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jbyte, Byte) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jchar, Char) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jshort, Short) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jint, Int) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jlong, Long) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jfloat, Float) -DEFINE_PRIMITIVE_NON_VIRTUAL_CALL(jdouble, Double) -#pragma pop_macro("DEFINE_PRIMITIVE_NON_VIRTUAL_CALL") - -/// JNonvirtualMethod specialization for references that wraps the return value in a @ref local_ref -template -class JNonvirtualMethod : public JMethodBase { - public: - using JniRet = typename detail::Convert::type>::jniType; - static_assert(IsPlainJniReference(), "T* must be a JNI reference"); - using JMethodBase::JMethodBase; - JNonvirtualMethod() noexcept {}; - JNonvirtualMethod(const JNonvirtualMethod& other) noexcept = default; - - /// Invoke a method and return a local reference wrapping the result - local_ref operator()(alias_ref self, alias_ref cls, Args... args){ - const auto env = internal::getEnv(); - auto result = env->CallNonvirtualObjectMethod( - self.get(), - cls.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return adopt_local(static_cast(result)); - } - - friend class JClass; -}; - -template -local_ref slowCall(jmethodID method_id, alias_ref self, Args... args) { - static auto invoke = findClassStatic("java/lang/reflect/Method") - ->getMethod::javaobject)>("invoke"); - // TODO(xxxxxxx): Provide fbjni interface to ToReflectedMethod. - auto reflected = adopt_local(Environment::current()->ToReflectedMethod(self->getClass().get(), method_id, JNI_FALSE)); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - if (!reflected) throw std::runtime_error("Unable to get reflected java.lang.reflect.Method"); - auto argsArray = makeArgsArray(args...); - // No need to check for exceptions since invoke is itself a JMethod that will do that for us. - return invoke(reflected, self.get(), argsArray.get()); -} - - -// JField /////////////////////////////////////////////////////////////////////////////////////// - -template -inline JField::JField(jfieldID field) noexcept - : field_id_{field} -{} - -template -inline JField::operator bool() const noexcept { - return field_id_ != nullptr; -} - -template -inline jfieldID JField::getId() const noexcept { - return field_id_; -} - -#pragma push_macro("DEFINE_FIELD_PRIMITIVE_GET_SET") -#undef DEFINE_FIELD_PRIMITIVE_GET_SET -#define DEFINE_FIELD_PRIMITIVE_GET_SET(TYPE, METHOD) \ -template<> \ -inline TYPE JField::get(jobject object) const noexcept { \ - const auto env = internal::getEnv(); \ - return env->Get ## METHOD ## Field(object, field_id_); \ -} \ - \ -template<> \ -inline void JField::set(jobject object, TYPE value) noexcept { \ - const auto env = internal::getEnv(); \ - env->Set ## METHOD ## Field(object, field_id_, value); \ -} - -DEFINE_FIELD_PRIMITIVE_GET_SET(jboolean, Boolean) -DEFINE_FIELD_PRIMITIVE_GET_SET(jbyte, Byte) -DEFINE_FIELD_PRIMITIVE_GET_SET(jchar, Char) -DEFINE_FIELD_PRIMITIVE_GET_SET(jshort, Short) -DEFINE_FIELD_PRIMITIVE_GET_SET(jint, Int) -DEFINE_FIELD_PRIMITIVE_GET_SET(jlong, Long) -DEFINE_FIELD_PRIMITIVE_GET_SET(jfloat, Float) -DEFINE_FIELD_PRIMITIVE_GET_SET(jdouble, Double) -#pragma pop_macro("DEFINE_FIELD_PRIMITIVE_GET_SET") - -template -inline T JField::get(jobject object) const noexcept { - return static_cast(internal::getEnv()->GetObjectField(object, field_id_)); -} - -template -inline void JField::set(jobject object, T value) noexcept { - internal::getEnv()->SetObjectField(object, field_id_, static_cast(value)); -} - -// JStaticField ///////////////////////////////////////////////////////////////////////////////// - -template -inline JStaticField::JStaticField(jfieldID field) noexcept - : field_id_{field} -{} - -template -inline JStaticField::operator bool() const noexcept { - return field_id_ != nullptr; -} - -template -inline jfieldID JStaticField::getId() const noexcept { - return field_id_; -} - -#pragma push_macro("DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET") -#undef DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET -#define DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(TYPE, METHOD) \ -template<> \ -inline TYPE JStaticField::get(jclass jcls) const noexcept { \ - const auto env = internal::getEnv(); \ - return env->GetStatic ## METHOD ## Field(jcls, field_id_); \ -} \ - \ -template<> \ -inline void JStaticField::set(jclass jcls, TYPE value) noexcept { \ - const auto env = internal::getEnv(); \ - env->SetStatic ## METHOD ## Field(jcls, field_id_, value); \ -} - -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jboolean, Boolean) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jbyte, Byte) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jchar, Char) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jshort, Short) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jint, Int) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jlong, Long) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jfloat, Float) -DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET(jdouble, Double) -#pragma pop_macro("DEFINE_STATIC_FIELD_PRIMITIVE_GET_SET") - -template -inline T JStaticField::get(jclass jcls) const noexcept { - const auto env = internal::getEnv(); - return static_cast(env->GetStaticObjectField(jcls, field_id_)); -} - -template -inline void JStaticField::set(jclass jcls, T value) noexcept { - internal::getEnv()->SetStaticObjectField(jcls, field_id_, value); -} - - -// jmethod_traits ////////////////////////////////////////////////////////////////////////////////// - -// TODO(T6608405) Adapt this to implement a register natives method that requires no descriptor -namespace internal { - -template -inline std::string JavaDescriptor() { - return jtype_traits::descriptor(); -} - -template -inline std::string JavaDescriptor() { - return JavaDescriptor() + JavaDescriptor(); -} - -template -inline std::string JMethodDescriptor() { - return "(" + JavaDescriptor() + ")" + JavaDescriptor(); -} - -template -inline std::string JMethodDescriptor() { - return "()" + JavaDescriptor(); -} - -} // internal - -template -inline std::string jmethod_traits::descriptor() { - return internal::JMethodDescriptor(); -} - -template -inline std::string jmethod_traits::constructor_descriptor() { - return internal::JMethodDescriptor(); -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h deleted file mode 100644 index ec5eb6ef17f288..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** @file meta.h - * - * Provides wrappers for meta data such as methods and fields. - */ - -#pragma once - -#include -#include - -#include - -#include "References-forward.h" - -#ifdef __ANDROID__ -# include -# define XLOG_TAG "fb-jni" -# define XLOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, XLOG_TAG, __VA_ARGS__) -# define XLOGD(...) __android_log_print(ANDROID_LOG_DEBUG, XLOG_TAG, __VA_ARGS__) -# define XLOGI(...) __android_log_print(ANDROID_LOG_INFO, XLOG_TAG, __VA_ARGS__) -# define XLOGW(...) __android_log_print(ANDROID_LOG_WARN, XLOG_TAG, __VA_ARGS__) -# define XLOGE(...) __android_log_print(ANDROID_LOG_ERROR, XLOG_TAG, __VA_ARGS__) -# define XLOGWTF(...) __android_log_print(ANDROID_LOG_FATAL, XLOG_TAG, __VA_ARGS__) -#endif - -namespace facebook { -namespace jni { - -// This will get the reflected Java Method from the method_id, get it's invoke -// method, and call the method via that. This shouldn't ever be needed, but -// Android 6.0 crashes when calling a method on a java.lang.Proxy via jni. -template -local_ref slowCall(jmethodID method_id, alias_ref self, Args... args); - -class JObject; - - -/// Wrapper of a jmethodID. Provides a common base for JMethod specializations -class JMethodBase { - public: - /// Verify that the method is valid - explicit operator bool() const noexcept; - - /// Access the wrapped id - jmethodID getId() const noexcept; - - protected: - /// Create a wrapper of a method id - explicit JMethodBase(jmethodID method_id = nullptr) noexcept; - - private: - jmethodID method_id_; -}; - - -/// Representation of a jmethodID -template -class JMethod; - -/// @cond INTERNAL -#pragma push_macro("DEFINE_PRIMITIVE_METHOD_CLASS") - -#undef DEFINE_PRIMITIVE_METHOD_CLASS - -// Defining JMethod specializations based on return value -#define DEFINE_PRIMITIVE_METHOD_CLASS(TYPE) \ -template \ -class JMethod : public JMethodBase { \ - public: \ - static_assert(std::is_void::value || IsJniPrimitive(), \ - "TYPE must be primitive or void"); \ - \ - using JMethodBase::JMethodBase; \ - JMethod() noexcept {}; \ - JMethod(const JMethod& other) noexcept = default; \ - \ - TYPE operator()(alias_ref self, Args... args); \ - \ - friend class JClass; \ -} - -DEFINE_PRIMITIVE_METHOD_CLASS(void); -DEFINE_PRIMITIVE_METHOD_CLASS(jboolean); -DEFINE_PRIMITIVE_METHOD_CLASS(jbyte); -DEFINE_PRIMITIVE_METHOD_CLASS(jchar); -DEFINE_PRIMITIVE_METHOD_CLASS(jshort); -DEFINE_PRIMITIVE_METHOD_CLASS(jint); -DEFINE_PRIMITIVE_METHOD_CLASS(jlong); -DEFINE_PRIMITIVE_METHOD_CLASS(jfloat); -DEFINE_PRIMITIVE_METHOD_CLASS(jdouble); - -#pragma pop_macro("DEFINE_PRIMITIVE_METHOD_CLASS") -/// @endcond - - -/// Convenience type representing constructors -/// These should only be used with JClass::getConstructor and JClass::newObject. -template -struct JConstructor : private JMethod { - using JMethod::JMethod; - private: - JConstructor(const JMethod& other) : JMethod(other.getId()) {} - friend class JClass; -}; - -/// Representation of a jStaticMethodID -template -class JStaticMethod; - -/// @cond INTERNAL -#pragma push_macro("DEFINE_PRIMITIVE_STATIC_METHOD_CLASS") - -#undef DEFINE_PRIMITIVE_STATIC_METHOD_CLASS - -// Defining JStaticMethod specializations based on return value -#define DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(TYPE) \ -template \ -class JStaticMethod : public JMethodBase { \ - static_assert(std::is_void::value || IsJniPrimitive(), \ - "T must be a JNI primitive or void"); \ - \ - public: \ - using JMethodBase::JMethodBase; \ - JStaticMethod() noexcept {}; \ - JStaticMethod(const JStaticMethod& other) noexcept = default; \ - \ - TYPE operator()(alias_ref cls, Args... args); \ - \ - friend class JClass; \ -} - -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(void); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jboolean); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jbyte); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jchar); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jshort); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jint); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jlong); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jfloat); -DEFINE_PRIMITIVE_STATIC_METHOD_CLASS(jdouble); - -#pragma pop_macro("DEFINE_PRIMITIVE_STATIC_METHOD_CLASS") -/// @endcond - - -/// Representation of a jNonvirtualMethodID -template -class JNonvirtualMethod; - -/// @cond INTERNAL -#pragma push_macro("DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS") - -#undef DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS - -// Defining JNonvirtualMethod specializations based on return value -#define DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(TYPE) \ -template \ -class JNonvirtualMethod : public JMethodBase { \ - static_assert(std::is_void::value || IsJniPrimitive(), \ - "T must be a JNI primitive or void"); \ - \ - public: \ - using JMethodBase::JMethodBase; \ - JNonvirtualMethod() noexcept {}; \ - JNonvirtualMethod(const JNonvirtualMethod& other) noexcept = default; \ - \ - TYPE operator()(alias_ref self, alias_ref cls, Args... args); \ - \ - friend class JClass; \ -} - -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(void); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jboolean); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jbyte); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jchar); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jshort); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jint); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jlong); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jfloat); -DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS(jdouble); - -#pragma pop_macro("DEFINE_PRIMITIVE_NON_VIRTUAL_METHOD_CLASS") -/// @endcond - - -/** - * JField represents typed fields and simplifies their access. Note that object types return - * raw pointers which generally should promptly get a wrap_local treatment. - */ -template -class JField { - static_assert(IsJniScalar(), "T must be a JNI scalar"); - - public: - /// Wraps an existing field id - explicit JField(jfieldID field = nullptr) noexcept; - - /// Verify that the id is valid - explicit operator bool() const noexcept; - - /// Access the wrapped id - jfieldID getId() const noexcept; - - private: - jfieldID field_id_; - - /// Get field value - /// @pre object != nullptr - T get(jobject object) const noexcept; - - /// Set field value - /// @pre object != nullptr - void set(jobject object, T value) noexcept; - - friend class JObject; -}; - - -/** - * JStaticField represents typed fields and simplifies their access. Note that object types - * return raw pointers which generally should promptly get a wrap_local treatment. - */ -template -class JStaticField { - static_assert(IsJniScalar(), "T must be a JNI scalar"); - - public: - /// Wraps an existing field id - explicit JStaticField(jfieldID field = nullptr) noexcept; - - /// Verify that the id is valid - explicit operator bool() const noexcept; - - /// Access the wrapped id - jfieldID getId() const noexcept; - - private: - jfieldID field_id_; - - /// Get field value - /// @pre object != nullptr - T get(jclass jcls) const noexcept; - - /// Set field value - /// @pre object != nullptr - void set(jclass jcls, T value) noexcept; - - friend class JClass; - friend class JObject; -}; - - -/// Template magic to provide @ref jmethod_traits -template -struct jmethod_traits { - static std::string descriptor(); - static std::string constructor_descriptor(); -}; - - -// jtype_traits //////////////////////////////////////////////////////////////////////////////////// - -template -struct jtype_traits { -private: - using Repr = ReprType; -public: - // The jni type signature (described at - // http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html). - static std::string descriptor() { - std::string descriptor; - if (Repr::kJavaDescriptor == nullptr) { - descriptor = Repr::get_instantiated_java_descriptor(); - } else { - descriptor = Repr::kJavaDescriptor; - } - return descriptor; - } - - // The signature used for class lookups. See - // http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getName(). - static std::string base_name() { - if (Repr::kJavaDescriptor != nullptr) { - std::string base_name = Repr::kJavaDescriptor; - return base_name.substr(1, base_name.size() - 2); - } - return Repr::get_instantiated_base_name(); - } -}; - -#pragma push_macro("DEFINE_FIELD_AND_ARRAY_TRAIT") -#undef DEFINE_FIELD_AND_ARRAY_TRAIT - -#define DEFINE_FIELD_AND_ARRAY_TRAIT(TYPE, DSC) \ -template<> \ -struct jtype_traits { \ - static std::string descriptor() { return std::string{#DSC}; } \ - static std::string base_name() { return descriptor(); } \ - using array_type = TYPE ## Array; \ -}; \ -template<> \ -struct jtype_traits { \ - static std::string descriptor() { return std::string{"[" #DSC}; } \ - static std::string base_name() { return descriptor(); } \ - using entry_type = TYPE; \ -}; - -// There is no voidArray, handle that without the macro. -template<> -struct jtype_traits { - static std::string descriptor() { return std::string{"V"}; }; -}; - -DEFINE_FIELD_AND_ARRAY_TRAIT(jboolean, Z) -DEFINE_FIELD_AND_ARRAY_TRAIT(jbyte, B) -DEFINE_FIELD_AND_ARRAY_TRAIT(jchar, C) -DEFINE_FIELD_AND_ARRAY_TRAIT(jshort, S) -DEFINE_FIELD_AND_ARRAY_TRAIT(jint, I) -DEFINE_FIELD_AND_ARRAY_TRAIT(jlong, J) -DEFINE_FIELD_AND_ARRAY_TRAIT(jfloat, F) -DEFINE_FIELD_AND_ARRAY_TRAIT(jdouble, D) - -#pragma pop_macro("DEFINE_FIELD_AND_ARRAY_TRAIT") - - -template -struct jmethod_traits_from_cxx; - -}} - -#include "Meta-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h deleted file mode 100644 index cb0317d3fbb5ae..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include "Common.h" -#include "References.h" - -namespace facebook { -namespace jni { - -namespace detail { - -// In order to avoid potentially filling the jni locals table, -// temporary objects (right now, this is just jstrings) need to be -// released. This is done by returning a holder which autoconverts to -// jstring. -template -inline T callToJni(T&& t) { - return t; -} - -template -inline JniType callToJni(local_ref&& sref) { - return sref.get(); -} - -// Normally, pass through types unmolested. -template -struct Convert { - typedef T jniType; - static jniType fromJni(jniType t) { - return t; - } - static jniType toJniRet(jniType t) { - return t; - } - static jniType toCall(jniType t) { - return t; - } -}; - -// This is needed for return conversion -template <> -struct Convert { - typedef void jniType; -}; - -// jboolean is an unsigned char, not a bool. Allow it to work either way. -template<> -struct Convert { - typedef jboolean jniType; - static bool fromJni(jniType t) { - return t; - } - static jniType toJniRet(bool t) { - return t; - } - static jniType toCall(bool t) { - return t; - } -}; - -// convert to alias_ref from T -template -struct Convert> { - typedef JniType jniType; - static alias_ref fromJni(jniType t) { - return wrap_alias(t); - } - static jniType toJniRet(alias_ref t) { - return t.get(); - } - static jniType toCall(alias_ref t) { - return t.get(); - } -}; - -// convert return from local_ref -template -struct Convert> { - typedef JniType jniType; - // No automatic synthesis of local_ref - static jniType toJniRet(local_ref t) { - return t.release(); - } - static jniType toCall(local_ref t) { - return t.get(); - } -}; - -// convert return from global_ref -template -struct Convert> { - typedef JniType jniType; - // No automatic synthesis of global_ref - static jniType toJniRet(global_ref&& t) { - // If this gets called, ownership the global_ref was passed in here. (It's - // probably a copy of a persistent global_ref made when a function was - // declared to return a global_ref, but it could moved out or otherwise not - // referenced elsewhere. Doesn't matter.) Either way, the only safe way - // to return it is to make a local_ref, release it, and return the - // underlying local jobject. - auto ret = make_local(t); - return ret.release(); - } - static jniType toJniRet(const global_ref& t) { - // If this gets called, the function was declared to return const&. We - // have a ref to a global_ref whose lifetime will exceed this call, so we - // can just get the underlying jobject and return it to java without - // needing to make a local_ref. - return t.get(); - } - static jniType toCall(global_ref t) { - return t.get(); - } -}; - -template struct jni_sig_from_cxx_t; -template -struct jni_sig_from_cxx_t { - using JniRet = typename Convert::type>::jniType; - using JniSig = JniRet(typename Convert::type>::jniType...); -}; - -template -using jni_sig_from_cxx = typename jni_sig_from_cxx_t::JniSig; - -} // namespace detail - -template -struct jmethod_traits_from_cxx : jmethod_traits> { -}; - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/NativeRunnable.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/NativeRunnable.h deleted file mode 100644 index 015c42e5ab3cc5..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/NativeRunnable.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "CoreClasses.h" -#include "Hybrid.h" -#include "Registration.h" - -#include - -namespace facebook { -namespace jni { - -struct JRunnable : public JavaClass { - static auto constexpr kJavaDescriptor = "Ljava/lang/Runnable;"; -}; - -struct JNativeRunnable : public HybridClass { - public: - static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/NativeRunnable;"; - - JNativeRunnable(std::function&& runnable) : runnable_(std::move(runnable)) {} - - static void OnLoad() { - registerHybrid({ - makeNativeMethod("run", JNativeRunnable::run), - }); - } - - void run() { - runnable_(); - } - - private: - std::function runnable_; -}; - - -} // namespace jni -} // namespace facebook diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReadableByteChannel.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReadableByteChannel.h deleted file mode 100644 index 69b8f2aae31488..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReadableByteChannel.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -namespace facebook { -namespace jni { - -class JReadableByteChannel : public JavaClass { -public: - static constexpr const char* kJavaDescriptor = "Ljava/nio/channels/ReadableByteChannel;"; - - int read(alias_ref dest) const; -}; - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h deleted file mode 100644 index f3303078b0407c..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook { -namespace jni { - -/// @cond INTERNAL -namespace internal { - -// Statistics mostly provided for test (only updated if FBJNI_DEBUG_REFS is defined) -struct ReferenceStats { - std::atomic_uint locals_created, globals_created, weaks_created, - locals_deleted, globals_deleted, weaks_deleted; - - void reset() noexcept; -}; - -extern ReferenceStats g_reference_stats; -} -/// @endcond - - -// LocalReferenceAllocator ///////////////////////////////////////////////////////////////////////// - -inline jobject LocalReferenceAllocator::newReference(jobject original) const { - internal::dbglog("Local new: %p", original); - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.locals_created; - #endif - auto ref = internal::getEnv()->NewLocalRef(original); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return ref; -} - -inline void LocalReferenceAllocator::deleteReference(jobject reference) const noexcept { - internal::dbglog("Local release: %p", reference); - - if (reference) { - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.locals_deleted; - #endif - assert(verifyReference(reference)); - internal::getEnv()->DeleteLocalRef(reference); - } -} - -inline bool LocalReferenceAllocator::verifyReference(jobject reference) const noexcept { - if (!reference || !internal::doesGetObjectRefTypeWork()) { - return true; - } - return internal::getEnv()->GetObjectRefType(reference) == JNILocalRefType; -} - - -// GlobalReferenceAllocator //////////////////////////////////////////////////////////////////////// - -inline jobject GlobalReferenceAllocator::newReference(jobject original) const { - internal::dbglog("Global new: %p", original); - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.globals_created; - #endif - auto ref = internal::getEnv()->NewGlobalRef(original); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return ref; -} - -inline void GlobalReferenceAllocator::deleteReference(jobject reference) const noexcept { - internal::dbglog("Global release: %p", reference); - - if (reference) { - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.globals_deleted; - #endif - assert(verifyReference(reference)); - internal::getEnv()->DeleteGlobalRef(reference); - } -} - -inline bool GlobalReferenceAllocator::verifyReference(jobject reference) const noexcept { - if (!reference || !internal::doesGetObjectRefTypeWork()) { - return true; - } - return internal::getEnv()->GetObjectRefType(reference) == JNIGlobalRefType; -} - - -// WeakGlobalReferenceAllocator //////////////////////////////////////////////////////////////////// - -inline jobject WeakGlobalReferenceAllocator::newReference(jobject original) const { - internal::dbglog("Weak global new: %p", original); - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.weaks_created; - #endif - auto ref = internal::getEnv()->NewWeakGlobalRef(original); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return ref; -} - -inline void WeakGlobalReferenceAllocator::deleteReference(jobject reference) const noexcept { - internal::dbglog("Weak Global release: %p", reference); - - if (reference) { - #ifdef FBJNI_DEBUG_REFS - ++internal::g_reference_stats.weaks_deleted; - #endif - assert(verifyReference(reference)); - internal::getEnv()->DeleteWeakGlobalRef(reference); - } -} - -inline bool WeakGlobalReferenceAllocator::verifyReference(jobject reference) const noexcept { - if (!reference || !internal::doesGetObjectRefTypeWork()) { - return true; - } - return internal::getEnv()->GetObjectRefType(reference) == JNIWeakGlobalRefType; -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h deleted file mode 100644 index 7ccdc5dbd687e9..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * @file ReferenceAllocators.h - * - * Reference allocators are used to create and delete various classes of JNI references (local, - * global, and weak global). - */ - -#pragma once - -#include - -#include "Common.h" - -namespace facebook { namespace jni { - -/// Allocator that handles local references -class FBEXPORT LocalReferenceAllocator { - public: - jobject newReference(jobject original) const; - void deleteReference(jobject reference) const noexcept; - bool verifyReference(jobject reference) const noexcept; -}; - -/// Allocator that handles global references -class FBEXPORT GlobalReferenceAllocator { - public: - jobject newReference(jobject original) const; - void deleteReference(jobject reference) const noexcept; - bool verifyReference(jobject reference) const noexcept; -}; - -/// Allocator that handles weak global references -class FBEXPORT WeakGlobalReferenceAllocator { - public: - jobject newReference(jobject original) const; - void deleteReference(jobject reference) const noexcept; - bool verifyReference(jobject reference) const noexcept; -}; - -/// @cond INTERNAL -namespace internal { - -/** - * @return true iff env->GetObjectRefType is expected to work properly. - */ -FBEXPORT bool doesGetObjectRefTypeWork(); - -} -/// @endcond - -}} - -#include "ReferenceAllocators-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h deleted file mode 100644 index 78b4f3273b97d0..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "ReferenceAllocators.h" - -namespace facebook { -namespace jni { - -template -class JObjectWrapper; - -namespace detail { -struct JObjectBase { - jobject get() const noexcept; - void set(jobject reference) noexcept; - jobject this_; -}; - -// RefReprType maps a type to the representation used by fbjni smart references. -template -struct RefReprType; - -template -struct JavaObjectType; - -template -struct ReprAccess; -} - -// Given T, either a jobject-like type or a JavaClass-derived type, ReprType -// is the corresponding JavaClass-derived type and JniType is the -// jobject-like type. -template -using ReprType = typename detail::RefReprType::type; - -template -using JniType = typename detail::JavaObjectType::type; - -template -class base_owned_ref; - -template -class basic_strong_ref; - -template -class weak_ref; - -template -class alias_ref; - -/// A smart unique reference owning a local JNI reference -template -using local_ref = basic_strong_ref; - -/// A smart unique reference owning a global JNI reference -template -using global_ref = basic_strong_ref; - -}} // namespace facebook::jni diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h deleted file mode 100644 index 53d4f4488d2b49..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include "CoreClasses.h" - -namespace facebook { -namespace jni { - -template -inline enable_if_t(), T> getPlainJniReference(T ref) { - return ref; -} - -template -inline JniType getPlainJniReference(alias_ref ref) { - return ref.get(); -} - -template -inline JniType getPlainJniReference(const base_owned_ref& ref) { - return ref.get(); -} - - -namespace detail { -template -struct ReprAccess { - using javaobject = JniType; - static void set(Repr& repr, javaobject obj) noexcept { - repr.JObjectBase::set(obj); - } - static javaobject get(const Repr& repr) { - return static_cast(repr.JObject::get()); - } -}; - -namespace { -template -void StaticAssertValidRepr() noexcept { - static_assert(std::is_base_of::value, - "A smart ref representation must be derived from JObject."); - static_assert(IsPlainJniReference>(), "T must be a JNI reference"); - static_assert(sizeof(Repr) == sizeof(JObjectBase), ""); - static_assert(alignof(Repr) == alignof(JObjectBase), ""); -} -} - -template -ReprStorage::ReprStorage(JniType obj) noexcept { - StaticAssertValidRepr(); - set(obj); -} - -template -void ReprStorage::set(JniType obj) noexcept { - new (&storage_) Repr; - ReprAccess::set(get(), obj); -} - -template -Repr& ReprStorage::get() noexcept { - return *reinterpret_cast(&storage_); -} - -template -const Repr& ReprStorage::get() const noexcept { - return *reinterpret_cast(&storage_); -} - -template -JniType ReprStorage::jobj() const noexcept { - ReprAccess::get(get()); - return ReprAccess::get(get()); -} - -template -void ReprStorage::swap(ReprStorage& other) noexcept { - StaticAssertValidRepr(); - using std::swap; - swap(get(), other.get()); -} - -inline void JObjectBase::set(jobject reference) noexcept { - this_ = reference; -} - -inline jobject JObjectBase::get() const noexcept { - return this_; -} - -template -enable_if_t(), plain_jni_reference_t> make_ref(const T& reference) { - auto old_reference = getPlainJniReference(reference); - if (!old_reference) { - return nullptr; - } - - auto ref = Alloc{}.newReference(old_reference); - if (!ref) { - // Note that we end up here if we pass a weak ref that refers to a collected object. - // Thus, it's hard to come up with a reason why this function should be used with - // weak references. - throw std::bad_alloc{}; - } - - return static_cast>(ref); -} - -} // namespace detail - -template -inline local_ref adopt_local(T ref) noexcept { - static_assert(IsPlainJniReference(), "T must be a plain jni reference"); - return local_ref{ref}; -} - -template -inline global_ref adopt_global(T ref) noexcept { - static_assert(IsPlainJniReference(), "T must be a plain jni reference"); - return global_ref{ref}; -} - -template -inline weak_ref adopt_weak_global(T ref) noexcept { - static_assert(IsPlainJniReference(), "T must be a plain jni reference"); - return weak_ref{ref}; -} - - -template -inline enable_if_t(), alias_ref> wrap_alias(T ref) noexcept { - return alias_ref(ref); -} - - -template -enable_if_t(), alias_ref> wrap_alias(T ref) noexcept; - - -template -enable_if_t(), local_ref>> -make_local(const T& ref) { - return adopt_local(detail::make_ref(ref)); -} - -template -enable_if_t(), global_ref>> -make_global(const T& ref) { - return adopt_global(detail::make_ref(ref)); -} - -template -enable_if_t(), weak_ref>> -make_weak(const T& ref) { - return adopt_weak_global(detail::make_ref(ref)); -} - -template -inline enable_if_t() && IsNonWeakReference(), bool> -operator==(const T1& a, const T2& b) { - return isSameObject(getPlainJniReference(a), getPlainJniReference(b)); -} - -template -inline enable_if_t() && IsNonWeakReference(), bool> -operator!=(const T1& a, const T2& b) { - return !(a == b); -} - - -// base_owned_ref /////////////////////////////////////////////////////////////////////// - -template -inline base_owned_ref::base_owned_ref() noexcept - : base_owned_ref(nullptr) -{} - -template -inline base_owned_ref::base_owned_ref(std::nullptr_t t) noexcept - : base_owned_ref(static_cast(nullptr)) -{} - -template -inline base_owned_ref::base_owned_ref(const base_owned_ref& other) - : storage_{static_cast(Alloc{}.newReference(other.get()))} -{} - -template -template -inline base_owned_ref::base_owned_ref(const base_owned_ref& other) - : storage_{static_cast(Alloc{}.newReference(other.get()))} -{ - static_assert(std::is_convertible, javaobject>::value, ""); -} - -template -inline facebook::jni::base_owned_ref::base_owned_ref( - javaobject reference) noexcept - : storage_(reference) { - assert(Alloc{}.verifyReference(reference)); - internal::dbglog("New wrapped ref=%p this=%p", get(), this); -} - -template -inline base_owned_ref::base_owned_ref( - base_owned_ref&& other) noexcept - : storage_(other.get()) { - internal::dbglog("New move from ref=%p other=%p", other.get(), &other); - internal::dbglog("New move to ref=%p this=%p", get(), this); - // JObject is a simple type and does not support move semantics so we explicitly - // clear other - other.set(nullptr); -} - -template -template -base_owned_ref::base_owned_ref(base_owned_ref&& other) noexcept - : storage_(other.get()) { - internal::dbglog("New move from ref=%p other=%p", other.get(), &other); - internal::dbglog("New move to ref=%p this=%p", get(), this); - // JObject is a simple type and does not support move semantics so we explicitly - // clear other - other.set(nullptr); -} - -template -inline base_owned_ref::~base_owned_ref() noexcept { - reset(); - internal::dbglog("Ref destruct ref=%p this=%p", get(), this); -} - -template -inline auto base_owned_ref::release() noexcept -> javaobject { - auto value = get(); - internal::dbglog("Ref release ref=%p this=%p", value, this); - set(nullptr); - return value; -} - -template -inline void base_owned_ref::reset() noexcept { - reset(nullptr); -} - -template -inline void base_owned_ref::reset(javaobject reference) noexcept { - if (get()) { - assert(Alloc{}.verifyReference(reference)); - Alloc{}.deleteReference(get()); - } - set(reference); -} - -template -inline auto base_owned_ref::get() const noexcept -> javaobject { - return storage_.jobj(); -} - -template -inline void base_owned_ref::set(javaobject ref) noexcept { - storage_.set(ref); -} - - -// weak_ref /////////////////////////////////////////////////////////////////////// - -template -inline weak_ref& weak_ref::operator=( - const weak_ref& other) { - auto otherCopy = other; - swap(*this, otherCopy); - return *this; -} - -template -inline weak_ref& weak_ref::operator=( - weak_ref&& other) noexcept { - internal::dbglog("Op= move ref=%p this=%p oref=%p other=%p", - get(), this, other.get(), &other); - reset(other.release()); - return *this; -} - -template -local_ref weak_ref::lockLocal() const { - return adopt_local( - static_cast(LocalReferenceAllocator{}.newReference(get()))); -} - -template -global_ref weak_ref::lockGlobal() const { - return adopt_global( - static_cast(GlobalReferenceAllocator{}.newReference(get()))); -} - -template -inline void swap( - weak_ref& a, - weak_ref& b) noexcept { - internal::dbglog("Ref swap a.ref=%p a=%p b.ref=%p b=%p", - a.get(), &a, b.get(), &b); - a.storage_.swap(b.storage_); -} - - -// basic_strong_ref //////////////////////////////////////////////////////////////////////////// - -template -inline basic_strong_ref& basic_strong_ref::operator=( - const basic_strong_ref& other) { - auto otherCopy = other; - swap(*this, otherCopy); - return *this; -} - -template -inline basic_strong_ref& basic_strong_ref::operator=( - basic_strong_ref&& other) noexcept { - internal::dbglog("Op= move ref=%p this=%p oref=%p other=%p", - get(), this, other.get(), &other); - reset(other.release()); - return *this; -} - -template -inline alias_ref basic_strong_ref::releaseAlias() noexcept { - return wrap_alias(release()); -} - -template -inline basic_strong_ref::operator bool() const noexcept { - return get() != nullptr; -} - -template -inline auto basic_strong_ref::operator->() noexcept -> Repr* { - return &storage_.get(); -} - -template -inline auto basic_strong_ref::operator->() const noexcept -> const Repr* { - return &storage_.get(); -} - -template -inline auto basic_strong_ref::operator*() noexcept -> Repr& { - return storage_.get(); -} - -template -inline auto basic_strong_ref::operator*() const noexcept -> const Repr& { - return storage_.get(); -} - -template -inline void swap( - basic_strong_ref& a, - basic_strong_ref& b) noexcept { - internal::dbglog("Ref swap a.ref=%p a=%p b.ref=%p b=%p", - a.get(), &a, b.get(), &b); - using std::swap; - a.storage_.swap(b.storage_); -} - - -// alias_ref ////////////////////////////////////////////////////////////////////////////// - -template -inline alias_ref::alias_ref() noexcept - : storage_{nullptr} -{} - -template -inline alias_ref::alias_ref(std::nullptr_t) noexcept - : storage_{nullptr} -{} - -template -inline alias_ref::alias_ref(const alias_ref& other) noexcept - : storage_{other.get()} -{} - -template -inline alias_ref::alias_ref(javaobject ref) noexcept - : storage_(ref) { - assert( - LocalReferenceAllocator{}.verifyReference(ref) || - GlobalReferenceAllocator{}.verifyReference(ref)); -} - -template -template -inline alias_ref::alias_ref(alias_ref other) noexcept - : storage_{other.get()} -{} - -template -template -inline alias_ref::alias_ref(const basic_strong_ref& other) noexcept - : storage_{other.get()} -{} - -template -inline alias_ref& alias_ref::operator=(alias_ref other) noexcept { - swap(*this, other); - return *this; -} - -template -inline alias_ref::operator bool() const noexcept { - return get() != nullptr; -} - -template -inline auto facebook::jni::alias_ref::get() const noexcept -> javaobject { - return storage_.jobj(); -} - -template -inline auto alias_ref::operator->() noexcept -> Repr* { - return &(**this); -} - -template -inline auto alias_ref::operator->() const noexcept -> const Repr* { - return &(**this); -} - -template -inline auto alias_ref::operator*() noexcept -> Repr& { - return storage_.get(); -} - -template -inline auto alias_ref::operator*() const noexcept -> const Repr& { - return storage_.get(); -} - -template -inline void alias_ref::set(javaobject ref) noexcept { - storage_.set(ref); -} - -template -inline void swap(alias_ref& a, alias_ref& b) noexcept { - a.storage_.swap(b.storage_); -} - -// Could reduce code duplication by using a pointer-to-function -// template argument. I'm not sure whether that would make the code -// more maintainable (DRY), or less (too clever/confusing.). -template -enable_if_t(), local_ref> -static_ref_cast(const local_ref& ref) noexcept -{ - T p = static_cast(ref.get()); - return make_local(p); -} - -template -enable_if_t(), global_ref> -static_ref_cast(const global_ref& ref) noexcept -{ - T p = static_cast(ref.get()); - return make_global(p); -} - -template -enable_if_t(), alias_ref> -static_ref_cast(const alias_ref& ref) noexcept -{ - T p = static_cast(ref.get()); - return wrap_alias(p); -} - -template -auto dynamic_ref_cast(const RefType& ref) -> -enable_if_t(), decltype(static_ref_cast(ref))> -{ - if (!ref) { - return decltype(static_ref_cast(ref))(); - } - - static alias_ref target_class = findClassStatic(jtype_traits::base_name().c_str()); - if (!target_class) { - throwNewJavaException("java/lang/ClassCastException", - "Could not find class %s.", - jtype_traits::base_name().c_str()); - - } - - local_ref source_class = ref->getClass(); - - if (!target_class->isAssignableFrom(source_class)) { - throwNewJavaException("java/lang/ClassCastException", - "Tried to cast from %s to %s.", - source_class->toString().c_str(), - jtype_traits::base_name().c_str()); - } - - return static_ref_cast(ref); -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h deleted file mode 100644 index 109b8cd46606f3..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - - -/** @file References.h - * - * Functionality similar to smart pointers, but for references into the VM. Four main reference - * types are provided: local_ref, global_ref, weak_ref, and alias_ref. All are generic - * templates that and refer to objects in the jobject hierarchy. The type of the referred objects - * are specified using the template parameter. All reference types except alias_ref own their - * underlying reference, just as a std smart pointer owns the underlying raw pointer. In the context - * of std smart pointers, these references behave like unique_ptr, and have basically the same - * interface. Thus, when the reference is destructed, the plain JNI reference, i.e. the underlying - * JNI reference (like the parameters passed directly to JNI functions), is released. The alias - * references provides no ownership and is a simple wrapper for plain JNI references. - * - * All but the weak references provides access to the underlying object using dereferencing, and a - * get() method. It is also possible to convert these references to booleans to test for nullity. - * To access the underlying object of a weak reference, the reference must either be released, or - * the weak reference can be used to create a local or global reference. - * - * An owning reference is created either by moving the reference from an existing owned reference, - * by copying an existing owned reference (which creates a new underlying reference), by using the - * default constructor which initialize the reference to nullptr, or by using a helper function. The - * helper function exist in two flavors: make_XXX or adopt_XXX. - * - * Adopting takes a plain JNI reference and wrap it in an owned reference. It takes ownership of the - * plain JNI reference so be sure that no one else owns the reference when you adopt it, and make - * sure that you know what kind of reference it is. - * - * New owned references can be created from existing plain JNI references, alias references, local - * references, and global references (i.e. non-weak references) using the make_local, make_global, - * and make_weak functions. - * - * Alias references can be implicitly initialized using global, local and plain JNI references using - * the wrap_alias function. Here, we don't assume ownership of the passed-in reference, but rather - * create a separate reference that we do own, leaving the passed-in reference to its fate. - * - * Similar rules apply for assignment. An owned reference can be copy or move assigned using a smart - * reference of the same type. In the case of copy assignment a new reference is created. Alias - * reference can also be assigned new values, but since they are simple wrappers of plain JNI - * references there is no move semantics involved. - * - * Alias references are special in that they do not own the object and can therefore safely be - * converted to and from its corresponding plain JNI reference. They are useful as parameters of - * functions that do not affect the lifetime of a reference. Usage can be compared with using plain - * JNI pointers as parameters where a function does not take ownership of the underlying object. - * - * The local, global, and alias references makes it possible to access methods in the underlying - * objects. A core set of classes are implemented in CoreClasses.h, and user defined wrappers are - * supported (see example below). The wrappers also supports inheritance so a wrapper can inherit - * from another wrapper to gain access to its functionality. As an example the jstring wrapper - * inherits from the jobject wrapper, so does the jclass wrapper. That means that you can for - * example call the toString() method using the jclass wrapper, or any other class that inherits - * from the jobject wrapper. - * - * Note that the wrappers are parameterized on the static type of your (jobject) pointer, thus if - * you have a jobject that refers to a Java String you will need to cast it to jstring to get the - * jstring wrapper. This also mean that if you make a down cast that is invalid there will be no one - * stopping you and the wrappers currently does not detect this which can cause crashes. Thus, cast - * wisely. - * - * @include WrapperSample.cpp - */ - -#pragma once - -#include -#include -#include - -#include - -#include - -#include "ReferenceAllocators.h" -#include "TypeTraits.h" -#include "References-forward.h" - -namespace facebook { -namespace jni { - -/// Convenience function to wrap an existing local reference -template -local_ref adopt_local(T ref) noexcept; - -/// Convenience function to wrap an existing global reference -template -global_ref adopt_global(T ref) noexcept; - -/// Convenience function to wrap an existing weak reference -template -weak_ref adopt_weak_global(T ref) noexcept; - - -/// Swaps two owning references of the same type -template -void swap(weak_ref& a, weak_ref& b) noexcept; - -/// Swaps two owning references of the same type -template -void swap(basic_strong_ref& a, basic_strong_ref& b) noexcept; - -/** - * Retrieve the plain reference from a plain reference. - */ -template -enable_if_t(), T> getPlainJniReference(T ref); - -/** - * Retrieve the plain reference from an alias reference. - */ -template -JniType getPlainJniReference(alias_ref ref); - -/** - * Retrieve the plain JNI reference from any reference owned reference. - */ -template -JniType getPlainJniReference(const base_owned_ref& ref); - -class JObject; -class JClass; - -namespace detail { - -template -struct HasJniRefRepr : std::false_type {}; - -template -struct HasJniRefRepr::value, void>::type> : std::true_type { - using type = typename T::JniRefRepr; -}; - -template -struct RefReprType { - using type = typename std::conditional::value, typename HasJniRefRepr::type, JObjectWrapper>::type; - static_assert(std::is_base_of::value, - "Repr type missing JObject base."); - static_assert(std::is_same::type>::value, - "RefReprType not idempotent"); -}; - -template -struct RefReprType::value, void>::type> { - using type = T; - static_assert(std::is_base_of::value, - "Repr type missing JObject base."); - static_assert(std::is_same::type>::value, - "RefReprType not idempotent"); -}; - -template -struct JavaObjectType { - using type = typename RefReprType::type::javaobject; - static_assert(IsPlainJniReference(), - "JavaObjectType not a plain jni reference"); - static_assert(std::is_same::type>::value, - "JavaObjectType not idempotent"); -}; - -template -struct JavaObjectType> { - using type = T; - static_assert(IsPlainJniReference(), - "JavaObjectType not a plain jni reference"); - static_assert(std::is_same::type>::value, - "JavaObjectType not idempotent"); -}; - -template -struct JavaObjectType { - using type = T*; - static_assert(IsPlainJniReference(), - "JavaObjectType not a plain jni reference"); - static_assert(std::is_same::type>::value, - "JavaObjectType not idempotent"); -}; - -template -struct ReprStorage { - explicit ReprStorage(JniType obj) noexcept; - - void set(JniType obj) noexcept; - - Repr& get() noexcept; - const Repr& get() const noexcept; - JniType jobj() const noexcept; - - void swap(ReprStorage& other) noexcept; - private: - ReprStorage() = delete; - ReprStorage(const ReprStorage&) = delete; - ReprStorage(ReprStorage&&) = delete; - ReprStorage& operator=(const ReprStorage&) = delete; - ReprStorage& operator=(ReprStorage&&) = delete; - - using Storage = typename std::aligned_storage::type; - Storage storage_; -}; - -} // namespace detail - -/** - * Create a new local reference from an existing reference - * - * @param ref a plain JNI, alias, or strong reference - * @return an owned local reference (referring to null if the input does) - * @throws std::bad_alloc if the JNI reference could not be created - */ -template -enable_if_t(), local_ref>> -make_local(const T& r); - -/** - * Create a new global reference from an existing reference - * - * @param ref a plain JNI, alias, or strong reference - * @return an owned global reference (referring to null if the input does) - * @throws std::bad_alloc if the JNI reference could not be created - */ -template -enable_if_t(), global_ref>> -make_global(const T& r); - -/** - * Create a new weak global reference from an existing reference - * - * @param ref a plain JNI, alias, or strong reference - * @return an owned weak global reference (referring to null if the input does) - * @throws std::bad_alloc if the returned reference is null - */ -template -enable_if_t(), weak_ref>> -make_weak(const T& r); - -/** - * Compare two references to see if they refer to the same object - */ -template -enable_if_t() && IsNonWeakReference(), bool> -operator==(const T1& a, const T2& b); - -/** - * Compare two references to see if they don't refer to the same object - */ -template -enable_if_t() && IsNonWeakReference(), bool> -operator!=(const T1& a, const T2& b); - -template -class base_owned_ref { - public: - using javaobject = JniType; - - /** - * Release the ownership and set the reference to null. Thus no deleter is invoked. - * @return Returns the reference - */ - javaobject release() noexcept; - - /** - * Reset the reference to refer to nullptr. - */ - void reset() noexcept; - - protected: - using Repr = ReprType; - detail::ReprStorage storage_; - - javaobject get() const noexcept; - void set(javaobject ref) noexcept; - - /* - * Wrap an existing reference and transfers its ownership to the newly created unique reference. - * NB! Does not create a new reference - */ - explicit base_owned_ref(javaobject reference) noexcept; - - /// Create a null reference - base_owned_ref() noexcept; - - /// Create a null reference - explicit base_owned_ref(std::nullptr_t) noexcept; - - /// Copy constructor (note creates a new reference) - base_owned_ref(const base_owned_ref& other); - template - base_owned_ref(const base_owned_ref& other); - - /// Transfers ownership of an underlying reference from one unique reference to another - base_owned_ref(base_owned_ref&& other) noexcept; - template - base_owned_ref(base_owned_ref&& other) noexcept; - - /// The delete the underlying reference if applicable - ~base_owned_ref() noexcept; - - - /// Assignment operator (note creates a new reference) - base_owned_ref& operator=(const base_owned_ref& other); - - /// Assignment by moving a reference thus not creating a new reference - base_owned_ref& operator=(base_owned_ref&& rhs) noexcept; - - void reset(javaobject reference) noexcept; - - friend javaobject jni::getPlainJniReference<>(const base_owned_ref& ref); - - template - friend class base_owned_ref; -}; - - -/** - * A smart reference that owns its underlying JNI reference. The class provides basic - * functionality to handle a reference but gives no access to it unless the reference is - * released, thus no longer owned. The API is stolen with pride from unique_ptr and the - * semantics should be basically the same. This class should not be used directly, instead use - * @ref weak_ref - */ -template -class weak_ref : public base_owned_ref { - public: - using javaobject = JniType; - - using Allocator = WeakGlobalReferenceAllocator; - - // This inherits non-default, non-copy, non-move ctors. - using base_owned_ref::base_owned_ref; - - /// Create a null reference - weak_ref() noexcept - : base_owned_ref{} {} - - /// Create a null reference - /* implicit */ weak_ref(std::nullptr_t) noexcept - : base_owned_ref{nullptr} {} - - /// Copy constructor (note creates a new reference) - weak_ref(const weak_ref& other) - : base_owned_ref{other} {} - - // This needs to be explicit to change its visibility. - template - weak_ref(const weak_ref& other) - : base_owned_ref{other} {} - - /// Transfers ownership of an underlying reference from one unique reference to another - weak_ref(weak_ref&& other) noexcept - : base_owned_ref{std::move(other)} {} - - - /// Assignment operator (note creates a new reference) - weak_ref& operator=(const weak_ref& other); - - /// Assignment by moving a reference thus not creating a new reference - weak_ref& operator=(weak_ref&& rhs) noexcept; - - // Creates an owned local reference to the referred object or to null if the object is reclaimed - local_ref lockLocal() const; - - // Creates an owned global reference to the referred object or to null if the object is reclaimed - global_ref lockGlobal() const; - - private: - // get/release/reset on weak_ref are not exposed to users. - using base_owned_ref::get; - using base_owned_ref::release; - using base_owned_ref::reset; - /* - * Wrap an existing reference and transfers its ownership to the newly created unique reference. - * NB! Does not create a new reference - */ - explicit weak_ref(javaobject reference) noexcept - : base_owned_ref{reference} {} - - template friend class weak_ref; - friend weak_ref adopt_weak_global(javaobject ref) noexcept; - friend void swap(weak_ref& a, weak_ref& b) noexcept; -}; - - -/** - * A class representing owned strong references to Java objects. This class - * should not be used directly, instead use @ref local_ref, or @ref global_ref. - */ -template -class basic_strong_ref : public base_owned_ref { - using typename base_owned_ref::Repr; - public: - using javaobject = JniType; - - using Allocator = Alloc; - - // This inherits non-default, non-copy, non-move ctors. - using base_owned_ref::base_owned_ref; - using base_owned_ref::release; - using base_owned_ref::reset; - - /// Create a null reference - basic_strong_ref() noexcept - : base_owned_ref{} {} - - /// Create a null reference - /* implicit */ basic_strong_ref(std::nullptr_t) noexcept - : base_owned_ref{nullptr} {} - - /// Copy constructor (note creates a new reference) - basic_strong_ref(const basic_strong_ref& other) - : base_owned_ref{other} {} - - // This needs to be explicit to change its visibility. - template - basic_strong_ref(const basic_strong_ref& other) - : base_owned_ref{other} {} - - /// Transfers ownership of an underlying reference from one unique reference to another - basic_strong_ref(basic_strong_ref&& other) noexcept - : base_owned_ref{std::move(other)} {} - - /// Assignment operator (note creates a new reference) - basic_strong_ref& operator=(const basic_strong_ref& other); - - /// Assignment by moving a reference thus not creating a new reference - basic_strong_ref& operator=(basic_strong_ref&& rhs) noexcept; - - /// Get the plain JNI reference - using base_owned_ref::get; - - /// Release the ownership of the reference and return the wrapped reference in an alias - alias_ref releaseAlias() noexcept; - - /// Checks if the reference points to a non-null object - explicit operator bool() const noexcept; - - /// Access the functionality provided by the object wrappers - Repr* operator->() noexcept; - - /// Access the functionality provided by the object wrappers - const Repr* operator->() const noexcept; - - /// Provide a reference to the underlying wrapper (be sure that it is non-null before invoking) - Repr& operator*() noexcept; - - /// Provide a const reference to the underlying wrapper (be sure that it is non-null - /// before invoking) - const Repr& operator*() const noexcept; - - private: - - using base_owned_ref::storage_; - - /* - * Wrap an existing reference and transfers its ownership to the newly created unique reference. - * NB! Does not create a new reference - */ - explicit basic_strong_ref(javaobject reference) noexcept - : base_owned_ref{reference} {} - - - friend local_ref adopt_local(T ref) noexcept; - friend global_ref adopt_global(T ref) noexcept; - friend void swap(basic_strong_ref& a, basic_strong_ref& b) noexcept; -}; - - -template -enable_if_t(), alias_ref> wrap_alias(T ref) noexcept; - -/// Swaps to alias reference of the same type -template -void swap(alias_ref& a, alias_ref& b) noexcept; - -/** - * A non-owning variant of the smart references (a dumb reference). These references still provide - * access to the functionality of the @ref JObjectWrapper specializations including exception - * handling and ease of use. Use this representation when you don't want to claim ownership of the - * underlying reference (compare to using raw pointers instead of smart pointers.) For symmetry use - * @ref alias_ref instead of this class. - */ -template -class alias_ref { - using Repr = ReprType; - - public: - using javaobject = JniType; - - /// Create a null reference - alias_ref() noexcept; - - /// Create a null reference - /* implicit */ alias_ref(std::nullptr_t) noexcept; - - /// Copy constructor - alias_ref(const alias_ref& other) noexcept; - - /// Wrap an existing plain JNI reference - /* implicit */ alias_ref(javaobject ref) noexcept; - - /// Wrap an existing smart reference of any type convertible to T - template< - typename TOther, - typename = enable_if_t< - IsConvertible, javaobject>(), T> - > - alias_ref(alias_ref other) noexcept; - - /// Wrap an existing alias reference of a type convertible to T - template< - typename TOther, - typename AOther, - typename = enable_if_t< - IsConvertible, javaobject>(), T> - > - alias_ref(const basic_strong_ref& other) noexcept; - - /// Assignment operator - alias_ref& operator=(alias_ref other) noexcept; - - /// Checks if the reference points to a non-null object - explicit operator bool() const noexcept; - - /// Converts back to a plain JNI reference - javaobject get() const noexcept; - - /// Access the functionality provided by the object wrappers - Repr* operator->() noexcept; - - /// Access the functionality provided by the object wrappers - const Repr* operator->() const noexcept; - - /// Provide a guaranteed non-null reference (be sure that it is non-null before invoking) - Repr& operator*() noexcept; - - /// Provide a guaranteed non-null reference (be sure that it is non-null before invoking) - const Repr& operator*() const noexcept; - - private: - void set(javaobject ref) noexcept; - - detail::ReprStorage storage_; - - friend void swap(alias_ref& a, alias_ref& b) noexcept; -}; - - -/** - * RAII object to create a local JNI frame, using PushLocalFrame/PopLocalFrame. - * - * This is useful when you have a call which is initiated from C++-land, and therefore - * doesn't automatically get a local JNI frame managed for you by the JNI framework. - */ -class FBEXPORT JniLocalScope { -public: - JniLocalScope(JNIEnv* p_env, jint capacity); - ~JniLocalScope(); - -private: - JNIEnv* env_; - bool hasFrame_; -}; - -template -enable_if_t(), local_ref> -static_ref_cast(const local_ref& ref) noexcept; - -template -enable_if_t(), global_ref> -static_ref_cast(const global_ref& ref) noexcept; - -template -enable_if_t(), alias_ref> -static_ref_cast(const alias_ref& ref) noexcept; - -template -auto dynamic_ref_cast(const RefType& ref) -> -enable_if_t(), decltype(static_ref_cast(ref))> ; - -}} - -#include "References-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h deleted file mode 100644 index e08533c52c5336..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include "Exceptions.h" -#include "Hybrid.h" - -namespace facebook { -namespace jni { - -namespace detail { - -#ifdef __i386__ -// X86 ABI forces 16 byte stack alignment on calls. Unfortunately -// sometimes Dalvik chooses not to obey the ABI: -// - https://code.google.com/p/android/issues/detail?id=61012 -// - https://android.googlesource.com/platform/ndk/+/81696d2%5E!/ -// Therefore, we tell the compiler to re-align the stack on entry -// to our JNI functions. -#define JNI_ENTRY_POINT __attribute__((force_align_arg_pointer)) -#else -#define JNI_ENTRY_POINT -#endif - -template -struct CreateDefault { - static R create() { - return R{}; - } -}; - -template <> -struct CreateDefault { - static void create() {} -}; - -template -using Converter = Convert::type>; - -template -struct WrapForVoidReturn { - static typename Converter::jniType call(Args&&... args) { - return Converter::toJniRet(func(std::forward(args)...)); - } -}; - -template -struct WrapForVoidReturn { - static void call(Args&&... args) { - func(std::forward(args)...); - } -}; - -// registration wrapper for legacy JNI-style functions -template -struct BareJniWrapper { - JNI_ENTRY_POINT static R call(JNIEnv* env, jobject obj, Args... args) { - ThreadScope ts(env, internal::CacheEnvTag{}); - try { - return (*func)(env, static_cast>(obj), args...); - } catch (...) { - translatePendingCppExceptionToJavaException(); - return CreateDefault::create(); - } - } -}; - -// registration wrappers for functions, with autoconversion of arguments. -template -struct FunctionWrapper { - using jniRet = typename Converter::jniType; - JNI_ENTRY_POINT static jniRet call(JNIEnv* env, jobject obj, typename Converter::jniType... args) { - ThreadScope ts(env, internal::CacheEnvTag{}); - try { - return WrapForVoidReturn, Args...>::call( - static_cast>(obj), Converter::fromJni(args)...); - } catch (...) { - translatePendingCppExceptionToJavaException(); - return CreateDefault::create(); - } - } -}; - -// registration wrappers for non-static methods, with autoconversion of arguments. -template -struct MethodWrapper { - using jhybrid = typename C::jhybridobject; - static R dispatch(alias_ref ref, Args&&... args) { - try { - // This is usually a noop, but if the hybrid object is a - // base class of other classes which register JNI methods, - // this will get the right type for the registered method. - auto cobj = static_cast(ref->cthis()); - return (cobj->*method)(std::forward(args)...); - } catch (const std::exception& ex) { - C::mapException(ex); - throw; - } - } - - JNI_ENTRY_POINT static typename Converter::jniType call( - JNIEnv* env, jobject obj, typename Converter::jniType... args) { - return FunctionWrapper, Args&&...), dispatch, jhybrid, R, Args...>::call(env, obj, args...); - } -}; - -template -inline NativeMethodWrapper* exceptionWrapJNIMethod(R (*)(JNIEnv*, C, Args... args)) { - // This intentionally erases the real type; JNI will do it anyway - return reinterpret_cast(&(BareJniWrapper::call)); -} - -template -inline NativeMethodWrapper* exceptionWrapJNIMethod(R (*)(alias_ref, Args... args)) { - // This intentionally erases the real type; JNI will do it anyway - return reinterpret_cast(&(FunctionWrapper::call)); -} - -template -inline NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args)) { - // This intentionally erases the real type; JNI will do it anyway - return reinterpret_cast(&(MethodWrapper::call)); -} - -template -inline std::string makeDescriptor(R (*)(JNIEnv*, C, Args... args)) { - return jmethod_traits::descriptor(); -} - -template -inline std::string makeDescriptor(R (*)(alias_ref, Args... args)) { - return jmethod_traits_from_cxx::descriptor(); -} - -template -inline std::string makeDescriptor(R (C::*)(Args... args)) { - return jmethod_traits_from_cxx::descriptor(); -} - -template -template -JNI_ENTRY_POINT R CriticalMethod::call(alias_ref, Args... args) { - static_assert( - IsJniPrimitive() || std::is_void(), - "Critical Native Methods may only return primitive JNI types, or void."); - static_assert( - AreJniPrimitives(), - "Critical Native Methods may only use primitive JNI types as parameters"); - - return func(std::forward(args)...); -} - -template -template -inline std::string CriticalMethod::desc() { - return makeDescriptor(call); -} - -} - -}} diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h deleted file mode 100644 index c87fdd75b1890c..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include "References.h" - -namespace facebook { -namespace jni { - -namespace detail { - -// This uses the real JNI function as a non-type template parameter to -// cause a (static member) function to exist with the same signature, -// but with try/catch exception translation. -template -NativeMethodWrapper* exceptionWrapJNIMethod(R (*func0)(JNIEnv*, jobject, Args... args)); - -// Automatically wrap object argument, and don't take env explicitly. -template -NativeMethodWrapper* exceptionWrapJNIMethod(R (*func0)(alias_ref, Args... args)); - -// Extract C++ instance from object, and invoke given method on it, -template -NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args)); - -// This uses deduction to figure out the descriptor name if the types -// are primitive or have JObjectWrapper specializations. -template -std::string makeDescriptor(R (*func)(JNIEnv*, C, Args... args)); - -// This uses deduction to figure out the descriptor name if the types -// are primitive or have JObjectWrapper specializations. -template -std::string makeDescriptor(R (*func)(alias_ref, Args... args)); - -// This uses deduction to figure out the descriptor name if the types -// are primitive or have JObjectWrapper specializations. -template -std::string makeDescriptor(R (C::*method0)(Args... args)); - -template -struct CriticalMethod; - -template -struct CriticalMethod { - template - static R call(alias_ref, Args... args); - - template - inline static std::string desc(); -}; - -} - -// We have to use macros here, because the func needs to be used -// as both a decltype expression argument and as a non-type template -// parameter, since C++ provides no way for translateException -// to deduce the type of its non-type template parameter. -// The empty string in the macros below ensures that name -// is always a string literal (because that syntax is only -// valid when name is a string literal). -#define makeNativeMethod2(name, func) \ - { name "", ::facebook::jni::detail::makeDescriptor(&func), \ - ::facebook::jni::detail::exceptionWrapJNIMethod(&func) } - -#define makeNativeMethod3(name, desc, func) \ - { name "", desc, \ - ::facebook::jni::detail::exceptionWrapJNIMethod(&func) } - -// Variadic template hacks to get macros with different numbers of -// arguments. Usage instructions are in CoreClasses.h. -#define makeNativeMethodN(a, b, c, count, ...) makeNativeMethod ## count -#define makeNativeMethod(...) makeNativeMethodN(__VA_ARGS__, 3, 2)(__VA_ARGS__) - - -// FAST CALLS / CRITICAL CALLS -// Android up to and including v7 supports "fast calls" by prefixing the method -// signature with an exclamation mark. -// Android v8+ supports fast calls by annotating methods: -// https://source.android.com/devices/tech/dalvik/improvements#faster-native-methods -// -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// -// "Fast" calls are only on the order of a few dozen NANO-seconds faster than -// regular JNI calls. If your method does almost aaanything of consequence - if -// you loop, if you write to a log, if you call another method, if you even -// simply allocate or deallocate - then the method body will significantly -// outweigh the method overhead. -// -// The difference between a regular JNI method and a "FastJNI" method (as -// they're called inside the runtime) is that a FastJNI method doesn't mark the -// thread as executing native code, and by skipping that avoids the locking and -// thread state check overhead of interacting with the Garbage Collector. -// -// To understand why this is dangerous, you need to understand a bit about the -// GC. In order to perform its work the GC needs to have at least one (usually -// two in modern implementations) "stop the world" checkpoints where it can -// guarantee that all managed-code execution is paused. The VM performs these -// checkpoints at allocations, method boundaries, and each backward branch (ie -// anytime you loop). When the GC wants to run, it will signal to all managed -// threads that they should pause at the next checkpoint, and then it will wait -// for every thread in the system to transition from the "runnable" state into a -// "waiting" state. Once every thread has stopped, the GC thread can perform the -// work it needs to and then it will trigger the execution threads to resume. -// -// JNI methods fit neatly into the above paradigm: They're still methods, so -// they perform GC checkpoints at method entry and method exit. JNI methods also -// perform checkpoints at any JNI boundary crossing - ie, any time you call -// GetObjectField etc. Because access to managed objects from native code is -// tightly controlled, the VM is able to mark threads executing native methods -// into a special "native" state which the GC is able to ignore: It knows they -// can't touch managed objects (without hitting a checkpoint) so it doesn't care -// about them. -// -// JNI critical methods don't perform that "runnable" -> "native" thread state -// transition. Skipping that transition allows them to shave about 20ns off -// their total execution time, but it means that the GC has to wait for them to -// complete before it can move forward. If a critical method begins blocking, -// say on a long loop, or an I/O operation, or on perhaps a mutex, then the GC -// will also block, and because the GC is blocking the entire rest of the VM -// (which is waiting on the GC) will block. If the critical method is blocking -// on a mutex that's already held by the GC - for example, the VM's internal -// weak_globals_lock_ which guards modifications to the weak global reference -// table (and is required in order to create or free a weak_ref<>) - then you -// have a system-wide deadlock. - -// prefixes a JNI method signature as android "fast call". -#if defined(__ANDROID__) && defined(FBJNI_WITH_FAST_CALLS) -#define FBJNI_PREFIX_FAST_CALL(desc) (std::string{"!"} + desc) -#else -#define FBJNI_PREFIX_FAST_CALL(desc) (desc) -#endif - -#define makeCriticalNativeMethod3(name, desc, func) \ - makeNativeMethod3( \ - name, \ - FBJNI_PREFIX_FAST_CALL(desc), \ - ::facebook::jni::detail::CriticalMethod::call<&func>) - -#define makeCriticalNativeMethod2(name, func) \ - makeCriticalNativeMethod3( \ - name, \ - ::facebook::jni::detail::CriticalMethod::desc<&func>(), \ - func) - -#define makeCriticalNativeMethodN(a, b, c, count, ...) makeCriticalNativeMethod ## count - -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// YOU ALMOST CERTAINLY DO NOT NEED THIS AND IT IS DANGEROUS. -// See above for an explanation. -#define makeCriticalNativeMethod_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...) makeCriticalNativeMethodN(__VA_ARGS__, 3, 2)(__VA_ARGS__) - -}} - -#include "Registration-inl.h" diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h deleted file mode 100644 index e8dff3be74d6d8..00000000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include "References-forward.h" - -namespace facebook { -namespace jni { - -/// Generic std::enable_if helper -template -using enable_if_t = typename std::enable_if::type; - -/// Generic std::is_convertible helper -template -constexpr bool IsConvertible() { - return std::is_convertible::value; -} - -template class TT, typename T> -struct is_instantiation_of : std::false_type {}; - -template class TT, typename... Ts> -struct is_instantiation_of> : std::true_type {}; - -template class TT, typename... Ts> -constexpr bool IsInstantiationOf() { - return is_instantiation_of::value; -} - -/// Metafunction to determine whether a type is a JNI reference or not -template -struct is_plain_jni_reference : - std::integral_constant::value && - std::is_base_of< - typename std::remove_pointer::type, - typename std::remove_pointer::type>::value> {}; - -/// Helper to simplify use of is_plain_jni_reference -template -constexpr bool IsPlainJniReference() { - return is_plain_jni_reference::value; -} - -/// Metafunction to determine whether a type is a primitive JNI type or not -template -struct is_jni_primitive : - std::integral_constant::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value> {}; - -/// Helper to simplify use of is_jni_primitive -template -constexpr bool IsJniPrimitive() { - return is_jni_primitive::value; -} - -/// Metafunction to determine whether a series of types are all primitive JNI types. -template -struct are_jni_primitives; - -template -struct are_jni_primitives : - std::integral_constant::value && are_jni_primitives::value> {}; - -template<> -struct are_jni_primitives<> : std::integral_constant {}; - -/// Helper to simplify use of are_jni_primitives -template -constexpr bool AreJniPrimitives() { - return are_jni_primitives::value; -} - - -/// Metafunction to determine whether a type is a JNI array of primitives or not -template -struct is_jni_primitive_array : - std::integral_constant::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value || - std::is_same::value> {}; - -/// Helper to simplify use of is_jni_primitive_array -template -constexpr bool IsJniPrimitiveArray() { - return is_jni_primitive_array::value; -} - -/// Metafunction to determine if a type is a scalar (primitive or reference) JNI type -template -struct is_jni_scalar : - std::integral_constant::value || - is_jni_primitive::value> {}; - -/// Helper to simplify use of is_jni_scalar -template -constexpr bool IsJniScalar() { - return is_jni_scalar::value; -} - -// Metafunction to determine if a type is a JNI type -template -struct is_jni_type : - std::integral_constant::value || - std::is_void::value> {}; - -/// Helper to simplify use of is_jni_type -template -constexpr bool IsJniType() { - return is_jni_type::value; -} - -template -struct is_non_weak_reference : - std::integral_constant() || - IsInstantiationOf() || - IsInstantiationOf()> {}; - -template -constexpr bool IsNonWeakReference() { - return is_non_weak_reference::value; -} - -template -struct is_any_reference : - std::integral_constant() || - IsInstantiationOf() || - IsInstantiationOf() || - IsInstantiationOf()> {}; - -template -constexpr bool IsAnyReference() { - return is_any_reference::value; -} - -template -struct reference_traits { - using plain_jni_reference_t = JniType; - static_assert(IsPlainJniReference(), "Need a plain JNI reference"); -}; - -template

This callback can be used by different implementations of ReactTextViewManager to customize + * Spannable or extend managed created by React. + */ + void onPostProcessSpannable(Spannable text); +} From 84adc85523770ebfee749a020920e0b216cf69f8 Mon Sep 17 00:00:00 2001 From: Scott Kyle Date: Sun, 19 Jan 2020 00:08:36 -0800 Subject: [PATCH 0056/1126] Export exception classes with default visibility Summary: This fixes a crash caused by a `JSError` exception not being successfully caught in a different dynamic library from where it was thrown. Since the libraries were compiled with hidden symbols and loaded with `RTLD_LOCAL`, the exception typeinfo becomes unique to each module. Reading on this subject: https://gcc.gnu.org/wiki/Visibility https://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error Reviewed By: mhorowitz Differential Revision: D19343161 fbshipit-source-id: 4eb3bc2576bbcca2c3aef4f52b5a27dfde214c6a --- ReactCommon/jsi/jsi/jsi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ReactCommon/jsi/jsi/jsi.h b/ReactCommon/jsi/jsi/jsi.h index 33e3008335c641..f336bec742ddaf 100644 --- a/ReactCommon/jsi/jsi/jsi.h +++ b/ReactCommon/jsi/jsi/jsi.h @@ -1191,7 +1191,7 @@ class Scope { }; /// Base class for jsi exceptions -class JSIException : public std::exception { +class JSI_EXPORT JSIException : public std::exception { protected: JSIException(){}; JSIException(std::string what) : what_(std::move(what)){}; @@ -1207,7 +1207,7 @@ class JSIException : public std::exception { /// This exception will be thrown by API functions on errors not related to /// JavaScript execution. -class JSINativeException : public JSIException { +class JSI_EXPORT JSINativeException : public JSIException { public: JSINativeException(std::string what) : JSIException(std::move(what)) {} }; @@ -1215,7 +1215,7 @@ class JSINativeException : public JSIException { /// This exception will be thrown by API functions whenever a JS /// operation causes an exception as described by the spec, or as /// otherwise described. -class JSError : public JSIException { +class JSI_EXPORT JSError : public JSIException { public: /// Creates a JSError referring to provided \c value JSError(Runtime& r, Value&& value); From 582738bdc8ffd391362faf8b75ff17c1b024e2c3 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:06:16 -0800 Subject: [PATCH 0057/1126] Use EXPECT instead of ASSERT in tests Summary: Changelog: [Internal] 1. Replace ASSERT_* with EXPECT_*. Assert is a fatal assertion. Expect is non-fatal assertion. So if assert fails, tests do not continue and therefore provide less information. 2. Rename tests in `RawPropsTest.cpp` from `ShadowNodeTest` to `RawPropsTest`. Source: https://github.com/google/googletest/blob/master/googletest/docs/primer.md#basic-assertions Reviewed By: shergin Differential Revision: D19464967 fbshipit-source-id: add83751ebdb0a12fbf8f70b851747aa5624366a --- .../core/tests/ComponentDescriptorTest.cpp | 32 ++--- .../fabric/core/tests/PrimitivesTest.cpp | 6 +- .../fabric/core/tests/RawPropsTest.cpp | 116 +++++++++--------- .../fabric/core/tests/ShadowNodeTest.cpp | 70 +++++------ 4 files changed, 112 insertions(+), 112 deletions(-) diff --git a/ReactCommon/fabric/core/tests/ComponentDescriptorTest.cpp b/ReactCommon/fabric/core/tests/ComponentDescriptorTest.cpp index 2a77081ffa59ac..ca951a8eac19b4 100644 --- a/ReactCommon/fabric/core/tests/ComponentDescriptorTest.cpp +++ b/ReactCommon/fabric/core/tests/ComponentDescriptorTest.cpp @@ -17,9 +17,9 @@ TEST(ComponentDescriptorTest, createShadowNode) { std::make_shared( ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - ASSERT_EQ(descriptor->getComponentHandle(), TestShadowNode::Handle()); - ASSERT_STREQ(descriptor->getComponentName(), TestShadowNode::Name()); - ASSERT_STREQ(descriptor->getComponentName(), "Test"); + EXPECT_EQ(descriptor->getComponentHandle(), TestShadowNode::Handle()); + EXPECT_STREQ(descriptor->getComponentName(), TestShadowNode::Name()); + EXPECT_STREQ(descriptor->getComponentName(), "Test"); const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc")); SharedProps props = descriptor->cloneProps(nullptr, raw); @@ -34,12 +34,12 @@ TEST(ComponentDescriptorTest, createShadowNode) { /* .eventEmitter = */ descriptor->createEventEmitter(0, 9), }); - ASSERT_EQ(node->getComponentHandle(), TestShadowNode::Handle()); - ASSERT_STREQ(node->getComponentName(), TestShadowNode::Name()); - ASSERT_STREQ(node->getComponentName(), "Test"); - ASSERT_EQ(node->getTag(), 9); - ASSERT_EQ(node->getSurfaceId(), 1); - ASSERT_STREQ(node->getProps()->nativeId.c_str(), "abc"); + EXPECT_EQ(node->getComponentHandle(), TestShadowNode::Handle()); + EXPECT_STREQ(node->getComponentName(), TestShadowNode::Name()); + EXPECT_STREQ(node->getComponentName(), "Test"); + EXPECT_EQ(node->getTag(), 9); + EXPECT_EQ(node->getSurfaceId(), 1); + EXPECT_STREQ(node->getProps()->nativeId.c_str(), "abc"); } TEST(ComponentDescriptorTest, cloneShadowNode) { @@ -61,10 +61,10 @@ TEST(ComponentDescriptorTest, cloneShadowNode) { }); SharedShadowNode cloned = descriptor->cloneShadowNode(*node, {}); - ASSERT_STREQ(cloned->getComponentName(), "Test"); - ASSERT_EQ(cloned->getTag(), 9); - ASSERT_EQ(cloned->getSurfaceId(), 1); - ASSERT_STREQ(cloned->getProps()->nativeId.c_str(), "abc"); + EXPECT_STREQ(cloned->getComponentName(), "Test"); + EXPECT_EQ(cloned->getTag(), 9); + EXPECT_EQ(cloned->getSurfaceId(), 1); + EXPECT_STREQ(cloned->getProps()->nativeId.c_str(), "abc"); } TEST(ComponentDescriptorTest, appendChild) { @@ -108,7 +108,7 @@ TEST(ComponentDescriptorTest, appendChild) { descriptor->appendChild(node1, node3); auto node1Children = node1->getChildren(); - ASSERT_EQ(node1Children.size(), 2); - ASSERT_EQ(node1Children.at(0), node2); - ASSERT_EQ(node1Children.at(1), node3); + EXPECT_EQ(node1Children.size(), 2); + EXPECT_EQ(node1Children.at(0), node2); + EXPECT_EQ(node1Children.at(1), node3); } diff --git a/ReactCommon/fabric/core/tests/PrimitivesTest.cpp b/ReactCommon/fabric/core/tests/PrimitivesTest.cpp index f6fe13ebfae8a0..f156ed77b420c0 100644 --- a/ReactCommon/fabric/core/tests/PrimitivesTest.cpp +++ b/ReactCommon/fabric/core/tests/PrimitivesTest.cpp @@ -14,10 +14,10 @@ using namespace facebook::react; TEST(SealableTest, sealObjectCorrectly) { Sealable obj; - ASSERT_FALSE(obj.getSealed()); + EXPECT_FALSE(obj.getSealed()); obj.seal(); - ASSERT_TRUE(obj.getSealed()); + EXPECT_TRUE(obj.getSealed()); } TEST(SealableTest, handleAssignmentsCorrectly) { @@ -37,5 +37,5 @@ TEST(SealableTest, handleAssignmentsCorrectly) { // Fresh creation off other Sealable is still unsealed. Sealable other3(obj); - ASSERT_FALSE(other3.getSealed()); + EXPECT_FALSE(other3.getSealed()); } diff --git a/ReactCommon/fabric/core/tests/RawPropsTest.cpp b/ReactCommon/fabric/core/tests/RawPropsTest.cpp index 7d22b8132eb15f..7a5ecb1f94b9c4 100644 --- a/ReactCommon/fabric/core/tests/RawPropsTest.cpp +++ b/ReactCommon/fabric/core/tests/RawPropsTest.cpp @@ -118,7 +118,7 @@ class PropsMultiLookup : public Props { const float derivedFloatValue{40}; }; -TEST(ShadowNodeTest, handleProps) { +TEST(RawPropsTest, handleProps) { const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc")); auto parser = RawPropsParser(); parser.prepare(); @@ -127,12 +127,12 @@ TEST(ShadowNodeTest, handleProps) { auto props = std::make_shared(Props(), raw); // Props are not sealed after applying raw props. - ASSERT_FALSE(props->getSealed()); + EXPECT_FALSE(props->getSealed()); - ASSERT_STREQ(props->nativeId.c_str(), "abc"); + EXPECT_STREQ(props->nativeId.c_str(), "abc"); } -TEST(ShadowNodeTest, handleRawPropsSingleString) { +TEST(RawPropsTest, handleRawPropsSingleString) { const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc")); auto parser = RawPropsParser(); parser.prepare(); @@ -140,10 +140,10 @@ TEST(ShadowNodeTest, handleRawPropsSingleString) { std::string value = (std::string)*raw.at("nativeID", nullptr, nullptr); - ASSERT_STREQ(value.c_str(), "abc"); + EXPECT_STREQ(value.c_str(), "abc"); } -TEST(ShadowNodeTest, handleRawPropsSingleFloat) { +TEST(RawPropsTest, handleRawPropsSingleFloat) { const auto &raw = RawProps(folly::dynamic::object("floatValue", (float)42.42)); auto parser = RawPropsParser(); @@ -152,10 +152,10 @@ TEST(ShadowNodeTest, handleRawPropsSingleFloat) { float value = (float)*raw.at("floatValue", nullptr, nullptr); - ASSERT_NEAR(value, 42.42, 0.00001); + EXPECT_NEAR(value, 42.42, 0.00001); } -TEST(ShadowNodeTest, handleRawPropsSingleDouble) { +TEST(RawPropsTest, handleRawPropsSingleDouble) { const auto &raw = RawProps(folly::dynamic::object("doubleValue", (double)42.42)); auto parser = RawPropsParser(); @@ -164,10 +164,10 @@ TEST(ShadowNodeTest, handleRawPropsSingleDouble) { double value = (double)*raw.at("doubleValue", nullptr, nullptr); - ASSERT_NEAR(value, 42.42, 0.00001); + EXPECT_NEAR(value, 42.42, 0.00001); } -TEST(ShadowNodeTest, handleRawPropsSingleInt) { +TEST(RawPropsTest, handleRawPropsSingleInt) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42.42)); auto parser = RawPropsParser(); parser.prepare(); @@ -175,21 +175,21 @@ TEST(ShadowNodeTest, handleRawPropsSingleInt) { int value = (int)*raw.at("intValue", nullptr, nullptr); - ASSERT_EQ(value, 42); + EXPECT_EQ(value, 42); } -TEST(ShadowNodeTest, handleRawPropsSingleIntGetManyTimes) { +TEST(RawPropsTest, handleRawPropsSingleIntGetManyTimes) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42.42)); auto parser = RawPropsParser(); parser.prepare(); raw.parse(parser); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); } -TEST(ShadowNodeTest, handleRawPropsPrimitiveTypes) { +TEST(RawPropsTest, handleRawPropsPrimitiveTypes) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( "doubleValue", (double)17.42)("floatValue", (float)66.67)( "stringValue", "helloworld")("boolValue", true)); @@ -198,16 +198,16 @@ TEST(ShadowNodeTest, handleRawPropsPrimitiveTypes) { parser.prepare(); raw.parse(parser); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); - ASSERT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); - ASSERT_STREQ( + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); + EXPECT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); + EXPECT_STREQ( ((std::string)*raw.at("stringValue", nullptr, nullptr)).c_str(), "helloworld"); - ASSERT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); + EXPECT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); } -TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesGetTwice) { +TEST(RawPropsTest, handleRawPropsPrimitiveTypesGetTwice) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( "doubleValue", (double)17.42)("floatValue", (float)66.67)( "stringValue", "helloworld")("boolValue", true)); @@ -216,24 +216,24 @@ TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesGetTwice) { parser.prepare(); raw.parse(parser); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); - ASSERT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); - ASSERT_STREQ( + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); + EXPECT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); + EXPECT_STREQ( ((std::string)*raw.at("stringValue", nullptr, nullptr)).c_str(), "helloworld"); - ASSERT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); + EXPECT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); - ASSERT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); - ASSERT_STREQ( + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); + EXPECT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); + EXPECT_STREQ( ((std::string)*raw.at("stringValue", nullptr, nullptr)).c_str(), "helloworld"); - ASSERT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); + EXPECT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); } -TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesGetOutOfOrder) { +TEST(RawPropsTest, handleRawPropsPrimitiveTypesGetOutOfOrder) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( "doubleValue", (double)17.42)("floatValue", (float)66.67)( "stringValue", "helloworld")("boolValue", true)); @@ -242,41 +242,41 @@ TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesGetOutOfOrder) { parser.prepare(); raw.parse(parser); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); - ASSERT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); - ASSERT_STREQ( + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); + EXPECT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); + EXPECT_STREQ( ((std::string)*raw.at("stringValue", nullptr, nullptr)).c_str(), "helloworld"); - ASSERT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); + EXPECT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); - ASSERT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); - ASSERT_STREQ( + EXPECT_NEAR((double)*raw.at("doubleValue", nullptr, nullptr), 17.42, 0.0001); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_NEAR((float)*raw.at("floatValue", nullptr, nullptr), 66.67, 0.00001); + EXPECT_STREQ( ((std::string)*raw.at("stringValue", nullptr, nullptr)).c_str(), "helloworld"); - ASSERT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); + EXPECT_EQ((bool)*raw.at("boolValue", nullptr, nullptr), true); } -TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesIncomplete) { +TEST(RawPropsTest, handleRawPropsPrimitiveTypesIncomplete) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)); auto parser = RawPropsParser(); parser.prepare(); raw.parse(parser); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_EQ(raw.at("doubleValue", nullptr, nullptr), nullptr); - ASSERT_EQ(raw.at("floatValue", nullptr, nullptr), nullptr); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); - ASSERT_EQ(raw.at("stringValue", nullptr, nullptr), nullptr); - ASSERT_EQ(raw.at("boolValue", nullptr, nullptr), nullptr); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ(raw.at("doubleValue", nullptr, nullptr), nullptr); + EXPECT_EQ(raw.at("floatValue", nullptr, nullptr), nullptr); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ(raw.at("stringValue", nullptr, nullptr), nullptr); + EXPECT_EQ(raw.at("boolValue", nullptr, nullptr), nullptr); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); } #ifndef NDEBUG -TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesIncorrectLookup) { +TEST(RawPropsTest, handleRawPropsPrimitiveTypesIncorrectLookup) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)); auto parser = RawPropsParser(); @@ -286,12 +286,12 @@ TEST(ShadowNodeTest, handleRawPropsPrimitiveTypesIncorrectLookup) { // Before D18662135, looking up an invalid key would trigger // an infinite loop. This is out of contract, so we should only // test this in debug. - ASSERT_EQ(raw.at("flurb", nullptr, nullptr), nullptr); - ASSERT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); + EXPECT_EQ(raw.at("flurb", nullptr, nullptr), nullptr); + EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); } #endif -TEST(ShadowNodeTest, handlePropsMultiLookup) { +TEST(RawPropsTest, handlePropsMultiLookup) { const auto &raw = RawProps(folly::dynamic::object("floatValue", (float)10.0)); auto parser = RawPropsParser(); parser.prepare(); @@ -300,8 +300,8 @@ TEST(ShadowNodeTest, handlePropsMultiLookup) { auto props = std::make_shared(PropsMultiLookup(), raw); // Props are not sealed after applying raw props. - ASSERT_FALSE(props->getSealed()); + EXPECT_FALSE(props->getSealed()); - ASSERT_NEAR(props->floatValue, 10.0, 0.00001); - ASSERT_NEAR(props->derivedFloatValue, 20.0, 0.00001); + EXPECT_NEAR(props->floatValue, 10.0, 0.00001); + EXPECT_NEAR(props->derivedFloatValue, 20.0, 0.00001); } diff --git a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp index 1e33586b75029e..fbe4016d15059e 100644 --- a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp +++ b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp @@ -34,16 +34,16 @@ TEST(ShadowNodeTest, handleShadowNodeCreation) { family, ShadowNodeTraits{}); - ASSERT_FALSE(node->getSealed()); - ASSERT_STREQ(node->getComponentName(), "Test"); - ASSERT_EQ(node->getTag(), 9); - ASSERT_EQ(node->getSurfaceId(), 1); - ASSERT_EQ(node->getEventEmitter(), nullptr); - ASSERT_EQ(node->getChildren().size(), 0); + EXPECT_FALSE(node->getSealed()); + EXPECT_STREQ(node->getComponentName(), "Test"); + EXPECT_EQ(node->getTag(), 9); + EXPECT_EQ(node->getSurfaceId(), 1); + EXPECT_EQ(node->getEventEmitter(), nullptr); + EXPECT_EQ(node->getChildren().size(), 0); node->sealRecursive(); - ASSERT_TRUE(node->getSealed()); - ASSERT_TRUE(node->getProps()->getSealed()); + EXPECT_TRUE(node->getSealed()); + EXPECT_TRUE(node->getProps()->getSealed()); } TEST(ShadowNodeTest, handleShadowNodeSimpleCloning) { @@ -66,10 +66,10 @@ TEST(ShadowNodeTest, handleShadowNodeSimpleCloning) { ShadowNodeTraits{}); auto node2 = std::make_shared(*node, ShadowNodeFragment{}); - ASSERT_STREQ(node->getComponentName(), "Test"); - ASSERT_EQ(node->getTag(), 9); - ASSERT_EQ(node->getSurfaceId(), 1); - ASSERT_EQ(node->getEventEmitter(), nullptr); + EXPECT_STREQ(node->getComponentName(), "Test"); + EXPECT_EQ(node->getTag(), 9); + EXPECT_EQ(node->getSurfaceId(), 1); + EXPECT_EQ(node->getEventEmitter(), nullptr); } TEST(ShadowNodeTest, handleShadowNodeMutation) { @@ -123,29 +123,29 @@ TEST(ShadowNodeTest, handleShadowNodeMutation) { node1->appendChild(node2); node1->appendChild(node3); auto node1Children = node1->getChildren(); - ASSERT_EQ(node1Children.size(), 2); - ASSERT_EQ(node1Children.at(0), node2); - ASSERT_EQ(node1Children.at(1), node3); + EXPECT_EQ(node1Children.size(), 2); + EXPECT_EQ(node1Children.at(0), node2); + EXPECT_EQ(node1Children.at(1), node3); auto node4 = std::make_shared(*node2, ShadowNodeFragment{}); node1->replaceChild(*node2, node4); node1Children = node1->getChildren(); - ASSERT_EQ(node1Children.size(), 2); - ASSERT_EQ(node1Children.at(0), node4); - ASSERT_EQ(node1Children.at(1), node3); + EXPECT_EQ(node1Children.size(), 2); + EXPECT_EQ(node1Children.at(0), node4); + EXPECT_EQ(node1Children.at(1), node3); // Seal the entire tree. node1->sealRecursive(); - ASSERT_TRUE(node1->getSealed()); - ASSERT_TRUE(node3->getSealed()); - ASSERT_TRUE(node4->getSealed()); + EXPECT_TRUE(node1->getSealed()); + EXPECT_TRUE(node3->getSealed()); + EXPECT_TRUE(node4->getSealed()); // No more mutation after sealing. EXPECT_THROW(node4->setLocalData(nullptr), std::runtime_error); auto node5 = std::make_shared(*node4, ShadowNodeFragment{}); node5->setLocalData(nullptr); - ASSERT_EQ(node5->getLocalData(), nullptr); + EXPECT_EQ(node5->getLocalData(), nullptr); } TEST(ShadowNodeTest, handleCloneFunction) { @@ -171,16 +171,16 @@ TEST(ShadowNodeTest, handleCloneFunction) { auto firstNodeClone = firstNode->clone({}); // Those two nodes are *not* same. - ASSERT_NE(firstNode, firstNodeClone); + EXPECT_NE(firstNode, firstNodeClone); // `secondNodeClone` is an instance of `TestShadowNode`. - ASSERT_NE( + EXPECT_NE( std::dynamic_pointer_cast(firstNodeClone), nullptr); // Both nodes have same content. - ASSERT_EQ(firstNode->getTag(), firstNodeClone->getTag()); - ASSERT_EQ(firstNode->getSurfaceId(), firstNodeClone->getSurfaceId()); - ASSERT_EQ(firstNode->getProps(), firstNodeClone->getProps()); + EXPECT_EQ(firstNode->getTag(), firstNodeClone->getTag()); + EXPECT_EQ(firstNode->getSurfaceId(), firstNodeClone->getSurfaceId()); + EXPECT_EQ(firstNode->getProps(), firstNodeClone->getProps()); } TEST(ShadowNodeTest, handleLocalData) { @@ -230,14 +230,14 @@ TEST(ShadowNodeTest, handleLocalData) { thirdNode->setLocalData(localDataOver9000); // LocalData object are compared by pointer, not by value. - ASSERT_EQ(firstNode->getLocalData(), secondNode->getLocalData()); - ASSERT_NE(firstNode->getLocalData(), thirdNode->getLocalData()); + EXPECT_EQ(firstNode->getLocalData(), secondNode->getLocalData()); + EXPECT_NE(firstNode->getLocalData(), thirdNode->getLocalData()); secondNode->setLocalData(anotherLocalData42); - ASSERT_NE(firstNode->getLocalData(), secondNode->getLocalData()); + EXPECT_NE(firstNode->getLocalData(), secondNode->getLocalData()); // LocalData cannot be changed for sealed shadow node. secondNode->sealRecursive(); - ASSERT_ANY_THROW(secondNode->setLocalData(localDataOver9000)); + EXPECT_ANY_THROW(secondNode->setLocalData(localDataOver9000)); } TEST(ShadowNodeTest, handleBacktracking) { @@ -389,11 +389,11 @@ TEST(ShadowNodeTest, handleBacktracking) { // Negative case: auto ancestors1 = nodeZ->getAncestors(*nodeA); - ASSERT_EQ(ancestors1.size(), 0); + EXPECT_EQ(ancestors1.size(), 0); // Positive case: auto ancestors2 = nodeABC->getAncestors(*nodeA); - ASSERT_EQ(ancestors2.size(), 2); - ASSERT_EQ(&ancestors2[0].first.get(), nodeA.get()); - ASSERT_EQ(&ancestors2[1].first.get(), nodeAB.get()); + EXPECT_EQ(ancestors2.size(), 2); + EXPECT_EQ(&ancestors2[0].first.get(), nodeA.get()); + EXPECT_EQ(&ancestors2[1].first.get(), nodeAB.get()); } From 1e81b67701f9a25f9f7c4a35a58356e1f763e503 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:06:16 -0800 Subject: [PATCH 0058/1126] Use fixtures for ShadowNodeTests Summary: Changelog: [Internal] Refactor the setup code for tests to a single place. Now there is fixed set of nodes where we test different methods of ShadowNode. Reviewed By: shergin Differential Revision: D19464966 fbshipit-source-id: 749e9f56ac2e5489647885b2ddcb1309eb20909a --- .../fabric/core/tests/ShadowNodeTest.cpp | 552 +++++++----------- 1 file changed, 211 insertions(+), 341 deletions(-) diff --git a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp index fbe4016d15059e..0ad36960db59b5 100644 --- a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp +++ b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp @@ -15,185 +15,222 @@ using namespace facebook::react; -TEST(ShadowNodeTest, handleShadowNodeCreation) { - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto family = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 9, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto node = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - - EXPECT_FALSE(node->getSealed()); - EXPECT_STREQ(node->getComponentName(), "Test"); - EXPECT_EQ(node->getTag(), 9); - EXPECT_EQ(node->getSurfaceId(), 1); - EXPECT_EQ(node->getEventEmitter(), nullptr); - EXPECT_EQ(node->getChildren().size(), 0); - - node->sealRecursive(); - EXPECT_TRUE(node->getSealed()); - EXPECT_TRUE(node->getProps()->getSealed()); +class ShadowNodeTest : public ::testing::Test { + protected: + ShadowNodeTest() + : eventDispatcher_(std::shared_ptr()), + componentDescriptor_(TestComponentDescriptor({eventDispatcher_})) { + /* + * The structure: + * + * + * + * + * + * + * + * + * + */ + + auto props = std::make_shared(); + + auto familyAA = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 11, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeAA_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyAA, + ShadowNodeTraits{}); + + auto familyABA = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 12, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeABA_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyABA, + ShadowNodeTraits{}); + + auto familyABB = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 13, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeABB_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyABB, + ShadowNodeTraits{}); + + auto nodeABChildren = std::make_shared( + SharedShadowNodeList{nodeABA_, nodeABB_}); + + auto familyAB = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 15, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeAB_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ nodeABChildren, + }, + familyAB, + ShadowNodeTraits{}); + + auto familyAC = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 16, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeAC_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyAC, + ShadowNodeTraits{}); + + auto nodeAChildren = std::make_shared( + SharedShadowNodeList{nodeAA_, nodeAB_, nodeAC_}); + + auto familyA = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 17, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeA_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ nodeAChildren, + }, + familyA, + ShadowNodeTraits{}); + + auto familyZ = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 18, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + nodeZ_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyZ, + ShadowNodeTraits{}); + } + + std::shared_ptr eventDispatcher_; + std::shared_ptr nodeA_; + std::shared_ptr nodeAA_; + std::shared_ptr nodeABA_; + std::shared_ptr nodeABB_; + std::shared_ptr nodeAB_; + std::shared_ptr nodeAC_; + std::shared_ptr nodeZ_; + TestComponentDescriptor componentDescriptor_; + + SurfaceId surfaceId_ = 1; +}; + +TEST_F(ShadowNodeTest, handleShadowNodeCreation) { + EXPECT_FALSE(nodeZ_->getSealed()); + EXPECT_STREQ(nodeZ_->getComponentName(), "Test"); + EXPECT_EQ(nodeZ_->getTag(), 18); + EXPECT_EQ(nodeZ_->getSurfaceId(), surfaceId_); + EXPECT_EQ(nodeZ_->getEventEmitter(), nullptr); + EXPECT_EQ(nodeZ_->getChildren().size(), 0); } -TEST(ShadowNodeTest, handleShadowNodeSimpleCloning) { - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto family = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 9, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto node = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - auto node2 = std::make_shared(*node, ShadowNodeFragment{}); - - EXPECT_STREQ(node->getComponentName(), "Test"); - EXPECT_EQ(node->getTag(), 9); - EXPECT_EQ(node->getSurfaceId(), 1); - EXPECT_EQ(node->getEventEmitter(), nullptr); +TEST_F(ShadowNodeTest, handleSealRecusive) { + nodeZ_->sealRecursive(); + EXPECT_TRUE(nodeZ_->getSealed()); + EXPECT_TRUE(nodeZ_->getProps()->getSealed()); } -TEST(ShadowNodeTest, handleShadowNodeMutation) { - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto family1 = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 1, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto props = std::make_shared(); - auto node1 = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family1, - ShadowNodeTraits{}); - auto family2 = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 2, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto node2 = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family2, - ShadowNodeTraits{}); - auto family3 = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 2, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto node3 = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family3, - ShadowNodeTraits{}); - - node1->appendChild(node2); - node1->appendChild(node3); - auto node1Children = node1->getChildren(); - EXPECT_EQ(node1Children.size(), 2); - EXPECT_EQ(node1Children.at(0), node2); - EXPECT_EQ(node1Children.at(1), node3); - - auto node4 = std::make_shared(*node2, ShadowNodeFragment{}); - node1->replaceChild(*node2, node4); - node1Children = node1->getChildren(); - EXPECT_EQ(node1Children.size(), 2); - EXPECT_EQ(node1Children.at(0), node4); - EXPECT_EQ(node1Children.at(1), node3); +TEST_F(ShadowNodeTest, handleShadowNodeSimpleCloning) { + auto nodeARevision2 = + std::make_shared(*nodeA_, ShadowNodeFragment{}); + + EXPECT_STREQ(nodeA_->getComponentName(), nodeARevision2->getComponentName()); + EXPECT_EQ(nodeA_->getTag(), nodeARevision2->getTag()); + EXPECT_EQ(nodeA_->getSurfaceId(), nodeARevision2->getSurfaceId()); + EXPECT_EQ(nodeA_->getEventEmitter(), nodeARevision2->getEventEmitter()); +} + +TEST_F(ShadowNodeTest, handleShadowNodeMutation) { + auto nodeABChildren = nodeAB_->getChildren(); + EXPECT_EQ(nodeABChildren.size(), 2); + EXPECT_EQ(nodeABChildren.at(0), nodeABA_); + EXPECT_EQ(nodeABChildren.at(1), nodeABB_); + + auto nodeABArevision2 = + std::make_shared(*nodeABA_, ShadowNodeFragment{}); + nodeAB_->replaceChild(*nodeABA_, nodeABArevision2); + nodeABChildren = nodeAB_->getChildren(); + EXPECT_EQ(nodeABChildren.size(), 2); + EXPECT_EQ(nodeABChildren.at(0), nodeABArevision2); + EXPECT_EQ(nodeABChildren.at(1), nodeABB_); // Seal the entire tree. - node1->sealRecursive(); - EXPECT_TRUE(node1->getSealed()); - EXPECT_TRUE(node3->getSealed()); - EXPECT_TRUE(node4->getSealed()); + nodeAB_->sealRecursive(); + EXPECT_TRUE(nodeAB_->getSealed()); + EXPECT_TRUE(nodeABArevision2->getSealed()); + EXPECT_TRUE(nodeABB_->getSealed()); // No more mutation after sealing. - EXPECT_THROW(node4->setLocalData(nullptr), std::runtime_error); + EXPECT_THROW(nodeABArevision2->setLocalData(nullptr), std::runtime_error); - auto node5 = std::make_shared(*node4, ShadowNodeFragment{}); - node5->setLocalData(nullptr); - EXPECT_EQ(node5->getLocalData(), nullptr); + auto nodeABArevision3 = + std::make_shared(*nodeABArevision2, ShadowNodeFragment{}); + nodeABArevision3->setLocalData(nullptr); + EXPECT_EQ(nodeABArevision3->getLocalData(), nullptr); } -TEST(ShadowNodeTest, handleCloneFunction) { - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto family = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 9, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - - auto firstNode = std::make_shared( - ShadowNodeFragment{ - /* .props = */ std::make_shared(), - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - - auto firstNodeClone = firstNode->clone({}); +TEST_F(ShadowNodeTest, handleCloneFunction) { + auto nodeABClone = nodeAB_->clone({}); // Those two nodes are *not* same. - EXPECT_NE(firstNode, firstNodeClone); + EXPECT_NE(nodeAB_, nodeABClone); // `secondNodeClone` is an instance of `TestShadowNode`. EXPECT_NE( - std::dynamic_pointer_cast(firstNodeClone), nullptr); + std::dynamic_pointer_cast(nodeABClone), nullptr); // Both nodes have same content. - EXPECT_EQ(firstNode->getTag(), firstNodeClone->getTag()); - EXPECT_EQ(firstNode->getSurfaceId(), firstNodeClone->getSurfaceId()); - EXPECT_EQ(firstNode->getProps(), firstNodeClone->getProps()); + EXPECT_EQ(nodeAB_->getTag(), nodeABClone->getTag()); + EXPECT_EQ(nodeAB_->getSurfaceId(), nodeABClone->getSurfaceId()); + EXPECT_EQ(nodeAB_->getProps(), nodeABClone->getProps()); } -TEST(ShadowNodeTest, handleLocalData) { - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto family = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 9, - /* .surfaceId = */ 1, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); +TEST_F(ShadowNodeTest, handleLocalData) { auto localData42 = std::make_shared(); localData42->setNumber(42); @@ -203,197 +240,30 @@ TEST(ShadowNodeTest, handleLocalData) { auto localDataOver9000 = std::make_shared(); localDataOver9000->setNumber(9001); auto props = std::make_shared(); - auto firstNode = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - auto secondNode = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - auto thirdNode = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - family, - ShadowNodeTraits{}); - - firstNode->setLocalData(localData42); - secondNode->setLocalData(localData42); - thirdNode->setLocalData(localDataOver9000); + + nodeAA_->setLocalData(localData42); + nodeAB_->setLocalData(localData42); + nodeAC_->setLocalData(localDataOver9000); // LocalData object are compared by pointer, not by value. - EXPECT_EQ(firstNode->getLocalData(), secondNode->getLocalData()); - EXPECT_NE(firstNode->getLocalData(), thirdNode->getLocalData()); - secondNode->setLocalData(anotherLocalData42); - EXPECT_NE(firstNode->getLocalData(), secondNode->getLocalData()); + EXPECT_EQ(nodeAA_->getLocalData(), nodeAB_->getLocalData()); + EXPECT_NE(nodeAA_->getLocalData(), nodeAC_->getLocalData()); + nodeAB_->setLocalData(anotherLocalData42); + EXPECT_NE(nodeAA_->getLocalData(), nodeAB_->getLocalData()); // LocalData cannot be changed for sealed shadow node. - secondNode->sealRecursive(); - EXPECT_ANY_THROW(secondNode->setLocalData(localDataOver9000)); + nodeAB_->sealRecursive(); + EXPECT_ANY_THROW(nodeAB_->setLocalData(localDataOver9000)); } -TEST(ShadowNodeTest, handleBacktracking) { - /* - * The structure: - * - * - * - * - * - * - * - * - * - */ - - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptor = TestComponentDescriptor( - ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr}); - auto props = std::make_shared(); - - auto familyAA = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeAA = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyAA, - ShadowNodeTraits{}); - - auto familyABA = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeABA = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyABA, - ShadowNodeTraits{}); - - auto familyABB = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeABB = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyABB, - ShadowNodeTraits{}); - - auto familyABC = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeABC = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyABC, - ShadowNodeTraits{}); - - auto nodeABChildren = std::make_shared( - SharedShadowNodeList{nodeABA, nodeABB, nodeABC}); - - auto familyAB = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeAB = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ nodeABChildren, - }, - familyAB, - ShadowNodeTraits{}); - - auto familyAC = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeAC = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyAC, - ShadowNodeTraits{}); - - auto nodeAChildren = std::make_shared( - SharedShadowNodeList{nodeAA, nodeAB, nodeAC}); - - auto familyA = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeA = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ nodeAChildren, - }, - familyA, - ShadowNodeTraits{}); - - auto familyZ = std::make_shared( - ShadowNodeFamilyFragment{ - /* .tag = */ 0, - /* .surfaceId = */ 0, - /* .eventEmitter = */ nullptr, - }, - componentDescriptor); - auto nodeZ = std::make_shared( - ShadowNodeFragment{ - /* .props = */ props, - /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), - }, - familyZ, - ShadowNodeTraits{}); - - std::vector> ancestors = {}; - +TEST_F(ShadowNodeTest, handleBacktracking) { // Negative case: - auto ancestors1 = nodeZ->getAncestors(*nodeA); + auto ancestors1 = nodeZ_->getAncestors(*nodeA_); EXPECT_EQ(ancestors1.size(), 0); // Positive case: - auto ancestors2 = nodeABC->getAncestors(*nodeA); + auto ancestors2 = nodeABB_->getAncestors(*nodeA_); EXPECT_EQ(ancestors2.size(), 2); - EXPECT_EQ(&ancestors2[0].first.get(), nodeA.get()); - EXPECT_EQ(&ancestors2[1].first.get(), nodeAB.get()); + EXPECT_EQ(&ancestors2[0].first.get(), nodeA_.get()); + EXPECT_EQ(&ancestors2[1].first.get(), nodeAB_.get()); } From 5b156f83fa9dc2d0af4016aed14a643a005c7a16 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:28:55 -0800 Subject: [PATCH 0059/1126] Fix origin calculation in getRelativeLayoutMetrics Summary: # Problem The issue is in implementation of `LayoutableShadowNode::getRelativeLayoutMetrics`. If you have view tree (A has a child B), and you call `B.getRelativeLayoutMetrics(A)`, the expected result is B's origin within A. The implementation wasn't reflecting that, it was reflecting B's origin within A + A's origin within its parent. # Fix When iterating over ancestors of ShadowNode, the last ancestor should be skipped. AncestorList is a list that starts with provided ancestor and ends with parent of `this`. To skip provided ancestor we iterate to `rend() - 1`. # Why does it work in some cases? This function is triggered from `UIManager.getRelativeLayoutMetrics` without `ancestorShadowNode` provided, we find the RootShadowNode, which has origin `{0, 0}`. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19447900 fbshipit-source-id: 4a9606dc1fab3fecfb85d337b014188d80e5b355 --- ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp index 05740d4bd75bba..b681634887f4c6 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp @@ -55,7 +55,10 @@ LayoutMetrics LayoutableShadowNode::getRelativeLayoutMetrics( auto layoutMetrics = getLayoutMetrics(); - for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) { + // `AncestorList` starts from the given ancestor node and ends with the parent + // node. We iterate from parent node (reverse iteration) and stop before the + // given ancestor (rend() - 1). + for (auto it = ancestors.rbegin(); it != ancestors.rend() - 1; ++it) { auto ¤tShadowNode = it->first.get(); auto layoutableCurrentShadowNode = From b3af384a13e7e1d3ed4527b5455a0be708f6f00f Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:28:55 -0800 Subject: [PATCH 0060/1126] Fix wrong layoutMetrics being returned by `measure` call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: # Logs ``` [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 0 tag: 1432 debugValue: r1 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r2 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r2 [tid:com.facebook.react.JavaScript][UIManager.cpp:197] width: 0 tag: 1432 debugValue: r1/sealed <----------------- FIRST TAP [tid:com.facebook.react.JavaScript][UIManager.cpp:197] width: 0 tag: 1432 debugValue: r1/sealed <----------------- FIRST TAP [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r4 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r5 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r6 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r7 [tid:com.facebook.react.JavaScript][ConcreteViewShadowNode.h:119] width: 375 tag: 1432 debugValue: r8 [tid:com.facebook.react.JavaScript][UIManager.cpp:197] width: 375 tag: 1432 debugValue: r7/sealed <----------------- SECOND TAP [tid:com.facebook.react.JavaScript][UIManager.cpp:197] width: 375 tag: 1432 debugValue: r7/sealed <----------------- SECOND TAP ``` # What’s happening here? Opening a *BottomSheet* and tapping the first item. As you can see before the item is tapped, it has *width* set to 375 in revision *r2*. When the tap happens, JavaScript is requesting an old revision of ShadowNode, which still has width 0. # My assumption. 1. Native creates node with *width* 0 and returns handle to *JS*. 2. Native *clones* the node, sets its *width* to 375, doesn’t tell *JS* about it. This update is due to state change. 3. *JS* tries to get the size of the node, but asking for first revision of the component it receives width 0. # Other observations 1. Manually setting width to 375 in UIManager::getRelativeLayoutMetrics fixes the problem. 2. This happens only on device, I wasn’t able to reproduce this on simulator. # Fix Find the newest revision of ShadowNodeFamily, and return its layoutMetrics. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19433873 fbshipit-source-id: 4558cf6e704051e9b3968e83821d8d25b3dadcda --- .../core/layout/LayoutableShadowNode.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp index b681634887f4c6..d7ddc2688f26fe 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp @@ -17,6 +17,22 @@ namespace facebook { namespace react { +/* + * `shadowNode` might not be the newest revision of `ShadowNodeFamily`. + * This function looks at `parentNode`'s children and finds one that belongs + * to the same family as `shadowNode`. + */ +static ShadowNode const *findNewestChildInParent( + ShadowNode const &parentNode, + ShadowNode const &shadowNode) { + for (auto const &child : parentNode.getChildren()) { + if (ShadowNode::sameFamily(*child, shadowNode)) { + return child.get(); + } + } + return nullptr; +} + LayoutMetrics LayoutableShadowNode::getLayoutMetrics() const { return layoutMetrics_; } @@ -53,7 +69,15 @@ LayoutMetrics LayoutableShadowNode::getRelativeLayoutMetrics( return EmptyLayoutMetrics; } - auto layoutMetrics = getLayoutMetrics(); + auto newestChild = + findNewestChildInParent(ancestors.rbegin()->first.get(), shadowNode); + + if (!newestChild) { + return EmptyLayoutMetrics; + } + + auto layoutMetrics = dynamic_cast(newestChild) + ->getLayoutMetrics(); // `AncestorList` starts from the given ancestor node and ends with the parent // node. We iterate from parent node (reverse iteration) and stop before the From 291b45b6865b66281d65bcc813a2cbc3252e6d2b Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:28:55 -0800 Subject: [PATCH 0061/1126] Add unit tests for LayoutableShadowNode::getRelativeLayoutMetrics Summary: Adds a bare minimum test that verifies correct behaviour of `getRelativeLayoutMetrics`. Changelog: [internal] Reviewed By: shergin Differential Revision: D19449128 fbshipit-source-id: afde997a770921d580575eb0cdd04fce6252cb5a --- ReactCommon/fabric/core/BUCK | 1 + .../core/tests/LayoutableShadowNodeTest.cpp | 89 +++++++++++++++++++ ReactCommon/fabric/core/tests/TestComponent.h | 19 ++-- 3 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp diff --git a/ReactCommon/fabric/core/BUCK b/ReactCommon/fabric/core/BUCK index 43e110c7efcf49..f866fdc5203ed4 100644 --- a/ReactCommon/fabric/core/BUCK +++ b/ReactCommon/fabric/core/BUCK @@ -85,6 +85,7 @@ fb_xplat_cxx_test( deps = [ "fbsource//xplat/folly:molly", "fbsource//xplat/third-party/gmock:gtest", + react_native_xplat_target("fabric/components/view:view"), ":core", ], ) diff --git a/ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp b/ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp new file mode 100644 index 00000000000000..fd0978d8ff0feb --- /dev/null +++ b/ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include "TestComponent.h" + +using namespace facebook::react; + +class LayoutableShadowNodeTest : public ::testing::Test { + protected: + LayoutableShadowNodeTest() + : eventDispatcher_(std::shared_ptr()), + componentDescriptor_(TestComponentDescriptor({eventDispatcher_})) { + auto familyA = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 9, + /* .surfaceId = */ 1, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + + nodeA_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ std::make_shared(), + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyA, + ShadowNodeTraits{}); + + auto familyB = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 10, + /* .surfaceId = */ 1, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + + nodeB_ = std::make_shared( + ShadowNodeFragment{ + /* .props = */ std::make_shared(), + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + }, + familyB, + ShadowNodeTraits{}); + + nodeA_->appendChild(nodeB_); + } + + std::shared_ptr eventDispatcher_; + std::shared_ptr nodeA_; + std::shared_ptr nodeB_; + TestComponentDescriptor componentDescriptor_; +}; + +TEST_F(LayoutableShadowNodeTest, relativeLayourMetrics) { + auto layoutMetrics = EmptyLayoutMetrics; + layoutMetrics.frame.origin = {10, 20}; + layoutMetrics.frame.size = {100, 200}; + nodeA_->setLayoutMetrics(layoutMetrics); + nodeB_->setLayoutMetrics(layoutMetrics); + + auto relativeLayoutMetrics = nodeB_->getRelativeLayoutMetrics(*nodeA_, {}); + + // A is a parent to B, A has origin {10, 10}, B has origin {10, 10}. + // B's relative origin to A should be {10, 10}. + // D19447900 has more about the issue. + EXPECT_EQ(relativeLayoutMetrics.frame.origin.x, 10); + EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 20); +} + +TEST_F(LayoutableShadowNodeTest, relativeLayourMetricsOnClonedNode) { + // B is cloned and mutated. + auto nodeBRevision2 = std::static_pointer_cast( + componentDescriptor_.cloneShadowNode(*nodeB_, ShadowNodeFragment{})); + auto layoutMetrics = EmptyLayoutMetrics; + layoutMetrics.frame.size = {500, 600}; + nodeBRevision2->setLayoutMetrics(layoutMetrics); + nodeA_->replaceChild(*nodeB_, nodeBRevision2); + + // Even if we ask old ShadowNode for its relative layoutMetrics, it needs to + // return correct, new layoutMetrics. D19433873 has more about the issue. + auto newRelativeLayoutMetrics = nodeB_->getRelativeLayoutMetrics(*nodeA_, {}); + EXPECT_EQ(newRelativeLayoutMetrics.frame.size.width, 500); + EXPECT_EQ(newRelativeLayoutMetrics.frame.size.height, 600); +} diff --git a/ReactCommon/fabric/core/tests/TestComponent.h b/ReactCommon/fabric/core/tests/TestComponent.h index f8ea2349d8ba2b..9e0616923d25c9 100644 --- a/ReactCommon/fabric/core/tests/TestComponent.h +++ b/ReactCommon/fabric/core/tests/TestComponent.h @@ -10,8 +10,9 @@ #include #include +#include +#include #include -#include #include #include #include @@ -39,9 +40,12 @@ class TestLocalData : public LocalData { static const char TestComponentName[] = "Test"; -class TestProps : public Props { +class TestProps : public ViewProps { public: - using Props::Props; + using ViewProps::ViewProps; + + TestProps(const TestProps &sourceProps, const RawProps &rawProps) + : ViewProps(sourceProps, rawProps) {} }; using SharedTestProps = std::shared_ptr; @@ -50,9 +54,14 @@ class TestShadowNode; using SharedTestShadowNode = std::shared_ptr; -class TestShadowNode : public ConcreteShadowNode { +class TestShadowNode + : public ConcreteViewShadowNode { public: - using ConcreteShadowNode::ConcreteShadowNode; + using ConcreteViewShadowNode::ConcreteViewShadowNode; + + bool setLayoutMetrics(LayoutMetrics layoutMetrics) { + return YogaLayoutableShadowNode::setLayoutMetrics(layoutMetrics); + } }; class TestComponentDescriptor From f43c9316e184b7a569804c2805458196b2875dd5 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 03:06:14 -0800 Subject: [PATCH 0062/1126] Add blur and focus native commands to TextInput Summary: Add Native Commands handlers to TextInput. It is intentionally done in a way so that it can be easily swapped for codegened implementation once we properly type TextInput. We also add native commands to view managers for backwards compatibility. Changelog: [Internal] Reviewed By: TheSavior, shergin Differential Revision: D19412026 fbshipit-source-id: 8dc64275cf1da599b1bd5992a41035d51dd4148f --- .../RCTMultilineTextInputViewManager.m | 1 - .../TextInput/RCTBaseTextInputViewManager.m | 16 ++++++ .../TextInput/RCTTextInputComponentView.mm | 20 ++++++- .../TextInput/RCTTextInputNativeCommands.h | 53 +++++++++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index 3ce76b116df11d..6f9696029b049f 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -6,7 +6,6 @@ */ #import - #import @implementation RCTMultilineTextInputViewManager diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 788657c6c8110f..3d289464bd15c7 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -100,6 +100,22 @@ - (void)setBridge:(RCTBridge *)bridge lazilyLoadIfNecessary:YES]]; } +RCT_EXPORT_METHOD(focus : (nonnull NSNumber *)viewTag) +{ + [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + UIView *view = viewRegistry[viewTag]; + [view reactFocus]; + }]; +} + +RCT_EXPORT_METHOD(blur : (nonnull NSNumber *)viewTag) +{ + [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + UIView *view = viewRegistry[viewTag]; + [view reactBlur]; + }]; +} + #pragma mark - RCTUIManagerObserver - (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 532cc5754e8665..a81291d5a210d0 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -17,11 +17,12 @@ #import #import "RCTConversions.h" +#import "RCTTextInputNativeCommands.h" #import "RCTTextInputUtils.h" using namespace facebook::react; -@interface RCTTextInputComponentView () +@interface RCTTextInputComponentView () @end @implementation RCTTextInputComponentView { @@ -342,4 +343,21 @@ - (void)_updateState return AttributedString::Range{(int)start, (int)(end - start)}; } +#pragma mark - Native Commands + +- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args +{ + RCTTextInputHandleCommand(self, commandName, args); +} + +- (void)focus +{ + [_backedTextInputView becomeFirstResponder]; +} + +- (void)blur +{ + [_backedTextInputView resignFirstResponder]; +} + @end diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h new file mode 100644 index 00000000000000..9fe35851a7a610 --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol RCTTextInputViewProtocol +- (void)focus; +- (void)blur; +@end + +RCT_EXTERN inline void +RCTTextInputHandleCommand(id componentView, NSString const *commandName, NSArray const *args) +{ + if ([commandName isEqualToString:@"focus"]) { +#if RCT_DEBUG + if ([args count] != 0) { + RCTLogError( + @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); + return; + } +#endif + + [componentView focus]; + return; + } + + if ([commandName isEqualToString:@"blur"]) { +#if RCT_DEBUG + if ([args count] != 0) { + RCTLogError( + @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); + return; + } +#endif + + [componentView blur]; + return; + } + +#if RCT_DEBUG + RCTLogError(@"%@ received command %@, which is not a supported command.", @"TextInput", commandName); +#endif +} + +NS_ASSUME_NONNULL_END From 7a8e10dac83b6a43e4cea7e92df0dcfbcf3ad3ac Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 03:06:14 -0800 Subject: [PATCH 0063/1126] Use commands to send focus and blur to TextInput Summary: Migrate to Native commands with Blur and Focus on TextInput. Changelog: [Internal] Reviewed By: TheSavior, shergin Differential Revision: D19412085 fbshipit-source-id: 33b29b2699bc74d31ef1b4b0e585daffd88c4140 --- .../RCTMultilineTextInputNativeComponent.js | 33 +++++++++++++++++++ .../RCTSingelineTextInputNativeComponent.js | 33 +++++++++++++++++++ Libraries/Components/TextInput/TextInput.js | 10 +++--- 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js create mode 100644 Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js diff --git a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js new file mode 100644 index 00000000000000..0dcd904baa73f8 --- /dev/null +++ b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import requireNativeComponent from '../../ReactNative/requireNativeComponent'; +import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; +import * as React from 'react'; + +type NativeType = HostComponent; + +interface NativeCommands { + +focus: (viewRef: React.ElementRef) => void; + +blur: (viewRef: React.ElementRef) => void; +} + +export const Commands: NativeCommands = codegenNativeCommands({ + supportedCommands: ['focus', 'blur'], +}); + +const SinglelineTextInputNativeComponent: HostComponent = requireNativeComponent( + 'RCTMultilineTextInputView', +); + +export default SinglelineTextInputNativeComponent; diff --git a/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js new file mode 100644 index 00000000000000..bd600e2698f159 --- /dev/null +++ b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import requireNativeComponent from '../../ReactNative/requireNativeComponent'; +import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; +import * as React from 'react'; + +type NativeType = HostComponent; + +interface NativeCommands { + +focus: (viewRef: React.ElementRef) => void; + +blur: (viewRef: React.ElementRef) => void; +} + +export const Commands: NativeCommands = codegenNativeCommands({ + supportedCommands: ['focus', 'blur'], +}); + +const SinglelineTextInputNativeComponent: HostComponent = requireNativeComponent( + 'RCTSinglelineTextInputView', +); + +export default SinglelineTextInputNativeComponent; diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 02e1db674aff5e..dd3d5667afad70 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -43,12 +43,10 @@ let RCTSinglelineTextInputView; if (Platform.OS === 'android') { AndroidTextInput = require('./AndroidTextInputNativeComponent').default; } else if (Platform.OS === 'ios') { - RCTMultilineTextInputView = requireNativeComponent( - 'RCTMultilineTextInputView', - ); - RCTSinglelineTextInputView = requireNativeComponent( - 'RCTSinglelineTextInputView', - ); + RCTMultilineTextInputView = require('./RCTMultilineTextInputNativeComponent.js') + .default; + RCTSinglelineTextInputView = require('./RCTSingelineTextInputNativeComponent.js') + .default; } export type ChangeEvent = SyntheticEvent< From 55319a3fbbcb722763b47eaa888fe1f18cc8667f Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 03:39:31 -0800 Subject: [PATCH 0064/1126] Remove const qualifier from codegened props Summary: To make testing easier, we allow mutation of Props classes. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19390813 fbshipit-source-id: ea8ce78de4effe1bbc002baad4e297b2d52a8ddc --- .../generators/components/GeneratePropsH.js | 2 +- .../__snapshots__/GeneratePropsH-test.js.snap | 98 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index 8a9bc13f17748b..557a7e4d27baa3 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -454,7 +454,7 @@ function generatePropsString( const nativeType = getNativeTypeFromAnnotation(componentName, prop, []); const defaultValue = convertDefaultTypeToString(componentName, prop); - return `const ${nativeType} ${prop.name}{${defaultValue}};`; + return `${nativeType} ${prop.name}{${defaultValue}};`; }) .join('\n' + ' '); } diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 86b4dd28d228ff..687290a402e574 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -194,17 +194,17 @@ class ArrayPropsNativeComponentProps final : public ViewProps { #pragma mark - Props - const std::vector names{}; - const std::vector disableds{}; - const std::vector progress{}; - const std::vector radii{}; - const std::vector colors{}; - const std::vector srcs{}; - const std::vector points{}; - const ArrayPropsNativeComponentSizesMask sizes{static_cast(ArrayPropsNativeComponentSizes::Small)}; - const std::vector object{}; - const std::vector array{}; - const std::vector> arrayOfArrayOfObject{}; + std::vector names{}; + std::vector disableds{}; + std::vector progress{}; + std::vector radii{}; + std::vector colors{}; + std::vector srcs{}; + std::vector points{}; + ArrayPropsNativeComponentSizesMask sizes{static_cast(ArrayPropsNativeComponentSizes::Small)}; + std::vector object{}; + std::vector array{}; + std::vector> arrayOfArrayOfObject{}; }; } // namespace react @@ -277,7 +277,7 @@ class ArrayPropsNativeComponentProps final : public ViewProps { #pragma mark - Props - const std::vector nativePrimitives{}; + std::vector nativePrimitives{}; }; } // namespace react @@ -309,7 +309,7 @@ class BooleanPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{false}; + bool disabled{false}; }; } // namespace react @@ -342,7 +342,7 @@ class ColorPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const SharedColor tintColor{}; + SharedColor tintColor{}; }; } // namespace react @@ -406,7 +406,7 @@ class CommandNativeComponentProps final : public ViewProps { #pragma mark - Props - const std::string accessibilityHint{\\"\\"}; + std::string accessibilityHint{\\"\\"}; }; } // namespace react @@ -438,12 +438,12 @@ class DoublePropNativeComponentProps final : public ViewProps { #pragma mark - Props - const double blurRadius{0.0}; - const double blurRadius2{0.001}; - const double blurRadius3{2.1}; - const double blurRadius4{0.0}; - const double blurRadius5{1.0}; - const double blurRadius6{0.0}; + double blurRadius{0.0}; + double blurRadius2{0.001}; + double blurRadius3{2.1}; + double blurRadius4{0.0}; + double blurRadius5{1.0}; + double blurRadius6{0.0}; }; } // namespace react @@ -475,7 +475,7 @@ class EventsNestedObjectNativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{false}; + bool disabled{false}; }; } // namespace react @@ -507,7 +507,7 @@ class EventsNativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{false}; + bool disabled{false}; }; } // namespace react @@ -603,12 +603,12 @@ class FloatPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const Float blurRadius{0.0}; - const Float blurRadius2{0.001}; - const Float blurRadius3{2.1}; - const Float blurRadius4{0.0}; - const Float blurRadius5{1.0}; - const Float blurRadius6{0.0}; + Float blurRadius{0.0}; + Float blurRadius2{0.001}; + Float blurRadius3{2.1}; + Float blurRadius4{0.0}; + Float blurRadius5{1.0}; + Float blurRadius6{0.0}; }; } // namespace react @@ -641,7 +641,7 @@ class ImagePropNativeComponentProps final : public ViewProps { #pragma mark - Props - const ImageSource thumbImage{}; + ImageSource thumbImage{}; }; } // namespace react @@ -674,7 +674,7 @@ class InsetsPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const EdgeInsets contentInset{}; + EdgeInsets contentInset{}; }; } // namespace react @@ -733,7 +733,7 @@ class Int32EnumPropsNativeComponentProps final : public ViewProps { #pragma mark - Props - const Int32EnumPropsNativeComponentMaxInterval maxInterval{Int32EnumPropsNativeComponentMaxInterval::MaxInterval0}; + Int32EnumPropsNativeComponentMaxInterval maxInterval{Int32EnumPropsNativeComponentMaxInterval::MaxInterval0}; }; } // namespace react @@ -765,9 +765,9 @@ class IntegerPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const int progress1{0}; - const int progress2{-1}; - const int progress3{10}; + int progress1{0}; + int progress2{-1}; + int progress3{10}; }; } // namespace react @@ -799,7 +799,7 @@ class InterfaceOnlyComponentProps final : public ViewProps { #pragma mark - Props - const std::string accessibilityHint{\\"\\"}; + std::string accessibilityHint{\\"\\"}; }; } // namespace react @@ -834,10 +834,10 @@ class ImageColorPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const ImageSource thumbImage{}; - const SharedColor color{}; - const SharedColor thumbTintColor{}; - const Point point{}; + ImageSource thumbImage{}; + SharedColor color{}; + SharedColor thumbTintColor{}; + Point point{}; }; } // namespace react @@ -1121,7 +1121,7 @@ class ObjectPropsProps final : public ViewProps { #pragma mark - Props - const ObjectPropsObjectPropStruct objectProp{}; + ObjectPropsObjectPropStruct objectProp{}; }; } // namespace react @@ -1154,7 +1154,7 @@ class PointPropNativeComponentProps final : public ViewProps { #pragma mark - Props - const Point startPoint{}; + Point startPoint{}; }; } // namespace react @@ -1204,7 +1204,7 @@ class StringEnumPropsNativeComponentProps final : public ViewProps { #pragma mark - Props - const StringEnumPropsNativeComponentAlignment alignment{StringEnumPropsNativeComponentAlignment::Center}; + StringEnumPropsNativeComponentAlignment alignment{StringEnumPropsNativeComponentAlignment::Center}; }; } // namespace react @@ -1236,8 +1236,8 @@ class StringPropComponentProps final : public ViewProps { #pragma mark - Props - const std::string accessibilityHint{\\"\\"}; - const std::string accessibilityRole{}; + std::string accessibilityHint{\\"\\"}; + std::string accessibilityRole{}; }; } // namespace react @@ -1269,7 +1269,7 @@ class MultiFile1NativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{false}; + bool disabled{false}; }; class MultiFile2NativeComponentProps final : public ViewProps { @@ -1279,7 +1279,7 @@ class MultiFile2NativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{true}; + bool disabled{true}; }; } // namespace react @@ -1311,7 +1311,7 @@ class MultiComponent1NativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{false}; + bool disabled{false}; }; class MultiComponent2NativeComponentProps final : public ViewProps { @@ -1321,7 +1321,7 @@ class MultiComponent2NativeComponentProps final : public ViewProps { #pragma mark - Props - const bool disabled{true}; + bool disabled{true}; }; } // namespace react From 5a94471650c48269d452fd8692a89031caff0ece Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 05:46:03 -0800 Subject: [PATCH 0065/1126] Fabric: remove LocalData from ShadowNodeFragment Summary: LocalData isn't used by any components. We've moved towards State. Changelog: [internal] Reviewed By: mdvacca Differential Revision: D19250603 fbshipit-source-id: f95da375117dcb8f6540a6c75d3a80bba630672c --- ReactCommon/fabric/core/shadownode/ShadowNode.cpp | 3 --- ReactCommon/fabric/core/shadownode/ShadowNodeFragment.cpp | 8 +------- ReactCommon/fabric/core/shadownode/ShadowNodeFragment.h | 4 ---- .../fabric/uimanager/ComponentDescriptorRegistry.cpp | 1 - ReactCommon/fabric/uimanager/UIManager.cpp | 3 --- 5 files changed, 1 insertion(+), 18 deletions(-) diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp index 1178933848f09a..27281d9fc4530f 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp @@ -66,9 +66,6 @@ ShadowNode::ShadowNode( props_(fragment.props ? fragment.props : sourceShadowNode.props_), children_( fragment.children ? fragment.children : sourceShadowNode.children_), - localData_( - fragment.localData ? fragment.localData - : sourceShadowNode.localData_), state_( fragment.state ? fragment.state : sourceShadowNode.getMostRecentState()), diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.cpp b/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.cpp index 64ea2bb63ac526..e70e79b6be3052 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.cpp @@ -21,11 +21,6 @@ ShadowNodeFragment::childrenPlaceholder() { return instance; } -LocalData::Shared const &ShadowNodeFragment::localDataPlaceholder() { - static auto &instance = *new LocalData::Shared(); - return instance; -} - State::Shared const &ShadowNodeFragment::statePlaceholder() { static auto &instance = *new State::Shared(); return instance; @@ -36,11 +31,10 @@ using Value = ShadowNodeFragment::Value; Value::Value(ShadowNodeFragment const &fragment) : props_(fragment.props), children_(fragment.children), - localData_(fragment.localData), state_(fragment.state) {} Value::operator ShadowNodeFragment() const { - return ShadowNodeFragment{props_, children_, localData_, state_}; + return ShadowNodeFragment{props_, children_, state_}; } } // namespace react diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.h b/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.h index 208479122fb8a2..5cec5dde8d0c90 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFragment.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -29,7 +28,6 @@ namespace react { struct ShadowNodeFragment { Props::Shared const &props = propsPlaceholder(); ShadowNode::SharedListOfShared const &children = childrenPlaceholder(); - LocalData::Shared const &localData = localDataPlaceholder(); State::Shared const &state = statePlaceholder(); /* @@ -39,7 +37,6 @@ struct ShadowNodeFragment { */ static Props::Shared const &propsPlaceholder(); static ShadowNode::SharedListOfShared const &childrenPlaceholder(); - static LocalData::Shared const &localDataPlaceholder(); static State::Shared const &statePlaceholder(); /* @@ -62,7 +59,6 @@ struct ShadowNodeFragment { private: Props::Shared const props_; ShadowNode::SharedListOfShared const children_; - LocalData::Shared const localData_; State::Shared const state_; }; }; diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp index 583e657aa5bb19..298d6d5b21808a 100644 --- a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp @@ -183,7 +183,6 @@ SharedShadowNode ComponentDescriptorRegistry::createNode( { /* .props = */ props, /* .children = */ ShadowNodeFragment::childrenPlaceholder(), - /* .localData = */ ShadowNodeFragment::localDataPlaceholder(), /* .state = */ state, }, {tag, surfaceId, eventEmitter}); diff --git a/ReactCommon/fabric/uimanager/UIManager.cpp b/ReactCommon/fabric/uimanager/UIManager.cpp index e8f1a54d8269c6..ba322cbe42f412 100644 --- a/ReactCommon/fabric/uimanager/UIManager.cpp +++ b/ReactCommon/fabric/uimanager/UIManager.cpp @@ -49,7 +49,6 @@ SharedShadowNode UIManager::createNode( props, RawProps(folly::dynamic::object("name", name))) : props, /* .children = */ ShadowNodeFragment::childrenPlaceholder(), - /* .localData = */ ShadowNodeFragment::localDataPlaceholder(), /* .state = */ state, }, ShadowNodeFamilyFragment{tag, surfaceId, eventEmitter}); @@ -209,8 +208,6 @@ void UIManager::updateState( return oldShadowNode.clone({ /* .props = */ ShadowNodeFragment::propsPlaceholder(), /* .children = */ ShadowNodeFragment::childrenPlaceholder(), - /* .localData = */ - ShadowNodeFragment::localDataPlaceholder(), /* .state = */ state, }); }); From 9948fbdeec7597142cbfc536a4d8210f9390afea Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 05:46:03 -0800 Subject: [PATCH 0066/1126] Fabric: remove LocalData from ShadowNode Summary: LocalData isn't used by any components. We've moved towards State. Changelog: [internal] Reviewed By: mdvacca Differential Revision: D19250732 fbshipit-source-id: dd23a723c5392632165798f6365ea107b37b54cd --- .../fabric/core/shadownode/ShadowNode.cpp | 9 ----- .../fabric/core/shadownode/ShadowNode.h | 16 --------- .../fabric/core/tests/ShadowNodeTest.cpp | 34 ------------------- ReactCommon/fabric/mounting/ShadowView.cpp | 2 +- 4 files changed, 1 insertion(+), 60 deletions(-) diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp index 27281d9fc4530f..f3567d33a7f09c 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp @@ -142,10 +142,6 @@ State::Shared ShadowNode::getMostRecentState() const { return ShadowNodeFragment::statePlaceholder(); } -SharedLocalData ShadowNode::getLocalData() const { - return localData_; -} - void ShadowNode::sealRecursive() const { if (getSealed()) { return; @@ -206,11 +202,6 @@ void ShadowNode::replaceChild( assert(false && "Child to replace was not found."); } -void ShadowNode::setLocalData(const SharedLocalData &localData) { - ensureUnsealed(); - localData_ = localData; -} - void ShadowNode::cloneChildrenIfShared() { if (!traits_.check(ShadowNodeTraits::Trait::ChildrenAreShared)) { return; diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.h b/ReactCommon/fabric/core/shadownode/ShadowNode.h index 9021c4e4aea096..cc3471f8073691 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.h @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -126,14 +125,6 @@ class ShadowNode : public virtual Sealable, */ State::Shared getMostRecentState() const; - /* - * Returns a local data associated with the node. - * `LocalData` object might be used for data exchange between native view and - * shadow node instances. - * Concrete type of the object depends on concrete type of the `ShadowNode`. - */ - SharedLocalData getLocalData() const; - void sealRecursive() const; #pragma mark - Mutating Methods @@ -144,12 +135,6 @@ class ShadowNode : public virtual Sealable, ShadowNode::Shared const &newChild, int suggestedIndex = -1); - /* - * Sets local data associated with the node. - * The node must be unsealed at this point. - */ - void setLocalData(const SharedLocalData &localData); - /* * Performs all side effects associated with mounting/unmounting in one place. * This is not `virtual` on purpose, do not override this. @@ -187,7 +172,6 @@ class ShadowNode : public virtual Sealable, protected: SharedProps props_; SharedShadowNodeSharedList children_; - SharedLocalData localData_; State::Shared state_; private: diff --git a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp index 0ad36960db59b5..bab859649d37e8 100644 --- a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp +++ b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp @@ -204,14 +204,6 @@ TEST_F(ShadowNodeTest, handleShadowNodeMutation) { EXPECT_TRUE(nodeAB_->getSealed()); EXPECT_TRUE(nodeABArevision2->getSealed()); EXPECT_TRUE(nodeABB_->getSealed()); - - // No more mutation after sealing. - EXPECT_THROW(nodeABArevision2->setLocalData(nullptr), std::runtime_error); - - auto nodeABArevision3 = - std::make_shared(*nodeABArevision2, ShadowNodeFragment{}); - nodeABArevision3->setLocalData(nullptr); - EXPECT_EQ(nodeABArevision3->getLocalData(), nullptr); } TEST_F(ShadowNodeTest, handleCloneFunction) { @@ -230,32 +222,6 @@ TEST_F(ShadowNodeTest, handleCloneFunction) { EXPECT_EQ(nodeAB_->getProps(), nodeABClone->getProps()); } -TEST_F(ShadowNodeTest, handleLocalData) { - auto localData42 = std::make_shared(); - localData42->setNumber(42); - - auto anotherLocalData42 = std::make_shared(); - anotherLocalData42->setNumber(42); - - auto localDataOver9000 = std::make_shared(); - localDataOver9000->setNumber(9001); - auto props = std::make_shared(); - - nodeAA_->setLocalData(localData42); - nodeAB_->setLocalData(localData42); - nodeAC_->setLocalData(localDataOver9000); - - // LocalData object are compared by pointer, not by value. - EXPECT_EQ(nodeAA_->getLocalData(), nodeAB_->getLocalData()); - EXPECT_NE(nodeAA_->getLocalData(), nodeAC_->getLocalData()); - nodeAB_->setLocalData(anotherLocalData42); - EXPECT_NE(nodeAA_->getLocalData(), nodeAB_->getLocalData()); - - // LocalData cannot be changed for sealed shadow node. - nodeAB_->sealRecursive(); - EXPECT_ANY_THROW(nodeAB_->setLocalData(localDataOver9000)); -} - TEST_F(ShadowNodeTest, handleBacktracking) { // Negative case: auto ancestors1 = nodeZ_->getAncestors(*nodeA_); diff --git a/ReactCommon/fabric/mounting/ShadowView.cpp b/ReactCommon/fabric/mounting/ShadowView.cpp index 35b244d733779d..e78e765ba19ed7 100644 --- a/ReactCommon/fabric/mounting/ShadowView.cpp +++ b/ReactCommon/fabric/mounting/ShadowView.cpp @@ -26,7 +26,7 @@ ShadowView::ShadowView(const ShadowNode &shadowNode) props(shadowNode.getProps()), eventEmitter(shadowNode.getEventEmitter()), layoutMetrics(layoutMetricsFromShadowNode(shadowNode)), - localData(shadowNode.getLocalData()), + localData({}), state(shadowNode.getState()) {} bool ShadowView::operator==(const ShadowView &rhs) const { From 6a128bd8104c04e74a39da39cc808e6616205b63 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 05:46:03 -0800 Subject: [PATCH 0067/1126] Fabric: remove LocalData from ShadowView Summary: LocalData isn't used by any components. We've moved towards State. Changelog: [internal] Reviewed By: mdvacca Differential Revision: D19250737 fbshipit-source-id: 10bf0b62ffad01ad10b07d029e84df4f312780a1 --- .../com/facebook/react/fabric/jni/Binding.cpp | 34 ------------------- ReactCommon/fabric/mounting/ShadowView.cpp | 4 --- ReactCommon/fabric/mounting/ShadowView.h | 3 -- 3 files changed, 41 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index 4e88dda6afdd22..a83a714043a1b4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -426,29 +426,6 @@ local_ref createInsertMountItem( mutation.index); } -local_ref createUpdateLocalData( - const jni::global_ref &javaUIManager, - const ShadowViewMutation &mutation) { - static auto updateLocalDataInstruction = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jint, ReadableMap::javaobject)>( - "updateLocalDataMountItem"); - - auto localData = mutation.newChildShadowView.localData; - - folly::dynamic newLocalData = folly::dynamic::object(); - if (localData) { - newLocalData = localData->getDynamic(); - } - - local_ref readableNativeMap = - ReadableNativeMap::newObjectCxxArgs(newLocalData); - return updateLocalDataInstruction( - javaUIManager, - mutation.newChildShadowView.tag, - castReadableMap(readableNativeMap).get()); -} - local_ref createUpdateStateMountItem( const jni::global_ref &javaUIManager, const ShadowViewMutation &mutation) { @@ -737,11 +714,6 @@ void Binding::schedulerDidFinishTransaction( mountItems[position++] = createUpdatePropsMountItem(localJavaUIManager, mutation); } - if (mutation.oldChildShadowView.localData != - mutation.newChildShadowView.localData) { - mountItems[position++] = - createUpdateLocalData(localJavaUIManager, mutation); - } if (mutation.oldChildShadowView.state != mutation.newChildShadowView.state) { mountItems[position++] = @@ -791,12 +763,6 @@ void Binding::schedulerDidFinishTransaction( createUpdateStateMountItem(localJavaUIManager, mutation); } - // LocalData - if (mutation.newChildShadowView.localData) { - mountItems[position++] = - createUpdateLocalData(localJavaUIManager, mutation); - } - // Layout auto updateLayoutMountItem = createUpdateLayoutMountItem(localJavaUIManager, mutation); diff --git a/ReactCommon/fabric/mounting/ShadowView.cpp b/ReactCommon/fabric/mounting/ShadowView.cpp index e78e765ba19ed7..0bf2e57cd1884d 100644 --- a/ReactCommon/fabric/mounting/ShadowView.cpp +++ b/ReactCommon/fabric/mounting/ShadowView.cpp @@ -26,7 +26,6 @@ ShadowView::ShadowView(const ShadowNode &shadowNode) props(shadowNode.getProps()), eventEmitter(shadowNode.getEventEmitter()), layoutMetrics(layoutMetricsFromShadowNode(shadowNode)), - localData({}), state(shadowNode.getState()) {} bool ShadowView::operator==(const ShadowView &rhs) const { @@ -36,7 +35,6 @@ bool ShadowView::operator==(const ShadowView &rhs) const { this->props, this->eventEmitter, this->layoutMetrics, - this->localData, this->state) == std::tie( rhs.tag, @@ -44,7 +42,6 @@ bool ShadowView::operator==(const ShadowView &rhs) const { rhs.props, rhs.eventEmitter, rhs.layoutMetrics, - rhs.localData, rhs.state); } @@ -66,7 +63,6 @@ std::vector getDebugProps( {"props", getDebugDescription(object.props, options)}, {"eventEmitter", getDebugDescription(object.eventEmitter, options)}, {"layoutMetrics", getDebugDescription(object.layoutMetrics, options)}, - {"localData", getDebugDescription(object.localData, options)}, {"state", getDebugDescription(object.state, options)}, }; } diff --git a/ReactCommon/fabric/mounting/ShadowView.h b/ReactCommon/fabric/mounting/ShadowView.h index dce82f2fb79a2b..1372b44928af37 100644 --- a/ReactCommon/fabric/mounting/ShadowView.h +++ b/ReactCommon/fabric/mounting/ShadowView.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,6 @@ struct ShadowView final { Props::Shared props{}; EventEmitter::Shared eventEmitter{}; LayoutMetrics layoutMetrics{EmptyLayoutMetrics}; - LocalData::Shared localData{}; State::Shared state{}; }; @@ -88,7 +86,6 @@ struct hash { shadowView.tag, shadowView.props, shadowView.eventEmitter, - shadowView.localData, shadowView.state); } }; From e5ba9f67d3b8ef97fa27e40ec8599d8ecc11fdf8 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 05:46:03 -0800 Subject: [PATCH 0068/1126] Fabric: delete LocalData.h Summary: LocalData isn't used by any components. We've moved towards State. Changelog: [internal] Reviewed By: shergin Differential Revision: D19250738 fbshipit-source-id: 38ab19f63e4a249748555e9181141340729b4510 --- .../fabric/core/shadownode/LocalData.h | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 ReactCommon/fabric/core/shadownode/LocalData.h diff --git a/ReactCommon/fabric/core/shadownode/LocalData.h b/ReactCommon/fabric/core/shadownode/LocalData.h deleted file mode 100644 index cf3aead21768c4..00000000000000 --- a/ReactCommon/fabric/core/shadownode/LocalData.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook { -namespace react { - -class LocalData; - -using SharedLocalData = std::shared_ptr; - -/* - * Abstract class for any kind of concrete pieces of local data specific for - * some kinds of `ShadowNode`s. - * LocalData might be used to communicate some information between `ShadowNode`s - * and native component views. - * All `LocalData` objects *must* be immutable (sealed) when they became - * a part of the shadow tree. - */ -class LocalData : public Sealable, public DebugStringConvertible { - public: - using Shared = std::shared_ptr; - - virtual ~LocalData() = default; - - virtual folly::dynamic getDynamic() const { - return folly::dynamic::object(); - } -}; - -} // namespace react -} // namespace facebook From b9a9e8aed6c09b267d648aa88ffeff21751d8d87 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 05:46:03 -0800 Subject: [PATCH 0069/1126] Add unit test for ShadowNode::State Summary: Add unit tests for ShadowNode::State Changelog: [Internal] Reviewed By: JoshuaGross, mdvacca Differential Revision: D19345738 fbshipit-source-id: efb8b797e1a69b9d19631bf5cc4552283c05c107 --- .../fabric/core/tests/ShadowNodeTest.cpp | 57 +++++++++++++++++++ ReactCommon/fabric/core/tests/TestComponent.h | 22 +++---- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp index bab859649d37e8..e1d9c2ae8094a8 100644 --- a/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp +++ b/ReactCommon/fabric/core/tests/ShadowNodeTest.cpp @@ -233,3 +233,60 @@ TEST_F(ShadowNodeTest, handleBacktracking) { EXPECT_EQ(&ancestors2[0].first.get(), nodeA_.get()); EXPECT_EQ(&ancestors2[1].first.get(), nodeAB_.get()); } + +TEST_F(ShadowNodeTest, handleState) { + auto family = std::make_shared( + ShadowNodeFamilyFragment{ + /* .tag = */ 9, + /* .surfaceId = */ surfaceId_, + /* .eventEmitter = */ nullptr, + }, + componentDescriptor_); + + auto props = std::make_shared(); + auto fragment = ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + /* .state = */ {}}; + + auto const initialState = + componentDescriptor_.createInitialState(fragment, surfaceId_); + + auto firstNode = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + /* .state = */ initialState}, + family, + ShadowNodeTraits{}); + auto secondNode = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + /* .state = */ initialState}, + family, + ShadowNodeTraits{}); + auto thirdNode = std::make_shared( + ShadowNodeFragment{ + /* .props = */ props, + /* .children = */ ShadowNode::emptySharedShadowNodeSharedList(), + /* .state = */ initialState}, + family, + ShadowNodeTraits{}); + + TestShadowNode::ConcreteState::Shared _state = + std::static_pointer_cast( + initialState); + _state->updateState(TestState{42}); + + thirdNode->setStateData({9001}); + // State object are compared by pointer, not by value. + EXPECT_EQ(firstNode->getState(), secondNode->getState()); + EXPECT_NE(firstNode->getState(), thirdNode->getState()); + secondNode->setStateData(TestState{42}); + EXPECT_NE(firstNode->getState(), secondNode->getState()); + + // State cannot be changed for sealed shadow node. + secondNode->sealRecursive(); + EXPECT_ANY_THROW(secondNode->setStateData(TestState{42})); +} diff --git a/ReactCommon/fabric/core/tests/TestComponent.h b/ReactCommon/fabric/core/tests/TestComponent.h index 9e0616923d25c9..3f468459e5101a 100644 --- a/ReactCommon/fabric/core/tests/TestComponent.h +++ b/ReactCommon/fabric/core/tests/TestComponent.h @@ -11,9 +11,9 @@ #include #include +#include #include #include -#include #include #include @@ -24,18 +24,9 @@ using namespace facebook::react; * ComponentDescriptor. To be used for testing purpose. */ -class TestLocalData : public LocalData { +class TestState { public: - void setNumber(const int &number) { - number_ = number; - } - - int getNumber() const { - return number_; - } - - private: - int number_{0}; + int number; }; static const char TestComponentName[] = "Test"; @@ -54,8 +45,11 @@ class TestShadowNode; using SharedTestShadowNode = std::shared_ptr; -class TestShadowNode - : public ConcreteViewShadowNode { +class TestShadowNode : public ConcreteViewShadowNode< + TestComponentName, + TestProps, + ViewEventEmitter, + TestState> { public: using ConcreteViewShadowNode::ConcreteViewShadowNode; From 9ad5e72b77013083f925108870ea6b17f4711a1d Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Tue, 21 Jan 2020 02:30:57 -0800 Subject: [PATCH 0070/1126] Migrate to FBJNI (#27729) Summary: This is an incomplete effort to migrate from libfb to libfbjni. This is needed to restore the compatibility with Flipper and other FB Android projects that make use of FBJNI. Effectively, the outcome is that `fbjni` no longer has a checked-in copy here, but instead relies on the public artifacts published at github.com/facebookincubator/fbjni that can be deduplicated at build-time. **A non-exhaustive list of tasks:** * [X] Gradle builds the SDK and RNTester for Android. * [X] Buck build for rntester works in OSS. * [ ] Move from `java-only` release to full `fbjni` release. This requires finding a solution for stripping out `.so` files that the old `Android.mk` insists on including in the final artifacts and will clash with the full distribution. * [ ] Import this and fix potential internal build issues. * [ ] Verify that the changes made to the Hermes integration don't have any unintended consequences. ## Changelog [Android] [Changed] - Migrated from libfb to libfbjni for JNI calls Pull Request resolved: https://github.com/facebook/react-native/pull/27729 Test Plan: - CI is already passing again for Gradle and Buck in OSS. - After applying the following patch, RNTester builds and works with the latest Flipper SDK: ``` diff --git a/RNTester/android/app/build.gradle b/RNTester/android/app/build.gradle index b8a6437d7..eac942104 100644 --- a/RNTester/android/app/build.gradle +++ b/RNTester/android/app/build.gradle @@ -170,10 +170,19 @@ dependencies { debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") - debugImplementation("com.facebook.flipper:flipper:0.23.4") { + debugImplementation("com.facebook.flipper:flipper:+") { exclude group:'com.facebook.yoga' - exclude group:'com.facebook.flipper', module: 'fbjni' - exclude group:'com.facebook.litho', module: 'litho-annotations' + exclude group:'com.facebook.fbjni' + } + + debugImplementation("com.facebook.flipper:flipper-network-plugin:+") { + exclude group:'com.facebook.yoga' + exclude group:'com.facebook.fbjni' + } + + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:+") { + exclude group:'com.facebook.yoga' + exclude group:'com.facebook.fbjni' } if (useIntlJsc) { ``` Reviewed By: mdvacca Differential Revision: D19345270 Pulled By: passy fbshipit-source-id: 33811e7f97f44f2ec5999e1c35339909dc4fd3b1 --- .buckconfig | 1 + .../react/uiapp/ReactNativeFlipper.java | 1 - ReactAndroid/build.gradle | 43 +- ReactAndroid/src/main/java/com/facebook/BUCK | 2 +- .../hermes/instrumentation/Android.mk | 2 +- .../com/facebook/hermes/instrumentation/BUCK | 2 +- .../instrumentation/HermesMemoryDumper.h | 2 +- .../instrumentation/HermesSamplingProfiler.h | 3 +- .../facebook/hermes/reactexecutor/Android.mk | 4 +- .../facebook/hermes/reactexecutor/OnLoad.cpp | 2 +- .../src/main/java/com/facebook/jni/BUCK | 16 - .../main/java/com/facebook/jni/Countable.java | 39 -- .../com/facebook/jni/CpuCapabilitiesJni.java | 29 - .../com/facebook/jni/DestructorThread.java | 139 ---- .../com/facebook/jni/HybridClassBase.java | 13 - .../java/com/facebook/jni/HybridData.java | 78 --- .../java/com/facebook/jni/IteratorHelper.java | 50 -- .../com/facebook/jni/JniTerminateHandler.java | 20 - .../com/facebook/jni/MapIteratorHelper.java | 49 -- .../java/com/facebook/jni/NativeRunnable.java | 24 - .../com/facebook/jni/ThreadScopeSupport.java | 27 - .../src/main/java/com/facebook/jni/fbjni.pro | 16 - .../main/java/com/facebook/react/bridge/BUCK | 2 +- .../com/facebook/react/fabric/jni/Binding.cpp | 2 +- .../com/facebook/react/fabric/jni/Binding.h | 2 +- .../fabric/jni/ComponentFactoryDelegate.cpp | 2 +- .../fabric/jni/ComponentFactoryDelegate.h | 2 +- .../react/fabric/jni/EventBeatManager.cpp | 2 +- .../react/fabric/jni/EventBeatManager.h | 2 +- .../react/fabric/jni/EventEmitterWrapper.cpp | 4 +- .../react/fabric/jni/EventEmitterWrapper.h | 2 +- .../react/fabric/jni/NodeStateWrapper.cpp | 2 +- .../react/fabric/jni/NodeStateWrapper.h | 2 +- .../com/facebook/react/fabric/jni/OnLoad.cpp | 2 +- .../fabric/jni/ReactNativeConfigHolder.cpp | 2 +- .../fabric/jni/ReactNativeConfigHolder.h | 2 +- .../react/fabric/jni/StateWrapperImpl.cpp | 2 +- .../react/fabric/jni/StateWrapperImpl.h | 2 +- .../com/facebook/react/jscexecutor/Android.mk | 2 +- .../com/facebook/react/jscexecutor/OnLoad.cpp | 2 +- .../react/modules/blob/jni/Android.mk | 2 +- .../react/modules/blob/jni/BlobCollector.cpp | 2 +- .../react/modules/blob/jni/BlobCollector.h | 2 +- .../react/modules/blob/jni/OnLoad.cpp | 2 +- .../facebook/react/packagerconnection/BUCK | 2 +- .../com/facebook/react/turbomodule/core/BUCK | 2 +- .../react/turbomodule/core/jni/Android.mk | 2 +- .../core/jni/ReactCommon/CallInvokerHolder.h | 2 +- .../core/jni/ReactCommon/OnLoad.cpp | 2 +- .../jni/ReactCommon/TurboModuleManager.cpp | 2 +- .../core/jni/ReactCommon/TurboModuleManager.h | 2 +- .../ReactCommon/TurboModuleManagerDelegate.h | 2 +- .../src/main/jni/first-party/fb/Android.mk | 15 - .../src/main/jni/first-party/fb/Doxyfile | 15 - .../jni/first-party/fb/include/fb/fbjni.h | 22 - .../first-party/fb/include/fb/fbjni/Boxed.h | 67 -- .../fb/include/fb/fbjni/ByteBuffer.h | 39 -- .../first-party/fb/include/fb/fbjni/Common.h | 104 --- .../first-party/fb/include/fb/fbjni/Context.h | 33 - .../fb/include/fb/fbjni/CoreClasses-inl.h | 659 ------------------ .../fb/include/fb/fbjni/CoreClasses.h | 615 ---------------- .../fb/include/fb/fbjni/Exceptions.h | 128 ---- .../first-party/fb/include/fb/fbjni/File.h | 28 - .../first-party/fb/include/fb/fbjni/Hybrid.h | 304 -------- .../fb/include/fb/fbjni/Iterator-inl.h | 197 ------ .../fb/include/fb/fbjni/Iterator.h | 144 ---- .../first-party/fb/include/fb/fbjni/JThread.h | 37 - .../fb/include/fb/fbjni/JWeakReference.h | 42 -- .../fb/include/fb/fbjni/Meta-forward.h | 34 - .../fb/include/fb/fbjni/Meta-inl.h | 427 ------------ .../first-party/fb/include/fb/fbjni/Meta.h | 338 --------- .../fb/include/fb/fbjni/MetaConvert.h | 141 ---- .../fb/include/fb/fbjni/NativeRunnable.h | 45 -- .../fb/include/fb/fbjni/ReadableByteChannel.h | 23 - .../fb/fbjni/ReferenceAllocators-inl.h | 128 ---- .../fb/include/fb/fbjni/ReferenceAllocators.h | 60 -- .../fb/include/fb/fbjni/References-forward.h | 65 -- .../fb/include/fb/fbjni/References-inl.h | 511 -------------- .../fb/include/fb/fbjni/References.h | 586 ---------------- .../fb/include/fb/fbjni/Registration-inl.h | 166 ----- .../fb/include/fb/fbjni/Registration.h | 168 ----- .../fb/include/fb/fbjni/TypeTraits.h | 177 ----- .../main/jni/first-party/fb/include/fb/lyra.h | 173 ----- .../jni/first-party/fb/include/fbjni/fbjni.h | 10 - .../first-party/fb/include/jni/Countable.h | 34 - .../fb/include/jni/GlobalReference.h | 89 --- .../fb/include/jni/JniTerminateHandler.h | 16 - .../fb/include/jni/LocalReference.h | 35 - .../first-party/fb/include/jni/LocalString.h | 99 --- .../first-party/fb/include/jni/Registration.h | 25 - .../fb/include/jni/WeakReference.h | 53 -- .../first-party/fb/include/jni/jni_helpers.h | 137 ---- .../jni/first-party/fb/jni/ByteBuffer.cpp | 80 --- .../main/jni/first-party/fb/jni/Countable.cpp | 67 -- .../jni/first-party/fb/jni/Environment.cpp | 196 ------ .../jni/first-party/fb/jni/Exceptions.cpp | 394 ----------- .../main/jni/first-party/fb/jni/Hybrid.cpp | 34 - .../jni/first-party/fb/jni/LocalString.cpp | 311 --------- .../main/jni/first-party/fb/jni/OnLoad.cpp | 20 - .../fb/jni/ReadableByteChannel.cpp | 21 - .../jni/first-party/fb/jni/References.cpp | 39 -- .../jni/first-party/fb/jni/WeakReference.cpp | 41 -- .../fb/jni/android/CpuCapabilities.cpp | 75 -- .../fb/jni/android/ReferenceChecking.cpp | 35 - .../src/main/jni/first-party/fb/jni/fbjni.cpp | 193 ----- .../src/main/jni/first-party/fb/jni/java/BUCK | 10 - .../first-party/fb/jni/java/CppException.java | 18 - .../fb/jni/java/CppSystemErrorException.java | 25 - .../fb/jni/java/UnknownCppException.java | 23 - .../jni/first-party/fb/jni/jni_helpers.cpp | 195 ------ .../src/main/jni/first-party/fb/lyra/lyra.cpp | 125 ---- .../src/main/jni/first-party/fb/onload.cpp | 29 - .../src/main/jni/first-party/fbjni/.gitignore | 2 + .../src/main/jni/first-party/fbjni/Android.mk | 14 + .../main/jni/first-party/yogajni/Android.mk | 3 +- .../src/main/jni/react/jni/Android.mk | 3 +- .../jni/react/jni/CatalystInstanceImpl.cpp | 4 +- .../main/jni/react/jni/CatalystInstanceImpl.h | 2 +- .../main/jni/react/jni/CxxModuleWrapperBase.h | 2 +- .../src/main/jni/react/jni/JCallback.h | 2 +- .../src/main/jni/react/jni/JInspector.h | 2 +- .../jni/react/jni/JMessageQueueThread.cpp | 2 +- .../main/jni/react/jni/JMessageQueueThread.h | 2 +- .../src/main/jni/react/jni/JReactMarker.cpp | 2 +- .../src/main/jni/react/jni/JReactMarker.h | 2 +- .../src/main/jni/react/jni/JSLoader.cpp | 2 +- .../src/main/jni/react/jni/JSLoader.h | 2 +- .../main/jni/react/jni/JavaModuleWrapper.cpp | 2 +- .../main/jni/react/jni/JavaModuleWrapper.h | 2 +- .../jni/react/jni/JavaScriptExecutorHolder.h | 2 +- .../src/main/jni/react/jni/MethodInvoker.cpp | 2 +- .../src/main/jni/react/jni/MethodInvoker.h | 2 +- .../jni/react/jni/ModuleRegistryBuilder.h | 2 +- .../src/main/jni/react/jni/NativeArray.cpp | 2 +- .../src/main/jni/react/jni/NativeArray.h | 2 +- .../src/main/jni/react/jni/NativeCommon.h | 2 +- .../src/main/jni/react/jni/NativeMap.h | 2 +- .../src/main/jni/react/jni/OnLoad.cpp | 2 +- .../src/main/jni/react/jni/ProxyExecutor.cpp | 6 +- .../src/main/jni/react/jni/ProxyExecutor.h | 3 +- .../main/jni/react/jni/ReadableNativeMap.h | 2 +- .../main/jni/react/jni/WritableNativeArray.h | 2 +- .../main/jni/react/jni/WritableNativeMap.h | 2 +- .../src/main/jni/react/perftests/OnLoad.cpp | 2 +- .../fbjni/java/com/facebook/fbjni/BUCK | 20 + .../android/SliderMeasurementsManager.cpp | 2 +- .../AndroidSwitchMeasurementsManager.cpp | 2 +- .../AndroidTextInputShadowNode.cpp | 2 +- ReactCommon/hermes/inspector/Android.mk | 2 +- .../hermes/inspector/detail/Thread.cpp | 2 +- .../core/platform/android/JavaTurboModule.cpp | 2 +- .../core/platform/android/JavaTurboModule.h | 2 +- 152 files changed, 158 insertions(+), 8505 deletions(-) delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/BUCK delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/Countable.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/CpuCapabilitiesJni.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/HybridClassBase.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/HybridData.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/IteratorHelper.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/JniTerminateHandler.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/MapIteratorHelper.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/NativeRunnable.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/ThreadScopeSupport.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/jni/fbjni.pro delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/Doxyfile delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JThread.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/JWeakReference.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/NativeRunnable.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReadableByteChannel.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/lyra.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fbjni/fbjni.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/Countable.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/GlobalReference.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/JniTerminateHandler.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalReference.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalString.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/Registration.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/WeakReference.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/jni/jni_helpers.h delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/ByteBuffer.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/Countable.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/Environment.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/Exceptions.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/Hybrid.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/LocalString.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/OnLoad.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/ReadableByteChannel.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/References.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/WeakReference.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/android/CpuCapabilities.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/android/ReferenceChecking.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/fbjni.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/BUCK delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/CppException.java delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/CppSystemErrorException.java delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/UnknownCppException.java delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/jni_helpers.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/lyra/lyra.cpp delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/onload.cpp create mode 100644 ReactAndroid/src/main/jni/first-party/fbjni/.gitignore create mode 100644 ReactAndroid/src/main/jni/first-party/fbjni/Android.mk create mode 100644 ReactAndroid/src/main/libraries/fbjni/java/com/facebook/fbjni/BUCK diff --git a/.buckconfig b/.buckconfig index 7f56a4943a410d..14ee0b460b6e1c 100644 --- a/.buckconfig +++ b/.buckconfig @@ -8,6 +8,7 @@ [maven_repositories] central = https://repo1.maven.org/maven2 google = https://maven.google.com/ + jcenter = https://jcenter.bintray.com/ [alias] rntester = //RNTester/android/app:app diff --git a/RNTester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java b/RNTester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java index dfa6f24451724e..4a9072566f642e 100644 --- a/RNTester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java +++ b/RNTester/android/app/src/debug/java/com/facebook/react/uiapp/ReactNativeFlipper.java @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ - package com.facebook.react.uiapp; import android.content.Context; diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 92796d23ac635d..42675dd0d8fec5 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -296,7 +296,8 @@ def getNdkBuildFullPath() { } def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) { - dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog) + dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog, extractAARHeaders, extractJNIFiles) + inputs.dir("$projectDir/../ReactCommon") inputs.dir("src/main/jni") inputs.dir("src/main/java/com/facebook/react/modules/blob") @@ -344,6 +345,34 @@ def packageReactNdkLibsForBuck = tasks.register("packageReactNdkLibsForBuck", Co into("src/main/jni/prebuilt/lib") } +task extractAARHeaders { + doLast { + configurations.extractHeaders.files.each { + def file = it.absoluteFile + def packageName = file.name.tokenize('-')[0] + copy { + from zipTree(file) + into "$projectDir/src/main/jni/first-party/$packageName/headers" + include "**/*.h" + } + } + } +} + +task extractJNIFiles { + doLast { + configurations.extractJNI.files.each { + def file = it.absoluteFile + def packageName = file.name.tokenize('-')[0] + copy { + from zipTree(file) + into "$projectDir/src/main/jni/first-party/$packageName/" + include "jni/**/*" + } + } + } +} + android { compileSdkVersion 28 @@ -386,7 +415,8 @@ android { } tasks.withType(JavaCompile) { - compileTask -> compileTask.dependsOn(packageReactNdkLibs) + compileTask -> + compileTask.dependsOn(packageReactNdkLibs) } clean.dependsOn(cleanReactNdkLib) @@ -394,10 +424,16 @@ android { lintOptions { abortOnError(false) } + packagingOptions { exclude("META-INF/NOTICE") exclude("META-INF/LICENSE") } + + configurations { + extractHeaders + extractJNI + } } dependencies { @@ -412,6 +448,9 @@ dependencies { api("com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}") api("com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}") api("com.squareup.okio:okio:1.15.0") + api("com.facebook.fbjni:fbjni-java-only:0.0.3") + extractHeaders("com.facebook.fbjni:fbjni:0.0.2:headers") + extractJNI("com.facebook.fbjni:fbjni:0.0.2") testImplementation("junit:junit:${JUNIT_VERSION}") testImplementation("org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}") diff --git a/ReactAndroid/src/main/java/com/facebook/BUCK b/ReactAndroid/src/main/java/com/facebook/BUCK index 375cfdd543f841..a7461d145d8fc2 100644 --- a/ReactAndroid/src/main/java/com/facebook/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/BUCK @@ -5,7 +5,7 @@ rn_android_library( srcs = glob(["yoga/*.java"]), visibility = ["PUBLIC"], deps = [ - react_native_dep("java/com/facebook/jni:jni"), + react_native_dep("libraries/fbjni:java"), react_native_dep("java/com/facebook/proguard/annotations:annotations"), react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), react_native_dep("third-party/java/infer-annotations:infer-annotations"), diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk index 8f33762493adfa..3548e86abd3c93 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk @@ -19,7 +19,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no LOCAL_CPP_FEATURES := exceptions LOCAL_STATIC_LIBRARIES := libjsireact libjsi -LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes include $(BUILD_SHARED_LIBRARY) diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK index 414bae4a3b3573..aacd3e0fe2899b 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK @@ -15,7 +15,7 @@ rn_android_library( deps = [ react_native_dep("java/com/facebook/proguard/annotations:annotations"), react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), - react_native_dep("java/com/facebook/jni:jni"), + react_native_dep("libraries/fbjni:java"), ":jni_hermes_samplingprofiler", ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesMemoryDumper.h b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesMemoryDumper.h index c01cc56d9ab01c..46fddb751c5554 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesMemoryDumper.h +++ b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesMemoryDumper.h @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesSamplingProfiler.h b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesSamplingProfiler.h index 089bc6a6a4e681..48fb74b3d5d112 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesSamplingProfiler.h +++ b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/HermesSamplingProfiler.h @@ -8,8 +8,7 @@ #ifndef HERMESSAMPLINGPROFILER_H_ #define HERMESSAMPLINGPROFILER_H_ -#include -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk index 2bf9d26bda304c..d34b90af3ced05 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk @@ -18,7 +18,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no LOCAL_CPP_FEATURES := exceptions LOCAL_STATIC_LIBRARIES := libjsireact libjsi -LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes include $(BUILD_SHARED_LIBRARY) @@ -35,6 +35,6 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no LOCAL_CPP_FEATURES := exceptions LOCAL_STATIC_LIBRARIES := libjsireact libjsi libhermes-inspector -LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes include $(BUILD_SHARED_LIBRARY) diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp index c771bb1b27a3fc..b21457247ade2d 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp @@ -7,7 +7,7 @@ #include <../instrumentation/HermesMemoryDumper.h> #include -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/java/com/facebook/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/jni/BUCK deleted file mode 100644 index f3f8c049e3797f..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/BUCK +++ /dev/null @@ -1,16 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library") - -rn_android_library( - name = "jni", - srcs = glob(["**/*.java"]), - proguard_config = "fbjni.pro", - visibility = [ - "PUBLIC", - ], - deps = [ - react_native_dep("third-party/android/androidx:annotation"), - react_native_dep("java/com/facebook/proguard/annotations:annotations"), - react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), - react_native_dep("third-party/java/jsr-305:jsr-305"), - ], -) diff --git a/ReactAndroid/src/main/java/com/facebook/jni/Countable.java b/ReactAndroid/src/main/java/com/facebook/jni/Countable.java deleted file mode 100644 index 0ace033ed089bb..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/jni/Countable.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.jni; - -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.soloader.SoLoader; - -/** - * A Java Object that has native memory allocated corresponding to this instance. - * - *