Merge commit '8595f3f22c31e245b7b6b34ec8de011534803a74' into 0.67-merge-latest
This commit is contained in:
Коммит
bc18692ac1
|
@ -558,6 +558,32 @@ jobs:
|
|||
- store_test_results:
|
||||
path: ./reports/junit
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test Android Template
|
||||
# -------------------------
|
||||
test_android_template:
|
||||
executor: reactnativeandroid
|
||||
steps:
|
||||
- checkout
|
||||
- run_yarn
|
||||
|
||||
- run:
|
||||
name: Setup the Android Template
|
||||
command: |
|
||||
cd template
|
||||
sed -i 's/1000\.0\.0/file\:\.\./g' package.json
|
||||
npm install
|
||||
# react-native-community/cli is needed as the Android template is referencing a .gradle file inside it.
|
||||
npm i @react-native-community/cli
|
||||
|
||||
- run:
|
||||
name: Bundle the latest version of ReactAndroid
|
||||
command: ./gradlew :ReactAndroid:publishReleasePublicationToNpmRepository
|
||||
|
||||
- run:
|
||||
name: Build the template application
|
||||
command: cd template/android/ && ./gradlew assembleDebug
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test Docker
|
||||
# -------------------------
|
||||
|
@ -715,6 +741,19 @@ jobs:
|
|||
git config --global user.name "npm Deployment Script"
|
||||
echo "machine github.com login react-native-bot password $GITHUB_TOKEN" > ~/.netrc
|
||||
- run: node ./scripts/publish-npm.js << parameters.publish_npm_args >>
|
||||
- when:
|
||||
condition:
|
||||
equal: [ --dry-run, << parameters.publish_npm_args >> ]
|
||||
steps:
|
||||
- run:
|
||||
name: Build release package as a job artifact
|
||||
command: |
|
||||
mkdir -p build
|
||||
FILENAME=$(npm pack)
|
||||
mv $FILENAME build/
|
||||
- store_artifacts:
|
||||
path: ~/react-native/build/
|
||||
destination: build
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Nightly
|
||||
|
@ -746,6 +785,11 @@ workflows:
|
|||
branches:
|
||||
# TODO(macOS GH#774): disable this test which is redundant to Azure Devops test and it requires a CCI plan with resource-class:large.
|
||||
ignore: /.*/
|
||||
- test_android_template:
|
||||
filters:
|
||||
branches:
|
||||
# TODO(macOS GH#774): disable this test which is redundant to Azure Devops test and it requires a CCI plan with resource-class:large.
|
||||
ignore: /.*/
|
||||
- test_ios:
|
||||
name: test_ios_unit_jsc
|
||||
run_unit_tests: true
|
||||
|
@ -811,6 +855,16 @@ workflows:
|
|||
# Only act on version tags.
|
||||
tags:
|
||||
only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/
|
||||
- publish_npm_package:
|
||||
# Build a release package on every untagged commit, but do not publish to npm.
|
||||
name: build_commit_package
|
||||
publish_npm_args: --dry-run
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
tags:
|
||||
ignore: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/
|
||||
|
||||
analysis:
|
||||
jobs:
|
||||
|
|
|
@ -79,4 +79,4 @@ untyped-import
|
|||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.159.0
|
||||
^0.160.2
|
||||
|
|
|
@ -82,4 +82,4 @@ untyped-import
|
|||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.159.0
|
||||
^0.160.2
|
||||
|
|
5
BUCK
5
BUCK
|
@ -1,6 +1,7 @@
|
|||
load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native")
|
||||
load("//tools/build_defs/apple:config_utils_defs.bzl", "STATIC_LIBRARY_APPLETVOS_CONFIG", "fbobjc_configs")
|
||||
load("//tools/build_defs/apple:fb_apple_test.bzl", "fb_apple_test")
|
||||
load("//tools/build_defs/apple:flag_defs.bzl", "get_objc_arc_preprocessor_flags", "get_preprocessor_flags_for_build_mode", "get_static_library_ios_flags")
|
||||
load("//tools/build_defs/apple:flag_defs.bzl", "get_base_appletvos_flags", "get_objc_arc_preprocessor_flags", "get_preprocessor_flags_for_build_mode", "get_static_library_ios_flags")
|
||||
load("//tools/build_defs/apple/plugins:plugin_defs.bzl", "plugin")
|
||||
load("//tools/build_defs/oss:metro_defs.bzl", "rn_library")
|
||||
load(
|
||||
|
@ -183,6 +184,8 @@ rn_xplat_cxx_library2(
|
|||
prefix = "React",
|
||||
),
|
||||
apple_sdks = (IOS, APPLETVOS),
|
||||
appletvos_configs = fbobjc_configs(STATIC_LIBRARY_APPLETVOS_CONFIG),
|
||||
appletvos_inherited_buck_flags = get_base_appletvos_flags(),
|
||||
contacts = ["oncall+react_native@xmail.facebook.com"],
|
||||
fbobjc_enable_exceptions = True,
|
||||
frameworks = [
|
||||
|
|
|
@ -47,6 +47,7 @@ const ActionSheetIOS = {
|
|||
+cancelButtonIndex?: ?number,
|
||||
+anchor?: ?number,
|
||||
+tintColor?: ColorValue | ProcessedColorValue,
|
||||
+cancelButtonTintColor?: ColorValue | ProcessedColorValue,
|
||||
+userInterfaceStyle?: string,
|
||||
+disabledButtonIndices?: Array<number>,
|
||||
|},
|
||||
|
@ -59,7 +60,12 @@ const ActionSheetIOS = {
|
|||
invariant(typeof callback === 'function', 'Must provide a valid callback');
|
||||
invariant(RCTActionSheetManager, "ActionSheetManager doesn't exist");
|
||||
|
||||
const {tintColor, destructiveButtonIndex, ...remainingOptions} = options;
|
||||
const {
|
||||
tintColor,
|
||||
cancelButtonTintColor,
|
||||
destructiveButtonIndex,
|
||||
...remainingOptions
|
||||
} = options;
|
||||
let destructiveButtonIndices = null;
|
||||
|
||||
if (Array.isArray(destructiveButtonIndex)) {
|
||||
|
@ -69,14 +75,21 @@ const ActionSheetIOS = {
|
|||
}
|
||||
|
||||
const processedTintColor = processColor(tintColor);
|
||||
const processedCancelButtonTintColor = processColor(cancelButtonTintColor);
|
||||
invariant(
|
||||
processedTintColor == null || typeof processedTintColor === 'number',
|
||||
'Unexpected color given for ActionSheetIOS.showActionSheetWithOptions tintColor',
|
||||
);
|
||||
invariant(
|
||||
processedCancelButtonTintColor == null ||
|
||||
typeof processedCancelButtonTintColor === 'number',
|
||||
'Unexpected color given for ActionSheetIOS.showActionSheetWithOptions cancelButtonTintColor',
|
||||
);
|
||||
RCTActionSheetManager.showActionSheetWithOptions(
|
||||
{
|
||||
...remainingOptions,
|
||||
tintColor: processedTintColor,
|
||||
cancelButtonTintColor: processedCancelButtonTintColor,
|
||||
destructiveButtonIndices,
|
||||
},
|
||||
callback,
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface Spec extends TurboModule {
|
|||
+cancelButtonIndex?: ?number,
|
||||
+anchor?: ?number,
|
||||
+tintColor?: ?number,
|
||||
+cancelButtonTintColor?: ?number,
|
||||
+userInterfaceStyle?: ?string,
|
||||
+disabledButtonIndices?: Array<number>,
|
||||
|},
|
||||
|
@ -34,6 +35,7 @@ export interface Spec extends TurboModule {
|
|||
+subject?: ?string,
|
||||
+anchor?: ?number,
|
||||
+tintColor?: ?number,
|
||||
+cancelButtonTintColor?: ?number,
|
||||
+excludedActivityTypes?: ?Array<string>,
|
||||
+userInterfaceStyle?: ?string,
|
||||
|},
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const Image = require('./Image');
|
||||
const React = require('react');
|
||||
const StyleSheet = require('../StyleSheet/StyleSheet');
|
||||
const View = require('../Components/View/View');
|
||||
import Image from './Image';
|
||||
import * as React from 'react';
|
||||
import StyleSheet from '../StyleSheet/StyleSheet';
|
||||
import flattenStyle from '../StyleSheet/flattenStyle';
|
||||
import View from '../Components/View/View';
|
||||
import type {ImageBackgroundProps} from './ImageProps';
|
||||
|
||||
/**
|
||||
* Very simple drop-in replacement for <Image> which supports nesting views.
|
||||
|
@ -39,7 +41,7 @@ const View = require('../Components/View/View');
|
|||
* AppRegistry.registerComponent('DisplayAnImageBackground', () => DisplayAnImageBackground);
|
||||
* ```
|
||||
*/
|
||||
class ImageBackground extends React.Component<$FlowFixMeProps> {
|
||||
class ImageBackground extends React.Component<ImageBackgroundProps> {
|
||||
setNativeProps(props: Object) {
|
||||
// Work-around flow
|
||||
const viewRef = this._viewRef;
|
||||
|
@ -56,7 +58,7 @@ class ImageBackground extends React.Component<$FlowFixMeProps> {
|
|||
|
||||
render(): React.Node {
|
||||
const {children, style, imageStyle, imageRef, ...props} = this.props;
|
||||
|
||||
const flattenedStyle = flattenStyle(style);
|
||||
return (
|
||||
<View
|
||||
accessibilityIgnoresInvertColors={true}
|
||||
|
@ -74,8 +76,8 @@ class ImageBackground extends React.Component<$FlowFixMeProps> {
|
|||
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
|
||||
// This workaround should be removed after implementing proper support of
|
||||
// intrinsic content size of the <Image>.
|
||||
width: style?.width,
|
||||
height: style?.height,
|
||||
width: flattenedStyle?.width,
|
||||
height: flattenedStyle?.height,
|
||||
},
|
||||
imageStyle,
|
||||
]}
|
||||
|
|
|
@ -15,6 +15,8 @@ import type {EdgeInsetsProp} from '../StyleSheet/EdgeInsetsPropType';
|
|||
import type {ImageSource} from './ImageSource';
|
||||
import type {ViewStyleProp, ImageStyleProp} from '../StyleSheet/StyleSheet';
|
||||
import type {ViewProps} from '../Components/View/ViewPropTypes';
|
||||
import type {Node, Ref} from 'react';
|
||||
import typeof Image from './Image';
|
||||
|
||||
export type ImageLoadEvent = SyntheticEvent<
|
||||
$ReadOnly<{|
|
||||
|
@ -176,3 +178,29 @@ export type ImageProps = {|
|
|||
*/
|
||||
tooltip?: ?string,
|
||||
|};
|
||||
|
||||
export type ImageBackgroundProps = $ReadOnly<{|
|
||||
...ImageProps,
|
||||
children?: Node,
|
||||
|
||||
/**
|
||||
* Style applied to the outer View component
|
||||
*
|
||||
* See https://reactnative.dev/docs/imagebackground#style
|
||||
*/
|
||||
style?: ?ViewStyleProp,
|
||||
|
||||
/**
|
||||
* Style applied to the inner Image component
|
||||
*
|
||||
* See https://reactnative.dev/docs/imagebackground#imagestyle
|
||||
*/
|
||||
imageStyle?: ?ImageStyleProp,
|
||||
|
||||
/**
|
||||
* Allows to set a reference to the inner Image component
|
||||
*
|
||||
* See https://reactnative.dev/docs/imagebackground#imageref
|
||||
*/
|
||||
imageRef?: Ref<Image>,
|
||||
|}>;
|
||||
|
|
|
@ -142,7 +142,6 @@ static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notificatio
|
|||
return formattedLocalNotification;
|
||||
}
|
||||
|
||||
API_AVAILABLE(ios(10.0))
|
||||
static NSDictionary *RCTFormatUNNotification(UNNotification *notification)
|
||||
{
|
||||
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
|
||||
|
|
|
@ -1 +1 @@
|
|||
95d762e406bd37c07693e3a5ddbd0f75289e8c3f
|
||||
e8feb11b62e869804970258fa629922edbfc836b
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<1a3cb2d94c0721509af63438d7639b77>>
|
||||
* @generated SignedSource<<65d072c3d2937f89a7fadc55450af2f7>>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -2853,6 +2853,7 @@ var enableProfilerTimer = true;
|
|||
var enableProfilerCommitHooks = true;
|
||||
var enableLazyElements = false;
|
||||
var warnAboutStringRefs = false;
|
||||
var warnOnSubscriptionInsideStartTransition = false;
|
||||
var enableNewReconciler = false;
|
||||
var enableLazyContextPropagation = false;
|
||||
|
||||
|
@ -2903,21 +2904,25 @@ var HydratingAndUpdate =
|
|||
var Visibility =
|
||||
/* */
|
||||
4096;
|
||||
var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit)
|
||||
var StoreConsistency =
|
||||
/* */
|
||||
8192;
|
||||
var LifecycleEffectMask =
|
||||
Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
|
||||
|
||||
var HostEffectMask =
|
||||
/* */
|
||||
8191; // These are not really side effects, but we still reuse this field.
|
||||
16383; // These are not really side effects, but we still reuse this field.
|
||||
|
||||
var Incomplete =
|
||||
/* */
|
||||
8192;
|
||||
16384;
|
||||
var ShouldCapture =
|
||||
/* */
|
||||
16384;
|
||||
32768;
|
||||
var ForceUpdateForLegacySuspense =
|
||||
/* */
|
||||
32768;
|
||||
65536;
|
||||
// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
|
||||
// This enables us to defer more work in the unmount case,
|
||||
// since we can defer traversing the tree during layout to look for Passive effects,
|
||||
|
@ -2925,22 +2930,22 @@ var ForceUpdateForLegacySuspense =
|
|||
|
||||
var RefStatic =
|
||||
/* */
|
||||
262144;
|
||||
524288;
|
||||
var LayoutStatic =
|
||||
/* */
|
||||
524288;
|
||||
1048576;
|
||||
var PassiveStatic =
|
||||
/* */
|
||||
1048576; // These flags allow us to traverse to fibers that have effects on mount
|
||||
2097152; // These flags allow us to traverse to fibers that have effects on mount
|
||||
// without traversing the entire tree after every commit for
|
||||
// double invoking
|
||||
|
||||
var MountLayoutDev =
|
||||
/* */
|
||||
2097152;
|
||||
4194304;
|
||||
var MountPassiveDev =
|
||||
/* */
|
||||
4194304; // Groups of flags that are used in the commit phase to skip over trees that
|
||||
8388608; // Groups of flags that are used in the commit phase to skip over trees that
|
||||
// don't contain effects, by checking subtreeFlags.
|
||||
|
||||
var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
|
||||
|
@ -4499,16 +4504,10 @@ function includesOnlyRetries(lanes) {
|
|||
function includesOnlyTransitions(lanes) {
|
||||
return (lanes & TransitionLanes) === lanes;
|
||||
}
|
||||
function shouldTimeSlice(root, lanes) {
|
||||
if ((lanes & root.expiredLanes) !== NoLanes) {
|
||||
// At least one of these lanes expired. To prevent additional starvation,
|
||||
// finish rendering without yielding execution.
|
||||
return false;
|
||||
}
|
||||
|
||||
function includesBlockingLane(root, lanes) {
|
||||
if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode) {
|
||||
// Concurrent updates by default always use time slicing.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var SyncDefaultLanes =
|
||||
|
@ -4516,7 +4515,12 @@ function shouldTimeSlice(root, lanes) {
|
|||
InputContinuousLane |
|
||||
DefaultHydrationLane |
|
||||
DefaultLane;
|
||||
return (lanes & SyncDefaultLanes) === NoLanes;
|
||||
return (lanes & SyncDefaultLanes) !== NoLanes;
|
||||
}
|
||||
function includesExpiredLane(root, lanes) {
|
||||
// This is a separate check from includesBlockingLane because a lane can
|
||||
// expire after a render has already started.
|
||||
return (lanes & root.expiredLanes) !== NoLanes;
|
||||
}
|
||||
function isTransitionLane(lane) {
|
||||
return (lane & TransitionLanes) !== 0;
|
||||
|
@ -5835,6 +5839,18 @@ function findCurrentUnmaskedContext(fiber) {
|
|||
var LegacyRoot = 0;
|
||||
var ConcurrentRoot = 1;
|
||||
|
||||
/**
|
||||
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
||||
*/
|
||||
function is(x, y) {
|
||||
return (
|
||||
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
|
||||
);
|
||||
}
|
||||
|
||||
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
||||
|
||||
var syncQueue = null;
|
||||
var includesLegacySyncCallbacks = false;
|
||||
var isFlushingSyncQueue = false;
|
||||
|
@ -5904,7 +5920,7 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
|
||||
var ReactVersion = "18.0.0-95d762e40-20210908";
|
||||
var ReactVersion = "18.0.0-e8feb11b6-20210915";
|
||||
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
var NoTransition = 0;
|
||||
|
@ -5912,18 +5928,6 @@ function requestCurrentTransition() {
|
|||
return ReactCurrentBatchConfig.transition;
|
||||
}
|
||||
|
||||
/**
|
||||
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
||||
*/
|
||||
function is(x, y) {
|
||||
return (
|
||||
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
|
||||
);
|
||||
}
|
||||
|
||||
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
||||
|
||||
/**
|
||||
* Performs equality by iterating through keys on an object and returning false
|
||||
* when any key has values which are not strictly equal between the arguments.
|
||||
|
@ -9858,19 +9862,22 @@ function findFirstSuspended(row) {
|
|||
}
|
||||
|
||||
var NoFlags$1 =
|
||||
/* */
|
||||
/* */
|
||||
0; // Represents whether effect should fire.
|
||||
|
||||
var HasEffect =
|
||||
/* */
|
||||
1; // Represents the phase in which the effect (not the clean-up) fires.
|
||||
|
||||
var Insertion =
|
||||
/* */
|
||||
2;
|
||||
var Layout =
|
||||
/* */
|
||||
2;
|
||||
4;
|
||||
var Passive$1 =
|
||||
/* */
|
||||
4;
|
||||
8;
|
||||
|
||||
var isHydrating = false;
|
||||
|
||||
|
@ -10433,7 +10440,8 @@ function updateWorkInProgressHook() {
|
|||
|
||||
function createFunctionComponentUpdateQueue() {
|
||||
return {
|
||||
lastEffect: null
|
||||
lastEffect: null,
|
||||
stores: null
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -10962,6 +10970,7 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
}
|
||||
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var hook = mountWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
|
||||
// normal rules of React, and only works because store updates are
|
||||
// always synchronous.
|
||||
|
@ -10985,11 +10994,43 @@ function mountSyncExternalStore(subscribe, getSnapshot) {
|
|||
value: nextSnapshot,
|
||||
getSnapshot: getSnapshot
|
||||
};
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
hook.queue = inst; // Schedule an effect to subscribe to the store.
|
||||
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
|
||||
// this whenever subscribe, getSnapshot, or value changes. Because there's no
|
||||
// clean-up function, and we track the deps correctly, we can call pushEffect
|
||||
// directly, without storing any additional state. For the same reason, we
|
||||
// don't need to set a static flag, either.
|
||||
// TODO: We can move this to the passive phase once we add a pre-commit
|
||||
// consistency check. See the next comment.
|
||||
|
||||
fiber.flags |= Passive;
|
||||
pushEffect(
|
||||
HasEffect | Passive$1,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
undefined,
|
||||
null
|
||||
); // Unless we're rendering a blocking lane, schedule a consistency check. Right
|
||||
// before committing, we will walk the tree and check if any of the stores
|
||||
// were mutated.
|
||||
|
||||
var root = getWorkInProgressRoot();
|
||||
|
||||
if (!(root !== null)) {
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
}
|
||||
|
||||
if (!includesBlockingLane(root, renderLanes)) {
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function updateSyncExternalStore(subscribe, getSnapshot) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
|
||||
// normal rules of React, and only works because store updates are
|
||||
// always synchronous.
|
||||
|
@ -11009,69 +11050,102 @@ function updateSyncExternalStore(subscribe, getSnapshot) {
|
|||
}
|
||||
|
||||
var prevSnapshot = hook.memoizedState;
|
||||
var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
|
||||
|
||||
if (!objectIs(prevSnapshot, nextSnapshot)) {
|
||||
if (snapshotChanged) {
|
||||
hook.memoizedState = nextSnapshot;
|
||||
markWorkInProgressReceivedUpdate();
|
||||
}
|
||||
|
||||
var inst = hook.queue;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [
|
||||
subscribe
|
||||
]); // Whenever getSnapshot or subscribe changes, we need to check in the
|
||||
// commit phase if there was an interleaved mutation. In concurrent mode
|
||||
// this can happen all the time, but even in synchronous mode, an earlier
|
||||
// effect may have mutated the store.
|
||||
|
||||
if (
|
||||
inst.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
|
||||
// checking whether we scheduled a subscription effect above.
|
||||
(workInProgressHook !== null &&
|
||||
workInProgressHook.memoizedState.tag & HasEffect)
|
||||
) {
|
||||
fiber.flags |= Passive;
|
||||
pushEffect(
|
||||
HasEffect | Passive$1,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
undefined,
|
||||
null
|
||||
); // Unless we're rendering a blocking lane, schedule a consistency check.
|
||||
// Right before committing, we will walk the tree and check if any of the
|
||||
// stores were mutated.
|
||||
|
||||
var root = getWorkInProgressRoot();
|
||||
|
||||
if (!(root !== null)) {
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
}
|
||||
|
||||
if (!includesBlockingLane(root, renderLanes)) {
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var dispatcher = ReactCurrentDispatcher$1.current; // Track the latest getSnapshot function with a ref. This needs to be updated
|
||||
// in the layout phase so we can access it during the tearing check that
|
||||
// happens on subscribe.
|
||||
// TODO: Circumvent SSR warning
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= StoreConsistency;
|
||||
var check = {
|
||||
getSnapshot: getSnapshot,
|
||||
value: renderedSnapshot
|
||||
};
|
||||
var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
|
||||
|
||||
dispatcher.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot; // Whenever getSnapshot or subscribe changes, we need to check in the
|
||||
// commit phase if there was an interleaved mutation. In concurrent mode
|
||||
// this can happen all the time, but even in synchronous mode, an earlier
|
||||
// effect may have mutated the store.
|
||||
// TODO: Move the tearing checks to an earlier, pre-commit phase so that the
|
||||
// layout effects always observe a consistent tree.
|
||||
if (componentUpdateQueue === null) {
|
||||
componentUpdateQueue = createFunctionComponentUpdateQueue();
|
||||
currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
|
||||
componentUpdateQueue.stores = [check];
|
||||
} else {
|
||||
var stores = componentUpdateQueue.stores;
|
||||
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
dispatcher.useEffect(
|
||||
function() {
|
||||
var handleStoreChange = function() {
|
||||
// TODO: Because there is no cross-renderer API for batching updates, it's
|
||||
// up to the consumer of this library to wrap their subscription event
|
||||
// with unstable_batchedUpdates. Should we try to detect when this isn't
|
||||
// the case and print a warning in development?
|
||||
// The store changed. Check if the snapshot changed since the last time we
|
||||
// read from the store.
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}; // Check for changes right before subscribing. Subsequent changes will be
|
||||
// detected in the subscription handler.
|
||||
if (stores === null) {
|
||||
componentUpdateQueue.stores = [check];
|
||||
} else {
|
||||
stores.push(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleStoreChange(); // Subscribe to the store and return a clean-up function.
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
// These are updated in the passive phase
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
|
||||
// have been in an event that fired before the passive effects, or it could
|
||||
// have been in a layout effect. In that case, we would have used the old
|
||||
// snapsho and getSnapshot values to bail out. We need to check one more time.
|
||||
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
);
|
||||
return nextSnapshot;
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}
|
||||
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
var handleStoreChange = function() {
|
||||
// The store changed. Check if the snapshot changed since the last time we
|
||||
// read from the store.
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}; // Subscribe to the store and return a clean-up function.
|
||||
|
||||
return subscribe(handleStoreChange);
|
||||
}
|
||||
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
|
@ -11229,6 +11303,14 @@ function updateEffect(create, deps) {
|
|||
return updateEffectImpl(Passive, Passive$1, create, deps);
|
||||
}
|
||||
|
||||
function mountInsertionEffect(create, deps) {
|
||||
return mountEffectImpl(Update, Insertion, create, deps);
|
||||
}
|
||||
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(Update, Insertion, create, deps);
|
||||
}
|
||||
|
||||
function mountLayoutEffect(create, deps) {
|
||||
var fiberFlags = Update;
|
||||
|
||||
|
@ -11464,6 +11546,26 @@ function startTransition(setPending, callback) {
|
|||
} finally {
|
||||
setCurrentUpdatePriority(previousPriority);
|
||||
ReactCurrentBatchConfig$1.transition = prevTransition;
|
||||
|
||||
{
|
||||
if (
|
||||
prevTransition !== 1 &&
|
||||
warnOnSubscriptionInsideStartTransition &&
|
||||
ReactCurrentBatchConfig$1._updatedFibers
|
||||
) {
|
||||
var updatedFibersCount = ReactCurrentBatchConfig$1._updatedFibers.size;
|
||||
|
||||
if (updatedFibersCount > 10) {
|
||||
warn(
|
||||
"Detected a large number of updates inside startTransition. " +
|
||||
"If this is due to a subscription please re-write it to use React provided hooks. " +
|
||||
"Otherwise concurrent mode guarantees are off the table."
|
||||
);
|
||||
}
|
||||
|
||||
ReactCurrentBatchConfig$1._updatedFibers.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11686,6 +11788,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -11754,6 +11857,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
checkDepsAreArrayDev(deps);
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
mountHookTypesDev();
|
||||
checkDepsAreArrayDev(deps);
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
mountHookTypesDev();
|
||||
|
@ -11859,6 +11968,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -11962,6 +12076,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -12065,6 +12184,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -12173,6 +12297,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
mountHookTypesDev();
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
mountHookTypesDev();
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -12292,6 +12422,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -12411,6 +12547,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -17387,6 +17529,8 @@ function safelyDetachRef(current, nearestMountedAncestor) {
|
|||
|
||||
if (ref !== null) {
|
||||
if (typeof ref === "function") {
|
||||
var retVal;
|
||||
|
||||
try {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
|
@ -17395,12 +17539,12 @@ function safelyDetachRef(current, nearestMountedAncestor) {
|
|||
) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
ref(null);
|
||||
retVal = ref(null);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(current);
|
||||
}
|
||||
} else {
|
||||
ref(null);
|
||||
retVal = ref(null);
|
||||
}
|
||||
} catch (error) {
|
||||
reportUncaughtErrorInDEV(error);
|
||||
|
@ -17625,6 +17769,16 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
var destroy = effect.destroy;
|
||||
|
||||
if (destroy !== undefined && typeof destroy !== "function") {
|
||||
var hookName = void 0;
|
||||
|
||||
if ((effect.tag & Layout) !== NoFlags) {
|
||||
hookName = "useLayoutEffect";
|
||||
} else if ((effect.tag & Insertion) !== NoFlags) {
|
||||
hookName = "useInsertionEffect";
|
||||
} else {
|
||||
hookName = "useEffect";
|
||||
}
|
||||
|
||||
var addendum = void 0;
|
||||
|
||||
if (destroy === null) {
|
||||
|
@ -17633,10 +17787,13 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
"up, return undefined (or nothing).";
|
||||
} else if (typeof destroy.then === "function") {
|
||||
addendum =
|
||||
"\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " +
|
||||
"\n\nIt looks like you wrote " +
|
||||
hookName +
|
||||
"(async () => ...) or returned a Promise. " +
|
||||
"Instead, write the async function inside your effect " +
|
||||
"and call it immediately:\n\n" +
|
||||
"useEffect(() => {\n" +
|
||||
hookName +
|
||||
"(() => {\n" +
|
||||
" async function fetchData() {\n" +
|
||||
" // You can await here\n" +
|
||||
" const response = await MyAPI.getData(someId);\n" +
|
||||
|
@ -17650,8 +17807,9 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
}
|
||||
|
||||
error(
|
||||
"An effect function must not return anything besides a function, " +
|
||||
"%s must not return anything besides a function, " +
|
||||
"which is used for clean-up.%s",
|
||||
hookName,
|
||||
addendum
|
||||
);
|
||||
}
|
||||
|
@ -18058,15 +18216,17 @@ function commitAttachRef(finishedWork) {
|
|||
} // Moved outside to ensure DCE works with this flag
|
||||
|
||||
if (typeof ref === "function") {
|
||||
var retVal;
|
||||
|
||||
if (finishedWork.mode & ProfileMode) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
ref(instanceToUse);
|
||||
retVal = ref(instanceToUse);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(finishedWork);
|
||||
}
|
||||
} else {
|
||||
ref(instanceToUse);
|
||||
retVal = ref(instanceToUse);
|
||||
}
|
||||
} else {
|
||||
{
|
||||
|
@ -18130,7 +18290,10 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor) {
|
|||
tag = _effect.tag;
|
||||
|
||||
if (destroy !== undefined) {
|
||||
if ((tag & Layout) !== NoFlags$1) {
|
||||
if (
|
||||
(tag & Insertion) !== NoFlags$1 ||
|
||||
(tag & Layout) !== NoFlags$1
|
||||
) {
|
||||
if (current.mode & ProfileMode) {
|
||||
startLayoutEffectTimer();
|
||||
safelyCallDestroy(current, nearestMountedAncestor, destroy);
|
||||
|
@ -18358,7 +18521,12 @@ function commitWork(current, finishedWork) {
|
|||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
commitHookEffectListUnmount(
|
||||
Insertion | HasEffect,
|
||||
finishedWork,
|
||||
finishedWork.return
|
||||
);
|
||||
commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
// e.g. a destroy function in one component should never override a ref set
|
||||
|
@ -18368,6 +18536,7 @@ function commitWork(current, finishedWork) {
|
|||
// layout hooks. (However, since we null out the `destroy` function
|
||||
// right before calling it, the behavior is already correct, so this
|
||||
// would mostly be for modeling purposes.)
|
||||
|
||||
if (finishedWork.mode & ProfileMode) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
|
@ -19223,13 +19392,13 @@ function requestUpdateLane(fiber) {
|
|||
var isTransition = requestCurrentTransition() !== NoTransition;
|
||||
|
||||
if (isTransition) {
|
||||
// The algorithm for assigning an update to a lane should be stable for all
|
||||
// updates at the same priority within the same event. To do this, the
|
||||
// inputs to the algorithm must be the same.
|
||||
//
|
||||
// The trick we use is to cache the first of each of these inputs within an
|
||||
// event. Then reset the cached values once we can be sure the event is
|
||||
// over. Our heuristic for that is whenever we enter a concurrent work loop.
|
||||
|
||||
if (currentEventTransitionLane === NoLane) {
|
||||
// All transitions within the same event are assigned the same lane.
|
||||
currentEventTransitionLane = claimNextTransitionLane();
|
||||
|
@ -19559,38 +19728,26 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
// bug we're still investigating. Once the bug in Scheduler is fixed,
|
||||
// we can remove this, since we track expiration ourselves.
|
||||
|
||||
var exitStatus =
|
||||
shouldTimeSlice(root, lanes) && !didTimeout
|
||||
? renderRootConcurrent(root, lanes)
|
||||
: renderRootSync(root, lanes);
|
||||
var shouldTimeSlice =
|
||||
!includesBlockingLane(root, lanes) &&
|
||||
!includesExpiredLane(root, lanes) &&
|
||||
!didTimeout;
|
||||
var exitStatus = shouldTimeSlice
|
||||
? renderRootConcurrent(root, lanes)
|
||||
: renderRootSync(root, lanes);
|
||||
|
||||
if (exitStatus !== RootIncomplete) {
|
||||
if (exitStatus === RootErrored) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= RetryAfterError; // If an error occurred during hydration,
|
||||
// discard server response and fall back to client side render.
|
||||
|
||||
if (root.hydrate) {
|
||||
root.hydrate = false;
|
||||
|
||||
{
|
||||
errorHydratingContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
clearContainer(root.containerInfo);
|
||||
} // If something threw an error, try rendering one more time. We'll render
|
||||
// synchronously to block concurrent data mutations, and we'll includes
|
||||
// all pending updates are included. If it still fails after the second
|
||||
// attempt, we'll give up and commit the resulting tree.
|
||||
|
||||
// If something threw an error, try rendering one more time. We'll
|
||||
// render synchronously to block concurrent data mutations, and we'll
|
||||
// includes all pending updates are included. If it still fails after
|
||||
// the second attempt, we'll give up and commit the resulting tree.
|
||||
var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
|
||||
|
||||
if (errorRetryLanes !== NoLanes) {
|
||||
lanes = errorRetryLanes;
|
||||
exitStatus = renderRootSync(root, errorRetryLanes);
|
||||
exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
|
||||
}
|
||||
|
||||
executionContext = prevExecutionContext;
|
||||
}
|
||||
|
||||
if (exitStatus === RootFatalErrored) {
|
||||
|
@ -19599,10 +19756,43 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
ensureRootIsScheduled(root, now());
|
||||
throw fatalError;
|
||||
} // Check if this render may have yielded to a concurrent event, and if so,
|
||||
// confirm that any newly rendered stores are consistent.
|
||||
// TODO: It's possible that even a concurrent render may never have yielded
|
||||
// to the main thread, if it was fast enough, or if it expired. We could
|
||||
// skip the consistency check in that case, too.
|
||||
|
||||
var renderWasConcurrent = !includesBlockingLane(root, lanes);
|
||||
var finishedWork = root.current.alternate;
|
||||
|
||||
if (
|
||||
renderWasConcurrent &&
|
||||
!isRenderConsistentWithExternalStores(finishedWork)
|
||||
) {
|
||||
// A store was mutated in an interleaved event. Render again,
|
||||
// synchronously, to block further mutations.
|
||||
exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
|
||||
|
||||
if (exitStatus === RootErrored) {
|
||||
var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
|
||||
|
||||
if (_errorRetryLanes !== NoLanes) {
|
||||
lanes = _errorRetryLanes;
|
||||
exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
|
||||
// concurrent events.
|
||||
}
|
||||
}
|
||||
|
||||
if (exitStatus === RootFatalErrored) {
|
||||
var _fatalError = workInProgressRootFatalError;
|
||||
prepareFreshStack(root, NoLanes);
|
||||
markRootSuspended$1(root, lanes);
|
||||
ensureRootIsScheduled(root, now());
|
||||
throw _fatalError;
|
||||
}
|
||||
} // We now have a consistent tree. The next step is either to commit it,
|
||||
// or, if something suspended, wait to commit it after a timeout.
|
||||
|
||||
var finishedWork = root.current.alternate;
|
||||
root.finishedWork = finishedWork;
|
||||
root.finishedLanes = lanes;
|
||||
finishConcurrentRender(root, exitStatus, lanes);
|
||||
|
@ -19619,6 +19809,26 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= RetryAfterError; // If an error occurred during hydration, discard server response and fall
|
||||
// back to client side render.
|
||||
|
||||
if (root.hydrate) {
|
||||
root.hydrate = false;
|
||||
|
||||
{
|
||||
errorHydratingContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
clearContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
var exitStatus = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
function finishConcurrentRender(root, exitStatus, lanes) {
|
||||
switch (exitStatus) {
|
||||
case RootIncomplete:
|
||||
|
@ -19737,6 +19947,68 @@ function finishConcurrentRender(root, exitStatus, lanes) {
|
|||
}
|
||||
}
|
||||
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
// Search the rendered tree for external store reads, and check whether the
|
||||
// stores were mutated in a concurrent event. Intentionally using a iterative
|
||||
// loop instead of recursion so we can exit early.
|
||||
var node = finishedWork;
|
||||
|
||||
while (true) {
|
||||
if (node.flags & StoreConsistency) {
|
||||
var updateQueue = node.updateQueue;
|
||||
|
||||
if (updateQueue !== null) {
|
||||
var checks = updateQueue.stores;
|
||||
|
||||
if (checks !== null) {
|
||||
for (var i = 0; i < checks.length; i++) {
|
||||
var check = checks[i];
|
||||
var getSnapshot = check.getSnapshot;
|
||||
var renderedValue = check.value;
|
||||
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), renderedValue)) {
|
||||
// Found an inconsistent store.
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// If `getSnapshot` throws, return `false`. This will schedule
|
||||
// a re-render, and the error will be rethrown during render.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var child = node.child;
|
||||
|
||||
if (node.subtreeFlags & StoreConsistency && child !== null) {
|
||||
child.return = node;
|
||||
node = child;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node === finishedWork) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (node.sibling === null) {
|
||||
if (node.return === null || node.return === finishedWork) {
|
||||
return true;
|
||||
}
|
||||
|
||||
node = node.return;
|
||||
}
|
||||
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
} // Flow doesn't know this is unreachable, but eslint does
|
||||
// eslint-disable-next-line no-unreachable
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
// When suspending, we should always exclude lanes that were pinged or (more
|
||||
// rarely, since we try to avoid it) updated during the render phase.
|
||||
|
@ -20481,6 +20753,15 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
} // Read this again, since an effect might have updated it
|
||||
|
||||
remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
|
||||
// TODO: This is part of the `componentDidCatch` implementation. Its purpose
|
||||
// is to detect whether something might have called setState inside
|
||||
// `componentDidCatch`. The mechanism is known to be flawed because `setState`
|
||||
// inside `componentDidCatch` is itself flawed — that's why we recommend
|
||||
// `getDerivedStateFromError` instead. However, it could be improved by
|
||||
// checking if remainingLanes includes Sync work, instead of whether there's
|
||||
// any work remaining at all (which would also include stuff like Suspense
|
||||
// retries or transitions). It's been like this for a while, though, so fixing
|
||||
// it probably isn't that urgent.
|
||||
|
||||
if (remainingLanes === NoLanes) {
|
||||
// If there's no remaining work, we can clear the set of already failed
|
||||
|
@ -20494,22 +20775,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
if (includesSomeLane(remainingLanes, SyncLane)) {
|
||||
{
|
||||
markNestedUpdateScheduled();
|
||||
} // Count the number of times the root synchronously re-renders without
|
||||
// finishing. If there are too many, it indicates an infinite update loop.
|
||||
|
||||
if (root === rootWithNestedUpdates) {
|
||||
nestedUpdateCount++;
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
rootWithNestedUpdates = root;
|
||||
}
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
}
|
||||
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
|
||||
{
|
||||
|
@ -20540,6 +20805,24 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
root.tag !== LegacyRoot
|
||||
) {
|
||||
flushPassiveEffects();
|
||||
} // Read this again, since a passive effect might have updated it
|
||||
|
||||
remainingLanes = root.pendingLanes;
|
||||
|
||||
if (includesSomeLane(remainingLanes, SyncLane)) {
|
||||
{
|
||||
markNestedUpdateScheduled();
|
||||
} // Count the number of times the root synchronously re-renders without
|
||||
// finishing. If there are too many, it indicates an infinite update loop.
|
||||
|
||||
if (root === rootWithNestedUpdates) {
|
||||
nestedUpdateCount++;
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
rootWithNestedUpdates = root;
|
||||
}
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
} // If layout work was scheduled, flush it now.
|
||||
|
||||
flushSyncCallbacks();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<6fd8e2fc263f451cb6e073eae96b19f3>>
|
||||
* @generated SignedSource<<4538b6a9895755454ebc3d0f7b8f568e>>
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -931,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([
|
|||
"ReactNativeBridgeEventPlugin"
|
||||
]);
|
||||
recomputePluginOrdering();
|
||||
var injectedNamesToPlugins$jscomp$inline_221 = {
|
||||
var injectedNamesToPlugins$jscomp$inline_222 = {
|
||||
ResponderEventPlugin: ResponderEventPlugin,
|
||||
ReactNativeBridgeEventPlugin: {
|
||||
eventTypes: {},
|
||||
|
@ -966,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_221 = {
|
|||
}
|
||||
}
|
||||
},
|
||||
isOrderingDirty$jscomp$inline_222 = !1,
|
||||
pluginName$jscomp$inline_223;
|
||||
for (pluginName$jscomp$inline_223 in injectedNamesToPlugins$jscomp$inline_221)
|
||||
isOrderingDirty$jscomp$inline_223 = !1,
|
||||
pluginName$jscomp$inline_224;
|
||||
for (pluginName$jscomp$inline_224 in injectedNamesToPlugins$jscomp$inline_222)
|
||||
if (
|
||||
injectedNamesToPlugins$jscomp$inline_221.hasOwnProperty(
|
||||
pluginName$jscomp$inline_223
|
||||
injectedNamesToPlugins$jscomp$inline_222.hasOwnProperty(
|
||||
pluginName$jscomp$inline_224
|
||||
)
|
||||
) {
|
||||
var pluginModule$jscomp$inline_224 =
|
||||
injectedNamesToPlugins$jscomp$inline_221[pluginName$jscomp$inline_223];
|
||||
var pluginModule$jscomp$inline_225 =
|
||||
injectedNamesToPlugins$jscomp$inline_222[pluginName$jscomp$inline_224];
|
||||
if (
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_223) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_223] !==
|
||||
pluginModule$jscomp$inline_224
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_224) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_224] !==
|
||||
pluginModule$jscomp$inline_225
|
||||
) {
|
||||
if (namesToPlugins[pluginName$jscomp$inline_223])
|
||||
if (namesToPlugins[pluginName$jscomp$inline_224])
|
||||
throw Error(
|
||||
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
|
||||
pluginName$jscomp$inline_223 +
|
||||
pluginName$jscomp$inline_224 +
|
||||
"`."
|
||||
);
|
||||
namesToPlugins[
|
||||
pluginName$jscomp$inline_223
|
||||
] = pluginModule$jscomp$inline_224;
|
||||
isOrderingDirty$jscomp$inline_222 = !0;
|
||||
pluginName$jscomp$inline_224
|
||||
] = pluginModule$jscomp$inline_225;
|
||||
isOrderingDirty$jscomp$inline_223 = !0;
|
||||
}
|
||||
}
|
||||
isOrderingDirty$jscomp$inline_222 && recomputePluginOrdering();
|
||||
isOrderingDirty$jscomp$inline_223 && recomputePluginOrdering();
|
||||
function getInstanceFromInstance(instanceHandle) {
|
||||
return instanceHandle;
|
||||
}
|
||||
|
@ -1763,6 +1763,9 @@ function getLanesToRetrySynchronouslyOnError(root) {
|
|||
root = root.pendingLanes & -1073741825;
|
||||
return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0;
|
||||
}
|
||||
function includesBlockingLane(root, lanes) {
|
||||
return 0 !== (root.current.mode & 32) ? !1 : 0 !== (lanes & 30);
|
||||
}
|
||||
function createLaneMap(initial) {
|
||||
for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);
|
||||
return laneMap;
|
||||
|
@ -2085,7 +2088,11 @@ function invalidateContextProvider(workInProgress, type, didChange) {
|
|||
: pop(didPerformWorkStackCursor);
|
||||
push(didPerformWorkStackCursor, didChange);
|
||||
}
|
||||
var syncQueue = null,
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
||||
syncQueue = null,
|
||||
includesLegacySyncCallbacks = !1,
|
||||
isFlushingSyncQueue = !1;
|
||||
function flushSyncCallbacks() {
|
||||
|
@ -2114,10 +2121,6 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is;
|
||||
function shallowEqual(objA, objB) {
|
||||
if (objectIs(objA, objB)) return !0;
|
||||
if (
|
||||
|
@ -2402,7 +2405,7 @@ function processUpdateQueue(
|
|||
newState = workInProgress;
|
||||
break a;
|
||||
case 3:
|
||||
workInProgress.flags = (workInProgress.flags & -16385) | 128;
|
||||
workInProgress.flags = (workInProgress.flags & -32769) | 128;
|
||||
case 0:
|
||||
workInProgress = update.payload;
|
||||
updateLane =
|
||||
|
@ -3633,42 +3636,52 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
return useMutableSource(hook, source, getSnapshot, subscribe);
|
||||
}
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var hook = mountWorkInProgressHook(),
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = mountWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
hook.memoizedState = nextSnapshot;
|
||||
var inst = { value: nextSnapshot, getSnapshot: getSnapshot };
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
}
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
hook = ReactCurrentDispatcher$1.current;
|
||||
hook.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
hook.useEffect(
|
||||
function() {
|
||||
function handleStoreChange() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
handleStoreChange();
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= 8192;
|
||||
fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };
|
||||
getSnapshot = currentlyRenderingFiber$1.updateQueue;
|
||||
null === getSnapshot
|
||||
? ((getSnapshot = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = getSnapshot),
|
||||
(getSnapshot.stores = [fiber]))
|
||||
: ((renderedSnapshot = getSnapshot.stores),
|
||||
null === renderedSnapshot
|
||||
? (getSnapshot.stores = [fiber])
|
||||
: renderedSnapshot.push(fiber));
|
||||
}
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
return subscribe(function() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
});
|
||||
}
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
var latestGetSnapshot = inst.getSnapshot;
|
||||
inst = inst.value;
|
||||
|
@ -3703,7 +3716,7 @@ function pushEffect(tag, create, destroy, deps) {
|
|||
tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null };
|
||||
create = currentlyRenderingFiber$1.updateQueue;
|
||||
null === create
|
||||
? ((create = { lastEffect: null }),
|
||||
? ((create = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = create),
|
||||
(create.lastEffect = tag.next = tag))
|
||||
: ((destroy = create.lastEffect),
|
||||
|
@ -3744,13 +3757,16 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|||
hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps);
|
||||
}
|
||||
function mountEffect(create, deps) {
|
||||
return mountEffectImpl(1049600, 4, create, deps);
|
||||
return mountEffectImpl(2098176, 8, create, deps);
|
||||
}
|
||||
function updateEffect(create, deps) {
|
||||
return updateEffectImpl(1024, 4, create, deps);
|
||||
return updateEffectImpl(1024, 8, create, deps);
|
||||
}
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
}
|
||||
function updateLayoutEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
return updateEffectImpl(4, 4, create, deps);
|
||||
}
|
||||
function imperativeHandleEffect(create, ref) {
|
||||
if ("function" === typeof ref)
|
||||
|
@ -3774,7 +3790,7 @@ function updateImperativeHandle(ref, create, deps) {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return updateEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
|
@ -3892,6 +3908,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -3920,12 +3937,15 @@ var ContextOnlyDispatcher = {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return mountEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 4, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 2, create, deps);
|
||||
},
|
||||
useMemo: function(nextCreate, deps) {
|
||||
|
@ -4008,6 +4028,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: updateReducer,
|
||||
|
@ -4041,17 +4062,44 @@ var ContextOnlyDispatcher = {
|
|||
},
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: function(subscribe, getSnapshot) {
|
||||
var hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
objectIs(hook.memoizedState, nextSnapshot) ||
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot(),
|
||||
snapshotChanged = !objectIs(hook.memoizedState, nextSnapshot);
|
||||
snapshotChanged &&
|
||||
((hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0));
|
||||
return useSyncExternalStore(
|
||||
hook,
|
||||
hook.queue,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
);
|
||||
hook = hook.queue;
|
||||
updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [
|
||||
subscribe
|
||||
]);
|
||||
if (
|
||||
hook.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged ||
|
||||
(null !== workInProgressHook &&
|
||||
workInProgressHook.memoizedState.tag & 1)
|
||||
) {
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(
|
||||
null,
|
||||
fiber,
|
||||
hook,
|
||||
nextSnapshot,
|
||||
getSnapshot
|
||||
),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
return nextSnapshot;
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return updateReducer(basicStateReducer)[0];
|
||||
|
@ -4064,6 +4112,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: rerenderReducer,
|
||||
|
@ -4365,8 +4414,8 @@ function bubbleProperties(completedWork) {
|
|||
if (didBailout)
|
||||
for (var child$39 = completedWork.child; null !== child$39; )
|
||||
(newChildLanes |= child$39.lanes | child$39.childLanes),
|
||||
(subtreeFlags |= child$39.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= child$39.flags & 1835008),
|
||||
(subtreeFlags |= child$39.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= child$39.flags & 3670016),
|
||||
(child$39.return = completedWork),
|
||||
(child$39 = child$39.sibling);
|
||||
else
|
||||
|
@ -4584,7 +4633,7 @@ function completeWork(current, workInProgress, renderLanes) {
|
|||
for (newProps = workInProgress.child; null !== newProps; )
|
||||
(renderLanes = newProps),
|
||||
(type = current),
|
||||
(renderLanes.flags &= 1835010),
|
||||
(renderLanes.flags &= 3670018),
|
||||
(renderedTail = renderLanes.alternate),
|
||||
null === renderedTail
|
||||
? ((renderLanes.childLanes = 0),
|
||||
|
@ -4810,7 +4859,7 @@ function updateSimpleMemoComponent(
|
|||
current.ref === workInProgress.ref
|
||||
)
|
||||
if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes)))
|
||||
0 !== (current.flags & 32768) && (didReceiveUpdate = !0);
|
||||
0 !== (current.flags & 65536) && (didReceiveUpdate = !0);
|
||||
else
|
||||
return (
|
||||
(workInProgress.lanes = current.lanes),
|
||||
|
@ -5425,7 +5474,7 @@ function updateSuspenseFallbackChildren(
|
|||
primaryChildren
|
||||
))),
|
||||
(current.subtreeFlags =
|
||||
currentPrimaryChildFragment.subtreeFlags & 1835008));
|
||||
currentPrimaryChildFragment.subtreeFlags & 3670016));
|
||||
null !== currentFallbackChildFragment
|
||||
? (fallbackChildren = createWorkInProgress(
|
||||
currentFallbackChildFragment,
|
||||
|
@ -5653,8 +5702,8 @@ function unwindWork(workInProgress) {
|
|||
case 1:
|
||||
isContextProvider(workInProgress.type) && popContext();
|
||||
var flags = workInProgress.flags;
|
||||
return flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128), workInProgress)
|
||||
return flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128), workInProgress)
|
||||
: null;
|
||||
case 3:
|
||||
popHostContainer();
|
||||
|
@ -5666,7 +5715,7 @@ function unwindWork(workInProgress) {
|
|||
throw Error(
|
||||
"The root failed to unmount after an error. This is likely a bug in React. Please file an issue."
|
||||
);
|
||||
workInProgress.flags = (flags & -16385) | 128;
|
||||
workInProgress.flags = (flags & -32769) | 128;
|
||||
return workInProgress;
|
||||
case 5:
|
||||
return popHostContext(workInProgress), null;
|
||||
|
@ -5674,8 +5723,8 @@ function unwindWork(workInProgress) {
|
|||
return (
|
||||
pop(suspenseStackCursor),
|
||||
(flags = workInProgress.flags),
|
||||
flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128), workInProgress)
|
||||
flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128), workInProgress)
|
||||
: null
|
||||
);
|
||||
case 19:
|
||||
|
@ -5831,6 +5880,8 @@ function commitWork(current, finishedWork) {
|
|||
case 14:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListMount(3, finishedWork);
|
||||
commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
return;
|
||||
case 12:
|
||||
return;
|
||||
|
@ -5905,7 +5956,10 @@ function commitMutationEffects(root, firstChild) {
|
|||
var _effect = effect,
|
||||
destroy = _effect.destroy,
|
||||
tag = _effect.tag;
|
||||
if (void 0 !== destroy && 0 !== (tag & 2)) {
|
||||
if (
|
||||
void 0 !== destroy &&
|
||||
(0 !== (tag & 2) || 0 !== (tag & 4))
|
||||
) {
|
||||
_effect = current;
|
||||
var nearestMountedAncestor = root;
|
||||
try {
|
||||
|
@ -6038,7 +6092,7 @@ function commitLayoutEffects(finishedWork) {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListMount(3, firstChild);
|
||||
commitHookEffectListMount(5, firstChild);
|
||||
break;
|
||||
case 1:
|
||||
var instance = firstChild.stateNode;
|
||||
|
@ -6316,15 +6370,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
root === workInProgressRoot ? workInProgressRootRenderLanes : 0
|
||||
);
|
||||
if (0 === lanes) return null;
|
||||
var JSCompiler_inline_result =
|
||||
0 !== (lanes & root.expiredLanes)
|
||||
? !1
|
||||
: 0 !== (root.current.mode & 32)
|
||||
? !0
|
||||
: 0 === (lanes & 30);
|
||||
if (JSCompiler_inline_result && !didTimeout) {
|
||||
if (
|
||||
includesBlockingLane(root, lanes) ||
|
||||
0 !== (lanes & root.expiredLanes) ||
|
||||
didTimeout
|
||||
)
|
||||
didTimeout = renderRootSync(root, lanes);
|
||||
else {
|
||||
didTimeout = lanes;
|
||||
JSCompiler_inline_result = executionContext;
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 2;
|
||||
var prevDispatcher = pushDispatcher();
|
||||
if (
|
||||
|
@ -6343,30 +6397,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
while (1);
|
||||
resetContextDependencies();
|
||||
ReactCurrentDispatcher$2.current = prevDispatcher;
|
||||
executionContext = JSCompiler_inline_result;
|
||||
executionContext = prevExecutionContext;
|
||||
null !== workInProgress
|
||||
? (didTimeout = 0)
|
||||
: ((workInProgressRoot = null),
|
||||
(workInProgressRootRenderLanes = 0),
|
||||
(didTimeout = workInProgressRootExitStatus));
|
||||
} else didTimeout = renderRootSync(root, lanes);
|
||||
}
|
||||
if (0 !== didTimeout) {
|
||||
2 === didTimeout &&
|
||||
((JSCompiler_inline_result = executionContext),
|
||||
(executionContext |= 8),
|
||||
root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)),
|
||||
(prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = renderRootSync(root, prevDispatcher))),
|
||||
(executionContext = JSCompiler_inline_result));
|
||||
((prevExecutionContext = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevExecutionContext &&
|
||||
((lanes = prevExecutionContext),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevExecutionContext))));
|
||||
if (1 === didTimeout)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = root.current.alternate;
|
||||
prevDispatcher = !includesBlockingLane(root, lanes);
|
||||
prevExecutionContext = root.current.alternate;
|
||||
if (
|
||||
prevDispatcher &&
|
||||
!isRenderConsistentWithExternalStores(prevExecutionContext) &&
|
||||
((didTimeout = renderRootSync(root, lanes)),
|
||||
2 === didTimeout &&
|
||||
((prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevDispatcher)))),
|
||||
1 === didTimeout)
|
||||
)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = prevExecutionContext;
|
||||
root.finishedLanes = lanes;
|
||||
switch (didTimeout) {
|
||||
case 0:
|
||||
|
@ -6383,10 +6451,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
10 < didTimeout)
|
||||
) {
|
||||
if (0 !== getNextLanes(root, 0)) break;
|
||||
JSCompiler_inline_result = root.suspendedLanes;
|
||||
if ((JSCompiler_inline_result & lanes) !== lanes) {
|
||||
prevExecutionContext = root.suspendedLanes;
|
||||
if ((prevExecutionContext & lanes) !== lanes) {
|
||||
requestEventTime();
|
||||
root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result;
|
||||
root.pingedLanes |= root.suspendedLanes & prevExecutionContext;
|
||||
break;
|
||||
}
|
||||
root.timeoutHandle = scheduleTimeout(
|
||||
|
@ -6401,15 +6469,14 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
if ((lanes & 4194240) === lanes) break;
|
||||
didTimeout = root.eventTimes;
|
||||
for (JSCompiler_inline_result = -1; 0 < lanes; ) {
|
||||
for (prevExecutionContext = -1; 0 < lanes; ) {
|
||||
var index$4 = 31 - clz32(lanes);
|
||||
prevDispatcher = 1 << index$4;
|
||||
index$4 = didTimeout[index$4];
|
||||
index$4 > JSCompiler_inline_result &&
|
||||
(JSCompiler_inline_result = index$4);
|
||||
index$4 > prevExecutionContext && (prevExecutionContext = index$4);
|
||||
lanes &= ~prevDispatcher;
|
||||
}
|
||||
lanes = JSCompiler_inline_result;
|
||||
lanes = prevExecutionContext;
|
||||
lanes = now() - lanes;
|
||||
lanes =
|
||||
(120 > lanes
|
||||
|
@ -6446,6 +6513,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
? performConcurrentWorkOnRoot.bind(null, root)
|
||||
: null;
|
||||
}
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 8;
|
||||
root.hydrate && ((root.hydrate = !1), shim(root.containerInfo));
|
||||
root = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return root;
|
||||
}
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
for (var node = finishedWork; ; ) {
|
||||
if (node.flags & 8192) {
|
||||
var updateQueue = node.updateQueue;
|
||||
if (
|
||||
null !== updateQueue &&
|
||||
((updateQueue = updateQueue.stores), null !== updateQueue)
|
||||
)
|
||||
for (var i = 0; i < updateQueue.length; i++) {
|
||||
var check = updateQueue[i],
|
||||
getSnapshot = check.getSnapshot;
|
||||
check = check.value;
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), check)) return !1;
|
||||
} catch (error) {
|
||||
return !1;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateQueue = node.child;
|
||||
if (node.subtreeFlags & 8192 && null !== updateQueue)
|
||||
(updateQueue.return = node), (node = updateQueue);
|
||||
else {
|
||||
if (node === finishedWork) break;
|
||||
for (; null === node.sibling; ) {
|
||||
if (null === node.return || node.return === finishedWork) return !0;
|
||||
node = node.return;
|
||||
}
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
}
|
||||
}
|
||||
return !0;
|
||||
}
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
suspendedLanes &= ~workInProgressRootPingedLanes;
|
||||
suspendedLanes &= ~workInProgressRootUpdatedLanes;
|
||||
|
@ -6593,7 +6702,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
sourceFiber = erroredWork,
|
||||
value = thrownValue;
|
||||
thrownValue = workInProgressRootRenderLanes;
|
||||
sourceFiber.flags |= 8192;
|
||||
sourceFiber.flags |= 16384;
|
||||
if (
|
||||
null !== value &&
|
||||
"object" === typeof value &&
|
||||
|
@ -6644,8 +6753,8 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
workInProgress$30 !== returnFiber
|
||||
) {
|
||||
workInProgress$30.flags |= 128;
|
||||
sourceFiber.flags |= 32768;
|
||||
sourceFiber.flags &= -10053;
|
||||
sourceFiber.flags |= 65536;
|
||||
sourceFiber.flags &= -26437;
|
||||
if (
|
||||
enablePersistentOffscreenHostContainer &&
|
||||
null === workInProgress$30.alternate
|
||||
|
@ -6690,7 +6799,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
);
|
||||
wakeable.then(ping, ping);
|
||||
}
|
||||
workInProgress$30.flags |= 16384;
|
||||
workInProgress$30.flags |= 32768;
|
||||
workInProgress$30.lanes = thrownValue;
|
||||
break a;
|
||||
}
|
||||
|
@ -6709,7 +6818,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
switch (workInProgress$30.tag) {
|
||||
case 3:
|
||||
root = value;
|
||||
workInProgress$30.flags |= 16384;
|
||||
workInProgress$30.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$30.lanes |= thrownValue;
|
||||
var update$31 = createRootErrorUpdate(
|
||||
|
@ -6731,7 +6840,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
(null === legacyErrorBoundariesThatAlreadyFailed ||
|
||||
!legacyErrorBoundariesThatAlreadyFailed.has(instance))))
|
||||
) {
|
||||
workInProgress$30.flags |= 16384;
|
||||
workInProgress$30.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$30.lanes |= thrownValue;
|
||||
var update$34 = createClassErrorUpdate(
|
||||
|
@ -6805,7 +6914,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
do {
|
||||
var current = completedWork.alternate;
|
||||
unitOfWork = completedWork.return;
|
||||
if (0 === (completedWork.flags & 8192)) {
|
||||
if (0 === (completedWork.flags & 16384)) {
|
||||
if (
|
||||
((current = completeWork(current, completedWork, subtreeRenderLanes)),
|
||||
null !== current)
|
||||
|
@ -6816,12 +6925,12 @@ function completeUnitOfWork(unitOfWork) {
|
|||
} else {
|
||||
current = unwindWork(completedWork);
|
||||
if (null !== current) {
|
||||
current.flags &= 8191;
|
||||
current.flags &= 16383;
|
||||
workInProgress = current;
|
||||
return;
|
||||
}
|
||||
null !== unitOfWork &&
|
||||
((unitOfWork.flags |= 8192),
|
||||
((unitOfWork.flags |= 16384),
|
||||
(unitOfWork.subtreeFlags = 0),
|
||||
(unitOfWork.deletions = null));
|
||||
}
|
||||
|
@ -6900,11 +7009,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
(pendingPassiveEffectsLanes = lanes));
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null);
|
||||
0 !== (remainingLanes & 1)
|
||||
? root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))
|
||||
: (nestedUpdateCount = 0);
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
ensureRootIsScheduled(root, now());
|
||||
if (hasUncaughtError)
|
||||
|
@ -6915,6 +7019,12 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
0 !== (pendingPassiveEffectsLanes & 1) &&
|
||||
0 !== root.tag &&
|
||||
flushPassiveEffects();
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 !== (remainingLanes & 1)
|
||||
? root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))
|
||||
: (nestedUpdateCount = 0);
|
||||
flushSyncCallbacks();
|
||||
return null;
|
||||
}
|
||||
|
@ -6950,7 +7060,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(4, fiber$jscomp$0, fiber);
|
||||
commitHookEffectListUnmount(8, fiber$jscomp$0, fiber);
|
||||
}
|
||||
var child$jscomp$0 = fiber$jscomp$0.child;
|
||||
if (null !== child$jscomp$0)
|
||||
|
@ -7000,7 +7110,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(5, fiber, fiber.return);
|
||||
commitHookEffectListUnmount(9, fiber, fiber.return);
|
||||
}
|
||||
var sibling$jscomp$0 = fiber.sibling;
|
||||
if (null !== sibling$jscomp$0) {
|
||||
|
@ -7026,7 +7136,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListMount(5, deletions);
|
||||
commitHookEffectListMount(9, deletions);
|
||||
}
|
||||
} catch (error) {
|
||||
captureCommitPhaseError(deletions, deletions.return, error);
|
||||
|
@ -7172,7 +7282,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) {
|
|||
renderLanes
|
||||
)
|
||||
);
|
||||
didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1;
|
||||
didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1;
|
||||
}
|
||||
else didReceiveUpdate = !1;
|
||||
workInProgress.lanes = 0;
|
||||
|
@ -7638,7 +7748,7 @@ function createWorkInProgress(current, pendingProps) {
|
|||
(workInProgress.flags = 0),
|
||||
(workInProgress.subtreeFlags = 0),
|
||||
(workInProgress.deletions = null));
|
||||
workInProgress.flags = current.flags & 1835008;
|
||||
workInProgress.flags = current.flags & 3670016;
|
||||
workInProgress.childLanes = current.childLanes;
|
||||
workInProgress.lanes = current.lanes;
|
||||
workInProgress.child = current.child;
|
||||
|
@ -7995,10 +8105,10 @@ batchedUpdatesImpl = function(fn, a) {
|
|||
}
|
||||
};
|
||||
var roots = new Map(),
|
||||
devToolsConfig$jscomp$inline_953 = {
|
||||
devToolsConfig$jscomp$inline_950 = {
|
||||
findFiberByHostInstance: getInstanceFromInstance,
|
||||
bundleType: 0,
|
||||
version: "18.0.0-95d762e40-20210908",
|
||||
version: "18.0.0-e8feb11b6-20210915",
|
||||
rendererPackageName: "react-native-renderer",
|
||||
rendererConfig: {
|
||||
getInspectorDataForViewTag: function() {
|
||||
|
@ -8013,11 +8123,11 @@ var roots = new Map(),
|
|||
}.bind(null, findNodeHandle)
|
||||
}
|
||||
};
|
||||
var internals$jscomp$inline_1194 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_953.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_953.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_953.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_953.rendererConfig,
|
||||
var internals$jscomp$inline_1191 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_950.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_950.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_950.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_950.rendererConfig,
|
||||
overrideHookState: null,
|
||||
overrideHookStateDeletePath: null,
|
||||
overrideHookStateRenamePath: null,
|
||||
|
@ -8033,7 +8143,7 @@ var internals$jscomp$inline_1194 = {
|
|||
return null === fiber ? null : fiber.stateNode;
|
||||
},
|
||||
findFiberByHostInstance:
|
||||
devToolsConfig$jscomp$inline_953.findFiberByHostInstance ||
|
||||
devToolsConfig$jscomp$inline_950.findFiberByHostInstance ||
|
||||
emptyFindFiberByHostInstance,
|
||||
findHostInstancesForRefresh: null,
|
||||
scheduleRefresh: null,
|
||||
|
@ -8041,19 +8151,19 @@ var internals$jscomp$inline_1194 = {
|
|||
setRefreshHandler: null,
|
||||
getCurrentFiber: null,
|
||||
getIsStrictMode: null,
|
||||
reconcilerVersion: "18.0.0-95d762e40-20210908"
|
||||
reconcilerVersion: "18.0.0-e8feb11b6-20210915"
|
||||
};
|
||||
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
var hook$jscomp$inline_1195 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
var hook$jscomp$inline_1192 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
if (
|
||||
!hook$jscomp$inline_1195.isDisabled &&
|
||||
hook$jscomp$inline_1195.supportsFiber
|
||||
!hook$jscomp$inline_1192.isDisabled &&
|
||||
hook$jscomp$inline_1192.supportsFiber
|
||||
)
|
||||
try {
|
||||
(rendererID = hook$jscomp$inline_1195.inject(
|
||||
internals$jscomp$inline_1194
|
||||
(rendererID = hook$jscomp$inline_1192.inject(
|
||||
internals$jscomp$inline_1191
|
||||
)),
|
||||
(injectedHook = hook$jscomp$inline_1195);
|
||||
(injectedHook = hook$jscomp$inline_1192);
|
||||
} catch (err) {}
|
||||
}
|
||||
exports.createPortal = function(children, containerTag) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<a71955225824e1ab165c975361c725ed>>
|
||||
* @generated SignedSource<<9613963109b67072417dfb9843578a9d>>
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -931,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([
|
|||
"ReactNativeBridgeEventPlugin"
|
||||
]);
|
||||
recomputePluginOrdering();
|
||||
var injectedNamesToPlugins$jscomp$inline_229 = {
|
||||
var injectedNamesToPlugins$jscomp$inline_230 = {
|
||||
ResponderEventPlugin: ResponderEventPlugin,
|
||||
ReactNativeBridgeEventPlugin: {
|
||||
eventTypes: {},
|
||||
|
@ -966,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_229 = {
|
|||
}
|
||||
}
|
||||
},
|
||||
isOrderingDirty$jscomp$inline_230 = !1,
|
||||
pluginName$jscomp$inline_231;
|
||||
for (pluginName$jscomp$inline_231 in injectedNamesToPlugins$jscomp$inline_229)
|
||||
isOrderingDirty$jscomp$inline_231 = !1,
|
||||
pluginName$jscomp$inline_232;
|
||||
for (pluginName$jscomp$inline_232 in injectedNamesToPlugins$jscomp$inline_230)
|
||||
if (
|
||||
injectedNamesToPlugins$jscomp$inline_229.hasOwnProperty(
|
||||
pluginName$jscomp$inline_231
|
||||
injectedNamesToPlugins$jscomp$inline_230.hasOwnProperty(
|
||||
pluginName$jscomp$inline_232
|
||||
)
|
||||
) {
|
||||
var pluginModule$jscomp$inline_232 =
|
||||
injectedNamesToPlugins$jscomp$inline_229[pluginName$jscomp$inline_231];
|
||||
var pluginModule$jscomp$inline_233 =
|
||||
injectedNamesToPlugins$jscomp$inline_230[pluginName$jscomp$inline_232];
|
||||
if (
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_231) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_231] !==
|
||||
pluginModule$jscomp$inline_232
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_232) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_232] !==
|
||||
pluginModule$jscomp$inline_233
|
||||
) {
|
||||
if (namesToPlugins[pluginName$jscomp$inline_231])
|
||||
if (namesToPlugins[pluginName$jscomp$inline_232])
|
||||
throw Error(
|
||||
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
|
||||
pluginName$jscomp$inline_231 +
|
||||
pluginName$jscomp$inline_232 +
|
||||
"`."
|
||||
);
|
||||
namesToPlugins[
|
||||
pluginName$jscomp$inline_231
|
||||
] = pluginModule$jscomp$inline_232;
|
||||
isOrderingDirty$jscomp$inline_230 = !0;
|
||||
pluginName$jscomp$inline_232
|
||||
] = pluginModule$jscomp$inline_233;
|
||||
isOrderingDirty$jscomp$inline_231 = !0;
|
||||
}
|
||||
}
|
||||
isOrderingDirty$jscomp$inline_230 && recomputePluginOrdering();
|
||||
isOrderingDirty$jscomp$inline_231 && recomputePluginOrdering();
|
||||
function getInstanceFromInstance(instanceHandle) {
|
||||
return instanceHandle;
|
||||
}
|
||||
|
@ -1781,6 +1781,9 @@ function getLanesToRetrySynchronouslyOnError(root) {
|
|||
root = root.pendingLanes & -1073741825;
|
||||
return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0;
|
||||
}
|
||||
function includesBlockingLane(root, lanes) {
|
||||
return 0 !== (root.current.mode & 32) ? !1 : 0 !== (lanes & 30);
|
||||
}
|
||||
function createLaneMap(initial) {
|
||||
for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);
|
||||
return laneMap;
|
||||
|
@ -2133,7 +2136,11 @@ function invalidateContextProvider(workInProgress, type, didChange) {
|
|||
: pop(didPerformWorkStackCursor);
|
||||
push(didPerformWorkStackCursor, didChange);
|
||||
}
|
||||
var syncQueue = null,
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
||||
syncQueue = null,
|
||||
includesLegacySyncCallbacks = !1,
|
||||
isFlushingSyncQueue = !1;
|
||||
function flushSyncCallbacks() {
|
||||
|
@ -2162,10 +2169,6 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is;
|
||||
function shallowEqual(objA, objB) {
|
||||
if (objectIs(objA, objB)) return !0;
|
||||
if (
|
||||
|
@ -2450,7 +2453,7 @@ function processUpdateQueue(
|
|||
newState = workInProgress;
|
||||
break a;
|
||||
case 3:
|
||||
workInProgress.flags = (workInProgress.flags & -16385) | 128;
|
||||
workInProgress.flags = (workInProgress.flags & -32769) | 128;
|
||||
case 0:
|
||||
workInProgress = update.payload;
|
||||
updateLane =
|
||||
|
@ -3681,42 +3684,52 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
return useMutableSource(hook, source, getSnapshot, subscribe);
|
||||
}
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var hook = mountWorkInProgressHook(),
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = mountWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
hook.memoizedState = nextSnapshot;
|
||||
var inst = { value: nextSnapshot, getSnapshot: getSnapshot };
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
}
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
hook = ReactCurrentDispatcher$1.current;
|
||||
hook.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
hook.useEffect(
|
||||
function() {
|
||||
function handleStoreChange() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
handleStoreChange();
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= 8192;
|
||||
fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };
|
||||
getSnapshot = currentlyRenderingFiber$1.updateQueue;
|
||||
null === getSnapshot
|
||||
? ((getSnapshot = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = getSnapshot),
|
||||
(getSnapshot.stores = [fiber]))
|
||||
: ((renderedSnapshot = getSnapshot.stores),
|
||||
null === renderedSnapshot
|
||||
? (getSnapshot.stores = [fiber])
|
||||
: renderedSnapshot.push(fiber));
|
||||
}
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
return subscribe(function() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
});
|
||||
}
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
var latestGetSnapshot = inst.getSnapshot;
|
||||
inst = inst.value;
|
||||
|
@ -3751,7 +3764,7 @@ function pushEffect(tag, create, destroy, deps) {
|
|||
tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null };
|
||||
create = currentlyRenderingFiber$1.updateQueue;
|
||||
null === create
|
||||
? ((create = { lastEffect: null }),
|
||||
? ((create = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = create),
|
||||
(create.lastEffect = tag.next = tag))
|
||||
: ((destroy = create.lastEffect),
|
||||
|
@ -3792,13 +3805,16 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|||
hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps);
|
||||
}
|
||||
function mountEffect(create, deps) {
|
||||
return mountEffectImpl(1049600, 4, create, deps);
|
||||
return mountEffectImpl(2098176, 8, create, deps);
|
||||
}
|
||||
function updateEffect(create, deps) {
|
||||
return updateEffectImpl(1024, 4, create, deps);
|
||||
return updateEffectImpl(1024, 8, create, deps);
|
||||
}
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
}
|
||||
function updateLayoutEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
return updateEffectImpl(4, 4, create, deps);
|
||||
}
|
||||
function imperativeHandleEffect(create, ref) {
|
||||
if ("function" === typeof ref)
|
||||
|
@ -3822,7 +3838,7 @@ function updateImperativeHandle(ref, create, deps) {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return updateEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
|
@ -3940,6 +3956,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -3968,12 +3985,15 @@ var ContextOnlyDispatcher = {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return mountEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 4, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 2, create, deps);
|
||||
},
|
||||
useMemo: function(nextCreate, deps) {
|
||||
|
@ -4056,6 +4076,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: updateReducer,
|
||||
|
@ -4089,17 +4110,44 @@ var ContextOnlyDispatcher = {
|
|||
},
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: function(subscribe, getSnapshot) {
|
||||
var hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
objectIs(hook.memoizedState, nextSnapshot) ||
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot(),
|
||||
snapshotChanged = !objectIs(hook.memoizedState, nextSnapshot);
|
||||
snapshotChanged &&
|
||||
((hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0));
|
||||
return useSyncExternalStore(
|
||||
hook,
|
||||
hook.queue,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
);
|
||||
hook = hook.queue;
|
||||
updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [
|
||||
subscribe
|
||||
]);
|
||||
if (
|
||||
hook.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged ||
|
||||
(null !== workInProgressHook &&
|
||||
workInProgressHook.memoizedState.tag & 1)
|
||||
) {
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(
|
||||
null,
|
||||
fiber,
|
||||
hook,
|
||||
nextSnapshot,
|
||||
getSnapshot
|
||||
),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
return nextSnapshot;
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return updateReducer(basicStateReducer)[0];
|
||||
|
@ -4112,6 +4160,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: rerenderReducer,
|
||||
|
@ -4477,8 +4526,8 @@ function bubbleProperties(completedWork) {
|
|||
|
||||
)
|
||||
(newChildLanes |= child$43.lanes | child$43.childLanes),
|
||||
(subtreeFlags |= child$43.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= child$43.flags & 1835008),
|
||||
(subtreeFlags |= child$43.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= child$43.flags & 3670016),
|
||||
(treeBaseDuration$42 += child$43.treeBaseDuration),
|
||||
(child$43 = child$43.sibling);
|
||||
completedWork.treeBaseDuration = treeBaseDuration$42;
|
||||
|
@ -4490,8 +4539,8 @@ function bubbleProperties(completedWork) {
|
|||
)
|
||||
(newChildLanes |=
|
||||
treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes),
|
||||
(subtreeFlags |= treeBaseDuration$42.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= treeBaseDuration$42.flags & 1835008),
|
||||
(subtreeFlags |= treeBaseDuration$42.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= treeBaseDuration$42.flags & 3670016),
|
||||
(treeBaseDuration$42.return = completedWork),
|
||||
(treeBaseDuration$42 = treeBaseDuration$42.sibling);
|
||||
else if (0 !== (completedWork.mode & 2)) {
|
||||
|
@ -4737,7 +4786,7 @@ function completeWork(current, workInProgress, renderLanes) {
|
|||
for (newProps = workInProgress.child; null !== newProps; )
|
||||
(renderLanes = newProps),
|
||||
(renderedTail = current),
|
||||
(renderLanes.flags &= 1835010),
|
||||
(renderLanes.flags &= 3670018),
|
||||
(type = renderLanes.alternate),
|
||||
null === type
|
||||
? ((renderLanes.childLanes = 0),
|
||||
|
@ -4965,7 +5014,7 @@ function updateSimpleMemoComponent(
|
|||
current.ref === workInProgress.ref
|
||||
)
|
||||
if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes)))
|
||||
0 !== (current.flags & 32768) && (didReceiveUpdate = !0);
|
||||
0 !== (current.flags & 65536) && (didReceiveUpdate = !0);
|
||||
else
|
||||
return (
|
||||
(workInProgress.lanes = current.lanes),
|
||||
|
@ -5596,7 +5645,7 @@ function updateSuspenseFallbackChildren(
|
|||
primaryChildren
|
||||
))),
|
||||
(current.subtreeFlags =
|
||||
currentPrimaryChildFragment.subtreeFlags & 1835008));
|
||||
currentPrimaryChildFragment.subtreeFlags & 3670016));
|
||||
null !== currentFallbackChildFragment
|
||||
? (fallbackChildren = createWorkInProgress(
|
||||
currentFallbackChildFragment,
|
||||
|
@ -5832,8 +5881,8 @@ function unwindWork(workInProgress) {
|
|||
case 1:
|
||||
isContextProvider(workInProgress.type) && popContext();
|
||||
var flags = workInProgress.flags;
|
||||
return flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128),
|
||||
return flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128),
|
||||
0 !== (workInProgress.mode & 2) &&
|
||||
transferActualDuration(workInProgress),
|
||||
workInProgress)
|
||||
|
@ -5848,7 +5897,7 @@ function unwindWork(workInProgress) {
|
|||
throw Error(
|
||||
"The root failed to unmount after an error. This is likely a bug in React. Please file an issue."
|
||||
);
|
||||
workInProgress.flags = (flags & -16385) | 128;
|
||||
workInProgress.flags = (flags & -32769) | 128;
|
||||
return workInProgress;
|
||||
case 5:
|
||||
return popHostContext(workInProgress), null;
|
||||
|
@ -5856,8 +5905,8 @@ function unwindWork(workInProgress) {
|
|||
return (
|
||||
pop(suspenseStackCursor),
|
||||
(flags = workInProgress.flags),
|
||||
flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128),
|
||||
flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128),
|
||||
0 !== (workInProgress.mode & 2) &&
|
||||
transferActualDuration(workInProgress),
|
||||
workInProgress)
|
||||
|
@ -6023,14 +6072,16 @@ function commitWork(current, finishedWork) {
|
|||
case 11:
|
||||
case 14:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListMount(3, finishedWork);
|
||||
if (finishedWork.mode & 2)
|
||||
try {
|
||||
startLayoutEffectTimer(),
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(finishedWork);
|
||||
}
|
||||
else commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
else commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
return;
|
||||
case 12:
|
||||
return;
|
||||
|
@ -6120,8 +6171,8 @@ function commitMutationEffects(root, firstChild, committedLanes) {
|
|||
var _effect = effect,
|
||||
destroy = _effect.destroy,
|
||||
tag = _effect.tag;
|
||||
void 0 !== destroy &&
|
||||
0 !== (tag & 2) &&
|
||||
void 0 === destroy ||
|
||||
(0 === (tag & 2) && 0 === (tag & 4)) ||
|
||||
(current.mode & 2
|
||||
? (startLayoutEffectTimer(),
|
||||
safelyCallDestroy(current, root, destroy),
|
||||
|
@ -6271,11 +6322,11 @@ function commitLayoutEffects(finishedWork, root, committedLanes) {
|
|||
if (committedLanes.mode & 2)
|
||||
try {
|
||||
startLayoutEffectTimer(),
|
||||
commitHookEffectListMount(3, committedLanes);
|
||||
commitHookEffectListMount(5, committedLanes);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(committedLanes);
|
||||
}
|
||||
else commitHookEffectListMount(3, committedLanes);
|
||||
else commitHookEffectListMount(5, committedLanes);
|
||||
break;
|
||||
case 1:
|
||||
var instance = committedLanes.stateNode;
|
||||
|
@ -6629,15 +6680,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
root === workInProgressRoot ? workInProgressRootRenderLanes : 0
|
||||
);
|
||||
if (0 === lanes) return null;
|
||||
var JSCompiler_inline_result =
|
||||
0 !== (lanes & root.expiredLanes)
|
||||
? !1
|
||||
: 0 !== (root.current.mode & 32)
|
||||
? !0
|
||||
: 0 === (lanes & 30);
|
||||
if (JSCompiler_inline_result && !didTimeout) {
|
||||
if (
|
||||
includesBlockingLane(root, lanes) ||
|
||||
0 !== (lanes & root.expiredLanes) ||
|
||||
didTimeout
|
||||
)
|
||||
didTimeout = renderRootSync(root, lanes);
|
||||
else {
|
||||
didTimeout = lanes;
|
||||
JSCompiler_inline_result = executionContext;
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 2;
|
||||
var prevDispatcher = pushDispatcher();
|
||||
if (
|
||||
|
@ -6664,30 +6715,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
while (1);
|
||||
resetContextDependencies();
|
||||
ReactCurrentDispatcher$2.current = prevDispatcher;
|
||||
executionContext = JSCompiler_inline_result;
|
||||
executionContext = prevExecutionContext;
|
||||
null !== workInProgress
|
||||
? (didTimeout = 0)
|
||||
: ((workInProgressRoot = null),
|
||||
(workInProgressRootRenderLanes = 0),
|
||||
(didTimeout = workInProgressRootExitStatus));
|
||||
} else didTimeout = renderRootSync(root, lanes);
|
||||
}
|
||||
if (0 !== didTimeout) {
|
||||
2 === didTimeout &&
|
||||
((JSCompiler_inline_result = executionContext),
|
||||
(executionContext |= 8),
|
||||
root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)),
|
||||
(prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = renderRootSync(root, prevDispatcher))),
|
||||
(executionContext = JSCompiler_inline_result));
|
||||
((prevExecutionContext = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevExecutionContext &&
|
||||
((lanes = prevExecutionContext),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevExecutionContext))));
|
||||
if (1 === didTimeout)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = root.current.alternate;
|
||||
prevDispatcher = !includesBlockingLane(root, lanes);
|
||||
prevExecutionContext = root.current.alternate;
|
||||
if (
|
||||
prevDispatcher &&
|
||||
!isRenderConsistentWithExternalStores(prevExecutionContext) &&
|
||||
((didTimeout = renderRootSync(root, lanes)),
|
||||
2 === didTimeout &&
|
||||
((prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevDispatcher)))),
|
||||
1 === didTimeout)
|
||||
)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = prevExecutionContext;
|
||||
root.finishedLanes = lanes;
|
||||
switch (didTimeout) {
|
||||
case 0:
|
||||
|
@ -6704,10 +6769,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
10 < didTimeout)
|
||||
) {
|
||||
if (0 !== getNextLanes(root, 0)) break;
|
||||
JSCompiler_inline_result = root.suspendedLanes;
|
||||
if ((JSCompiler_inline_result & lanes) !== lanes) {
|
||||
prevExecutionContext = root.suspendedLanes;
|
||||
if ((prevExecutionContext & lanes) !== lanes) {
|
||||
requestEventTime();
|
||||
root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result;
|
||||
root.pingedLanes |= root.suspendedLanes & prevExecutionContext;
|
||||
break;
|
||||
}
|
||||
root.timeoutHandle = scheduleTimeout(
|
||||
|
@ -6722,14 +6787,14 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
if ((lanes & 4194240) === lanes) break;
|
||||
didTimeout = root.eventTimes;
|
||||
for (JSCompiler_inline_result = -1; 0 < lanes; )
|
||||
for (prevExecutionContext = -1; 0 < lanes; )
|
||||
(memoizedUpdaters = 31 - clz32(lanes)),
|
||||
(prevDispatcher = 1 << memoizedUpdaters),
|
||||
(memoizedUpdaters = didTimeout[memoizedUpdaters]),
|
||||
memoizedUpdaters > JSCompiler_inline_result &&
|
||||
(JSCompiler_inline_result = memoizedUpdaters),
|
||||
memoizedUpdaters > prevExecutionContext &&
|
||||
(prevExecutionContext = memoizedUpdaters),
|
||||
(lanes &= ~prevDispatcher);
|
||||
lanes = JSCompiler_inline_result;
|
||||
lanes = prevExecutionContext;
|
||||
lanes = now() - lanes;
|
||||
lanes =
|
||||
(120 > lanes
|
||||
|
@ -6766,6 +6831,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
? performConcurrentWorkOnRoot.bind(null, root)
|
||||
: null;
|
||||
}
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 8;
|
||||
root.hydrate && ((root.hydrate = !1), shim(root.containerInfo));
|
||||
root = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return root;
|
||||
}
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
for (var node = finishedWork; ; ) {
|
||||
if (node.flags & 8192) {
|
||||
var updateQueue = node.updateQueue;
|
||||
if (
|
||||
null !== updateQueue &&
|
||||
((updateQueue = updateQueue.stores), null !== updateQueue)
|
||||
)
|
||||
for (var i = 0; i < updateQueue.length; i++) {
|
||||
var check = updateQueue[i],
|
||||
getSnapshot = check.getSnapshot;
|
||||
check = check.value;
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), check)) return !1;
|
||||
} catch (error) {
|
||||
return !1;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateQueue = node.child;
|
||||
if (node.subtreeFlags & 8192 && null !== updateQueue)
|
||||
(updateQueue.return = node), (node = updateQueue);
|
||||
else {
|
||||
if (node === finishedWork) break;
|
||||
for (; null === node.sibling; ) {
|
||||
if (null === node.return || node.return === finishedWork) return !0;
|
||||
node = node.return;
|
||||
}
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
}
|
||||
}
|
||||
return !0;
|
||||
}
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
suspendedLanes &= ~workInProgressRootPingedLanes;
|
||||
suspendedLanes &= ~workInProgressRootUpdatedLanes;
|
||||
|
@ -6917,7 +7024,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
sourceFiber = erroredWork,
|
||||
value = thrownValue;
|
||||
thrownValue = workInProgressRootRenderLanes;
|
||||
sourceFiber.flags |= 8192;
|
||||
sourceFiber.flags |= 16384;
|
||||
isDevToolsPresent && restorePendingUpdaters(root, thrownValue);
|
||||
if (
|
||||
null !== value &&
|
||||
|
@ -6969,8 +7076,8 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
workInProgress$32 !== returnFiber
|
||||
) {
|
||||
workInProgress$32.flags |= 128;
|
||||
sourceFiber.flags |= 32768;
|
||||
sourceFiber.flags &= -10053;
|
||||
sourceFiber.flags |= 65536;
|
||||
sourceFiber.flags &= -26437;
|
||||
if (
|
||||
enablePersistentOffscreenHostContainer &&
|
||||
null === workInProgress$32.alternate
|
||||
|
@ -7016,7 +7123,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
isDevToolsPresent && restorePendingUpdaters(root, sourceFiber);
|
||||
wakeable.then(ping, ping);
|
||||
}
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
workInProgress$32.lanes = thrownValue;
|
||||
break a;
|
||||
}
|
||||
|
@ -7035,7 +7142,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
switch (workInProgress$32.tag) {
|
||||
case 3:
|
||||
root = value;
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$32.lanes |= thrownValue;
|
||||
var update$33 = createRootErrorUpdate(
|
||||
|
@ -7057,7 +7164,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
(null === legacyErrorBoundariesThatAlreadyFailed ||
|
||||
!legacyErrorBoundariesThatAlreadyFailed.has(instance))))
|
||||
) {
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$32.lanes |= thrownValue;
|
||||
var update$36 = createClassErrorUpdate(
|
||||
|
@ -7147,7 +7254,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
do {
|
||||
var current = completedWork.alternate;
|
||||
unitOfWork = completedWork.return;
|
||||
if (0 === (completedWork.flags & 8192)) {
|
||||
if (0 === (completedWork.flags & 16384)) {
|
||||
if (0 === (completedWork.mode & 2))
|
||||
current = completeWork(current, completedWork, subtreeRenderLanes);
|
||||
else {
|
||||
|
@ -7164,7 +7271,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
} else {
|
||||
current = unwindWork(completedWork);
|
||||
if (null !== current) {
|
||||
current.flags &= 8191;
|
||||
current.flags &= 16383;
|
||||
workInProgress = current;
|
||||
return;
|
||||
}
|
||||
|
@ -7176,7 +7283,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
completedWork.actualDuration = current;
|
||||
}
|
||||
null !== unitOfWork &&
|
||||
((unitOfWork.flags |= 8192),
|
||||
((unitOfWork.flags |= 16384),
|
||||
(unitOfWork.subtreeFlags = 0),
|
||||
(unitOfWork.deletions = null));
|
||||
}
|
||||
|
@ -7256,12 +7363,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
(pendingPassiveEffectsLanes = lanes));
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null);
|
||||
0 !== (remainingLanes & 1)
|
||||
? ((nestedUpdateScheduled = !0),
|
||||
root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)))
|
||||
: (nestedUpdateCount = 0);
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
isDevToolsPresent && root.memoizedUpdaters.clear();
|
||||
ensureRootIsScheduled(root, now());
|
||||
|
@ -7273,6 +7374,13 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
0 !== (pendingPassiveEffectsLanes & 1) &&
|
||||
0 !== root.tag &&
|
||||
flushPassiveEffects();
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 !== (remainingLanes & 1)
|
||||
? ((nestedUpdateScheduled = !0),
|
||||
root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)))
|
||||
: (nestedUpdateCount = 0);
|
||||
flushSyncCallbacks();
|
||||
return null;
|
||||
}
|
||||
|
@ -7311,9 +7419,9 @@ function flushPassiveEffects() {
|
|||
case 15:
|
||||
current.mode & 2
|
||||
? ((passiveEffectStartTime = now$1()),
|
||||
commitHookEffectListUnmount(4, current, fiber),
|
||||
commitHookEffectListUnmount(8, current, fiber),
|
||||
recordPassiveEffectDuration(current))
|
||||
: commitHookEffectListUnmount(4, current, fiber);
|
||||
: commitHookEffectListUnmount(8, current, fiber);
|
||||
}
|
||||
var child$jscomp$0 = fiber$jscomp$0.child;
|
||||
if (null !== child$jscomp$0)
|
||||
|
@ -7365,9 +7473,9 @@ function flushPassiveEffects() {
|
|||
case 15:
|
||||
i.mode & 2
|
||||
? ((passiveEffectStartTime = now$1()),
|
||||
commitHookEffectListUnmount(5, i, i.return),
|
||||
commitHookEffectListUnmount(9, i, i.return),
|
||||
recordPassiveEffectDuration(i))
|
||||
: commitHookEffectListUnmount(5, i, i.return);
|
||||
: commitHookEffectListUnmount(9, i, i.return);
|
||||
}
|
||||
var sibling$jscomp$0 = fiber.sibling;
|
||||
if (null !== sibling$jscomp$0) {
|
||||
|
@ -7396,11 +7504,11 @@ function flushPassiveEffects() {
|
|||
if (fiberToDelete.mode & 2) {
|
||||
passiveEffectStartTime = now$1();
|
||||
try {
|
||||
commitHookEffectListMount(5, fiberToDelete);
|
||||
commitHookEffectListMount(9, fiberToDelete);
|
||||
} finally {
|
||||
recordPassiveEffectDuration(fiberToDelete);
|
||||
}
|
||||
} else commitHookEffectListMount(5, fiberToDelete);
|
||||
} else commitHookEffectListMount(9, fiberToDelete);
|
||||
}
|
||||
} catch (error) {
|
||||
captureCommitPhaseError(deletions, deletions.return, error);
|
||||
|
@ -7595,7 +7703,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) {
|
|||
renderLanes
|
||||
)
|
||||
);
|
||||
didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1;
|
||||
didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1;
|
||||
}
|
||||
else didReceiveUpdate = !1;
|
||||
workInProgress.lanes = 0;
|
||||
|
@ -8076,7 +8184,7 @@ function createWorkInProgress(current, pendingProps) {
|
|||
(workInProgress.deletions = null),
|
||||
(workInProgress.actualDuration = 0),
|
||||
(workInProgress.actualStartTime = -1));
|
||||
workInProgress.flags = current.flags & 1835008;
|
||||
workInProgress.flags = current.flags & 3670016;
|
||||
workInProgress.childLanes = current.childLanes;
|
||||
workInProgress.lanes = current.lanes;
|
||||
workInProgress.child = current.child;
|
||||
|
@ -8440,10 +8548,10 @@ batchedUpdatesImpl = function(fn, a) {
|
|||
}
|
||||
};
|
||||
var roots = new Map(),
|
||||
devToolsConfig$jscomp$inline_983 = {
|
||||
devToolsConfig$jscomp$inline_980 = {
|
||||
findFiberByHostInstance: getInstanceFromInstance,
|
||||
bundleType: 0,
|
||||
version: "18.0.0-95d762e40-20210908",
|
||||
version: "18.0.0-e8feb11b6-20210915",
|
||||
rendererPackageName: "react-native-renderer",
|
||||
rendererConfig: {
|
||||
getInspectorDataForViewTag: function() {
|
||||
|
@ -8458,11 +8566,11 @@ var roots = new Map(),
|
|||
}.bind(null, findNodeHandle)
|
||||
}
|
||||
};
|
||||
var internals$jscomp$inline_1244 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_983.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_983.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_983.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_983.rendererConfig,
|
||||
var internals$jscomp$inline_1241 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_980.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_980.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_980.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_980.rendererConfig,
|
||||
overrideHookState: null,
|
||||
overrideHookStateDeletePath: null,
|
||||
overrideHookStateRenamePath: null,
|
||||
|
@ -8478,7 +8586,7 @@ var internals$jscomp$inline_1244 = {
|
|||
return null === fiber ? null : fiber.stateNode;
|
||||
},
|
||||
findFiberByHostInstance:
|
||||
devToolsConfig$jscomp$inline_983.findFiberByHostInstance ||
|
||||
devToolsConfig$jscomp$inline_980.findFiberByHostInstance ||
|
||||
emptyFindFiberByHostInstance,
|
||||
findHostInstancesForRefresh: null,
|
||||
scheduleRefresh: null,
|
||||
|
@ -8486,19 +8594,19 @@ var internals$jscomp$inline_1244 = {
|
|||
setRefreshHandler: null,
|
||||
getCurrentFiber: null,
|
||||
getIsStrictMode: null,
|
||||
reconcilerVersion: "18.0.0-95d762e40-20210908"
|
||||
reconcilerVersion: "18.0.0-e8feb11b6-20210915"
|
||||
};
|
||||
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
var hook$jscomp$inline_1245 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
var hook$jscomp$inline_1242 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
if (
|
||||
!hook$jscomp$inline_1245.isDisabled &&
|
||||
hook$jscomp$inline_1245.supportsFiber
|
||||
!hook$jscomp$inline_1242.isDisabled &&
|
||||
hook$jscomp$inline_1242.supportsFiber
|
||||
)
|
||||
try {
|
||||
(rendererID = hook$jscomp$inline_1245.inject(
|
||||
internals$jscomp$inline_1244
|
||||
(rendererID = hook$jscomp$inline_1242.inject(
|
||||
internals$jscomp$inline_1241
|
||||
)),
|
||||
(injectedHook = hook$jscomp$inline_1245);
|
||||
(injectedHook = hook$jscomp$inline_1242);
|
||||
} catch (err) {}
|
||||
}
|
||||
exports.createPortal = function(children, containerTag) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<0aa534c810fde3c5289b4c849e474d9e>>
|
||||
* @generated SignedSource<<f868e099a07acdc3cfb6e5c0b1efcb0d>>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -3140,6 +3140,7 @@ var enableProfilerTimer = true;
|
|||
var enableProfilerCommitHooks = true;
|
||||
var enableLazyElements = false;
|
||||
var warnAboutStringRefs = false;
|
||||
var warnOnSubscriptionInsideStartTransition = false;
|
||||
var enableNewReconciler = false;
|
||||
var enableLazyContextPropagation = false;
|
||||
|
||||
|
@ -3190,21 +3191,25 @@ var HydratingAndUpdate =
|
|||
var Visibility =
|
||||
/* */
|
||||
4096;
|
||||
var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit)
|
||||
var StoreConsistency =
|
||||
/* */
|
||||
8192;
|
||||
var LifecycleEffectMask =
|
||||
Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
|
||||
|
||||
var HostEffectMask =
|
||||
/* */
|
||||
8191; // These are not really side effects, but we still reuse this field.
|
||||
16383; // These are not really side effects, but we still reuse this field.
|
||||
|
||||
var Incomplete =
|
||||
/* */
|
||||
8192;
|
||||
16384;
|
||||
var ShouldCapture =
|
||||
/* */
|
||||
16384;
|
||||
32768;
|
||||
var ForceUpdateForLegacySuspense =
|
||||
/* */
|
||||
32768;
|
||||
65536;
|
||||
// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
|
||||
// This enables us to defer more work in the unmount case,
|
||||
// since we can defer traversing the tree during layout to look for Passive effects,
|
||||
|
@ -3212,22 +3217,22 @@ var ForceUpdateForLegacySuspense =
|
|||
|
||||
var RefStatic =
|
||||
/* */
|
||||
262144;
|
||||
524288;
|
||||
var LayoutStatic =
|
||||
/* */
|
||||
524288;
|
||||
1048576;
|
||||
var PassiveStatic =
|
||||
/* */
|
||||
1048576; // These flags allow us to traverse to fibers that have effects on mount
|
||||
2097152; // These flags allow us to traverse to fibers that have effects on mount
|
||||
// without traversing the entire tree after every commit for
|
||||
// double invoking
|
||||
|
||||
var MountLayoutDev =
|
||||
/* */
|
||||
2097152;
|
||||
4194304;
|
||||
var MountPassiveDev =
|
||||
/* */
|
||||
4194304; // Groups of flags that are used in the commit phase to skip over trees that
|
||||
8388608; // Groups of flags that are used in the commit phase to skip over trees that
|
||||
// don't contain effects, by checking subtreeFlags.
|
||||
|
||||
var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
|
||||
|
@ -4742,16 +4747,10 @@ function includesOnlyRetries(lanes) {
|
|||
function includesOnlyTransitions(lanes) {
|
||||
return (lanes & TransitionLanes) === lanes;
|
||||
}
|
||||
function shouldTimeSlice(root, lanes) {
|
||||
if ((lanes & root.expiredLanes) !== NoLanes) {
|
||||
// At least one of these lanes expired. To prevent additional starvation,
|
||||
// finish rendering without yielding execution.
|
||||
return false;
|
||||
}
|
||||
|
||||
function includesBlockingLane(root, lanes) {
|
||||
if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode) {
|
||||
// Concurrent updates by default always use time slicing.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var SyncDefaultLanes =
|
||||
|
@ -4759,7 +4758,12 @@ function shouldTimeSlice(root, lanes) {
|
|||
InputContinuousLane |
|
||||
DefaultHydrationLane |
|
||||
DefaultLane;
|
||||
return (lanes & SyncDefaultLanes) === NoLanes;
|
||||
return (lanes & SyncDefaultLanes) !== NoLanes;
|
||||
}
|
||||
function includesExpiredLane(root, lanes) {
|
||||
// This is a separate check from includesBlockingLane because a lane can
|
||||
// expire after a render has already started.
|
||||
return (lanes & root.expiredLanes) !== NoLanes;
|
||||
}
|
||||
function isTransitionLane(lane) {
|
||||
return (lane & TransitionLanes) !== 0;
|
||||
|
@ -6069,6 +6073,18 @@ function findCurrentUnmaskedContext(fiber) {
|
|||
var LegacyRoot = 0;
|
||||
var ConcurrentRoot = 1;
|
||||
|
||||
/**
|
||||
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
||||
*/
|
||||
function is(x, y) {
|
||||
return (
|
||||
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
|
||||
);
|
||||
}
|
||||
|
||||
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
||||
|
||||
var syncQueue = null;
|
||||
var includesLegacySyncCallbacks = false;
|
||||
var isFlushingSyncQueue = false;
|
||||
|
@ -6138,7 +6154,7 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
|
||||
var ReactVersion = "18.0.0-95d762e40-20210908";
|
||||
var ReactVersion = "18.0.0-e8feb11b6-20210915";
|
||||
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
var NoTransition = 0;
|
||||
|
@ -6146,18 +6162,6 @@ function requestCurrentTransition() {
|
|||
return ReactCurrentBatchConfig.transition;
|
||||
}
|
||||
|
||||
/**
|
||||
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
||||
*/
|
||||
function is(x, y) {
|
||||
return (
|
||||
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
|
||||
);
|
||||
}
|
||||
|
||||
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
||||
|
||||
/**
|
||||
* Performs equality by iterating through keys on an object and returning false
|
||||
* when any key has values which are not strictly equal between the arguments.
|
||||
|
@ -10092,19 +10096,22 @@ function findFirstSuspended(row) {
|
|||
}
|
||||
|
||||
var NoFlags$1 =
|
||||
/* */
|
||||
/* */
|
||||
0; // Represents whether effect should fire.
|
||||
|
||||
var HasEffect =
|
||||
/* */
|
||||
1; // Represents the phase in which the effect (not the clean-up) fires.
|
||||
|
||||
var Insertion =
|
||||
/* */
|
||||
2;
|
||||
var Layout =
|
||||
/* */
|
||||
2;
|
||||
4;
|
||||
var Passive$1 =
|
||||
/* */
|
||||
4;
|
||||
8;
|
||||
|
||||
var isHydrating = false;
|
||||
|
||||
|
@ -10667,7 +10674,8 @@ function updateWorkInProgressHook() {
|
|||
|
||||
function createFunctionComponentUpdateQueue() {
|
||||
return {
|
||||
lastEffect: null
|
||||
lastEffect: null,
|
||||
stores: null
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11196,6 +11204,7 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
}
|
||||
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var hook = mountWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
|
||||
// normal rules of React, and only works because store updates are
|
||||
// always synchronous.
|
||||
|
@ -11219,11 +11228,43 @@ function mountSyncExternalStore(subscribe, getSnapshot) {
|
|||
value: nextSnapshot,
|
||||
getSnapshot: getSnapshot
|
||||
};
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
hook.queue = inst; // Schedule an effect to subscribe to the store.
|
||||
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
|
||||
// this whenever subscribe, getSnapshot, or value changes. Because there's no
|
||||
// clean-up function, and we track the deps correctly, we can call pushEffect
|
||||
// directly, without storing any additional state. For the same reason, we
|
||||
// don't need to set a static flag, either.
|
||||
// TODO: We can move this to the passive phase once we add a pre-commit
|
||||
// consistency check. See the next comment.
|
||||
|
||||
fiber.flags |= Passive;
|
||||
pushEffect(
|
||||
HasEffect | Passive$1,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
undefined,
|
||||
null
|
||||
); // Unless we're rendering a blocking lane, schedule a consistency check. Right
|
||||
// before committing, we will walk the tree and check if any of the stores
|
||||
// were mutated.
|
||||
|
||||
var root = getWorkInProgressRoot();
|
||||
|
||||
if (!(root !== null)) {
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
}
|
||||
|
||||
if (!includesBlockingLane(root, renderLanes)) {
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function updateSyncExternalStore(subscribe, getSnapshot) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
|
||||
// normal rules of React, and only works because store updates are
|
||||
// always synchronous.
|
||||
|
@ -11243,69 +11284,102 @@ function updateSyncExternalStore(subscribe, getSnapshot) {
|
|||
}
|
||||
|
||||
var prevSnapshot = hook.memoizedState;
|
||||
var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
|
||||
|
||||
if (!objectIs(prevSnapshot, nextSnapshot)) {
|
||||
if (snapshotChanged) {
|
||||
hook.memoizedState = nextSnapshot;
|
||||
markWorkInProgressReceivedUpdate();
|
||||
}
|
||||
|
||||
var inst = hook.queue;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [
|
||||
subscribe
|
||||
]); // Whenever getSnapshot or subscribe changes, we need to check in the
|
||||
// commit phase if there was an interleaved mutation. In concurrent mode
|
||||
// this can happen all the time, but even in synchronous mode, an earlier
|
||||
// effect may have mutated the store.
|
||||
|
||||
if (
|
||||
inst.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
|
||||
// checking whether we scheduled a subscription effect above.
|
||||
(workInProgressHook !== null &&
|
||||
workInProgressHook.memoizedState.tag & HasEffect)
|
||||
) {
|
||||
fiber.flags |= Passive;
|
||||
pushEffect(
|
||||
HasEffect | Passive$1,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
undefined,
|
||||
null
|
||||
); // Unless we're rendering a blocking lane, schedule a consistency check.
|
||||
// Right before committing, we will walk the tree and check if any of the
|
||||
// stores were mutated.
|
||||
|
||||
var root = getWorkInProgressRoot();
|
||||
|
||||
if (!(root !== null)) {
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
}
|
||||
|
||||
if (!includesBlockingLane(root, renderLanes)) {
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
return nextSnapshot;
|
||||
}
|
||||
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
var dispatcher = ReactCurrentDispatcher$1.current; // Track the latest getSnapshot function with a ref. This needs to be updated
|
||||
// in the layout phase so we can access it during the tearing check that
|
||||
// happens on subscribe.
|
||||
// TODO: Circumvent SSR warning
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= StoreConsistency;
|
||||
var check = {
|
||||
getSnapshot: getSnapshot,
|
||||
value: renderedSnapshot
|
||||
};
|
||||
var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
|
||||
|
||||
dispatcher.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot; // Whenever getSnapshot or subscribe changes, we need to check in the
|
||||
// commit phase if there was an interleaved mutation. In concurrent mode
|
||||
// this can happen all the time, but even in synchronous mode, an earlier
|
||||
// effect may have mutated the store.
|
||||
// TODO: Move the tearing checks to an earlier, pre-commit phase so that the
|
||||
// layout effects always observe a consistent tree.
|
||||
if (componentUpdateQueue === null) {
|
||||
componentUpdateQueue = createFunctionComponentUpdateQueue();
|
||||
currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
|
||||
componentUpdateQueue.stores = [check];
|
||||
} else {
|
||||
var stores = componentUpdateQueue.stores;
|
||||
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
dispatcher.useEffect(
|
||||
function() {
|
||||
var handleStoreChange = function() {
|
||||
// TODO: Because there is no cross-renderer API for batching updates, it's
|
||||
// up to the consumer of this library to wrap their subscription event
|
||||
// with unstable_batchedUpdates. Should we try to detect when this isn't
|
||||
// the case and print a warning in development?
|
||||
// The store changed. Check if the snapshot changed since the last time we
|
||||
// read from the store.
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}; // Check for changes right before subscribing. Subsequent changes will be
|
||||
// detected in the subscription handler.
|
||||
if (stores === null) {
|
||||
componentUpdateQueue.stores = [check];
|
||||
} else {
|
||||
stores.push(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleStoreChange(); // Subscribe to the store and return a clean-up function.
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
// These are updated in the passive phase
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
|
||||
// have been in an event that fired before the passive effects, or it could
|
||||
// have been in a layout effect. In that case, we would have used the old
|
||||
// snapsho and getSnapshot values to bail out. We need to check one more time.
|
||||
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
);
|
||||
return nextSnapshot;
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}
|
||||
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
var handleStoreChange = function() {
|
||||
// The store changed. Check if the snapshot changed since the last time we
|
||||
// read from the store.
|
||||
if (checkIfSnapshotChanged(inst)) {
|
||||
// Force a re-render.
|
||||
forceStoreRerender(fiber);
|
||||
}
|
||||
}; // Subscribe to the store and return a clean-up function.
|
||||
|
||||
return subscribe(handleStoreChange);
|
||||
}
|
||||
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
|
@ -11477,6 +11551,14 @@ function updateEffect(create, deps) {
|
|||
return updateEffectImpl(Passive, Passive$1, create, deps);
|
||||
}
|
||||
|
||||
function mountInsertionEffect(create, deps) {
|
||||
return mountEffectImpl(Update, Insertion, create, deps);
|
||||
}
|
||||
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(Update, Insertion, create, deps);
|
||||
}
|
||||
|
||||
function mountLayoutEffect(create, deps) {
|
||||
var fiberFlags = Update;
|
||||
|
||||
|
@ -11712,6 +11794,26 @@ function startTransition(setPending, callback) {
|
|||
} finally {
|
||||
setCurrentUpdatePriority(previousPriority);
|
||||
ReactCurrentBatchConfig$1.transition = prevTransition;
|
||||
|
||||
{
|
||||
if (
|
||||
prevTransition !== 1 &&
|
||||
warnOnSubscriptionInsideStartTransition &&
|
||||
ReactCurrentBatchConfig$1._updatedFibers
|
||||
) {
|
||||
var updatedFibersCount = ReactCurrentBatchConfig$1._updatedFibers.size;
|
||||
|
||||
if (updatedFibersCount > 10) {
|
||||
warn(
|
||||
"Detected a large number of updates inside startTransition. " +
|
||||
"If this is due to a subscription please re-write it to use React provided hooks. " +
|
||||
"Otherwise concurrent mode guarantees are off the table."
|
||||
);
|
||||
}
|
||||
|
||||
ReactCurrentBatchConfig$1._updatedFibers.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11941,6 +12043,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -12009,6 +12112,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
checkDepsAreArrayDev(deps);
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
mountHookTypesDev();
|
||||
checkDepsAreArrayDev(deps);
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
mountHookTypesDev();
|
||||
|
@ -12114,6 +12223,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -12217,6 +12331,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -12320,6 +12439,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
updateHookTypesDev();
|
||||
|
@ -12428,6 +12552,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
mountHookTypesDev();
|
||||
return mountImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
mountHookTypesDev();
|
||||
return mountInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -12547,6 +12677,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -12666,6 +12802,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
|
|||
updateHookTypesDev();
|
||||
return updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useInsertionEffect";
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateInsertionEffect(create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
currentHookNameInDev = "useLayoutEffect";
|
||||
warnInvalidHookAccess();
|
||||
|
@ -17437,6 +17579,8 @@ function safelyDetachRef(current, nearestMountedAncestor) {
|
|||
|
||||
if (ref !== null) {
|
||||
if (typeof ref === "function") {
|
||||
var retVal;
|
||||
|
||||
try {
|
||||
if (
|
||||
enableProfilerTimer &&
|
||||
|
@ -17445,12 +17589,12 @@ function safelyDetachRef(current, nearestMountedAncestor) {
|
|||
) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
ref(null);
|
||||
retVal = ref(null);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(current);
|
||||
}
|
||||
} else {
|
||||
ref(null);
|
||||
retVal = ref(null);
|
||||
}
|
||||
} catch (error) {
|
||||
reportUncaughtErrorInDEV(error);
|
||||
|
@ -17680,6 +17824,16 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
var destroy = effect.destroy;
|
||||
|
||||
if (destroy !== undefined && typeof destroy !== "function") {
|
||||
var hookName = void 0;
|
||||
|
||||
if ((effect.tag & Layout) !== NoFlags) {
|
||||
hookName = "useLayoutEffect";
|
||||
} else if ((effect.tag & Insertion) !== NoFlags) {
|
||||
hookName = "useInsertionEffect";
|
||||
} else {
|
||||
hookName = "useEffect";
|
||||
}
|
||||
|
||||
var addendum = void 0;
|
||||
|
||||
if (destroy === null) {
|
||||
|
@ -17688,10 +17842,13 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
"up, return undefined (or nothing).";
|
||||
} else if (typeof destroy.then === "function") {
|
||||
addendum =
|
||||
"\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " +
|
||||
"\n\nIt looks like you wrote " +
|
||||
hookName +
|
||||
"(async () => ...) or returned a Promise. " +
|
||||
"Instead, write the async function inside your effect " +
|
||||
"and call it immediately:\n\n" +
|
||||
"useEffect(() => {\n" +
|
||||
hookName +
|
||||
"(() => {\n" +
|
||||
" async function fetchData() {\n" +
|
||||
" // You can await here\n" +
|
||||
" const response = await MyAPI.getData(someId);\n" +
|
||||
|
@ -17705,8 +17862,9 @@ function commitHookEffectListMount(tag, finishedWork) {
|
|||
}
|
||||
|
||||
error(
|
||||
"An effect function must not return anything besides a function, " +
|
||||
"%s must not return anything besides a function, " +
|
||||
"which is used for clean-up.%s",
|
||||
hookName,
|
||||
addendum
|
||||
);
|
||||
}
|
||||
|
@ -18181,15 +18339,17 @@ function commitAttachRef(finishedWork) {
|
|||
} // Moved outside to ensure DCE works with this flag
|
||||
|
||||
if (typeof ref === "function") {
|
||||
var retVal;
|
||||
|
||||
if (finishedWork.mode & ProfileMode) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
ref(instanceToUse);
|
||||
retVal = ref(instanceToUse);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(finishedWork);
|
||||
}
|
||||
} else {
|
||||
ref(instanceToUse);
|
||||
retVal = ref(instanceToUse);
|
||||
}
|
||||
} else {
|
||||
{
|
||||
|
@ -18253,7 +18413,10 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor) {
|
|||
tag = _effect.tag;
|
||||
|
||||
if (destroy !== undefined) {
|
||||
if ((tag & Layout) !== NoFlags$1) {
|
||||
if (
|
||||
(tag & Insertion) !== NoFlags$1 ||
|
||||
(tag & Layout) !== NoFlags$1
|
||||
) {
|
||||
if (current.mode & ProfileMode) {
|
||||
startLayoutEffectTimer();
|
||||
safelyCallDestroy(current, nearestMountedAncestor, destroy);
|
||||
|
@ -18728,11 +18891,17 @@ function commitWork(current, finishedWork) {
|
|||
case ForwardRef:
|
||||
case MemoComponent:
|
||||
case SimpleMemoComponent: {
|
||||
// Layout effects are destroyed during the mutation phase so that all
|
||||
commitHookEffectListUnmount(
|
||||
Insertion | HasEffect,
|
||||
finishedWork,
|
||||
finishedWork.return
|
||||
);
|
||||
commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all
|
||||
// destroy functions for all fibers are called before any create functions.
|
||||
// This prevents sibling component effects from interfering with each other,
|
||||
// e.g. a destroy function in one component should never override a ref set
|
||||
// by a create function in another component during the same commit.
|
||||
|
||||
if (finishedWork.mode & ProfileMode) {
|
||||
try {
|
||||
startLayoutEffectTimer();
|
||||
|
@ -19654,13 +19823,13 @@ function requestUpdateLane(fiber) {
|
|||
var isTransition = requestCurrentTransition() !== NoTransition;
|
||||
|
||||
if (isTransition) {
|
||||
// The algorithm for assigning an update to a lane should be stable for all
|
||||
// updates at the same priority within the same event. To do this, the
|
||||
// inputs to the algorithm must be the same.
|
||||
//
|
||||
// The trick we use is to cache the first of each of these inputs within an
|
||||
// event. Then reset the cached values once we can be sure the event is
|
||||
// over. Our heuristic for that is whenever we enter a concurrent work loop.
|
||||
|
||||
if (currentEventTransitionLane === NoLane) {
|
||||
// All transitions within the same event are assigned the same lane.
|
||||
currentEventTransitionLane = claimNextTransitionLane();
|
||||
|
@ -19990,38 +20159,26 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
// bug we're still investigating. Once the bug in Scheduler is fixed,
|
||||
// we can remove this, since we track expiration ourselves.
|
||||
|
||||
var exitStatus =
|
||||
shouldTimeSlice(root, lanes) && !didTimeout
|
||||
? renderRootConcurrent(root, lanes)
|
||||
: renderRootSync(root, lanes);
|
||||
var shouldTimeSlice =
|
||||
!includesBlockingLane(root, lanes) &&
|
||||
!includesExpiredLane(root, lanes) &&
|
||||
!didTimeout;
|
||||
var exitStatus = shouldTimeSlice
|
||||
? renderRootConcurrent(root, lanes)
|
||||
: renderRootSync(root, lanes);
|
||||
|
||||
if (exitStatus !== RootIncomplete) {
|
||||
if (exitStatus === RootErrored) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= RetryAfterError; // If an error occurred during hydration,
|
||||
// discard server response and fall back to client side render.
|
||||
|
||||
if (root.hydrate) {
|
||||
root.hydrate = false;
|
||||
|
||||
{
|
||||
errorHydratingContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
clearContainer(root.containerInfo);
|
||||
} // If something threw an error, try rendering one more time. We'll render
|
||||
// synchronously to block concurrent data mutations, and we'll includes
|
||||
// all pending updates are included. If it still fails after the second
|
||||
// attempt, we'll give up and commit the resulting tree.
|
||||
|
||||
// If something threw an error, try rendering one more time. We'll
|
||||
// render synchronously to block concurrent data mutations, and we'll
|
||||
// includes all pending updates are included. If it still fails after
|
||||
// the second attempt, we'll give up and commit the resulting tree.
|
||||
var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
|
||||
|
||||
if (errorRetryLanes !== NoLanes) {
|
||||
lanes = errorRetryLanes;
|
||||
exitStatus = renderRootSync(root, errorRetryLanes);
|
||||
exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
|
||||
}
|
||||
|
||||
executionContext = prevExecutionContext;
|
||||
}
|
||||
|
||||
if (exitStatus === RootFatalErrored) {
|
||||
|
@ -20030,10 +20187,43 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
ensureRootIsScheduled(root, now());
|
||||
throw fatalError;
|
||||
} // Check if this render may have yielded to a concurrent event, and if so,
|
||||
// confirm that any newly rendered stores are consistent.
|
||||
// TODO: It's possible that even a concurrent render may never have yielded
|
||||
// to the main thread, if it was fast enough, or if it expired. We could
|
||||
// skip the consistency check in that case, too.
|
||||
|
||||
var renderWasConcurrent = !includesBlockingLane(root, lanes);
|
||||
var finishedWork = root.current.alternate;
|
||||
|
||||
if (
|
||||
renderWasConcurrent &&
|
||||
!isRenderConsistentWithExternalStores(finishedWork)
|
||||
) {
|
||||
// A store was mutated in an interleaved event. Render again,
|
||||
// synchronously, to block further mutations.
|
||||
exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
|
||||
|
||||
if (exitStatus === RootErrored) {
|
||||
var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
|
||||
|
||||
if (_errorRetryLanes !== NoLanes) {
|
||||
lanes = _errorRetryLanes;
|
||||
exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
|
||||
// concurrent events.
|
||||
}
|
||||
}
|
||||
|
||||
if (exitStatus === RootFatalErrored) {
|
||||
var _fatalError = workInProgressRootFatalError;
|
||||
prepareFreshStack(root, NoLanes);
|
||||
markRootSuspended$1(root, lanes);
|
||||
ensureRootIsScheduled(root, now());
|
||||
throw _fatalError;
|
||||
}
|
||||
} // We now have a consistent tree. The next step is either to commit it,
|
||||
// or, if something suspended, wait to commit it after a timeout.
|
||||
|
||||
var finishedWork = root.current.alternate;
|
||||
root.finishedWork = finishedWork;
|
||||
root.finishedLanes = lanes;
|
||||
finishConcurrentRender(root, exitStatus, lanes);
|
||||
|
@ -20050,6 +20240,26 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= RetryAfterError; // If an error occurred during hydration, discard server response and fall
|
||||
// back to client side render.
|
||||
|
||||
if (root.hydrate) {
|
||||
root.hydrate = false;
|
||||
|
||||
{
|
||||
errorHydratingContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
clearContainer(root.containerInfo);
|
||||
}
|
||||
|
||||
var exitStatus = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
function finishConcurrentRender(root, exitStatus, lanes) {
|
||||
switch (exitStatus) {
|
||||
case RootIncomplete:
|
||||
|
@ -20168,6 +20378,68 @@ function finishConcurrentRender(root, exitStatus, lanes) {
|
|||
}
|
||||
}
|
||||
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
// Search the rendered tree for external store reads, and check whether the
|
||||
// stores were mutated in a concurrent event. Intentionally using a iterative
|
||||
// loop instead of recursion so we can exit early.
|
||||
var node = finishedWork;
|
||||
|
||||
while (true) {
|
||||
if (node.flags & StoreConsistency) {
|
||||
var updateQueue = node.updateQueue;
|
||||
|
||||
if (updateQueue !== null) {
|
||||
var checks = updateQueue.stores;
|
||||
|
||||
if (checks !== null) {
|
||||
for (var i = 0; i < checks.length; i++) {
|
||||
var check = checks[i];
|
||||
var getSnapshot = check.getSnapshot;
|
||||
var renderedValue = check.value;
|
||||
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), renderedValue)) {
|
||||
// Found an inconsistent store.
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// If `getSnapshot` throws, return `false`. This will schedule
|
||||
// a re-render, and the error will be rethrown during render.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var child = node.child;
|
||||
|
||||
if (node.subtreeFlags & StoreConsistency && child !== null) {
|
||||
child.return = node;
|
||||
node = child;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node === finishedWork) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (node.sibling === null) {
|
||||
if (node.return === null || node.return === finishedWork) {
|
||||
return true;
|
||||
}
|
||||
|
||||
node = node.return;
|
||||
}
|
||||
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
} // Flow doesn't know this is unreachable, but eslint does
|
||||
// eslint-disable-next-line no-unreachable
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
// When suspending, we should always exclude lanes that were pinged or (more
|
||||
// rarely, since we try to avoid it) updated during the render phase.
|
||||
|
@ -20912,6 +21184,15 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
} // Read this again, since an effect might have updated it
|
||||
|
||||
remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
|
||||
// TODO: This is part of the `componentDidCatch` implementation. Its purpose
|
||||
// is to detect whether something might have called setState inside
|
||||
// `componentDidCatch`. The mechanism is known to be flawed because `setState`
|
||||
// inside `componentDidCatch` is itself flawed — that's why we recommend
|
||||
// `getDerivedStateFromError` instead. However, it could be improved by
|
||||
// checking if remainingLanes includes Sync work, instead of whether there's
|
||||
// any work remaining at all (which would also include stuff like Suspense
|
||||
// retries or transitions). It's been like this for a while, though, so fixing
|
||||
// it probably isn't that urgent.
|
||||
|
||||
if (remainingLanes === NoLanes) {
|
||||
// If there's no remaining work, we can clear the set of already failed
|
||||
|
@ -20925,22 +21206,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
if (includesSomeLane(remainingLanes, SyncLane)) {
|
||||
{
|
||||
markNestedUpdateScheduled();
|
||||
} // Count the number of times the root synchronously re-renders without
|
||||
// finishing. If there are too many, it indicates an infinite update loop.
|
||||
|
||||
if (root === rootWithNestedUpdates) {
|
||||
nestedUpdateCount++;
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
rootWithNestedUpdates = root;
|
||||
}
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
}
|
||||
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
|
||||
{
|
||||
|
@ -20971,6 +21236,24 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
root.tag !== LegacyRoot
|
||||
) {
|
||||
flushPassiveEffects();
|
||||
} // Read this again, since a passive effect might have updated it
|
||||
|
||||
remainingLanes = root.pendingLanes;
|
||||
|
||||
if (includesSomeLane(remainingLanes, SyncLane)) {
|
||||
{
|
||||
markNestedUpdateScheduled();
|
||||
} // Count the number of times the root synchronously re-renders without
|
||||
// finishing. If there are too many, it indicates an infinite update loop.
|
||||
|
||||
if (root === rootWithNestedUpdates) {
|
||||
nestedUpdateCount++;
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
rootWithNestedUpdates = root;
|
||||
}
|
||||
} else {
|
||||
nestedUpdateCount = 0;
|
||||
} // If layout work was scheduled, flush it now.
|
||||
|
||||
flushSyncCallbacks();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<5efc4e18a211a1edf88bf8bd3a184783>>
|
||||
* @generated SignedSource<<5c359ba9bcb80e09d414cf763d94b5d5>>
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -930,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([
|
|||
"ReactNativeBridgeEventPlugin"
|
||||
]);
|
||||
recomputePluginOrdering();
|
||||
var injectedNamesToPlugins$jscomp$inline_224 = {
|
||||
var injectedNamesToPlugins$jscomp$inline_225 = {
|
||||
ResponderEventPlugin: ResponderEventPlugin,
|
||||
ReactNativeBridgeEventPlugin: {
|
||||
eventTypes: {},
|
||||
|
@ -965,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_224 = {
|
|||
}
|
||||
}
|
||||
},
|
||||
isOrderingDirty$jscomp$inline_225 = !1,
|
||||
pluginName$jscomp$inline_226;
|
||||
for (pluginName$jscomp$inline_226 in injectedNamesToPlugins$jscomp$inline_224)
|
||||
isOrderingDirty$jscomp$inline_226 = !1,
|
||||
pluginName$jscomp$inline_227;
|
||||
for (pluginName$jscomp$inline_227 in injectedNamesToPlugins$jscomp$inline_225)
|
||||
if (
|
||||
injectedNamesToPlugins$jscomp$inline_224.hasOwnProperty(
|
||||
pluginName$jscomp$inline_226
|
||||
injectedNamesToPlugins$jscomp$inline_225.hasOwnProperty(
|
||||
pluginName$jscomp$inline_227
|
||||
)
|
||||
) {
|
||||
var pluginModule$jscomp$inline_227 =
|
||||
injectedNamesToPlugins$jscomp$inline_224[pluginName$jscomp$inline_226];
|
||||
var pluginModule$jscomp$inline_228 =
|
||||
injectedNamesToPlugins$jscomp$inline_225[pluginName$jscomp$inline_227];
|
||||
if (
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_226) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_226] !==
|
||||
pluginModule$jscomp$inline_227
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_227) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_227] !==
|
||||
pluginModule$jscomp$inline_228
|
||||
) {
|
||||
if (namesToPlugins[pluginName$jscomp$inline_226])
|
||||
if (namesToPlugins[pluginName$jscomp$inline_227])
|
||||
throw Error(
|
||||
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
|
||||
pluginName$jscomp$inline_226 +
|
||||
pluginName$jscomp$inline_227 +
|
||||
"`."
|
||||
);
|
||||
namesToPlugins[
|
||||
pluginName$jscomp$inline_226
|
||||
] = pluginModule$jscomp$inline_227;
|
||||
isOrderingDirty$jscomp$inline_225 = !0;
|
||||
pluginName$jscomp$inline_227
|
||||
] = pluginModule$jscomp$inline_228;
|
||||
isOrderingDirty$jscomp$inline_226 = !0;
|
||||
}
|
||||
}
|
||||
isOrderingDirty$jscomp$inline_225 && recomputePluginOrdering();
|
||||
isOrderingDirty$jscomp$inline_226 && recomputePluginOrdering();
|
||||
var instanceCache = new Map(),
|
||||
instanceProps = new Map();
|
||||
function getInstanceFromTag(tag) {
|
||||
|
@ -1841,6 +1841,9 @@ function getLanesToRetrySynchronouslyOnError(root) {
|
|||
root = root.pendingLanes & -1073741825;
|
||||
return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0;
|
||||
}
|
||||
function includesBlockingLane(root, lanes) {
|
||||
return 0 !== (root.current.mode & 32) ? !1 : 0 !== (lanes & 30);
|
||||
}
|
||||
function createLaneMap(initial) {
|
||||
for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);
|
||||
return laneMap;
|
||||
|
@ -2044,7 +2047,11 @@ function invalidateContextProvider(workInProgress, type, didChange) {
|
|||
: pop(didPerformWorkStackCursor);
|
||||
push(didPerformWorkStackCursor, didChange);
|
||||
}
|
||||
var syncQueue = null,
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
||||
syncQueue = null,
|
||||
includesLegacySyncCallbacks = !1,
|
||||
isFlushingSyncQueue = !1;
|
||||
function flushSyncCallbacks() {
|
||||
|
@ -2073,10 +2080,6 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is;
|
||||
function shallowEqual(objA, objB) {
|
||||
if (objectIs(objA, objB)) return !0;
|
||||
if (
|
||||
|
@ -2373,7 +2376,7 @@ function processUpdateQueue(
|
|||
newState = workInProgress;
|
||||
break a;
|
||||
case 3:
|
||||
workInProgress.flags = (workInProgress.flags & -16385) | 128;
|
||||
workInProgress.flags = (workInProgress.flags & -32769) | 128;
|
||||
case 0:
|
||||
workInProgress = update.payload;
|
||||
updateLane =
|
||||
|
@ -3604,42 +3607,52 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
return useMutableSource(hook, source, getSnapshot, subscribe);
|
||||
}
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var hook = mountWorkInProgressHook(),
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = mountWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
hook.memoizedState = nextSnapshot;
|
||||
var inst = { value: nextSnapshot, getSnapshot: getSnapshot };
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
}
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
hook = ReactCurrentDispatcher$1.current;
|
||||
hook.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
hook.useEffect(
|
||||
function() {
|
||||
function handleStoreChange() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
handleStoreChange();
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= 8192;
|
||||
fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };
|
||||
getSnapshot = currentlyRenderingFiber$1.updateQueue;
|
||||
null === getSnapshot
|
||||
? ((getSnapshot = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = getSnapshot),
|
||||
(getSnapshot.stores = [fiber]))
|
||||
: ((renderedSnapshot = getSnapshot.stores),
|
||||
null === renderedSnapshot
|
||||
? (getSnapshot.stores = [fiber])
|
||||
: renderedSnapshot.push(fiber));
|
||||
}
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
return subscribe(function() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
});
|
||||
}
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
var latestGetSnapshot = inst.getSnapshot;
|
||||
inst = inst.value;
|
||||
|
@ -3674,7 +3687,7 @@ function pushEffect(tag, create, destroy, deps) {
|
|||
tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null };
|
||||
create = currentlyRenderingFiber$1.updateQueue;
|
||||
null === create
|
||||
? ((create = { lastEffect: null }),
|
||||
? ((create = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = create),
|
||||
(create.lastEffect = tag.next = tag))
|
||||
: ((destroy = create.lastEffect),
|
||||
|
@ -3715,13 +3728,16 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|||
hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps);
|
||||
}
|
||||
function mountEffect(create, deps) {
|
||||
return mountEffectImpl(1049600, 4, create, deps);
|
||||
return mountEffectImpl(2098176, 8, create, deps);
|
||||
}
|
||||
function updateEffect(create, deps) {
|
||||
return updateEffectImpl(1024, 4, create, deps);
|
||||
return updateEffectImpl(1024, 8, create, deps);
|
||||
}
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
}
|
||||
function updateLayoutEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
return updateEffectImpl(4, 4, create, deps);
|
||||
}
|
||||
function imperativeHandleEffect(create, ref) {
|
||||
if ("function" === typeof ref)
|
||||
|
@ -3745,7 +3761,7 @@ function updateImperativeHandle(ref, create, deps) {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return updateEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
|
@ -3863,6 +3879,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -3891,12 +3908,15 @@ var ContextOnlyDispatcher = {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return mountEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 4, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 2, create, deps);
|
||||
},
|
||||
useMemo: function(nextCreate, deps) {
|
||||
|
@ -3979,6 +3999,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: updateReducer,
|
||||
|
@ -4012,17 +4033,44 @@ var ContextOnlyDispatcher = {
|
|||
},
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: function(subscribe, getSnapshot) {
|
||||
var hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
objectIs(hook.memoizedState, nextSnapshot) ||
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot(),
|
||||
snapshotChanged = !objectIs(hook.memoizedState, nextSnapshot);
|
||||
snapshotChanged &&
|
||||
((hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0));
|
||||
return useSyncExternalStore(
|
||||
hook,
|
||||
hook.queue,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
);
|
||||
hook = hook.queue;
|
||||
updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [
|
||||
subscribe
|
||||
]);
|
||||
if (
|
||||
hook.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged ||
|
||||
(null !== workInProgressHook &&
|
||||
workInProgressHook.memoizedState.tag & 1)
|
||||
) {
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(
|
||||
null,
|
||||
fiber,
|
||||
hook,
|
||||
nextSnapshot,
|
||||
getSnapshot
|
||||
),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
return nextSnapshot;
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return updateReducer(basicStateReducer)[0];
|
||||
|
@ -4035,6 +4083,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: rerenderReducer,
|
||||
|
@ -4204,8 +4253,8 @@ function bubbleProperties(completedWork) {
|
|||
if (didBailout)
|
||||
for (var child$39 = completedWork.child; null !== child$39; )
|
||||
(newChildLanes |= child$39.lanes | child$39.childLanes),
|
||||
(subtreeFlags |= child$39.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= child$39.flags & 1835008),
|
||||
(subtreeFlags |= child$39.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= child$39.flags & 3670016),
|
||||
(child$39.return = completedWork),
|
||||
(child$39 = child$39.sibling);
|
||||
else
|
||||
|
@ -4419,7 +4468,7 @@ function completeWork(current, workInProgress, renderLanes) {
|
|||
for (newProps = workInProgress.child; null !== newProps; )
|
||||
(renderLanes = newProps),
|
||||
(type = current),
|
||||
(renderLanes.flags &= 1835010),
|
||||
(renderLanes.flags &= 3670018),
|
||||
(updatePayload = renderLanes.alternate),
|
||||
null === updatePayload
|
||||
? ((renderLanes.childLanes = 0),
|
||||
|
@ -4649,7 +4698,7 @@ function updateSimpleMemoComponent(
|
|||
current.ref === workInProgress.ref
|
||||
)
|
||||
if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes)))
|
||||
0 !== (current.flags & 32768) && (didReceiveUpdate = !0);
|
||||
0 !== (current.flags & 65536) && (didReceiveUpdate = !0);
|
||||
else
|
||||
return (
|
||||
(workInProgress.lanes = current.lanes),
|
||||
|
@ -5193,7 +5242,7 @@ function updateSuspenseFallbackChildren(
|
|||
(primaryChildren.pendingProps = primaryChildProps),
|
||||
(workInProgress.deletions = null))
|
||||
: ((primaryChildren = createWorkInProgress(current, primaryChildProps)),
|
||||
(primaryChildren.subtreeFlags = current.subtreeFlags & 1835008));
|
||||
(primaryChildren.subtreeFlags = current.subtreeFlags & 3670016));
|
||||
null !== currentFallbackChildFragment
|
||||
? (fallbackChildren = createWorkInProgress(
|
||||
currentFallbackChildFragment,
|
||||
|
@ -5421,8 +5470,8 @@ function unwindWork(workInProgress) {
|
|||
case 1:
|
||||
isContextProvider(workInProgress.type) && popContext();
|
||||
var flags = workInProgress.flags;
|
||||
return flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128), workInProgress)
|
||||
return flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128), workInProgress)
|
||||
: null;
|
||||
case 3:
|
||||
popHostContainer();
|
||||
|
@ -5434,7 +5483,7 @@ function unwindWork(workInProgress) {
|
|||
throw Error(
|
||||
"The root failed to unmount after an error. This is likely a bug in React. Please file an issue."
|
||||
);
|
||||
workInProgress.flags = (flags & -16385) | 128;
|
||||
workInProgress.flags = (flags & -32769) | 128;
|
||||
return workInProgress;
|
||||
case 5:
|
||||
return popHostContext(workInProgress), null;
|
||||
|
@ -5442,8 +5491,8 @@ function unwindWork(workInProgress) {
|
|||
return (
|
||||
pop(suspenseStackCursor),
|
||||
(flags = workInProgress.flags),
|
||||
flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128), workInProgress)
|
||||
flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128), workInProgress)
|
||||
: null
|
||||
);
|
||||
case 19:
|
||||
|
@ -5596,7 +5645,10 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) {
|
|||
var _effect = effect,
|
||||
destroy = _effect.destroy;
|
||||
_effect = _effect.tag;
|
||||
if (void 0 !== destroy && 0 !== (_effect & 2)) {
|
||||
if (
|
||||
void 0 !== destroy &&
|
||||
(0 !== (_effect & 2) || 0 !== (_effect & 4))
|
||||
) {
|
||||
_effect = current;
|
||||
var nearestMountedAncestor = nearestMountedAncestor$jscomp$0;
|
||||
try {
|
||||
|
@ -5923,6 +5975,8 @@ function commitWork(current, finishedWork) {
|
|||
case 14:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListMount(3, finishedWork);
|
||||
commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
return;
|
||||
case 1:
|
||||
return;
|
||||
|
@ -6157,7 +6211,7 @@ function commitLayoutEffects(finishedWork) {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListMount(3, firstChild);
|
||||
commitHookEffectListMount(5, firstChild);
|
||||
break;
|
||||
case 1:
|
||||
var instance = firstChild.stateNode;
|
||||
|
@ -6421,15 +6475,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
root === workInProgressRoot ? workInProgressRootRenderLanes : 0
|
||||
);
|
||||
if (0 === lanes) return null;
|
||||
var JSCompiler_inline_result =
|
||||
0 !== (lanes & root.expiredLanes)
|
||||
? !1
|
||||
: 0 !== (root.current.mode & 32)
|
||||
? !0
|
||||
: 0 === (lanes & 30);
|
||||
if (JSCompiler_inline_result && !didTimeout) {
|
||||
if (
|
||||
includesBlockingLane(root, lanes) ||
|
||||
0 !== (lanes & root.expiredLanes) ||
|
||||
didTimeout
|
||||
)
|
||||
didTimeout = renderRootSync(root, lanes);
|
||||
else {
|
||||
didTimeout = lanes;
|
||||
JSCompiler_inline_result = executionContext;
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 2;
|
||||
var prevDispatcher = pushDispatcher();
|
||||
if (
|
||||
|
@ -6448,30 +6502,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
while (1);
|
||||
resetContextDependencies();
|
||||
ReactCurrentDispatcher$2.current = prevDispatcher;
|
||||
executionContext = JSCompiler_inline_result;
|
||||
executionContext = prevExecutionContext;
|
||||
null !== workInProgress
|
||||
? (didTimeout = 0)
|
||||
: ((workInProgressRoot = null),
|
||||
(workInProgressRootRenderLanes = 0),
|
||||
(didTimeout = workInProgressRootExitStatus));
|
||||
} else didTimeout = renderRootSync(root, lanes);
|
||||
}
|
||||
if (0 !== didTimeout) {
|
||||
2 === didTimeout &&
|
||||
((JSCompiler_inline_result = executionContext),
|
||||
(executionContext |= 8),
|
||||
root.hydrate && (root.hydrate = !1),
|
||||
(prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = renderRootSync(root, prevDispatcher))),
|
||||
(executionContext = JSCompiler_inline_result));
|
||||
((prevExecutionContext = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevExecutionContext &&
|
||||
((lanes = prevExecutionContext),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevExecutionContext))));
|
||||
if (1 === didTimeout)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = root.current.alternate;
|
||||
prevDispatcher = !includesBlockingLane(root, lanes);
|
||||
prevExecutionContext = root.current.alternate;
|
||||
if (
|
||||
prevDispatcher &&
|
||||
!isRenderConsistentWithExternalStores(prevExecutionContext) &&
|
||||
((didTimeout = renderRootSync(root, lanes)),
|
||||
2 === didTimeout &&
|
||||
((prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevDispatcher)))),
|
||||
1 === didTimeout)
|
||||
)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = prevExecutionContext;
|
||||
root.finishedLanes = lanes;
|
||||
switch (didTimeout) {
|
||||
case 0:
|
||||
|
@ -6488,10 +6556,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
10 < didTimeout)
|
||||
) {
|
||||
if (0 !== getNextLanes(root, 0)) break;
|
||||
JSCompiler_inline_result = root.suspendedLanes;
|
||||
if ((JSCompiler_inline_result & lanes) !== lanes) {
|
||||
prevExecutionContext = root.suspendedLanes;
|
||||
if ((prevExecutionContext & lanes) !== lanes) {
|
||||
requestEventTime();
|
||||
root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result;
|
||||
root.pingedLanes |= root.suspendedLanes & prevExecutionContext;
|
||||
break;
|
||||
}
|
||||
root.timeoutHandle = scheduleTimeout(
|
||||
|
@ -6506,15 +6574,14 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
if ((lanes & 4194240) === lanes) break;
|
||||
didTimeout = root.eventTimes;
|
||||
for (JSCompiler_inline_result = -1; 0 < lanes; ) {
|
||||
for (prevExecutionContext = -1; 0 < lanes; ) {
|
||||
var index$5 = 31 - clz32(lanes);
|
||||
prevDispatcher = 1 << index$5;
|
||||
index$5 = didTimeout[index$5];
|
||||
index$5 > JSCompiler_inline_result &&
|
||||
(JSCompiler_inline_result = index$5);
|
||||
index$5 > prevExecutionContext && (prevExecutionContext = index$5);
|
||||
lanes &= ~prevDispatcher;
|
||||
}
|
||||
lanes = JSCompiler_inline_result;
|
||||
lanes = prevExecutionContext;
|
||||
lanes = now() - lanes;
|
||||
lanes =
|
||||
(120 > lanes
|
||||
|
@ -6551,6 +6618,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
? performConcurrentWorkOnRoot.bind(null, root)
|
||||
: null;
|
||||
}
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 8;
|
||||
root.hydrate && (root.hydrate = !1);
|
||||
root = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return root;
|
||||
}
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
for (var node = finishedWork; ; ) {
|
||||
if (node.flags & 8192) {
|
||||
var updateQueue = node.updateQueue;
|
||||
if (
|
||||
null !== updateQueue &&
|
||||
((updateQueue = updateQueue.stores), null !== updateQueue)
|
||||
)
|
||||
for (var i = 0; i < updateQueue.length; i++) {
|
||||
var check = updateQueue[i],
|
||||
getSnapshot = check.getSnapshot;
|
||||
check = check.value;
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), check)) return !1;
|
||||
} catch (error) {
|
||||
return !1;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateQueue = node.child;
|
||||
if (node.subtreeFlags & 8192 && null !== updateQueue)
|
||||
(updateQueue.return = node), (node = updateQueue);
|
||||
else {
|
||||
if (node === finishedWork) break;
|
||||
for (; null === node.sibling; ) {
|
||||
if (null === node.return || node.return === finishedWork) return !0;
|
||||
node = node.return;
|
||||
}
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
}
|
||||
}
|
||||
return !0;
|
||||
}
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
suspendedLanes &= ~workInProgressRootPingedLanes;
|
||||
suspendedLanes &= ~workInProgressRootUpdatedLanes;
|
||||
|
@ -6698,7 +6807,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
sourceFiber = erroredWork,
|
||||
value = thrownValue;
|
||||
thrownValue = workInProgressRootRenderLanes;
|
||||
sourceFiber.flags |= 8192;
|
||||
sourceFiber.flags |= 16384;
|
||||
if (
|
||||
null !== value &&
|
||||
"object" === typeof value &&
|
||||
|
@ -6749,8 +6858,8 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
workInProgress$32 !== returnFiber
|
||||
) {
|
||||
workInProgress$32.flags |= 128;
|
||||
sourceFiber.flags |= 32768;
|
||||
sourceFiber.flags &= -10053;
|
||||
sourceFiber.flags |= 65536;
|
||||
sourceFiber.flags &= -26437;
|
||||
if (1 === sourceFiber.tag)
|
||||
if (null === sourceFiber.alternate) sourceFiber.tag = 17;
|
||||
else {
|
||||
|
@ -6781,7 +6890,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
);
|
||||
wakeable.then(ping, ping);
|
||||
}
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
workInProgress$32.lanes = thrownValue;
|
||||
break a;
|
||||
}
|
||||
|
@ -6800,7 +6909,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
switch (workInProgress$32.tag) {
|
||||
case 3:
|
||||
root = value;
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$32.lanes |= thrownValue;
|
||||
var update$33 = createRootErrorUpdate(
|
||||
|
@ -6822,7 +6931,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
(null === legacyErrorBoundariesThatAlreadyFailed ||
|
||||
!legacyErrorBoundariesThatAlreadyFailed.has(instance))))
|
||||
) {
|
||||
workInProgress$32.flags |= 16384;
|
||||
workInProgress$32.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$32.lanes |= thrownValue;
|
||||
var update$36 = createClassErrorUpdate(
|
||||
|
@ -6896,7 +7005,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
do {
|
||||
var current = completedWork.alternate;
|
||||
unitOfWork = completedWork.return;
|
||||
if (0 === (completedWork.flags & 8192)) {
|
||||
if (0 === (completedWork.flags & 16384)) {
|
||||
if (
|
||||
((current = completeWork(current, completedWork, subtreeRenderLanes)),
|
||||
null !== current)
|
||||
|
@ -6907,12 +7016,12 @@ function completeUnitOfWork(unitOfWork) {
|
|||
} else {
|
||||
current = unwindWork(completedWork);
|
||||
if (null !== current) {
|
||||
current.flags &= 8191;
|
||||
current.flags &= 16383;
|
||||
workInProgress = current;
|
||||
return;
|
||||
}
|
||||
null !== unitOfWork &&
|
||||
((unitOfWork.flags |= 8192),
|
||||
((unitOfWork.flags |= 16384),
|
||||
(unitOfWork.subtreeFlags = 0),
|
||||
(unitOfWork.deletions = null));
|
||||
}
|
||||
|
@ -6991,11 +7100,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
(pendingPassiveEffectsLanes = lanes));
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null);
|
||||
0 !== (remainingLanes & 1)
|
||||
? root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))
|
||||
: (nestedUpdateCount = 0);
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
ensureRootIsScheduled(root, now());
|
||||
if (hasUncaughtError)
|
||||
|
@ -7006,6 +7110,12 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
0 !== (pendingPassiveEffectsLanes & 1) &&
|
||||
0 !== root.tag &&
|
||||
flushPassiveEffects();
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 !== (remainingLanes & 1)
|
||||
? root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root))
|
||||
: (nestedUpdateCount = 0);
|
||||
flushSyncCallbacks();
|
||||
return null;
|
||||
}
|
||||
|
@ -7041,7 +7151,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(4, fiber$jscomp$0, fiber);
|
||||
commitHookEffectListUnmount(8, fiber$jscomp$0, fiber);
|
||||
}
|
||||
var child$jscomp$0 = fiber$jscomp$0.child;
|
||||
if (null !== child$jscomp$0)
|
||||
|
@ -7091,7 +7201,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(5, fiber, fiber.return);
|
||||
commitHookEffectListUnmount(9, fiber, fiber.return);
|
||||
}
|
||||
var sibling$jscomp$0 = fiber.sibling;
|
||||
if (null !== sibling$jscomp$0) {
|
||||
|
@ -7117,7 +7227,7 @@ function flushPassiveEffects() {
|
|||
case 0:
|
||||
case 11:
|
||||
case 15:
|
||||
commitHookEffectListMount(5, deletions);
|
||||
commitHookEffectListMount(9, deletions);
|
||||
}
|
||||
} catch (error) {
|
||||
captureCommitPhaseError(deletions, deletions.return, error);
|
||||
|
@ -7263,7 +7373,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) {
|
|||
renderLanes
|
||||
)
|
||||
);
|
||||
didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1;
|
||||
didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1;
|
||||
}
|
||||
else didReceiveUpdate = !1;
|
||||
workInProgress.lanes = 0;
|
||||
|
@ -7729,7 +7839,7 @@ function createWorkInProgress(current, pendingProps) {
|
|||
(workInProgress.flags = 0),
|
||||
(workInProgress.subtreeFlags = 0),
|
||||
(workInProgress.deletions = null));
|
||||
workInProgress.flags = current.flags & 1835008;
|
||||
workInProgress.flags = current.flags & 3670016;
|
||||
workInProgress.childLanes = current.childLanes;
|
||||
workInProgress.lanes = current.lanes;
|
||||
workInProgress.child = current.child;
|
||||
|
@ -8086,10 +8196,10 @@ batchedUpdatesImpl = function(fn, a) {
|
|||
}
|
||||
};
|
||||
var roots = new Map(),
|
||||
devToolsConfig$jscomp$inline_989 = {
|
||||
devToolsConfig$jscomp$inline_986 = {
|
||||
findFiberByHostInstance: getInstanceFromTag,
|
||||
bundleType: 0,
|
||||
version: "18.0.0-95d762e40-20210908",
|
||||
version: "18.0.0-e8feb11b6-20210915",
|
||||
rendererPackageName: "react-native-renderer",
|
||||
rendererConfig: {
|
||||
getInspectorDataForViewTag: function() {
|
||||
|
@ -8104,11 +8214,11 @@ var roots = new Map(),
|
|||
}.bind(null, findNodeHandle)
|
||||
}
|
||||
};
|
||||
var internals$jscomp$inline_1242 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_989.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_989.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_989.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_989.rendererConfig,
|
||||
var internals$jscomp$inline_1239 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_986.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_986.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig,
|
||||
overrideHookState: null,
|
||||
overrideHookStateDeletePath: null,
|
||||
overrideHookStateRenamePath: null,
|
||||
|
@ -8124,7 +8234,7 @@ var internals$jscomp$inline_1242 = {
|
|||
return null === fiber ? null : fiber.stateNode;
|
||||
},
|
||||
findFiberByHostInstance:
|
||||
devToolsConfig$jscomp$inline_989.findFiberByHostInstance ||
|
||||
devToolsConfig$jscomp$inline_986.findFiberByHostInstance ||
|
||||
emptyFindFiberByHostInstance,
|
||||
findHostInstancesForRefresh: null,
|
||||
scheduleRefresh: null,
|
||||
|
@ -8132,19 +8242,19 @@ var internals$jscomp$inline_1242 = {
|
|||
setRefreshHandler: null,
|
||||
getCurrentFiber: null,
|
||||
getIsStrictMode: null,
|
||||
reconcilerVersion: "18.0.0-95d762e40-20210908"
|
||||
reconcilerVersion: "18.0.0-e8feb11b6-20210915"
|
||||
};
|
||||
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
var hook$jscomp$inline_1243 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
var hook$jscomp$inline_1240 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
if (
|
||||
!hook$jscomp$inline_1243.isDisabled &&
|
||||
hook$jscomp$inline_1243.supportsFiber
|
||||
!hook$jscomp$inline_1240.isDisabled &&
|
||||
hook$jscomp$inline_1240.supportsFiber
|
||||
)
|
||||
try {
|
||||
(rendererID = hook$jscomp$inline_1243.inject(
|
||||
internals$jscomp$inline_1242
|
||||
(rendererID = hook$jscomp$inline_1240.inject(
|
||||
internals$jscomp$inline_1239
|
||||
)),
|
||||
(injectedHook = hook$jscomp$inline_1243);
|
||||
(injectedHook = hook$jscomp$inline_1240);
|
||||
} catch (err) {}
|
||||
}
|
||||
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @noflow
|
||||
* @nolint
|
||||
* @preventMunge
|
||||
* @generated SignedSource<<ad111484ca10270c3a7cd031b1e7fd26>>
|
||||
* @generated SignedSource<<fde7e13d1ac4bc64f671a420c5af657b>>
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -930,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([
|
|||
"ReactNativeBridgeEventPlugin"
|
||||
]);
|
||||
recomputePluginOrdering();
|
||||
var injectedNamesToPlugins$jscomp$inline_232 = {
|
||||
var injectedNamesToPlugins$jscomp$inline_233 = {
|
||||
ResponderEventPlugin: ResponderEventPlugin,
|
||||
ReactNativeBridgeEventPlugin: {
|
||||
eventTypes: {},
|
||||
|
@ -965,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_232 = {
|
|||
}
|
||||
}
|
||||
},
|
||||
isOrderingDirty$jscomp$inline_233 = !1,
|
||||
pluginName$jscomp$inline_234;
|
||||
for (pluginName$jscomp$inline_234 in injectedNamesToPlugins$jscomp$inline_232)
|
||||
isOrderingDirty$jscomp$inline_234 = !1,
|
||||
pluginName$jscomp$inline_235;
|
||||
for (pluginName$jscomp$inline_235 in injectedNamesToPlugins$jscomp$inline_233)
|
||||
if (
|
||||
injectedNamesToPlugins$jscomp$inline_232.hasOwnProperty(
|
||||
pluginName$jscomp$inline_234
|
||||
injectedNamesToPlugins$jscomp$inline_233.hasOwnProperty(
|
||||
pluginName$jscomp$inline_235
|
||||
)
|
||||
) {
|
||||
var pluginModule$jscomp$inline_235 =
|
||||
injectedNamesToPlugins$jscomp$inline_232[pluginName$jscomp$inline_234];
|
||||
var pluginModule$jscomp$inline_236 =
|
||||
injectedNamesToPlugins$jscomp$inline_233[pluginName$jscomp$inline_235];
|
||||
if (
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_234) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_234] !==
|
||||
pluginModule$jscomp$inline_235
|
||||
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_235) ||
|
||||
namesToPlugins[pluginName$jscomp$inline_235] !==
|
||||
pluginModule$jscomp$inline_236
|
||||
) {
|
||||
if (namesToPlugins[pluginName$jscomp$inline_234])
|
||||
if (namesToPlugins[pluginName$jscomp$inline_235])
|
||||
throw Error(
|
||||
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
|
||||
pluginName$jscomp$inline_234 +
|
||||
pluginName$jscomp$inline_235 +
|
||||
"`."
|
||||
);
|
||||
namesToPlugins[
|
||||
pluginName$jscomp$inline_234
|
||||
] = pluginModule$jscomp$inline_235;
|
||||
isOrderingDirty$jscomp$inline_233 = !0;
|
||||
pluginName$jscomp$inline_235
|
||||
] = pluginModule$jscomp$inline_236;
|
||||
isOrderingDirty$jscomp$inline_234 = !0;
|
||||
}
|
||||
}
|
||||
isOrderingDirty$jscomp$inline_233 && recomputePluginOrdering();
|
||||
isOrderingDirty$jscomp$inline_234 && recomputePluginOrdering();
|
||||
var instanceCache = new Map(),
|
||||
instanceProps = new Map();
|
||||
function getInstanceFromTag(tag) {
|
||||
|
@ -1859,6 +1859,9 @@ function getLanesToRetrySynchronouslyOnError(root) {
|
|||
root = root.pendingLanes & -1073741825;
|
||||
return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0;
|
||||
}
|
||||
function includesBlockingLane(root, lanes) {
|
||||
return 0 !== (root.current.mode & 32) ? !1 : 0 !== (lanes & 30);
|
||||
}
|
||||
function createLaneMap(initial) {
|
||||
for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);
|
||||
return laneMap;
|
||||
|
@ -2092,7 +2095,11 @@ function invalidateContextProvider(workInProgress, type, didChange) {
|
|||
: pop(didPerformWorkStackCursor);
|
||||
push(didPerformWorkStackCursor, didChange);
|
||||
}
|
||||
var syncQueue = null,
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
||||
syncQueue = null,
|
||||
includesLegacySyncCallbacks = !1,
|
||||
isFlushingSyncQueue = !1;
|
||||
function flushSyncCallbacks() {
|
||||
|
@ -2121,10 +2128,6 @@ function flushSyncCallbacks() {
|
|||
return null;
|
||||
}
|
||||
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
|
||||
function is(x, y) {
|
||||
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
||||
}
|
||||
var objectIs = "function" === typeof Object.is ? Object.is : is;
|
||||
function shallowEqual(objA, objB) {
|
||||
if (objectIs(objA, objB)) return !0;
|
||||
if (
|
||||
|
@ -2421,7 +2424,7 @@ function processUpdateQueue(
|
|||
newState = workInProgress;
|
||||
break a;
|
||||
case 3:
|
||||
workInProgress.flags = (workInProgress.flags & -16385) | 128;
|
||||
workInProgress.flags = (workInProgress.flags & -32769) | 128;
|
||||
case 0:
|
||||
workInProgress = update.payload;
|
||||
updateLane =
|
||||
|
@ -3652,42 +3655,52 @@ function updateMutableSource(source, getSnapshot, subscribe) {
|
|||
return useMutableSource(hook, source, getSnapshot, subscribe);
|
||||
}
|
||||
function mountSyncExternalStore(subscribe, getSnapshot) {
|
||||
var hook = mountWorkInProgressHook(),
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = mountWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
hook.memoizedState = nextSnapshot;
|
||||
var inst = { value: nextSnapshot, getSnapshot: getSnapshot };
|
||||
hook.queue = inst;
|
||||
return useSyncExternalStore(hook, inst, subscribe, getSnapshot, nextSnapshot);
|
||||
}
|
||||
function useSyncExternalStore(
|
||||
hook,
|
||||
inst,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
) {
|
||||
var fiber = currentlyRenderingFiber$1;
|
||||
hook = ReactCurrentDispatcher$1.current;
|
||||
hook.useLayoutEffect(
|
||||
function() {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
},
|
||||
[subscribe, nextSnapshot, getSnapshot]
|
||||
);
|
||||
hook.useEffect(
|
||||
function() {
|
||||
function handleStoreChange() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
handleStoreChange();
|
||||
return subscribe(handleStoreChange);
|
||||
},
|
||||
[subscribe]
|
||||
mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]);
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
return nextSnapshot;
|
||||
}
|
||||
function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
|
||||
fiber.flags |= 8192;
|
||||
fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };
|
||||
getSnapshot = currentlyRenderingFiber$1.updateQueue;
|
||||
null === getSnapshot
|
||||
? ((getSnapshot = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = getSnapshot),
|
||||
(getSnapshot.stores = [fiber]))
|
||||
: ((renderedSnapshot = getSnapshot.stores),
|
||||
null === renderedSnapshot
|
||||
? (getSnapshot.stores = [fiber])
|
||||
: renderedSnapshot.push(fiber));
|
||||
}
|
||||
function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
|
||||
inst.value = nextSnapshot;
|
||||
inst.getSnapshot = getSnapshot;
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
}
|
||||
function subscribeToStore(fiber, inst, subscribe) {
|
||||
return subscribe(function() {
|
||||
checkIfSnapshotChanged(inst) && scheduleUpdateOnFiber(fiber, 1, -1);
|
||||
});
|
||||
}
|
||||
function checkIfSnapshotChanged(inst) {
|
||||
var latestGetSnapshot = inst.getSnapshot;
|
||||
inst = inst.value;
|
||||
|
@ -3722,7 +3735,7 @@ function pushEffect(tag, create, destroy, deps) {
|
|||
tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null };
|
||||
create = currentlyRenderingFiber$1.updateQueue;
|
||||
null === create
|
||||
? ((create = { lastEffect: null }),
|
||||
? ((create = { lastEffect: null, stores: null }),
|
||||
(currentlyRenderingFiber$1.updateQueue = create),
|
||||
(create.lastEffect = tag.next = tag))
|
||||
: ((destroy = create.lastEffect),
|
||||
|
@ -3763,13 +3776,16 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
|
|||
hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps);
|
||||
}
|
||||
function mountEffect(create, deps) {
|
||||
return mountEffectImpl(1049600, 4, create, deps);
|
||||
return mountEffectImpl(2098176, 8, create, deps);
|
||||
}
|
||||
function updateEffect(create, deps) {
|
||||
return updateEffectImpl(1024, 4, create, deps);
|
||||
return updateEffectImpl(1024, 8, create, deps);
|
||||
}
|
||||
function updateInsertionEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
}
|
||||
function updateLayoutEffect(create, deps) {
|
||||
return updateEffectImpl(4, 2, create, deps);
|
||||
return updateEffectImpl(4, 4, create, deps);
|
||||
}
|
||||
function imperativeHandleEffect(create, ref) {
|
||||
if ("function" === typeof ref)
|
||||
|
@ -3793,7 +3809,7 @@ function updateImperativeHandle(ref, create, deps) {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return updateEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
|
@ -3911,6 +3927,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: throwInvalidHookError,
|
||||
useEffect: throwInvalidHookError,
|
||||
useImperativeHandle: throwInvalidHookError,
|
||||
useInsertionEffect: throwInvalidHookError,
|
||||
useLayoutEffect: throwInvalidHookError,
|
||||
useMemo: throwInvalidHookError,
|
||||
useReducer: throwInvalidHookError,
|
||||
|
@ -3939,12 +3956,15 @@ var ContextOnlyDispatcher = {
|
|||
deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;
|
||||
return mountEffectImpl(
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
imperativeHandleEffect.bind(null, create, ref),
|
||||
deps
|
||||
);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 4, create, deps);
|
||||
},
|
||||
useInsertionEffect: function(create, deps) {
|
||||
return mountEffectImpl(4, 2, create, deps);
|
||||
},
|
||||
useMemo: function(nextCreate, deps) {
|
||||
|
@ -4027,6 +4047,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: updateReducer,
|
||||
|
@ -4060,17 +4081,44 @@ var ContextOnlyDispatcher = {
|
|||
},
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: function(subscribe, getSnapshot) {
|
||||
var hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot();
|
||||
objectIs(hook.memoizedState, nextSnapshot) ||
|
||||
var fiber = currentlyRenderingFiber$1,
|
||||
hook = updateWorkInProgressHook(),
|
||||
nextSnapshot = getSnapshot(),
|
||||
snapshotChanged = !objectIs(hook.memoizedState, nextSnapshot);
|
||||
snapshotChanged &&
|
||||
((hook.memoizedState = nextSnapshot), (didReceiveUpdate = !0));
|
||||
return useSyncExternalStore(
|
||||
hook,
|
||||
hook.queue,
|
||||
subscribe,
|
||||
getSnapshot,
|
||||
nextSnapshot
|
||||
);
|
||||
hook = hook.queue;
|
||||
updateEffect(subscribeToStore.bind(null, fiber, hook, subscribe), [
|
||||
subscribe
|
||||
]);
|
||||
if (
|
||||
hook.getSnapshot !== getSnapshot ||
|
||||
snapshotChanged ||
|
||||
(null !== workInProgressHook &&
|
||||
workInProgressHook.memoizedState.tag & 1)
|
||||
) {
|
||||
fiber.flags |= 1024;
|
||||
pushEffect(
|
||||
9,
|
||||
updateStoreInstance.bind(
|
||||
null,
|
||||
fiber,
|
||||
hook,
|
||||
nextSnapshot,
|
||||
getSnapshot
|
||||
),
|
||||
void 0,
|
||||
null
|
||||
);
|
||||
subscribe = workInProgressRoot;
|
||||
if (null === subscribe)
|
||||
throw Error(
|
||||
"Expected a work-in-progress root. This is a bug in React. Please file an issue."
|
||||
);
|
||||
includesBlockingLane(subscribe, renderLanes) ||
|
||||
pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
|
||||
}
|
||||
return nextSnapshot;
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return updateReducer(basicStateReducer)[0];
|
||||
|
@ -4083,6 +4131,7 @@ var ContextOnlyDispatcher = {
|
|||
useContext: readContext,
|
||||
useEffect: updateEffect,
|
||||
useImperativeHandle: updateImperativeHandle,
|
||||
useInsertionEffect: updateInsertionEffect,
|
||||
useLayoutEffect: updateLayoutEffect,
|
||||
useMemo: updateMemo,
|
||||
useReducer: rerenderReducer,
|
||||
|
@ -4316,8 +4365,8 @@ function bubbleProperties(completedWork) {
|
|||
|
||||
)
|
||||
(newChildLanes |= child$43.lanes | child$43.childLanes),
|
||||
(subtreeFlags |= child$43.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= child$43.flags & 1835008),
|
||||
(subtreeFlags |= child$43.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= child$43.flags & 3670016),
|
||||
(treeBaseDuration$42 += child$43.treeBaseDuration),
|
||||
(child$43 = child$43.sibling);
|
||||
completedWork.treeBaseDuration = treeBaseDuration$42;
|
||||
|
@ -4329,8 +4378,8 @@ function bubbleProperties(completedWork) {
|
|||
)
|
||||
(newChildLanes |=
|
||||
treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes),
|
||||
(subtreeFlags |= treeBaseDuration$42.subtreeFlags & 1835008),
|
||||
(subtreeFlags |= treeBaseDuration$42.flags & 1835008),
|
||||
(subtreeFlags |= treeBaseDuration$42.subtreeFlags & 3670016),
|
||||
(subtreeFlags |= treeBaseDuration$42.flags & 3670016),
|
||||
(treeBaseDuration$42.return = completedWork),
|
||||
(treeBaseDuration$42 = treeBaseDuration$42.sibling);
|
||||
else if (0 !== (completedWork.mode & 2)) {
|
||||
|
@ -4572,7 +4621,7 @@ function completeWork(current, workInProgress, renderLanes) {
|
|||
for (newProps = workInProgress.child; null !== newProps; )
|
||||
(renderLanes = newProps),
|
||||
(updatePayload = current),
|
||||
(renderLanes.flags &= 1835010),
|
||||
(renderLanes.flags &= 3670018),
|
||||
(type = renderLanes.alternate),
|
||||
null === type
|
||||
? ((renderLanes.childLanes = 0),
|
||||
|
@ -4804,7 +4853,7 @@ function updateSimpleMemoComponent(
|
|||
current.ref === workInProgress.ref
|
||||
)
|
||||
if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes)))
|
||||
0 !== (current.flags & 32768) && (didReceiveUpdate = !0);
|
||||
0 !== (current.flags & 65536) && (didReceiveUpdate = !0);
|
||||
else
|
||||
return (
|
||||
(workInProgress.lanes = current.lanes),
|
||||
|
@ -5362,7 +5411,7 @@ function updateSuspenseFallbackChildren(
|
|||
(primaryChildren.treeBaseDuration = current.treeBaseDuration)),
|
||||
(workInProgress.deletions = null))
|
||||
: ((primaryChildren = createWorkInProgress(current, primaryChildProps)),
|
||||
(primaryChildren.subtreeFlags = current.subtreeFlags & 1835008));
|
||||
(primaryChildren.subtreeFlags = current.subtreeFlags & 3670016));
|
||||
null !== currentFallbackChildFragment
|
||||
? (fallbackChildren = createWorkInProgress(
|
||||
currentFallbackChildFragment,
|
||||
|
@ -5598,8 +5647,8 @@ function unwindWork(workInProgress) {
|
|||
case 1:
|
||||
isContextProvider(workInProgress.type) && popContext();
|
||||
var flags = workInProgress.flags;
|
||||
return flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128),
|
||||
return flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128),
|
||||
0 !== (workInProgress.mode & 2) &&
|
||||
transferActualDuration(workInProgress),
|
||||
workInProgress)
|
||||
|
@ -5614,7 +5663,7 @@ function unwindWork(workInProgress) {
|
|||
throw Error(
|
||||
"The root failed to unmount after an error. This is likely a bug in React. Please file an issue."
|
||||
);
|
||||
workInProgress.flags = (flags & -16385) | 128;
|
||||
workInProgress.flags = (flags & -32769) | 128;
|
||||
return workInProgress;
|
||||
case 5:
|
||||
return popHostContext(workInProgress), null;
|
||||
|
@ -5622,8 +5671,8 @@ function unwindWork(workInProgress) {
|
|||
return (
|
||||
pop(suspenseStackCursor),
|
||||
(flags = workInProgress.flags),
|
||||
flags & 16384
|
||||
? ((workInProgress.flags = (flags & -16385) | 128),
|
||||
flags & 32768
|
||||
? ((workInProgress.flags = (flags & -32769) | 128),
|
||||
0 !== (workInProgress.mode & 2) &&
|
||||
transferActualDuration(workInProgress),
|
||||
workInProgress)
|
||||
|
@ -5787,8 +5836,8 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor) {
|
|||
var _effect = effect,
|
||||
destroy = _effect.destroy;
|
||||
_effect = _effect.tag;
|
||||
void 0 !== destroy &&
|
||||
0 !== (_effect & 2) &&
|
||||
void 0 === destroy ||
|
||||
(0 === (_effect & 2) && 0 === (_effect & 4)) ||
|
||||
(current.mode & 2
|
||||
? (startLayoutEffectTimer(),
|
||||
safelyCallDestroy(current, nearestMountedAncestor, destroy),
|
||||
|
@ -6111,14 +6160,16 @@ function commitWork(current, finishedWork) {
|
|||
case 11:
|
||||
case 14:
|
||||
case 15:
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListMount(3, finishedWork);
|
||||
if (finishedWork.mode & 2)
|
||||
try {
|
||||
startLayoutEffectTimer(),
|
||||
commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(finishedWork);
|
||||
}
|
||||
else commitHookEffectListUnmount(3, finishedWork, finishedWork.return);
|
||||
else commitHookEffectListUnmount(5, finishedWork, finishedWork.return);
|
||||
return;
|
||||
case 1:
|
||||
return;
|
||||
|
@ -6379,11 +6430,11 @@ function commitLayoutEffects(finishedWork, root, committedLanes) {
|
|||
if (committedLanes.mode & 2)
|
||||
try {
|
||||
startLayoutEffectTimer(),
|
||||
commitHookEffectListMount(3, committedLanes);
|
||||
commitHookEffectListMount(5, committedLanes);
|
||||
} finally {
|
||||
recordLayoutEffectDuration(committedLanes);
|
||||
}
|
||||
else commitHookEffectListMount(3, committedLanes);
|
||||
else commitHookEffectListMount(5, committedLanes);
|
||||
break;
|
||||
case 1:
|
||||
var instance = committedLanes.stateNode;
|
||||
|
@ -6722,15 +6773,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
root === workInProgressRoot ? workInProgressRootRenderLanes : 0
|
||||
);
|
||||
if (0 === lanes) return null;
|
||||
var JSCompiler_inline_result =
|
||||
0 !== (lanes & root.expiredLanes)
|
||||
? !1
|
||||
: 0 !== (root.current.mode & 32)
|
||||
? !0
|
||||
: 0 === (lanes & 30);
|
||||
if (JSCompiler_inline_result && !didTimeout) {
|
||||
if (
|
||||
includesBlockingLane(root, lanes) ||
|
||||
0 !== (lanes & root.expiredLanes) ||
|
||||
didTimeout
|
||||
)
|
||||
didTimeout = renderRootSync(root, lanes);
|
||||
else {
|
||||
didTimeout = lanes;
|
||||
JSCompiler_inline_result = executionContext;
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 2;
|
||||
var prevDispatcher = pushDispatcher();
|
||||
if (
|
||||
|
@ -6757,30 +6808,44 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
while (1);
|
||||
resetContextDependencies();
|
||||
ReactCurrentDispatcher$2.current = prevDispatcher;
|
||||
executionContext = JSCompiler_inline_result;
|
||||
executionContext = prevExecutionContext;
|
||||
null !== workInProgress
|
||||
? (didTimeout = 0)
|
||||
: ((workInProgressRoot = null),
|
||||
(workInProgressRootRenderLanes = 0),
|
||||
(didTimeout = workInProgressRootExitStatus));
|
||||
} else didTimeout = renderRootSync(root, lanes);
|
||||
}
|
||||
if (0 !== didTimeout) {
|
||||
2 === didTimeout &&
|
||||
((JSCompiler_inline_result = executionContext),
|
||||
(executionContext |= 8),
|
||||
root.hydrate && (root.hydrate = !1),
|
||||
(prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = renderRootSync(root, prevDispatcher))),
|
||||
(executionContext = JSCompiler_inline_result));
|
||||
((prevExecutionContext = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevExecutionContext &&
|
||||
((lanes = prevExecutionContext),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevExecutionContext))));
|
||||
if (1 === didTimeout)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = root.current.alternate;
|
||||
prevDispatcher = !includesBlockingLane(root, lanes);
|
||||
prevExecutionContext = root.current.alternate;
|
||||
if (
|
||||
prevDispatcher &&
|
||||
!isRenderConsistentWithExternalStores(prevExecutionContext) &&
|
||||
((didTimeout = renderRootSync(root, lanes)),
|
||||
2 === didTimeout &&
|
||||
((prevDispatcher = getLanesToRetrySynchronouslyOnError(root)),
|
||||
0 !== prevDispatcher &&
|
||||
((lanes = prevDispatcher),
|
||||
(didTimeout = recoverFromConcurrentError(root, prevDispatcher)))),
|
||||
1 === didTimeout)
|
||||
)
|
||||
throw ((originalCallbackNode = workInProgressRootFatalError),
|
||||
prepareFreshStack(root, 0),
|
||||
markRootSuspended$1(root, lanes),
|
||||
ensureRootIsScheduled(root, now()),
|
||||
originalCallbackNode);
|
||||
root.finishedWork = prevExecutionContext;
|
||||
root.finishedLanes = lanes;
|
||||
switch (didTimeout) {
|
||||
case 0:
|
||||
|
@ -6797,10 +6862,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
10 < didTimeout)
|
||||
) {
|
||||
if (0 !== getNextLanes(root, 0)) break;
|
||||
JSCompiler_inline_result = root.suspendedLanes;
|
||||
if ((JSCompiler_inline_result & lanes) !== lanes) {
|
||||
prevExecutionContext = root.suspendedLanes;
|
||||
if ((prevExecutionContext & lanes) !== lanes) {
|
||||
requestEventTime();
|
||||
root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result;
|
||||
root.pingedLanes |= root.suspendedLanes & prevExecutionContext;
|
||||
break;
|
||||
}
|
||||
root.timeoutHandle = scheduleTimeout(
|
||||
|
@ -6815,14 +6880,14 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
markRootSuspended$1(root, lanes);
|
||||
if ((lanes & 4194240) === lanes) break;
|
||||
didTimeout = root.eventTimes;
|
||||
for (JSCompiler_inline_result = -1; 0 < lanes; )
|
||||
for (prevExecutionContext = -1; 0 < lanes; )
|
||||
(memoizedUpdaters = 31 - clz32(lanes)),
|
||||
(prevDispatcher = 1 << memoizedUpdaters),
|
||||
(memoizedUpdaters = didTimeout[memoizedUpdaters]),
|
||||
memoizedUpdaters > JSCompiler_inline_result &&
|
||||
(JSCompiler_inline_result = memoizedUpdaters),
|
||||
memoizedUpdaters > prevExecutionContext &&
|
||||
(prevExecutionContext = memoizedUpdaters),
|
||||
(lanes &= ~prevDispatcher);
|
||||
lanes = JSCompiler_inline_result;
|
||||
lanes = prevExecutionContext;
|
||||
lanes = now() - lanes;
|
||||
lanes =
|
||||
(120 > lanes
|
||||
|
@ -6859,6 +6924,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
|
|||
? performConcurrentWorkOnRoot.bind(null, root)
|
||||
: null;
|
||||
}
|
||||
function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
var prevExecutionContext = executionContext;
|
||||
executionContext |= 8;
|
||||
root.hydrate && (root.hydrate = !1);
|
||||
root = renderRootSync(root, errorRetryLanes);
|
||||
executionContext = prevExecutionContext;
|
||||
return root;
|
||||
}
|
||||
function isRenderConsistentWithExternalStores(finishedWork) {
|
||||
for (var node = finishedWork; ; ) {
|
||||
if (node.flags & 8192) {
|
||||
var updateQueue = node.updateQueue;
|
||||
if (
|
||||
null !== updateQueue &&
|
||||
((updateQueue = updateQueue.stores), null !== updateQueue)
|
||||
)
|
||||
for (var i = 0; i < updateQueue.length; i++) {
|
||||
var check = updateQueue[i],
|
||||
getSnapshot = check.getSnapshot;
|
||||
check = check.value;
|
||||
try {
|
||||
if (!objectIs(getSnapshot(), check)) return !1;
|
||||
} catch (error) {
|
||||
return !1;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateQueue = node.child;
|
||||
if (node.subtreeFlags & 8192 && null !== updateQueue)
|
||||
(updateQueue.return = node), (node = updateQueue);
|
||||
else {
|
||||
if (node === finishedWork) break;
|
||||
for (; null === node.sibling; ) {
|
||||
if (null === node.return || node.return === finishedWork) return !0;
|
||||
node = node.return;
|
||||
}
|
||||
node.sibling.return = node.return;
|
||||
node = node.sibling;
|
||||
}
|
||||
}
|
||||
return !0;
|
||||
}
|
||||
function markRootSuspended$1(root, suspendedLanes) {
|
||||
suspendedLanes &= ~workInProgressRootPingedLanes;
|
||||
suspendedLanes &= ~workInProgressRootUpdatedLanes;
|
||||
|
@ -7010,7 +7117,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
sourceFiber = erroredWork,
|
||||
value = thrownValue;
|
||||
thrownValue = workInProgressRootRenderLanes;
|
||||
sourceFiber.flags |= 8192;
|
||||
sourceFiber.flags |= 16384;
|
||||
isDevToolsPresent && restorePendingUpdaters(root, thrownValue);
|
||||
if (
|
||||
null !== value &&
|
||||
|
@ -7062,8 +7169,8 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
workInProgress$34 !== returnFiber
|
||||
) {
|
||||
workInProgress$34.flags |= 128;
|
||||
sourceFiber.flags |= 32768;
|
||||
sourceFiber.flags &= -10053;
|
||||
sourceFiber.flags |= 65536;
|
||||
sourceFiber.flags &= -26437;
|
||||
if (1 === sourceFiber.tag)
|
||||
if (null === sourceFiber.alternate) sourceFiber.tag = 17;
|
||||
else {
|
||||
|
@ -7095,7 +7202,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
isDevToolsPresent && restorePendingUpdaters(root, sourceFiber);
|
||||
wakeable.then(ping, ping);
|
||||
}
|
||||
workInProgress$34.flags |= 16384;
|
||||
workInProgress$34.flags |= 32768;
|
||||
workInProgress$34.lanes = thrownValue;
|
||||
break a;
|
||||
}
|
||||
|
@ -7114,7 +7221,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
switch (workInProgress$34.tag) {
|
||||
case 3:
|
||||
root = value;
|
||||
workInProgress$34.flags |= 16384;
|
||||
workInProgress$34.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$34.lanes |= thrownValue;
|
||||
var update$35 = createRootErrorUpdate(
|
||||
|
@ -7136,7 +7243,7 @@ function handleError(root$jscomp$0, thrownValue) {
|
|||
(null === legacyErrorBoundariesThatAlreadyFailed ||
|
||||
!legacyErrorBoundariesThatAlreadyFailed.has(instance))))
|
||||
) {
|
||||
workInProgress$34.flags |= 16384;
|
||||
workInProgress$34.flags |= 32768;
|
||||
thrownValue &= -thrownValue;
|
||||
workInProgress$34.lanes |= thrownValue;
|
||||
var update$38 = createClassErrorUpdate(
|
||||
|
@ -7226,7 +7333,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
do {
|
||||
var current = completedWork.alternate;
|
||||
unitOfWork = completedWork.return;
|
||||
if (0 === (completedWork.flags & 8192)) {
|
||||
if (0 === (completedWork.flags & 16384)) {
|
||||
if (0 === (completedWork.mode & 2))
|
||||
current = completeWork(current, completedWork, subtreeRenderLanes);
|
||||
else {
|
||||
|
@ -7243,7 +7350,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
} else {
|
||||
current = unwindWork(completedWork);
|
||||
if (null !== current) {
|
||||
current.flags &= 8191;
|
||||
current.flags &= 16383;
|
||||
workInProgress = current;
|
||||
return;
|
||||
}
|
||||
|
@ -7255,7 +7362,7 @@ function completeUnitOfWork(unitOfWork) {
|
|||
completedWork.actualDuration = current;
|
||||
}
|
||||
null !== unitOfWork &&
|
||||
((unitOfWork.flags |= 8192),
|
||||
((unitOfWork.flags |= 16384),
|
||||
(unitOfWork.subtreeFlags = 0),
|
||||
(unitOfWork.deletions = null));
|
||||
}
|
||||
|
@ -7335,12 +7442,6 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
(pendingPassiveEffectsLanes = lanes));
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null);
|
||||
0 !== (remainingLanes & 1)
|
||||
? ((nestedUpdateScheduled = !0),
|
||||
root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)))
|
||||
: (nestedUpdateCount = 0);
|
||||
onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
|
||||
isDevToolsPresent && root.memoizedUpdaters.clear();
|
||||
ensureRootIsScheduled(root, now());
|
||||
|
@ -7352,6 +7453,13 @@ function commitRootImpl(root, renderPriorityLevel) {
|
|||
0 !== (pendingPassiveEffectsLanes & 1) &&
|
||||
0 !== root.tag &&
|
||||
flushPassiveEffects();
|
||||
remainingLanes = root.pendingLanes;
|
||||
0 !== (remainingLanes & 1)
|
||||
? ((nestedUpdateScheduled = !0),
|
||||
root === rootWithNestedUpdates
|
||||
? nestedUpdateCount++
|
||||
: ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)))
|
||||
: (nestedUpdateCount = 0);
|
||||
flushSyncCallbacks();
|
||||
return null;
|
||||
}
|
||||
|
@ -7390,9 +7498,9 @@ function flushPassiveEffects() {
|
|||
case 15:
|
||||
current.mode & 2
|
||||
? ((passiveEffectStartTime = now$1()),
|
||||
commitHookEffectListUnmount(4, current, fiber),
|
||||
commitHookEffectListUnmount(8, current, fiber),
|
||||
recordPassiveEffectDuration(current))
|
||||
: commitHookEffectListUnmount(4, current, fiber);
|
||||
: commitHookEffectListUnmount(8, current, fiber);
|
||||
}
|
||||
var child$jscomp$0 = fiber$jscomp$0.child;
|
||||
if (null !== child$jscomp$0)
|
||||
|
@ -7444,9 +7552,9 @@ function flushPassiveEffects() {
|
|||
case 15:
|
||||
i.mode & 2
|
||||
? ((passiveEffectStartTime = now$1()),
|
||||
commitHookEffectListUnmount(5, i, i.return),
|
||||
commitHookEffectListUnmount(9, i, i.return),
|
||||
recordPassiveEffectDuration(i))
|
||||
: commitHookEffectListUnmount(5, i, i.return);
|
||||
: commitHookEffectListUnmount(9, i, i.return);
|
||||
}
|
||||
var sibling$jscomp$0 = fiber.sibling;
|
||||
if (null !== sibling$jscomp$0) {
|
||||
|
@ -7475,11 +7583,11 @@ function flushPassiveEffects() {
|
|||
if (fiberToDelete.mode & 2) {
|
||||
passiveEffectStartTime = now$1();
|
||||
try {
|
||||
commitHookEffectListMount(5, fiberToDelete);
|
||||
commitHookEffectListMount(9, fiberToDelete);
|
||||
} finally {
|
||||
recordPassiveEffectDuration(fiberToDelete);
|
||||
}
|
||||
} else commitHookEffectListMount(5, fiberToDelete);
|
||||
} else commitHookEffectListMount(9, fiberToDelete);
|
||||
}
|
||||
} catch (error) {
|
||||
captureCommitPhaseError(deletions, deletions.return, error);
|
||||
|
@ -7674,7 +7782,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) {
|
|||
renderLanes
|
||||
)
|
||||
);
|
||||
didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1;
|
||||
didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1;
|
||||
}
|
||||
else didReceiveUpdate = !1;
|
||||
workInProgress.lanes = 0;
|
||||
|
@ -8155,7 +8263,7 @@ function createWorkInProgress(current, pendingProps) {
|
|||
(workInProgress.deletions = null),
|
||||
(workInProgress.actualDuration = 0),
|
||||
(workInProgress.actualStartTime = -1));
|
||||
workInProgress.flags = current.flags & 1835008;
|
||||
workInProgress.flags = current.flags & 3670016;
|
||||
workInProgress.childLanes = current.childLanes;
|
||||
workInProgress.lanes = current.lanes;
|
||||
workInProgress.child = current.child;
|
||||
|
@ -8519,10 +8627,10 @@ batchedUpdatesImpl = function(fn, a) {
|
|||
}
|
||||
};
|
||||
var roots = new Map(),
|
||||
devToolsConfig$jscomp$inline_1019 = {
|
||||
devToolsConfig$jscomp$inline_1016 = {
|
||||
findFiberByHostInstance: getInstanceFromTag,
|
||||
bundleType: 0,
|
||||
version: "18.0.0-95d762e40-20210908",
|
||||
version: "18.0.0-e8feb11b6-20210915",
|
||||
rendererPackageName: "react-native-renderer",
|
||||
rendererConfig: {
|
||||
getInspectorDataForViewTag: function() {
|
||||
|
@ -8537,11 +8645,11 @@ var roots = new Map(),
|
|||
}.bind(null, findNodeHandle)
|
||||
}
|
||||
};
|
||||
var internals$jscomp$inline_1292 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_1019.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_1019.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_1019.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_1019.rendererConfig,
|
||||
var internals$jscomp$inline_1289 = {
|
||||
bundleType: devToolsConfig$jscomp$inline_1016.bundleType,
|
||||
version: devToolsConfig$jscomp$inline_1016.version,
|
||||
rendererPackageName: devToolsConfig$jscomp$inline_1016.rendererPackageName,
|
||||
rendererConfig: devToolsConfig$jscomp$inline_1016.rendererConfig,
|
||||
overrideHookState: null,
|
||||
overrideHookStateDeletePath: null,
|
||||
overrideHookStateRenamePath: null,
|
||||
|
@ -8557,7 +8665,7 @@ var internals$jscomp$inline_1292 = {
|
|||
return null === fiber ? null : fiber.stateNode;
|
||||
},
|
||||
findFiberByHostInstance:
|
||||
devToolsConfig$jscomp$inline_1019.findFiberByHostInstance ||
|
||||
devToolsConfig$jscomp$inline_1016.findFiberByHostInstance ||
|
||||
emptyFindFiberByHostInstance,
|
||||
findHostInstancesForRefresh: null,
|
||||
scheduleRefresh: null,
|
||||
|
@ -8565,19 +8673,19 @@ var internals$jscomp$inline_1292 = {
|
|||
setRefreshHandler: null,
|
||||
getCurrentFiber: null,
|
||||
getIsStrictMode: null,
|
||||
reconcilerVersion: "18.0.0-95d762e40-20210908"
|
||||
reconcilerVersion: "18.0.0-e8feb11b6-20210915"
|
||||
};
|
||||
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
var hook$jscomp$inline_1293 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
var hook$jscomp$inline_1290 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
if (
|
||||
!hook$jscomp$inline_1293.isDisabled &&
|
||||
hook$jscomp$inline_1293.supportsFiber
|
||||
!hook$jscomp$inline_1290.isDisabled &&
|
||||
hook$jscomp$inline_1290.supportsFiber
|
||||
)
|
||||
try {
|
||||
(rendererID = hook$jscomp$inline_1293.inject(
|
||||
internals$jscomp$inline_1292
|
||||
(rendererID = hook$jscomp$inline_1290.inject(
|
||||
internals$jscomp$inline_1289
|
||||
)),
|
||||
(injectedHook = hook$jscomp$inline_1293);
|
||||
(injectedHook = hook$jscomp$inline_1290);
|
||||
} catch (err) {}
|
||||
}
|
||||
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
|
||||
|
|
|
@ -288,20 +288,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
@"streetAddressLine2": UITextContentTypeStreetAddressLine2,
|
||||
@"sublocality": UITextContentTypeSublocality,
|
||||
@"telephoneNumber": UITextContentTypeTelephoneNumber,
|
||||
@"username": UITextContentTypeUsername,
|
||||
@"password": UITextContentTypePassword,
|
||||
};
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if (@available(iOS 11.0, *)) {
|
||||
NSDictionary<NSString *, NSString *> * iOS11extras = @{@"username": UITextContentTypeUsername,
|
||||
@"password": UITextContentTypePassword};
|
||||
|
||||
NSMutableDictionary<NSString *, NSString *> * 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, *)) {
|
||||
NSDictionary<NSString *, NSString *> * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword,
|
||||
|
|
|
@ -30,21 +30,17 @@
|
|||
_heightConstraint = [_safeAreaContainer.heightAnchor constraintEqualToConstant:0];
|
||||
_heightConstraint.active = YES;
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
if (@available(iOS 11.0, *)) {
|
||||
[_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
|
||||
[_safeAreaContainer.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
|
||||
[_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leadingAnchor].active = YES;
|
||||
[_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.trailingAnchor].active = YES;
|
||||
} else {
|
||||
#endif // TODO(macOS GH#774)
|
||||
[_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES;
|
||||
[_safeAreaContainer.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
|
||||
[_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = YES;
|
||||
[_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = YES;
|
||||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
}
|
||||
#endif // TODO(macOS GH#774)
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
[_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
|
||||
[_safeAreaContainer.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
|
||||
[_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leadingAnchor].active = YES;
|
||||
[_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.trailingAnchor].active = YES;
|
||||
#else // TODO(macOS GH#774)
|
||||
[_safeAreaContainer.bottomAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES;
|
||||
[_safeAreaContainer.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
|
||||
[_safeAreaContainer.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = YES;
|
||||
[_safeAreaContainer.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = YES;
|
||||
#endif // ]TODO(macOS GH#774)
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -16,12 +16,6 @@ RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollec
|
|||
RCT_EXTERN BOOL RCTExperimentGetPreemptiveViewAllocationDisabled(void);
|
||||
RCT_EXTERN void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value);
|
||||
|
||||
/*
|
||||
* Initial maximum surface size
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTGetInitialMaxSizeEnabled(void);
|
||||
RCT_EXTERN void RCTSetInitialMaxSizeEnabled(BOOL value);
|
||||
|
||||
/*
|
||||
* Remove clipped subviews
|
||||
*/
|
||||
|
|
|
@ -25,21 +25,6 @@ void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value)
|
|||
RCTExperimentPreemptiveViewAllocationDisabled = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial maximum surface size
|
||||
*/
|
||||
static BOOL RCTInitialMaxSizeEnabled = NO;
|
||||
|
||||
BOOL RCTGetInitialMaxSizeEnabled()
|
||||
{
|
||||
return RCTInitialMaxSizeEnabled;
|
||||
}
|
||||
|
||||
void RCTSetInitialMaxSizeEnabled(BOOL value)
|
||||
{
|
||||
RCTInitialMaxSizeEnabled = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove clipped subviews
|
||||
*/
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef NSURL RCTFileURL;
|
|||
#endif
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
+ (WKDataDetectorTypes)WKDataDetectorTypes:(id)json API_AVAILABLE(ios(10.0));
|
||||
+ (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
|
||||
#endif
|
||||
|
||||
+ (UIViewContentMode)UIViewContentMode:(id)json;
|
||||
|
|
|
@ -41,10 +41,6 @@
|
|||
|
||||
__weak RCTUIView *_cachedRootView; // TODO(macOS GH#774)
|
||||
|
||||
// See Touch.h and usage. This gives us a time-basis for a monotonic
|
||||
// clock that acts like a timestamp of milliseconds elapsed since UNIX epoch.
|
||||
NSTimeInterval _unixEpochBasisTime;
|
||||
|
||||
uint16_t _coalescingKey;
|
||||
#if TARGET_OS_OSX// [TODO(macOS GH#774)
|
||||
BOOL _shouldSendMouseUpOnSystemBehalf;
|
||||
|
@ -62,9 +58,6 @@
|
|||
_reactTouches = [NSMutableArray new];
|
||||
_touchViews = [NSMutableArray new];
|
||||
|
||||
// Get a UNIX epoch basis time:
|
||||
_unixEpochBasisTime = [[NSDate date] timeIntervalSince1970] - [NSProcessInfo processInfo].systemUptime;
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
// `cancelsTouchesInView` and `delaysTouches*` are needed in order to be used as a top level
|
||||
// event delegated recognizer. Otherwise, lower-level components not built
|
||||
|
@ -236,7 +229,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)coder)
|
|||
reactTouch[@"pageY"] = @(RCTSanitizeNaNValue(rootViewLocation.y, @"touchEvent.pageY"));
|
||||
reactTouch[@"locationX"] = @(RCTSanitizeNaNValue(touchViewLocation.x, @"touchEvent.locationX"));
|
||||
reactTouch[@"locationY"] = @(RCTSanitizeNaNValue(touchViewLocation.y, @"touchEvent.locationY"));
|
||||
reactTouch[@"timestamp"] = @((_unixEpochBasisTime + nativeTouch.timestamp) * 1000); // in ms, for JS
|
||||
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
// TODO: force for a 'normal' touch is usually 1.0;
|
||||
|
|
|
@ -40,6 +40,9 @@ RCT_EXTERN void RCTExecuteOnMainQueue(dispatch_block_t block);
|
|||
// Please do not use this unless you know what you're doing.
|
||||
RCT_EXTERN void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block);
|
||||
|
||||
// Get screen scale, can be only used on main
|
||||
RCT_EXTERN void RCTComputeScreenScale(void);
|
||||
|
||||
// Get screen metrics in a thread-safe way
|
||||
RCT_EXTERN CGFloat RCTScreenScale(void);
|
||||
RCT_EXTERN CGFloat RCTFontSizeMultiplier(void);
|
||||
|
|
|
@ -297,16 +297,23 @@ static void RCTUnsafeExecuteOnMainQueueOnceSync(dispatch_once_t *onceToken, disp
|
|||
}
|
||||
|
||||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
static dispatch_once_t onceTokenScreenScale;
|
||||
static CGFloat screenScale;
|
||||
|
||||
void RCTComputeScreenScale()
|
||||
{
|
||||
dispatch_once(&onceTokenScreenScale, ^{
|
||||
screenScale = [UIScreen mainScreen].scale;
|
||||
});
|
||||
}
|
||||
|
||||
CGFloat RCTScreenScale()
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static CGFloat scale;
|
||||
|
||||
RCTUnsafeExecuteOnMainQueueOnceSync(&onceToken, ^{
|
||||
scale = [UIScreen mainScreen].scale;
|
||||
RCTUnsafeExecuteOnMainQueueOnceSync(&onceTokenScreenScale, ^{
|
||||
screenScale = [UIScreen mainScreen].scale;
|
||||
});
|
||||
|
||||
return scale;
|
||||
return screenScale;
|
||||
}
|
||||
|
||||
CGFloat RCTFontSizeMultiplier()
|
||||
|
@ -335,7 +342,7 @@ CGFloat RCTFontSizeMultiplier()
|
|||
|
||||
CGSize RCTScreenSize()
|
||||
{
|
||||
// FIXME: this caches the bounds at app start, whatever those were, and then
|
||||
// FIXME: this caches whatever the bounds were when it was first called, and then
|
||||
// doesn't update when the device is rotated. We need to find another thread-
|
||||
// safe way to get the screen size.
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions
|
|||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
UIViewController *controller = RCTPresentedViewController();
|
||||
UIColor *tintColor = [RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];
|
||||
UIColor *cancelButtonTintColor =
|
||||
[RCTConvert UIColor:options.cancelButtonTintColor() ? @(*options.cancelButtonTintColor()) : nil];
|
||||
|
||||
if (controller == nil) {
|
||||
RCTLogError(
|
||||
|
@ -131,6 +133,7 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions
|
|||
@"destructiveButtonIndices" : destructiveButtonIndices ?: [NSNull null],
|
||||
@"anchor" : anchor ?: [NSNull null],
|
||||
@"tintColor" : tintColor ?: [NSNull null],
|
||||
@"cancelButtonTintColor" : cancelButtonTintColor ?: [NSNull null],
|
||||
@"disabledButtonIndices" : disabledButtonIndices ?: [NSNull null],
|
||||
}); /* // TODO(macOS GH#774): nil check our dict values before inserting them or we may crash ] */
|
||||
return;
|
||||
|
@ -149,20 +152,26 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions
|
|||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
NSInteger index = 0;
|
||||
bool isCancelButtonIndex = false;
|
||||
for (NSString *option in buttons) {
|
||||
UIAlertActionStyle style = UIAlertActionStyleDefault;
|
||||
if ([destructiveButtonIndices containsObject:@(index)]) {
|
||||
style = UIAlertActionStyleDestructive;
|
||||
} else if (index == cancelButtonIndex) {
|
||||
style = UIAlertActionStyleCancel;
|
||||
isCancelButtonIndex = true;
|
||||
}
|
||||
|
||||
NSInteger localIndex = index;
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:option
|
||||
style:style
|
||||
handler:^(__unused UIAlertAction *action) {
|
||||
callback(@[ @(localIndex) ]);
|
||||
}]];
|
||||
UIAlertAction *actionButton = [UIAlertAction actionWithTitle:option
|
||||
style:style
|
||||
handler:^(__unused UIAlertAction *action) {
|
||||
callback(@[ @(localIndex) ]);
|
||||
}];
|
||||
if (isCancelButtonIndex) {
|
||||
[actionButton setValue:cancelButtonTintColor forKey:@"titleTextColor"];
|
||||
}
|
||||
[alertController addAction:actionButton];
|
||||
|
||||
index++;
|
||||
}
|
||||
|
|
|
@ -128,16 +128,11 @@ RCT_EXPORT_MODULE()
|
|||
#if !TARGET_OS_OSX // TODO(macOS GH#774)
|
||||
CGSize screenSize = [UIScreen mainScreen].bounds.size;
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
UIWindow *window = RCTSharedApplication().keyWindow;
|
||||
self->_window =
|
||||
[[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, window.safeAreaInsets.top + 10)];
|
||||
self->_label =
|
||||
[[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, screenSize.width, 20)];
|
||||
} else {
|
||||
self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, 20)];
|
||||
self->_label = [[UILabel alloc] initWithFrame:self->_window.bounds];
|
||||
}
|
||||
UIWindow *window = RCTSharedApplication().keyWindow;
|
||||
self->_window =
|
||||
[[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, window.safeAreaInsets.top + 10)];
|
||||
self->_label =
|
||||
[[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, screenSize.width, 20)];
|
||||
[self->_window addSubview:self->_label];
|
||||
|
||||
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
|
||||
|
|
|
@ -206,11 +206,7 @@
|
|||
|
||||
- (NSInteger)bottomSafeViewHeight
|
||||
{
|
||||
if (@available(iOS 11.0, *)) {
|
||||
return RCTSharedApplication().delegate.window.safeAreaInsets.bottom;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return RCTSharedApplication().delegate.window.safeAreaInsets.bottom;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
||||
|
|
|
@ -59,6 +59,9 @@ typedef void (^RCTConnectedHandler)(void);
|
|||
/** Disconnects and removes all handlers. */
|
||||
- (void)stop;
|
||||
|
||||
/** Reconnect with given packager server. */
|
||||
- (void)reconnect:(NSString *)packagerServerHostPort;
|
||||
|
||||
/**
|
||||
* Historically no distinction was made between notification and request
|
||||
* handlers. If you use this method, it will be registered as *both* a
|
||||
|
|
|
@ -125,28 +125,32 @@ static RCTReconnectingWebSocket *socketForLocation(NSString *const serverHostPor
|
|||
_requestRegistrations.clear();
|
||||
}
|
||||
|
||||
- (void)bundleURLSettingsChanged
|
||||
- (void)reconnect:(NSString *)packagerServerHostPort
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_mutex);
|
||||
if (_socket == nil) {
|
||||
return; // already stopped
|
||||
}
|
||||
|
||||
NSString *const serverHostPort = [[RCTBundleURLProvider sharedSettings] packagerServerHostPort];
|
||||
NSString *const serverScheme = [[RCTBundleURLProvider sharedSettings] packagerScheme];
|
||||
if ([serverHostPort isEqual:_serverHostPortForSocket] && [serverScheme isEqual:_serverSchemeForSocket]) {
|
||||
if ([packagerServerHostPort isEqual:_serverHostPortForSocket] && [serverScheme isEqual:_serverSchemeForSocket]) {
|
||||
return; // unchanged
|
||||
}
|
||||
|
||||
_socket.delegate = nil;
|
||||
[_socket stop];
|
||||
_serverHostPortForSocket = serverHostPort;
|
||||
_serverHostPortForSocket = packagerServerHostPort;
|
||||
_serverSchemeForSocket = serverScheme;
|
||||
_socket = socketForLocation(serverHostPort, serverScheme);
|
||||
_socket = socketForLocation(packagerServerHostPort, serverScheme);
|
||||
_socket.delegate = self;
|
||||
[_socket start];
|
||||
}
|
||||
|
||||
- (void)bundleURLSettingsChanged
|
||||
{
|
||||
[self reconnect:[[RCTBundleURLProvider sharedSettings] packagerServerHostPort]];
|
||||
}
|
||||
|
||||
- (RCTHandlerToken)addNotificationHandler:(RCTNotificationHandler)handler
|
||||
queue:(dispatch_queue_t)queue
|
||||
forMethod:(NSString *)method
|
||||
|
|
|
@ -133,15 +133,6 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg
|
|||
[self.scrollViewDelegateSplitter removeAllDelegates];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
if (_subviewClippingEnabled) {
|
||||
[self _remountChildren];
|
||||
}
|
||||
}
|
||||
|
||||
- (RCTGenericDelegateSplitter<id<UIScrollViewDelegate>> *)scrollViewDelegateSplitter
|
||||
{
|
||||
return ((RCTEnhancedScrollView *)_scrollView).delegateSplitter;
|
||||
|
@ -611,6 +602,11 @@ static void RCTSendPaperScrollEvent_DEPRECATED(UIScrollView *scrollView, NSInteg
|
|||
|
||||
#pragma mark - Child views mounting
|
||||
|
||||
- (void)updateClippedSubviewsWithClipRect:(CGRect)clipRect relativeToView:(UIView *)clipView
|
||||
{
|
||||
// Do nothing. ScrollView manages its subview clipping individually in `_remountChildren`.
|
||||
}
|
||||
|
||||
- (void)_remountChildrenIfNeeded
|
||||
{
|
||||
CGPoint contentOffset = _scrollView.contentOffset;
|
||||
|
|
|
@ -331,11 +331,7 @@ using namespace facebook::react;
|
|||
|
||||
// `accessibilityIgnoresInvertColors`
|
||||
if (oldViewProps.accessibilityIgnoresInvertColors != newViewProps.accessibilityIgnoresInvertColors) {
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if (@available(iOS 11.0, *)) {
|
||||
self.accessibilityIgnoresInvertColors = newViewProps.accessibilityIgnoresInvertColors;
|
||||
}
|
||||
#endif
|
||||
self.accessibilityIgnoresInvertColors = newViewProps.accessibilityIgnoresInvertColors;
|
||||
}
|
||||
|
||||
// `accessibilityValue`
|
||||
|
|
|
@ -122,8 +122,8 @@ class LayoutAnimationDelegateProxy : public LayoutAnimationStatusDelegate, publi
|
|||
|
||||
if (reactNativeConfig->getBool("react_fabric:enabled_layout_animations_ios")) {
|
||||
_layoutAnimationDelegateProxy = std::make_shared<LayoutAnimationDelegateProxy>((__bridge void *)self);
|
||||
_animationDriver =
|
||||
std::make_shared<LayoutAnimationDriver>(toolbox.runtimeExecutor, _layoutAnimationDelegateProxy.get());
|
||||
_animationDriver = std::make_shared<LayoutAnimationDriver>(
|
||||
toolbox.runtimeExecutor, toolbox.contextContainer, _layoutAnimationDelegateProxy.get());
|
||||
if (reactNativeConfig->getBool("react_fabric:enabled_skip_invalidated_key_frames_ios")) {
|
||||
_animationDriver->enableSkipInvalidatedKeyFrames();
|
||||
}
|
||||
|
|
|
@ -261,10 +261,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
|
|||
RCTSetRemoveClippedSubviewsEnabled(YES);
|
||||
}
|
||||
|
||||
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_initial_max_size_ios")) {
|
||||
RCTSetInitialMaxSizeEnabled(YES);
|
||||
}
|
||||
|
||||
auto componentRegistryFactory =
|
||||
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
|
||||
EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#import <React/RCTUtils.h>
|
||||
#import <React/RCTViewComponentView.h>
|
||||
#import <UIKit/UIGestureRecognizerSubclass.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTConversions.h"
|
||||
#import "RCTTouchableComponentViewProtocol.h"
|
||||
|
@ -83,8 +82,7 @@ static void UpdateActiveTouchWithUITouch(
|
|||
ActiveTouch &activeTouch,
|
||||
UITouch *uiTouch,
|
||||
UIView *rootComponentView,
|
||||
CGPoint rootViewOriginOffset,
|
||||
NSTimeInterval unixTimestampBasis)
|
||||
CGPoint rootViewOriginOffset)
|
||||
{
|
||||
CGPoint offsetPoint = [uiTouch locationInView:activeTouch.componentView];
|
||||
CGPoint screenPoint = [uiTouch locationInView:uiTouch.window];
|
||||
|
@ -95,18 +93,14 @@ static void UpdateActiveTouchWithUITouch(
|
|||
activeTouch.touch.screenPoint = RCTPointFromCGPoint(screenPoint);
|
||||
activeTouch.touch.pagePoint = RCTPointFromCGPoint(pagePoint);
|
||||
|
||||
activeTouch.touch.timestamp = unixTimestampBasis + uiTouch.timestamp;
|
||||
activeTouch.touch.timestamp = uiTouch.timestamp;
|
||||
|
||||
if (RCTForceTouchAvailable()) {
|
||||
activeTouch.touch.force = RCTZeroIfNaN(uiTouch.force / uiTouch.maximumPossibleForce);
|
||||
}
|
||||
}
|
||||
|
||||
static ActiveTouch CreateTouchWithUITouch(
|
||||
UITouch *uiTouch,
|
||||
UIView *rootComponentView,
|
||||
CGPoint rootViewOriginOffset,
|
||||
NSTimeInterval unixTimestampBasis)
|
||||
static ActiveTouch CreateTouchWithUITouch(UITouch *uiTouch, UIView *rootComponentView, CGPoint rootViewOriginOffset)
|
||||
{
|
||||
ActiveTouch activeTouch = {};
|
||||
|
||||
|
@ -123,7 +117,7 @@ static ActiveTouch CreateTouchWithUITouch(
|
|||
componentView = componentView.superview;
|
||||
}
|
||||
|
||||
UpdateActiveTouchWithUITouch(activeTouch, uiTouch, rootComponentView, rootViewOriginOffset, unixTimestampBasis);
|
||||
UpdateActiveTouchWithUITouch(activeTouch, uiTouch, rootComponentView, rootViewOriginOffset);
|
||||
return activeTouch;
|
||||
}
|
||||
|
||||
|
@ -173,12 +167,6 @@ struct PointerHasher {
|
|||
*/
|
||||
__weak UIView *_rootComponentView;
|
||||
IdentifierPool<11> _identifierPool;
|
||||
|
||||
/*
|
||||
* See Touch.h and usage. This gives us a time-basis for a monotonic
|
||||
* clock that acts like a timestamp of milliseconds elapsed since UNIX epoch.
|
||||
*/
|
||||
NSTimeInterval _unixEpochBasisTime;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
|
@ -193,8 +181,6 @@ struct PointerHasher {
|
|||
self.delaysTouchesEnded = NO;
|
||||
|
||||
self.delegate = self;
|
||||
|
||||
_unixEpochBasisTime = [[NSDate date] timeIntervalSince1970] - [NSProcessInfo processInfo].systemUptime;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -222,7 +208,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithTarget : (id)target action : (SEL)act
|
|||
- (void)_registerTouches:(NSSet<UITouch *> *)touches
|
||||
{
|
||||
for (UITouch *touch in touches) {
|
||||
auto activeTouch = CreateTouchWithUITouch(touch, _rootComponentView, _viewOriginOffset, _unixEpochBasisTime);
|
||||
auto activeTouch = CreateTouchWithUITouch(touch, _rootComponentView, _viewOriginOffset);
|
||||
activeTouch.touch.identifier = _identifierPool.dequeue();
|
||||
_activeTouches.emplace(touch, activeTouch);
|
||||
}
|
||||
|
@ -237,7 +223,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithTarget : (id)target action : (SEL)act
|
|||
continue;
|
||||
}
|
||||
|
||||
UpdateActiveTouchWithUITouch(iterator->second, touch, _rootComponentView, _viewOriginOffset, _unixEpochBasisTime);
|
||||
UpdateActiveTouchWithUITouch(iterator->second, touch, _rootComponentView, _viewOriginOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,9 +61,7 @@ using namespace facebook::react;
|
|||
|
||||
[_surfacePresenter registerSurface:self];
|
||||
|
||||
if (RCTGetInitialMaxSizeEnabled()) {
|
||||
[self setMinimumSize:CGSizeZero maximumSize:RCTViewportSize()];
|
||||
}
|
||||
[self setMinimumSize:CGSizeZero maximumSize:RCTViewportSize()];
|
||||
|
||||
[self _updateLayoutContext];
|
||||
|
||||
|
|
|
@ -344,12 +344,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|||
|
||||
if (bundle) {
|
||||
NSURL *url = [bundle URLForResource:@"Localizable" withExtension:@"strings"];
|
||||
if (@available(iOS 11.0, *)) {
|
||||
rolesAndStatesDescription = [NSDictionary dictionaryWithContentsOfURL:url error:nil];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
rolesAndStatesDescription = [NSDictionary dictionaryWithContentsOfURL:url];
|
||||
}
|
||||
rolesAndStatesDescription = [NSDictionary dictionaryWithContentsOfURL:url error:nil];
|
||||
}
|
||||
if (rolesAndStatesDescription == nil) {
|
||||
// Falling back to hardcoded English list.
|
||||
|
|
|
@ -54,13 +54,9 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
|||
|
||||
- (UIEdgeInsets)safeAreaInsetsIfSupportedAndEnabled
|
||||
{
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if (self.isSupportedByOS) {
|
||||
if (@available(iOS 11.0, *)) {
|
||||
return self.safeAreaInsets;
|
||||
}
|
||||
return self.safeAreaInsets;
|
||||
}
|
||||
#endif
|
||||
return self.emulateUnlessSupported ? self.emulatedSafeAreaInsets : UIEdgeInsetsZero;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,10 +276,8 @@
|
|||
self.contentOffset = originalOffset;
|
||||
} else {
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
if (@available(iOS 11.0, *)) {
|
||||
if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, self.adjustedContentInset)) {
|
||||
contentInset = self.adjustedContentInset;
|
||||
}
|
||||
if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, self.adjustedContentInset)) {
|
||||
contentInset = self.adjustedContentInset;
|
||||
}
|
||||
#endif // [TODO(macOS GH#774)
|
||||
CGSize boundsSize = self.bounds.size;
|
||||
|
@ -409,17 +407,15 @@
|
|||
|
||||
#pragma clang diagnostic push // TODO(OSS Candidate ISS#2710739)
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability" // TODO(OSS Candidate ISS#2710739)
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
// `contentInsetAdjustmentBehavior` is only available since iOS 11.
|
||||
// We set the default behavior to "never" so that iOS
|
||||
// doesn't do weird things to UIScrollView insets automatically
|
||||
// and keeps it as an opt-in behavior.
|
||||
if ([_scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
|
||||
if (@available(iOS 11.0, *)) {
|
||||
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
#endif
|
||||
#endif // ]TODO(macOS GH#774)
|
||||
#pragma clang diagnostic pop // TODO(OSS Candidate ISS#2710739)
|
||||
|
||||
_automaticallyAdjustContentInsets = YES;
|
||||
|
@ -1302,19 +1298,17 @@ RCT_SET_AND_PRESERVE_OFFSET(setScrollIndicatorInsets, scrollIndicatorInsets, UIE
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior API_AVAILABLE(ios(11.0))
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior
|
||||
{
|
||||
// `contentInsetAdjustmentBehavior` is available since iOS 11.
|
||||
if ([_scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
|
||||
CGPoint contentOffset = _scrollView.contentOffset;
|
||||
if (@available(iOS 11.0, *)) {
|
||||
_scrollView.contentInsetAdjustmentBehavior = behavior;
|
||||
}
|
||||
_scrollView.contentInsetAdjustmentBehavior = behavior;
|
||||
_scrollView.contentOffset = contentOffset;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ]TODO(macOS GH#774)
|
||||
#pragma clang diagnostic pop // TODO(OSS Candidate ISS#2710739)
|
||||
|
||||
- (void)sendScrollEventWithName:(NSString *)eventName
|
||||
|
|
|
@ -37,9 +37,6 @@ RCT_ENUM_CONVERTER(
|
|||
UIScrollViewIndicatorStyleDefault,
|
||||
integerValue)
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
RCT_ENUM_CONVERTER(
|
||||
UIScrollViewContentInsetAdjustmentBehavior,
|
||||
(@{
|
||||
|
@ -50,8 +47,6 @@ RCT_ENUM_CONVERTER(
|
|||
}),
|
||||
UIScrollViewContentInsetAdjustmentNever,
|
||||
integerValue)
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@end
|
||||
#endif // TODO(OSS Candidate ISS#2710739)
|
||||
|
@ -109,9 +104,7 @@ RCT_EXPORT_VIEW_PROPERTY(inverted, BOOL)
|
|||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */
|
||||
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustsScrollIndicatorInsets, BOOL)
|
||||
#endif
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
|
||||
#endif
|
||||
|
||||
// overflow is used both in css-layout as well as by react-native. In css-layout
|
||||
// we always want to treat overflow as scroll but depending on what the overflow
|
||||
|
|
|
@ -47,21 +47,12 @@
|
|||
|
||||
- (BOOL)shouldAccessibilityIgnoresInvertColors
|
||||
{
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if (@available(iOS 11.0, *)) {
|
||||
return self.accessibilityIgnoresInvertColors;
|
||||
}
|
||||
#endif
|
||||
return NO;
|
||||
return self.accessibilityIgnoresInvertColors;
|
||||
}
|
||||
|
||||
- (void)setShouldAccessibilityIgnoresInvertColors:(BOOL)shouldAccessibilityIgnoresInvertColors
|
||||
{
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
if (@available(iOS 11.0, *)) {
|
||||
self.accessibilityIgnoresInvertColors = shouldAccessibilityIgnoresInvertColors;
|
||||
}
|
||||
#endif
|
||||
self.accessibilityIgnoresInvertColors = shouldAccessibilityIgnoresInvertColors;
|
||||
}
|
||||
|
||||
- (BOOL)isReactRootView
|
||||
|
|
|
@ -219,6 +219,7 @@ public class ReactInstanceManager {
|
|||
@Nullable String jsMainModulePath,
|
||||
List<ReactPackage> packages,
|
||||
boolean useDeveloperSupport,
|
||||
DevSupportManagerFactory devSupportManagerFactory,
|
||||
boolean requireActivity,
|
||||
@Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
|
||||
LifecycleState initialLifecycleState,
|
||||
|
@ -250,7 +251,7 @@ public class ReactInstanceManager {
|
|||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.initDevSupportManager");
|
||||
mDevSupportManager =
|
||||
DevSupportManagerFactory.create(
|
||||
devSupportManagerFactory.create(
|
||||
applicationContext,
|
||||
createDevHelperInterface(),
|
||||
mJSMainModulePath,
|
||||
|
@ -1225,7 +1226,8 @@ public class ReactInstanceManager {
|
|||
// If we can't get a UIManager something has probably gone horribly wrong
|
||||
if (uiManager == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to attach a rootView to ReactInstance when UIManager is not properly initialized.");
|
||||
"Unable to attach a rootView to ReactInstance when UIManager is not properly"
|
||||
+ " initialized.");
|
||||
}
|
||||
|
||||
@Nullable Bundle initialProperties = reactRoot.getAppProperties();
|
||||
|
@ -1366,10 +1368,6 @@ public class ReactInstanceManager {
|
|||
}
|
||||
}
|
||||
|
||||
if (ReactFeatureFlags.enableRuntimeScheduler) {
|
||||
catalystInstance.installRuntimeScheduler();
|
||||
}
|
||||
|
||||
if (mJSIModulePackage != null) {
|
||||
catalystInstance.addJSIModules(
|
||||
mJSIModulePackage.getJSIModules(
|
||||
|
|
|
@ -22,6 +22,8 @@ import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
|||
import com.facebook.react.bridge.NativeModuleCallExceptionHandler;
|
||||
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.devsupport.DefaultDevSupportManagerFactory;
|
||||
import com.facebook.react.devsupport.DevSupportManagerFactory;
|
||||
import com.facebook.react.devsupport.RedBoxHandler;
|
||||
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
|
@ -45,6 +47,7 @@ public class ReactInstanceManagerBuilder {
|
|||
private @Nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener;
|
||||
private @Nullable Application mApplication;
|
||||
private boolean mUseDeveloperSupport;
|
||||
private @Nullable DevSupportManagerFactory mDevSupportManagerFactory;
|
||||
private boolean mRequireActivity;
|
||||
private @Nullable LifecycleState mInitialLifecycleState;
|
||||
private @Nullable UIImplementationProvider mUIImplementationProvider;
|
||||
|
@ -172,6 +175,16 @@ public class ReactInstanceManagerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom {@link DevSupportManagerFactory}. If not set, will use {@link
|
||||
* DefaultDevSupportManagerFactory}.
|
||||
*/
|
||||
public ReactInstanceManagerBuilder setDevSupportManagerFactory(
|
||||
final DevSupportManagerFactory devSupportManagerFactory) {
|
||||
mDevSupportManagerFactory = devSupportManagerFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When {@code false}, indicates that correct usage of React Native will NOT involve an Activity.
|
||||
* For the vast majority of Android apps in the ecosystem, this will not need to change. Unless
|
||||
|
@ -294,6 +307,9 @@ public class ReactInstanceManagerBuilder {
|
|||
mJSMainModulePath,
|
||||
mPackages,
|
||||
mUseDeveloperSupport,
|
||||
mDevSupportManagerFactory == null
|
||||
? new DefaultDevSupportManagerFactory()
|
||||
: mDevSupportManagerFactory,
|
||||
mRequireActivity,
|
||||
mBridgeIdleDebugListener,
|
||||
Assertions.assertNotNull(mInitialLifecycleState, "Initial lifecycle state was not set"),
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
|||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.devsupport.DevSupportManagerFactory;
|
||||
import com.facebook.react.devsupport.RedBoxHandler;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
import java.util.List;
|
||||
|
@ -68,6 +69,7 @@ public abstract class ReactNativeHost {
|
|||
.setApplication(mApplication)
|
||||
.setJSMainModulePath(getJSMainModuleName())
|
||||
.setUseDeveloperSupport(getUseDeveloperSupport())
|
||||
.setDevSupportManagerFactory(getDevSupportManagerFactory())
|
||||
.setRequireActivity(getShouldRequireActivity())
|
||||
.setRedBoxHandler(getRedBoxHandler())
|
||||
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
|
||||
|
@ -160,6 +162,11 @@ public abstract class ReactNativeHost {
|
|||
/** Returns whether dev mode should be enabled. This enables e.g. the dev menu. */
|
||||
public abstract boolean getUseDeveloperSupport();
|
||||
|
||||
/** Get the {@link DevSupportManagerFactory}. Override this to use a custom dev support manager */
|
||||
protected @Nullable DevSupportManagerFactory getDevSupportManagerFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of {@link ReactPackage} used by the app. You'll most likely want to return at
|
||||
* least the {@code MainReactPackage}. If your app uses additional views or modules besides the
|
||||
|
|
|
@ -16,8 +16,10 @@ import android.content.Context;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
@ -647,6 +649,11 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
|||
mJSTouchDispatcher = new JSTouchDispatcher(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
/* package */ void simulateCheckForKeyboardForTesting() {
|
||||
getCustomGlobalLayoutListener().checkForKeyboardEvents();
|
||||
}
|
||||
|
||||
private CustomGlobalLayoutListener getCustomGlobalLayoutListener() {
|
||||
if (mCustomGlobalLayoutListener == null) {
|
||||
mCustomGlobalLayoutListener = new CustomGlobalLayoutListener();
|
||||
|
@ -766,8 +773,17 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
|||
|
||||
private void checkForKeyboardEvents() {
|
||||
getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea);
|
||||
int notchHeight = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
DisplayCutout displayCutout = getRootView().getRootWindowInsets().getDisplayCutout();
|
||||
if (displayCutout != null) {
|
||||
notchHeight = displayCutout.getSafeInsetTop();
|
||||
}
|
||||
}
|
||||
final int heightDiff =
|
||||
DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
|
||||
DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels
|
||||
- mVisibleViewArea.bottom
|
||||
+ notchHeight;
|
||||
|
||||
boolean isKeyboardShowingOrKeyboardHeightChanged =
|
||||
mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected;
|
||||
|
|
|
@ -113,8 +113,6 @@ public interface CatalystInstance
|
|||
|
||||
RuntimeScheduler getRuntimeScheduler();
|
||||
|
||||
void installRuntimeScheduler();
|
||||
|
||||
void addJSIModules(List<JSIModuleSpec> jsiModules);
|
||||
|
||||
/**
|
||||
|
|
|
@ -108,7 +108,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||
// C++ parts
|
||||
private final HybridData mHybridData;
|
||||
|
||||
private static native HybridData initHybrid();
|
||||
private static native HybridData initHybrid(
|
||||
boolean enableRuntimeScheduler, boolean enableRuntimeSchedulerInTurboModule);
|
||||
|
||||
public native CallInvokerHolderImpl getJSCallInvokerHolder();
|
||||
|
||||
|
@ -123,7 +124,15 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||
FLog.d(ReactConstants.TAG, "Initializing React Xplat Bridge.");
|
||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createCatalystInstanceImpl");
|
||||
|
||||
mHybridData = initHybrid();
|
||||
if (ReactFeatureFlags.enableRuntimeSchedulerInTurboModule
|
||||
&& !ReactFeatureFlags.enableRuntimeScheduler) {
|
||||
Assertions.assertUnreachable();
|
||||
}
|
||||
|
||||
mHybridData =
|
||||
initHybrid(
|
||||
ReactFeatureFlags.enableRuntimeScheduler,
|
||||
ReactFeatureFlags.enableRuntimeSchedulerInTurboModule);
|
||||
|
||||
mReactQueueConfiguration =
|
||||
ReactQueueConfigurationImpl.create(
|
||||
|
@ -560,8 +569,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||
|
||||
public native RuntimeScheduler getRuntimeScheduler();
|
||||
|
||||
public native void installRuntimeScheduler();
|
||||
|
||||
@Override
|
||||
public void addJSIModules(List<JSIModuleSpec> jsiModules) {
|
||||
mJSIModuleRegistry.registerModules(jsiModules);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_build_config", "rn_android_library")
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "HERMES_BYTECODE_VERSION", "react_native_dep", "rn_android_build_config", "rn_android_library")
|
||||
|
||||
SUB_PROJECTS = [
|
||||
"network/**/*",
|
||||
|
@ -41,7 +41,7 @@ rn_android_build_config(
|
|||
package = "com.facebook.react",
|
||||
values = [
|
||||
"boolean IS_INTERNAL_BUILD = true",
|
||||
"int HERMES_BYTECODE_VERSION = 0",
|
||||
"int HERMES_BYTECODE_VERSION = {}".format(HERMES_BYTECODE_VERSION),
|
||||
],
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
|
|
|
@ -72,6 +72,8 @@ public class ReactFeatureFlags {
|
|||
|
||||
public static boolean enableRuntimeScheduler = false;
|
||||
|
||||
public static boolean enableRuntimeSchedulerInTurboModule = false;
|
||||
|
||||
/** Enables a more aggressive cleanup during destruction of ReactContext */
|
||||
public static boolean enableReactContextCleanupFix = false;
|
||||
|
||||
|
@ -95,4 +97,6 @@ public class ReactFeatureFlags {
|
|||
public static boolean enableLockFreeEventDispatcher = false;
|
||||
|
||||
public static boolean enableAggressiveEventEmitterCleanup = false;
|
||||
|
||||
public static boolean insertZReorderBarriersOnViewGroupChildren = true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.devsupport;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.packagerconnection.RequestHandler;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple factory that creates instances of {@link DevSupportManager} implementations. Uses
|
||||
* reflection to create BridgeDevSupportManager if it exists. This allows ProGuard to strip that
|
||||
* class and its dependencies in release builds. If the class isn't found, {@link
|
||||
* DisabledDevSupportManager} is returned instead.
|
||||
*/
|
||||
public class DefaultDevSupportManagerFactory implements DevSupportManagerFactory {
|
||||
|
||||
private static final String DEVSUPPORT_IMPL_PACKAGE = "com.facebook.react.devsupport";
|
||||
private static final String DEVSUPPORT_IMPL_CLASS = "BridgeDevSupportManager";
|
||||
|
||||
public DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceDevHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
int minNumShakes) {
|
||||
|
||||
return create(
|
||||
applicationContext,
|
||||
reactInstanceDevHelper,
|
||||
packagerPathForJSBundleName,
|
||||
enableOnCreate,
|
||||
null,
|
||||
null,
|
||||
minNumShakes,
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceManagerHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
@Nullable RedBoxHandler redBoxHandler,
|
||||
@Nullable DevBundleDownloadListener devBundleDownloadListener,
|
||||
int minNumShakes,
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers) {
|
||||
if (!enableOnCreate) {
|
||||
return new DisabledDevSupportManager();
|
||||
}
|
||||
try {
|
||||
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
|
||||
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
|
||||
// confuse it.
|
||||
String className =
|
||||
new StringBuilder(DEVSUPPORT_IMPL_PACKAGE)
|
||||
.append(".")
|
||||
.append(DEVSUPPORT_IMPL_CLASS)
|
||||
.toString();
|
||||
Class<?> devSupportManagerClass = Class.forName(className);
|
||||
Constructor constructor =
|
||||
devSupportManagerClass.getConstructor(
|
||||
Context.class,
|
||||
ReactInstanceDevHelper.class,
|
||||
String.class,
|
||||
boolean.class,
|
||||
RedBoxHandler.class,
|
||||
DevBundleDownloadListener.class,
|
||||
int.class,
|
||||
Map.class);
|
||||
return (DevSupportManager)
|
||||
constructor.newInstance(
|
||||
applicationContext,
|
||||
reactInstanceManagerHelper,
|
||||
packagerPathForJSBundleName,
|
||||
true,
|
||||
redBoxHandler,
|
||||
devBundleDownloadListener,
|
||||
minNumShakes,
|
||||
customPackagerCommandHandlers);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Requested enabled DevSupportManager, but BridgeDevSupportManager class was not found"
|
||||
+ " or could not be created",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,39 +12,10 @@ import androidx.annotation.Nullable;
|
|||
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.packagerconnection.RequestHandler;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple factory that creates instances of {@link DevSupportManager} implementations. Uses
|
||||
* reflection to create BridgeDevSupportManager if it exists. This allows ProGuard to strip that
|
||||
* class and its dependencies in release builds. If the class isn't found, {@link
|
||||
* DisabledDevSupportManager} is returned instead.
|
||||
*/
|
||||
public class DevSupportManagerFactory {
|
||||
|
||||
private static final String DEVSUPPORT_IMPL_PACKAGE = "com.facebook.react.devsupport";
|
||||
private static final String DEVSUPPORT_IMPL_CLASS = "BridgeDevSupportManager";
|
||||
|
||||
public static DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceDevHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
int minNumShakes) {
|
||||
|
||||
return create(
|
||||
applicationContext,
|
||||
reactInstanceDevHelper,
|
||||
packagerPathForJSBundleName,
|
||||
enableOnCreate,
|
||||
null,
|
||||
null,
|
||||
minNumShakes,
|
||||
null);
|
||||
}
|
||||
|
||||
public static DevSupportManager create(
|
||||
public interface DevSupportManagerFactory {
|
||||
DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceManagerHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
|
@ -52,45 +23,5 @@ public class DevSupportManagerFactory {
|
|||
@Nullable RedBoxHandler redBoxHandler,
|
||||
@Nullable DevBundleDownloadListener devBundleDownloadListener,
|
||||
int minNumShakes,
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers) {
|
||||
if (!enableOnCreate) {
|
||||
return new DisabledDevSupportManager();
|
||||
}
|
||||
try {
|
||||
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
|
||||
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
|
||||
// confuse it.
|
||||
String className =
|
||||
new StringBuilder(DEVSUPPORT_IMPL_PACKAGE)
|
||||
.append(".")
|
||||
.append(DEVSUPPORT_IMPL_CLASS)
|
||||
.toString();
|
||||
Class<?> devSupportManagerClass = Class.forName(className);
|
||||
Constructor constructor =
|
||||
devSupportManagerClass.getConstructor(
|
||||
Context.class,
|
||||
ReactInstanceDevHelper.class,
|
||||
String.class,
|
||||
boolean.class,
|
||||
RedBoxHandler.class,
|
||||
DevBundleDownloadListener.class,
|
||||
int.class,
|
||||
Map.class);
|
||||
return (DevSupportManager)
|
||||
constructor.newInstance(
|
||||
applicationContext,
|
||||
reactInstanceManagerHelper,
|
||||
packagerPathForJSBundleName,
|
||||
true,
|
||||
redBoxHandler,
|
||||
devBundleDownloadListener,
|
||||
minNumShakes,
|
||||
customPackagerCommandHandlers);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Requested enabled DevSupportManager, but BridgeDevSupportManager class was not found"
|
||||
+ " or could not be created",
|
||||
e);
|
||||
}
|
||||
}
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 <jsi/jsi.h>
|
||||
#include <react/renderer/core/EventBeat.h>
|
||||
#include <react/renderer/uimanager/primitives.h>
|
||||
|
||||
#include "AsyncEventBeatV2.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
AsyncEventBeatV2::AsyncEventBeatV2(
|
||||
EventBeat::SharedOwnerBox const &ownerBox,
|
||||
EventBeatManager *eventBeatManager,
|
||||
RuntimeExecutor runtimeExecutor,
|
||||
jni::global_ref<jobject> javaUIManager)
|
||||
: EventBeat(ownerBox),
|
||||
eventBeatManager_(eventBeatManager),
|
||||
runtimeExecutor_(runtimeExecutor),
|
||||
javaUIManager_(javaUIManager) {
|
||||
eventBeatManager->addObserver(*this);
|
||||
}
|
||||
|
||||
AsyncEventBeatV2::~AsyncEventBeatV2() {
|
||||
eventBeatManager_->removeObserver(*this);
|
||||
}
|
||||
|
||||
void AsyncEventBeatV2::tick() const {
|
||||
if (!isRequested_ || isBeatCallbackScheduled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
isRequested_ = false;
|
||||
isBeatCallbackScheduled_ = true;
|
||||
|
||||
runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime &runtime) {
|
||||
isBeatCallbackScheduled_ = false;
|
||||
auto owner = ownerBox->owner.lock();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (beatCallback_) {
|
||||
beatCallback_(runtime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AsyncEventBeatV2::induce() const {
|
||||
tick();
|
||||
}
|
||||
|
||||
void AsyncEventBeatV2::request() const {
|
||||
bool alreadyRequested = isRequested_;
|
||||
EventBeat::request();
|
||||
if (!alreadyRequested) {
|
||||
// Notifies java side that an event will be dispatched (e.g. LayoutEvent)
|
||||
static auto onRequestEventBeat =
|
||||
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
|
||||
->getMethod<void()>("onRequestEventBeat");
|
||||
onRequestEventBeat(javaUIManager_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 <react/renderer/core/EventBeat.h>
|
||||
|
||||
#include "EventBeatManager.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class AsyncEventBeatV2 final : public EventBeat,
|
||||
public EventBeatManagerObserver {
|
||||
public:
|
||||
AsyncEventBeatV2(
|
||||
EventBeat::SharedOwnerBox const &ownerBox,
|
||||
EventBeatManager *eventBeatManager,
|
||||
RuntimeExecutor runtimeExecutor,
|
||||
jni::global_ref<jobject> javaUIManager);
|
||||
|
||||
~AsyncEventBeatV2() override;
|
||||
|
||||
void tick() const override;
|
||||
|
||||
void induce() const override;
|
||||
|
||||
void request() const override;
|
||||
|
||||
private:
|
||||
EventBeatManager *eventBeatManager_;
|
||||
RuntimeExecutor runtimeExecutor_;
|
||||
jni::global_ref<jobject> javaUIManager_;
|
||||
mutable std::atomic<bool> isBeatCallbackScheduled_{false};
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "Binding.h"
|
||||
#include "AsyncEventBeat.h"
|
||||
#include "AsyncEventBeatV2.h"
|
||||
#include "EventEmitterWrapper.h"
|
||||
#include "ReactNativeConfigHolder.h"
|
||||
#include "StateWrapperImpl.h"
|
||||
|
@ -529,7 +530,7 @@ void Binding::installFabricUIManager(
|
|||
auto runtimeExecutor = runtimeExecutorHolder->cthis()->get();
|
||||
|
||||
if (runtimeSchedulerHolder) {
|
||||
auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get();
|
||||
auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock();
|
||||
if (runtimeScheduler) {
|
||||
runtimeScheduler->setEnableYielding(config->getBool(
|
||||
"react_native_new_architecture:runtimescheduler_enable_yielding_android"));
|
||||
|
@ -541,22 +542,39 @@ void Binding::installFabricUIManager(
|
|||
}
|
||||
}
|
||||
|
||||
auto enableV2AsynchronousEventBeat =
|
||||
config->getBool("react_fabric:enable_asynchronous_event_beat_v2_android");
|
||||
|
||||
// TODO: T31905686 Create synchronous Event Beat
|
||||
jni::global_ref<jobject> localJavaUIManager = javaUIManager_;
|
||||
EventBeat::Factory synchronousBeatFactory =
|
||||
[eventBeatManager, runtimeExecutor, localJavaUIManager](
|
||||
EventBeat::SharedOwnerBox const &ownerBox)
|
||||
[eventBeatManager,
|
||||
runtimeExecutor,
|
||||
localJavaUIManager,
|
||||
enableV2AsynchronousEventBeat](EventBeat::SharedOwnerBox const &ownerBox)
|
||||
-> std::unique_ptr<EventBeat> {
|
||||
return std::make_unique<AsyncEventBeat>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
if (enableV2AsynchronousEventBeat) {
|
||||
return std::make_unique<AsyncEventBeatV2>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
} else {
|
||||
return std::make_unique<AsyncEventBeat>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
}
|
||||
};
|
||||
|
||||
EventBeat::Factory asynchronousBeatFactory =
|
||||
[eventBeatManager, runtimeExecutor, localJavaUIManager](
|
||||
EventBeat::SharedOwnerBox const &ownerBox)
|
||||
[eventBeatManager,
|
||||
runtimeExecutor,
|
||||
localJavaUIManager,
|
||||
enableV2AsynchronousEventBeat](EventBeat::SharedOwnerBox const &ownerBox)
|
||||
-> std::unique_ptr<EventBeat> {
|
||||
return std::make_unique<AsyncEventBeat>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
if (enableV2AsynchronousEventBeat) {
|
||||
return std::make_unique<AsyncEventBeatV2>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
} else {
|
||||
return std::make_unique<AsyncEventBeat>(
|
||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||
}
|
||||
};
|
||||
|
||||
contextContainer->insert("ReactNativeConfig", config);
|
||||
|
@ -587,8 +605,8 @@ void Binding::installFabricUIManager(
|
|||
toolbox.backgroundExecutor = backgroundExecutor_->get();
|
||||
}
|
||||
|
||||
animationDriver_ =
|
||||
std::make_shared<LayoutAnimationDriver>(runtimeExecutor, this);
|
||||
animationDriver_ = std::make_shared<LayoutAnimationDriver>(
|
||||
runtimeExecutor, contextContainer, this);
|
||||
scheduler_ = std::make_shared<Scheduler>(
|
||||
toolbox, (animationDriver_ ? animationDriver_.get() : nullptr), this);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ import androidx.annotation.Nullable;
|
|||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.touch.ReactHitSlopView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class responsible for identifying which react view should handle a given {@link MotionEvent}. It
|
||||
|
@ -81,7 +83,7 @@ public class TouchTargetHelper {
|
|||
// Store eventCoords in array so that they are modified to be relative to the targetView found.
|
||||
viewCoords[0] = eventX;
|
||||
viewCoords[1] = eventY;
|
||||
View nativeTargetView = findTouchTargetViewWithPointerEvents(viewCoords, viewGroup);
|
||||
View nativeTargetView = findTouchTargetViewWithPointerEvents(viewCoords, viewGroup, null);
|
||||
if (nativeTargetView != null) {
|
||||
View reactTargetView = findClosestReactAncestor(nativeTargetView);
|
||||
if (reactTargetView != null) {
|
||||
|
@ -94,6 +96,39 @@ public class TouchTargetHelper {
|
|||
return targetTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find touch event target view within the provided container given the coordinates provided via
|
||||
* {@link MotionEvent}.
|
||||
*
|
||||
* @param eventX the X screen coordinate of the touch location
|
||||
* @param eventY the Y screen coordinate of the touch location
|
||||
* @param viewGroup the container view to traverse
|
||||
* @param viewCoords an out parameter that will return the X,Y value in the target view
|
||||
* @return If a target was found, returns a path through the view tree of all react tags that are
|
||||
* a container for the touch target, ordered from target to root (last element)
|
||||
*/
|
||||
public static List<Integer> findTargetPathAndCoordinatesForTouch(
|
||||
float eventX, float eventY, ViewGroup viewGroup, float[] viewCoords) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
// Store eventCoords in array so that they are modified to be relative to the targetView found.
|
||||
viewCoords[0] = eventX;
|
||||
viewCoords[1] = eventY;
|
||||
|
||||
List<Integer> pathAccumulator = new ArrayList<>();
|
||||
View targetView = findTouchTargetViewWithPointerEvents(viewCoords, viewGroup, pathAccumulator);
|
||||
|
||||
if (targetView != null) {
|
||||
View reactTargetView = findClosestReactAncestor(targetView);
|
||||
int targetTag = getTouchTargetForView(reactTargetView, viewCoords[0], viewCoords[1]);
|
||||
if (targetTag != pathAccumulator.get(0)) {
|
||||
pathAccumulator.add(0, targetTag);
|
||||
}
|
||||
}
|
||||
|
||||
return pathAccumulator;
|
||||
}
|
||||
|
||||
private static View findClosestReactAncestor(View view) {
|
||||
while (view != null && view.getId() <= 0) {
|
||||
view = (View) view.getParent();
|
||||
|
@ -121,7 +156,10 @@ public class TouchTargetHelper {
|
|||
* relative to the targetView found.
|
||||
*/
|
||||
private static View findTouchTargetView(
|
||||
float[] eventCoords, View view, EnumSet<TouchTargetReturnType> allowReturnTouchTargetTypes) {
|
||||
float[] eventCoords,
|
||||
View view,
|
||||
EnumSet<TouchTargetReturnType> allowReturnTouchTargetTypes,
|
||||
List<Integer> pathAccumulator) {
|
||||
// We prefer returning a child, so we check for a child that can handle the touch first
|
||||
if (allowReturnTouchTargetTypes.contains(TouchTargetReturnType.CHILD)
|
||||
&& view instanceof ViewGroup) {
|
||||
|
@ -143,7 +181,7 @@ public class TouchTargetHelper {
|
|||
float restoreY = eventCoords[1];
|
||||
eventCoords[0] = childPoint.x;
|
||||
eventCoords[1] = childPoint.y;
|
||||
View targetView = findTouchTargetViewWithPointerEvents(eventCoords, child);
|
||||
View targetView = findTouchTargetViewWithPointerEvents(eventCoords, child, pathAccumulator);
|
||||
|
||||
if (targetView != null) {
|
||||
// We don't allow touches on views that are outside the bounds of an `overflow: hidden`
|
||||
|
@ -224,7 +262,7 @@ public class TouchTargetHelper {
|
|||
* its descendants are the touch target.
|
||||
*/
|
||||
private static @Nullable View findTouchTargetViewWithPointerEvents(
|
||||
float eventCoords[], View view) {
|
||||
float eventCoords[], View view, @Nullable List<Integer> pathAccumulator) {
|
||||
PointerEvents pointerEvents =
|
||||
view instanceof ReactPointerEventsView
|
||||
? ((ReactPointerEventsView) view).getPointerEvents()
|
||||
|
@ -247,13 +285,23 @@ public class TouchTargetHelper {
|
|||
|
||||
} else if (pointerEvents == PointerEvents.BOX_ONLY) {
|
||||
// This view may be the target, its children don't matter
|
||||
return findTouchTargetView(eventCoords, view, EnumSet.of(TouchTargetReturnType.SELF));
|
||||
View targetView =
|
||||
findTouchTargetView(
|
||||
eventCoords, view, EnumSet.of(TouchTargetReturnType.SELF), pathAccumulator);
|
||||
if (targetView != null && pathAccumulator != null) {
|
||||
pathAccumulator.add(view.getId());
|
||||
}
|
||||
return targetView;
|
||||
|
||||
} else if (pointerEvents == PointerEvents.BOX_NONE) {
|
||||
// This view can't be the target, but its children might.
|
||||
View targetView =
|
||||
findTouchTargetView(eventCoords, view, EnumSet.of(TouchTargetReturnType.CHILD));
|
||||
findTouchTargetView(
|
||||
eventCoords, view, EnumSet.of(TouchTargetReturnType.CHILD), pathAccumulator);
|
||||
if (targetView != null) {
|
||||
if (pathAccumulator != null) {
|
||||
pathAccumulator.add(view.getId());
|
||||
}
|
||||
return targetView;
|
||||
}
|
||||
|
||||
|
@ -266,8 +314,11 @@ public class TouchTargetHelper {
|
|||
if (view instanceof ReactCompoundView
|
||||
&& isTouchPointInView(eventCoords[0], eventCoords[1], view)) {
|
||||
int reactTag = ((ReactCompoundView) view).reactTagForTouch(eventCoords[0], eventCoords[1]);
|
||||
// make sure we exclude the View itself because of the PointerEvents.BOX_NONE
|
||||
if (reactTag != view.getId()) {
|
||||
// make sure we exclude the View itself because of the PointerEvents.BOX_NONE
|
||||
if (pathAccumulator != null) {
|
||||
pathAccumulator.add(view.getId());
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
@ -279,10 +330,22 @@ public class TouchTargetHelper {
|
|||
if (view instanceof ReactCompoundViewGroup
|
||||
&& isTouchPointInView(eventCoords[0], eventCoords[1], view)
|
||||
&& ((ReactCompoundViewGroup) view).interceptsTouchEvent(eventCoords[0], eventCoords[1])) {
|
||||
if (pathAccumulator != null) {
|
||||
pathAccumulator.add(view.getId());
|
||||
}
|
||||
return view;
|
||||
}
|
||||
return findTouchTargetView(
|
||||
eventCoords, view, EnumSet.of(TouchTargetReturnType.SELF, TouchTargetReturnType.CHILD));
|
||||
|
||||
View result =
|
||||
findTouchTargetView(
|
||||
eventCoords,
|
||||
view,
|
||||
EnumSet.of(TouchTargetReturnType.SELF, TouchTargetReturnType.CHILD),
|
||||
pathAccumulator);
|
||||
if (result != null && pathAccumulator != null) {
|
||||
pathAccumulator.add(view.getId());
|
||||
}
|
||||
return result;
|
||||
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
|
|
|
@ -40,15 +40,6 @@ public abstract class Event<T extends Event> {
|
|||
private long mTimestampMs;
|
||||
private int mUniqueID = sUniqueID++;
|
||||
|
||||
// Android native Event times use 'uptimeMillis', and historically we've used `uptimeMillis`
|
||||
// throughout this Event class as the coalescing key for events, and for other purposes.
|
||||
// To get an accurate(ish) absolute UNIX time for the event, we store the initial clock time here.
|
||||
// uptimeMillis can then be added to this to get an accurate UNIX time.
|
||||
// However, we still default to uptimeMillis: you must explicitly request UNIX time if you want
|
||||
// that; see `getUnixTimestampMs`.
|
||||
public static final long sInitialClockTimeUnixOffset =
|
||||
SystemClock.currentTimeMillis() - SystemClock.uptimeMillis();
|
||||
|
||||
protected Event() {}
|
||||
|
||||
@Deprecated
|
||||
|
@ -65,8 +56,16 @@ public abstract class Event<T extends Event> {
|
|||
init(-1, viewTag);
|
||||
}
|
||||
|
||||
/** This method needs to be called before event is sent to event dispatcher. */
|
||||
protected void init(int surfaceId, int viewTag) {
|
||||
init(surfaceId, viewTag, SystemClock.uptimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method needs to be called before event is sent to event dispatcher. Event timestamps can
|
||||
* optionally be dated/backdated to a custom time: for example, touch events should be dated with
|
||||
* the system event time.
|
||||
*/
|
||||
protected void init(int surfaceId, int viewTag, long timestampMs) {
|
||||
mSurfaceId = surfaceId;
|
||||
mViewTag = viewTag;
|
||||
|
||||
|
@ -82,9 +81,7 @@ public abstract class Event<T extends Event> {
|
|||
// At some point it would be great to pass the SurfaceContext here instead.
|
||||
mUIManagerType = (surfaceId == -1 ? UIManagerType.DEFAULT : UIManagerType.FABRIC);
|
||||
|
||||
// This is a *relative* time. See `getUnixTimestampMs`.
|
||||
mTimestampMs = SystemClock.uptimeMillis();
|
||||
|
||||
mTimestampMs = timestampMs;
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -106,11 +103,6 @@ public abstract class Event<T extends Event> {
|
|||
return mTimestampMs;
|
||||
}
|
||||
|
||||
/** @return the time at which the event happened as a UNIX timestamp, in milliseconds. */
|
||||
public final long getUnixTimestampMs() {
|
||||
return sInitialClockTimeUnixOffset + mTimestampMs;
|
||||
}
|
||||
|
||||
/** @return false if this Event can *never* be coalesced */
|
||||
public boolean canCoalesce() {
|
||||
return true;
|
||||
|
@ -174,7 +166,7 @@ public abstract class Event<T extends Event> {
|
|||
WritableMap eventData = getEventData();
|
||||
if (eventData == null) {
|
||||
throw new IllegalViewOperationException(
|
||||
"Event: you must return a valid, non-null value from `getEventData`, or override `dispatch` and `disatchModern`. Event: "
|
||||
"Event: you must return a valid, non-null value from `getEventData`, or override `dispatch` and `dispatchModern`. Event: "
|
||||
+ getEventName());
|
||||
}
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData);
|
||||
|
@ -224,7 +216,7 @@ public abstract class Event<T extends Event> {
|
|||
getEventName(),
|
||||
canCoalesce(),
|
||||
getCoalescingKey(),
|
||||
getEventData());
|
||||
eventData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
*/
|
||||
public class LockFreeEventDispatcherImpl implements EventDispatcher, LifecycleEventListener {
|
||||
|
||||
private final boolean DEBUG_MODE = true && ReactBuildConfig.DEBUG;
|
||||
private final boolean DEBUG_MODE = ReactBuildConfig.DEBUG;
|
||||
private final String TAG = LockFreeEventDispatcherImpl.class.getSimpleName();
|
||||
|
||||
private final ReactApplicationContext mReactContext;
|
||||
|
@ -77,7 +77,7 @@ public class LockFreeEventDispatcherImpl implements EventDispatcher, LifecycleEv
|
|||
Assertions.assertNotNull(mReactEventEmitter);
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
FLog.d(TAG, "dispatchEvent: " + event.toString());
|
||||
FLog.v(TAG, "dispatchEvent: " + event.toString());
|
||||
}
|
||||
|
||||
for (EventDispatcherListener listener : mListeners) {
|
||||
|
|
|
@ -61,15 +61,10 @@ public class ReactEventEmitter implements RCTModernEventEmitter {
|
|||
|
||||
@Override
|
||||
public void receiveEvent(
|
||||
int surfaceId,
|
||||
int targetTag,
|
||||
String eventName,
|
||||
boolean canCoalesceEvent,
|
||||
int customCoalesceKey,
|
||||
@Nullable WritableMap event) {
|
||||
int surfaceId, int targetTag, String eventName, @Nullable WritableMap event) {
|
||||
// The two additional params here, `canCoalesceEvent` and `customCoalesceKey`, have no
|
||||
// meaning outside of Fabric.
|
||||
receiveEvent(surfaceId, targetTag, eventName, event);
|
||||
receiveEvent(surfaceId, targetTag, eventName, false, 0, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -120,10 +115,16 @@ public class ReactEventEmitter implements RCTModernEventEmitter {
|
|||
|
||||
@Override
|
||||
public void receiveEvent(
|
||||
int surfaceId, int targetReactTag, String eventName, @Nullable WritableMap event) {
|
||||
int surfaceId,
|
||||
int targetReactTag,
|
||||
String eventName,
|
||||
boolean canCoalesceEvent,
|
||||
int customCoalesceKey,
|
||||
@Nullable WritableMap event) {
|
||||
@UIManagerType int uiManagerType = ViewUtil.getUIManagerType(targetReactTag);
|
||||
if (uiManagerType == UIManagerType.FABRIC && mFabricEventEmitter != null) {
|
||||
mFabricEventEmitter.receiveEvent(surfaceId, targetReactTag, eventName, event);
|
||||
mFabricEventEmitter.receiveEvent(
|
||||
surfaceId, targetReactTag, eventName, canCoalesceEvent, customCoalesceKey, event);
|
||||
} else if (uiManagerType == UIManagerType.DEFAULT && getEventEmitter(targetReactTag) != null) {
|
||||
mRCTEventEmitter.receiveEvent(targetReactTag, eventName, event);
|
||||
} else {
|
||||
|
|
|
@ -96,7 +96,7 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||
float viewX,
|
||||
float viewY,
|
||||
TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
|
||||
super.init(surfaceId, viewTag);
|
||||
super.init(surfaceId, viewTag, motionEventToCopy.getEventTime());
|
||||
|
||||
SoftAssertions.assertCondition(
|
||||
gestureStartTime != UNSET, "Gesture start time must be initialized");
|
||||
|
|
|
@ -64,7 +64,7 @@ public class TouchesHelper {
|
|||
touch.putDouble(LOCATION_Y_KEY, PixelUtil.toDIPFromPixel(locationY));
|
||||
touch.putInt(TARGET_SURFACE_KEY, surfaceId);
|
||||
touch.putInt(TARGET_KEY, reactTarget);
|
||||
touch.putDouble(TIMESTAMP_KEY, event.getUnixTimestampMs());
|
||||
touch.putDouble(TIMESTAMP_KEY, event.getTimestampMs());
|
||||
touch.putDouble(POINTER_IDENTIFIER_KEY, motionEvent.getPointerId(index));
|
||||
touches.pushMap(touch);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.view;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.Build;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Copied from <a
|
||||
* href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/CanvasUtils.android.kt;drc=3b2dde134afab8d58b9c39ad4820eaf9a6e014a9">
|
||||
* Compose canvas utils </a>
|
||||
*/
|
||||
public class CanvasUtil {
|
||||
private CanvasUtil() {}
|
||||
|
||||
private @Nullable static Method mReorderBarrierMethod = null;
|
||||
private @Nullable static Method mInorderBarrierMethod = null;
|
||||
private static boolean mOrderMethodsFetched = false;
|
||||
|
||||
/**
|
||||
* Enables Z support for the Canvas. The method is publicly available starting from API 29 and was
|
||||
* hidden before, so we have to resort to reflection tricks to ensure we can use this API.
|
||||
*/
|
||||
@SuppressLint({"SoonBlockedPrivateApi", "PrivateApi"})
|
||||
public static void enableZ(Canvas canvas, boolean enable) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
if (enable) {
|
||||
canvas.enableZ();
|
||||
} else {
|
||||
canvas.disableZ();
|
||||
}
|
||||
} else {
|
||||
fetchOrderMethods();
|
||||
try {
|
||||
if (enable && mReorderBarrierMethod != null) {
|
||||
mReorderBarrierMethod.invoke(canvas);
|
||||
}
|
||||
if (!enable && mInorderBarrierMethod != null) {
|
||||
mInorderBarrierMethod.invoke(canvas);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException ignore) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void fetchOrderMethods() {
|
||||
if (!mOrderMethodsFetched) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
|
||||
// use double reflection to avoid grey list on P
|
||||
Method getDeclaredMethod =
|
||||
Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);
|
||||
mReorderBarrierMethod =
|
||||
(Method) getDeclaredMethod.invoke(Canvas.class, "insertReorderBarrier", new Class[0]);
|
||||
mInorderBarrierMethod =
|
||||
(Method) getDeclaredMethod.invoke(Canvas.class, "insertInorderBarrier", new Class[0]);
|
||||
} else {
|
||||
mReorderBarrierMethod = Canvas.class.getDeclaredMethod("insertReorderBarrier");
|
||||
mInorderBarrierMethod = Canvas.class.getDeclaredMethod("insertInorderBarrier");
|
||||
}
|
||||
|
||||
if (mReorderBarrierMethod == null || mInorderBarrierMethod == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReorderBarrierMethod.setAccessible(true);
|
||||
mInorderBarrierMethod.setAccessible(true);
|
||||
} catch (IllegalAccessException ignore) {
|
||||
// Do nothing
|
||||
} catch (InvocationTargetException ignore) {
|
||||
// Do nothing
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
// Do nothing
|
||||
}
|
||||
mOrderMethodsFetched = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import com.facebook.react.bridge.ReactNoCrashSoftException;
|
|||
import com.facebook.react.bridge.ReactSoftExceptionLogger;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.modules.i18nmanager.I18nUtil;
|
||||
import com.facebook.react.touch.OnInterceptTouchEventListener;
|
||||
import com.facebook.react.touch.ReactHitSlopView;
|
||||
|
@ -759,6 +760,23 @@ public class ReactViewGroup extends ViewGroup
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
boolean drawWithZ =
|
||||
child.getElevation() > 0 && ReactFeatureFlags.insertZReorderBarriersOnViewGroupChildren;
|
||||
|
||||
if (drawWithZ) {
|
||||
CanvasUtil.enableZ(canvas, false);
|
||||
}
|
||||
|
||||
boolean result = super.drawChild(canvas, child, drawingTime);
|
||||
|
||||
if (drawWithZ) {
|
||||
CanvasUtil.enableZ(canvas, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void dispatchOverflowDraw(Canvas canvas) {
|
||||
if (mOverflow != null) {
|
||||
switch (mOverflow) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <glog/logging.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
|
||||
|
||||
#include <logger/react_native_log.h>
|
||||
|
||||
|
@ -92,12 +93,21 @@ class JInstanceCallback : public InstanceCallback {
|
|||
} // namespace
|
||||
|
||||
jni::local_ref<CatalystInstanceImpl::jhybriddata>
|
||||
CatalystInstanceImpl::initHybrid(jni::alias_ref<jclass>) {
|
||||
return makeCxxInstance();
|
||||
CatalystInstanceImpl::initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
bool enableRuntimeScheduler,
|
||||
bool enableRuntimeSchedulerInTurboModule) {
|
||||
return makeCxxInstance(
|
||||
enableRuntimeScheduler, enableRuntimeSchedulerInTurboModule);
|
||||
}
|
||||
|
||||
CatalystInstanceImpl::CatalystInstanceImpl()
|
||||
: instance_(std::make_unique<Instance>()) {}
|
||||
CatalystInstanceImpl::CatalystInstanceImpl(
|
||||
bool enableRuntimeScheduler,
|
||||
bool enableRuntimeSchedulerInTurboModule)
|
||||
: instance_(std::make_unique<Instance>()),
|
||||
enableRuntimeScheduler_(enableRuntimeScheduler),
|
||||
enableRuntimeSchedulerInTurboModule_(
|
||||
enableRuntimeScheduler && enableRuntimeSchedulerInTurboModule) {}
|
||||
|
||||
void CatalystInstanceImpl::warnOnLegacyNativeModuleSystemUse() {
|
||||
CxxNativeModule::setShouldWarnOnUse(true);
|
||||
|
@ -140,9 +150,6 @@ void CatalystInstanceImpl::registerNatives() {
|
|||
"getRuntimeExecutor", CatalystInstanceImpl::getRuntimeExecutor),
|
||||
makeNativeMethod(
|
||||
"getRuntimeScheduler", CatalystInstanceImpl::getRuntimeScheduler),
|
||||
makeNativeMethod(
|
||||
"installRuntimeScheduler",
|
||||
CatalystInstanceImpl::installRuntimeScheduler),
|
||||
makeNativeMethod(
|
||||
"warnOnLegacyNativeModuleSystemUse",
|
||||
CatalystInstanceImpl::warnOnLegacyNativeModuleSystemUse),
|
||||
|
@ -347,10 +354,18 @@ void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) {
|
|||
jni::alias_ref<CallInvokerHolder::javaobject>
|
||||
CatalystInstanceImpl::getJSCallInvokerHolder() {
|
||||
if (!jsCallInvokerHolder_) {
|
||||
jsCallInvokerHolder_ = jni::make_global(
|
||||
CallInvokerHolder::newObjectCxxArgs(instance_->getJSCallInvoker()));
|
||||
if (enableRuntimeSchedulerInTurboModule_) {
|
||||
auto runtimeScheduler = getRuntimeScheduler();
|
||||
auto runtimeSchedulerCallInvoker =
|
||||
std::make_shared<RuntimeSchedulerCallInvoker>(
|
||||
runtimeScheduler->cthis()->get());
|
||||
jsCallInvokerHolder_ = jni::make_global(
|
||||
CallInvokerHolder::newObjectCxxArgs(runtimeSchedulerCallInvoker));
|
||||
} else {
|
||||
jsCallInvokerHolder_ = jni::make_global(
|
||||
CallInvokerHolder::newObjectCxxArgs(instance_->getJSCallInvoker()));
|
||||
}
|
||||
}
|
||||
|
||||
return jsCallInvokerHolder_;
|
||||
}
|
||||
|
||||
|
@ -397,11 +412,7 @@ CatalystInstanceImpl::getRuntimeExecutor() {
|
|||
|
||||
jni::alias_ref<JRuntimeScheduler::javaobject>
|
||||
CatalystInstanceImpl::getRuntimeScheduler() {
|
||||
return runtimeScheduler_;
|
||||
}
|
||||
|
||||
void CatalystInstanceImpl::installRuntimeScheduler() {
|
||||
if (!runtimeScheduler_) {
|
||||
if (enableRuntimeScheduler_ && !runtimeScheduler_) {
|
||||
auto runtimeExecutor = instance_->getRuntimeExecutor();
|
||||
auto runtimeScheduler = std::make_shared<RuntimeScheduler>(runtimeExecutor);
|
||||
|
||||
|
@ -413,6 +424,8 @@ void CatalystInstanceImpl::installRuntimeScheduler() {
|
|||
runtime, runtimeScheduler);
|
||||
});
|
||||
}
|
||||
|
||||
return runtimeScheduler_;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -37,7 +37,10 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/facebook/react/bridge/CatalystInstanceImpl;";
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
bool enableRuntimeScheduler,
|
||||
bool enableRuntimeSchedulerInTurboModule);
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
|
@ -48,7 +51,9 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|||
private:
|
||||
friend HybridBase;
|
||||
|
||||
CatalystInstanceImpl();
|
||||
CatalystInstanceImpl(
|
||||
bool enableRuntimeScheduler,
|
||||
bool enableRuntimeSchedulerInTurboModule);
|
||||
|
||||
void initializeBridge(
|
||||
jni::alias_ref<ReactCallback::javaobject> callback,
|
||||
|
@ -100,11 +105,12 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|||
jni::alias_ref<CallInvokerHolder::javaobject> getNativeCallInvokerHolder();
|
||||
jni::alias_ref<JRuntimeExecutor::javaobject> getRuntimeExecutor();
|
||||
jni::alias_ref<JRuntimeScheduler::javaobject> getRuntimeScheduler();
|
||||
void installRuntimeScheduler();
|
||||
void setGlobalVariable(std::string propName, std::string &&jsonValue);
|
||||
jlong getJavaScriptContext();
|
||||
void handleMemoryPressure(int pressureLevel);
|
||||
|
||||
void createAndInstallRuntimeSchedulerIfNecessary();
|
||||
|
||||
// This should be the only long-lived strong reference, but every C++ class
|
||||
// will have a weak reference.
|
||||
std::shared_ptr<Instance> instance_;
|
||||
|
@ -114,6 +120,9 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|||
jni::global_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder_;
|
||||
jni::global_ref<JRuntimeExecutor::javaobject> runtimeExecutor_;
|
||||
jni::global_ref<JRuntimeScheduler::javaobject> runtimeScheduler_;
|
||||
|
||||
bool const enableRuntimeScheduler_;
|
||||
bool const enableRuntimeSchedulerInTurboModule_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace facebook {
|
|||
namespace react {
|
||||
|
||||
JRuntimeScheduler::JRuntimeScheduler(
|
||||
std::shared_ptr<RuntimeScheduler> const &runtimeScheduler)
|
||||
std::weak_ptr<RuntimeScheduler> runtimeScheduler)
|
||||
: runtimeScheduler_(runtimeScheduler) {}
|
||||
|
||||
std::shared_ptr<RuntimeScheduler> JRuntimeScheduler::get() {
|
||||
std::weak_ptr<RuntimeScheduler> JRuntimeScheduler::get() {
|
||||
return runtimeScheduler_;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ class JRuntimeScheduler : public jni::HybridClass<JRuntimeScheduler> {
|
|||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/facebook/react/bridge/RuntimeScheduler;";
|
||||
|
||||
std::shared_ptr<RuntimeScheduler> get();
|
||||
std::weak_ptr<RuntimeScheduler> get();
|
||||
|
||||
private:
|
||||
friend HybridBase;
|
||||
JRuntimeScheduler(std::shared_ptr<RuntimeScheduler> const &runtimeScheduler);
|
||||
std::shared_ptr<RuntimeScheduler> runtimeScheduler_;
|
||||
JRuntimeScheduler(std::weak_ptr<RuntimeScheduler> runtimeScheduler);
|
||||
std::weak_ptr<RuntimeScheduler> runtimeScheduler_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -16,6 +16,7 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.CatalystInstance;
|
||||
|
@ -25,7 +26,9 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
|||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactTestHelper;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.SystemClock;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
|
@ -37,6 +40,7 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
|
@ -209,4 +213,43 @@ public class RootViewTest {
|
|||
rootView.unmountReactApplication();
|
||||
rootView.startReactApplication(instanceManager, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckForKeyboardEvents() {
|
||||
ReactInstanceManager instanceManager = mock(ReactInstanceManager.class);
|
||||
RCTDeviceEventEmitter eventEmitterModuleMock = mock(RCTDeviceEventEmitter.class);
|
||||
|
||||
when(instanceManager.getCurrentReactContext()).thenReturn(mReactContext);
|
||||
when(mReactContext.getJSModule(RCTDeviceEventEmitter.class)).thenReturn(eventEmitterModuleMock);
|
||||
|
||||
ReactRootView rootView =
|
||||
new ReactRootView(mReactContext) {
|
||||
@Override
|
||||
public void getWindowVisibleDisplayFrame(Rect outRect) {
|
||||
if (outRect.bottom == 0) {
|
||||
outRect.bottom += 100;
|
||||
outRect.right += 370;
|
||||
} else {
|
||||
outRect.bottom += 370;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rootView.startReactApplication(instanceManager, "");
|
||||
rootView.simulateCheckForKeyboardForTesting();
|
||||
|
||||
WritableMap params = Arguments.createMap();
|
||||
WritableMap endCoordinates = Arguments.createMap();
|
||||
double screenHeight = 470.0;
|
||||
double keyboardHeight = 100.0;
|
||||
params.putDouble("duration", 0.0);
|
||||
endCoordinates.putDouble("width", screenHeight - keyboardHeight);
|
||||
endCoordinates.putDouble("screenX", 0.0);
|
||||
endCoordinates.putDouble("height", screenHeight - keyboardHeight);
|
||||
endCoordinates.putDouble("screenY", keyboardHeight);
|
||||
params.putMap("endCoordinates", endCoordinates);
|
||||
params.putString("easing", "keyboard");
|
||||
|
||||
verify(eventEmitterModuleMock, Mockito.times(1)).emit("keyboardDidShow", params);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "rn_xplat_cxx_library", "subdir_glob")
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "CXX", "rn_xplat_cxx_library", "subdir_glob")
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "callinvoker",
|
||||
|
@ -17,7 +17,7 @@ rn_xplat_cxx_library(
|
|||
"-Wall",
|
||||
],
|
||||
labels = ["supermodule:xplat/default/public.react_native.infra"],
|
||||
platforms = (ANDROID, APPLE),
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
preferred_linkage = "static",
|
||||
preprocessor_flags = [
|
||||
"-DLOG_TAG=\"ReactNative\"",
|
||||
|
|
|
@ -18,8 +18,12 @@ class LayoutAnimationDriver : public LayoutAnimationKeyFrameManager {
|
|||
public:
|
||||
LayoutAnimationDriver(
|
||||
RuntimeExecutor runtimeExecutor,
|
||||
ContextContainer::Shared &contextContainer,
|
||||
LayoutAnimationStatusDelegate *delegate)
|
||||
: LayoutAnimationKeyFrameManager(runtimeExecutor, delegate) {}
|
||||
: LayoutAnimationKeyFrameManager(
|
||||
runtimeExecutor,
|
||||
contextContainer,
|
||||
delegate) {}
|
||||
|
||||
protected:
|
||||
virtual void animationMutationsForFrame(
|
||||
|
|
|
@ -94,8 +94,10 @@ interpolateFloats(float coefficient, float oldValue, float newValue) {
|
|||
|
||||
LayoutAnimationKeyFrameManager::LayoutAnimationKeyFrameManager(
|
||||
RuntimeExecutor runtimeExecutor,
|
||||
ContextContainer::Shared &contextContainer,
|
||||
LayoutAnimationStatusDelegate *delegate)
|
||||
: runtimeExecutor_(runtimeExecutor),
|
||||
contextContainer_(contextContainer),
|
||||
layoutAnimationStatusDelegate_(delegate),
|
||||
now_([]() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
|
@ -228,14 +230,7 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
|||
LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!";
|
||||
#endif
|
||||
|
||||
// Stub PropsParserContext used for cloneProps.
|
||||
// This is/should be safe because cloning doesn't actually need to
|
||||
// parse props, and just copies them; therefore there should be no
|
||||
// need to actually use anything in the PropsParserContext.
|
||||
// If this ever changes, the LayoutAnimations API will need to change
|
||||
// to pass in a real PropsParserContext.
|
||||
ContextContainer contextContainer{};
|
||||
PropsParserContext propsParserContext{surfaceId, contextContainer};
|
||||
PropsParserContext propsParserContext{surfaceId, *contextContainer_};
|
||||
|
||||
// What to do if we detect a conflict? Get current value and make
|
||||
// that the baseline of the next animation. Scale the remaining time
|
||||
|
@ -1131,15 +1126,6 @@ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
|
|||
return finalView;
|
||||
}
|
||||
|
||||
// Stub PropsParserContext used for interpolateProps.
|
||||
// This is/should be safe because interpolating doesn't actually need to
|
||||
// parse props, and just copies them; therefore there should be no
|
||||
// need to actually use anything in the PropsParserContext.
|
||||
// If this ever changes, the LayoutAnimations API will need to change
|
||||
// to pass in a real PropsParserContext.
|
||||
ContextContainer contextContainer{};
|
||||
PropsParserContext propsParserContext{-1, contextContainer};
|
||||
|
||||
ComponentDescriptor const &componentDescriptor =
|
||||
getComponentDescriptorForShadowView(startingView);
|
||||
|
||||
|
@ -1160,6 +1146,8 @@ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView(
|
|||
}
|
||||
|
||||
// Animate opacity or scale/transform
|
||||
PropsParserContext propsParserContext{
|
||||
finalView.surfaceId, *contextContainer_};
|
||||
mutatedShadowView.props = componentDescriptor.interpolateProps(
|
||||
propsParserContext, progress, startingView.props, finalView.props);
|
||||
react_native_assert(mutatedShadowView.props != nullptr);
|
||||
|
@ -1202,7 +1190,7 @@ void LayoutAnimationKeyFrameManager::queueFinalMutationsForCompletedKeyFrame(
|
|||
AnimationKeyFrame const &keyframe,
|
||||
ShadowViewMutation::List &mutationsList,
|
||||
bool interrupted,
|
||||
std::string logPrefix) const {
|
||||
const std::string &logPrefix) const {
|
||||
if (skipInvalidatedKeyFrames_ && keyframe.invalidated) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
|||
public:
|
||||
LayoutAnimationKeyFrameManager(
|
||||
RuntimeExecutor runtimeExecutor,
|
||||
ContextContainer::Shared &contextContainer,
|
||||
LayoutAnimationStatusDelegate *delegate);
|
||||
|
||||
#pragma mark - UIManagerAnimationDelegate methods
|
||||
|
@ -138,10 +139,12 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
|||
AnimationKeyFrame const &keyframe,
|
||||
ShadowViewMutation::List &mutationsList,
|
||||
bool interrupted,
|
||||
std::string logPrefix) const;
|
||||
const std::string &logPrefix) const;
|
||||
|
||||
private:
|
||||
RuntimeExecutor runtimeExecutor_;
|
||||
ContextContainer::Shared contextContainer_;
|
||||
|
||||
mutable std::mutex layoutAnimationStatusDelegateMutex_;
|
||||
mutable LayoutAnimationStatusDelegate *layoutAnimationStatusDelegate_{};
|
||||
mutable std::mutex surfaceIdsToStopMutex_;
|
||||
|
|
|
@ -51,7 +51,7 @@ static void testShadowNodeTreeLifeCycleLayoutAnimations(
|
|||
auto entropy = seed == 0 ? Entropy() : Entropy(seed);
|
||||
|
||||
auto eventDispatcher = EventDispatcher::Shared{};
|
||||
auto contextContainer = std::make_shared<ContextContainer>();
|
||||
auto contextContainer = std::make_shared<ContextContainer const>();
|
||||
auto componentDescriptorParameters =
|
||||
ComponentDescriptorParameters{eventDispatcher, contextContainer, nullptr};
|
||||
auto viewComponentDescriptor =
|
||||
|
@ -77,8 +77,8 @@ static void testShadowNodeTreeLifeCycleLayoutAnimations(
|
|||
concreteComponentDescriptorProvider<ViewComponentDescriptor>());
|
||||
|
||||
// Create Animation Driver
|
||||
auto animationDriver =
|
||||
std::make_shared<LayoutAnimationDriver>(runtimeExecutor, nullptr);
|
||||
auto animationDriver = std::make_shared<LayoutAnimationDriver>(
|
||||
runtimeExecutor, contextContainer, nullptr);
|
||||
animationDriver->setComponentDescriptorRegistry(componentDescriptorRegistry);
|
||||
|
||||
// Mock animation timers
|
||||
|
|
|
@ -52,38 +52,7 @@ struct Touch {
|
|||
Float force;
|
||||
|
||||
/*
|
||||
* The time in seconds (with fractional milliseconds) when the touch occurred
|
||||
* or when it was last mutated.
|
||||
*
|
||||
* Whenever possible this should be computed as:
|
||||
* 1. Pick MONO_CLOCK_NOW, a monotonic system clock. Generally, something like
|
||||
* `systemUptimeMillis`.
|
||||
* 2. BASIS_TIME = unix timestamp from unix epoch (ms) - MONO_CLOCK_NOW
|
||||
* 3. Then assign timestamp = BASIS_TIME + MONO_CLOCK_NOW
|
||||
*
|
||||
* The effect should be UNIX timestamp from UNIX epoch, but as a monotonic
|
||||
* clock (if you just assign to current system time, it can move backwards due
|
||||
* to clock adjustements, leap seconds, etc etc). So the vast majority of the
|
||||
* time it will look identical to current UNIX time, but there are some
|
||||
* edge-cases where it can drift.
|
||||
*
|
||||
* If you are not able to use the scheme above for some reason, prefer to use
|
||||
* a monotonic clock. This timestamp MUST be monotonic. Do NOT just pass along
|
||||
* system time.
|
||||
*
|
||||
* The goal is to allow touch latency to be computed in JS. JS does not have
|
||||
* access to something like `systemUptimeMillis`, it generally can only access
|
||||
* the current system time. This *does* mean that the touch latency could be
|
||||
* computed incorrectly in cases of clock drift, so you should only use this
|
||||
* as telemetry to get a decent, but not totally perfect, idea of performance.
|
||||
* Do not use this latency information for anything "mission critical". You
|
||||
* can assume it's probably reasonably accurate 99% of the time.
|
||||
*
|
||||
* Note that we attempt to adhere to the spec of timestamp here:
|
||||
* https://dom.spec.whatwg.org/#dom-event-timestamp
|
||||
* Notably, since `global` is not a Window object in React Native, we have
|
||||
* some flexibility in how we define the time origin:
|
||||
* https://w3c.github.io/hr-time/#dfn-time-origin
|
||||
* The time in seconds when the touch occurred or when it was last mutated.
|
||||
*/
|
||||
Float timestamp;
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#include "Constants.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static bool isPropsForwardingEnabled = false;
|
||||
|
||||
void Constants::setPropsForwardingEnabled(bool propsForwardingEnabled) {
|
||||
isPropsForwardingEnabled = propsForwardingEnabled;
|
||||
}
|
||||
|
||||
bool Constants::getPropsForwardingEnabled() {
|
||||
return isPropsForwardingEnabled;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -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
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct Constants {
|
||||
/*
|
||||
Flag controlling props forwarding when shadow node is cloned on Android.
|
||||
Has no effect on iOS.
|
||||
*/
|
||||
static void setPropsForwardingEnabled(bool propsForwardingEnabled);
|
||||
static bool getPropsForwardingEnabled();
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
#include "ShadowNode.h"
|
||||
#include "Constants.h"
|
||||
#include "DynamicPropsUtilities.h"
|
||||
#include "ShadowNodeFragment.h"
|
||||
|
||||
|
@ -39,15 +38,13 @@ SharedProps ShadowNode::propsForClonedShadowNode(
|
|||
ShadowNode const &sourceShadowNode,
|
||||
Props::Shared const &props) {
|
||||
#ifdef ANDROID
|
||||
if (Constants::getPropsForwardingEnabled()) {
|
||||
bool hasBeenMounted = sourceShadowNode.hasBeenMounted_;
|
||||
bool sourceNodeHasRawProps = !sourceShadowNode.getProps()->rawProps.empty();
|
||||
if (!hasBeenMounted && sourceNodeHasRawProps && props) {
|
||||
auto &castedProps = const_cast<Props &>(*props);
|
||||
castedProps.rawProps = mergeDynamicProps(
|
||||
sourceShadowNode.getProps()->rawProps, props->rawProps);
|
||||
return props;
|
||||
}
|
||||
bool hasBeenMounted = sourceShadowNode.hasBeenMounted_;
|
||||
bool sourceNodeHasRawProps = !sourceShadowNode.getProps()->rawProps.empty();
|
||||
if (!hasBeenMounted && sourceNodeHasRawProps && props) {
|
||||
auto &castedProps = const_cast<Props &>(*props);
|
||||
castedProps.rawProps = mergeDynamicProps(
|
||||
sourceShadowNode.getProps()->rawProps, props->rawProps);
|
||||
return props;
|
||||
}
|
||||
#endif
|
||||
return props ? props : sourceShadowNode.getProps();
|
||||
|
|
|
@ -15,7 +15,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
|||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libruntimeexecutor libreact_render_core libreact_debug libjsi
|
||||
LOCAL_SHARED_LIBRARIES := libruntimeexecutor libreact_render_core libreact_debug libjsi callinvoker
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
-DLOG_TAG=\"Fabric\"
|
||||
|
@ -25,3 +25,4 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++17 -Wall
|
|||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
$(call import-module,runtimeexecutor)
|
||||
$(call import-module,callinvoker)
|
||||
|
|
|
@ -53,6 +53,7 @@ rn_xplat_cxx_library(
|
|||
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
|
||||
react_native_xplat_target("react/renderer/debug:debug"),
|
||||
react_native_xplat_target("better:better"),
|
||||
react_native_xplat_target("callinvoker:callinvoker"),
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 "RuntimeSchedulerCallInvoker.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
RuntimeSchedulerCallInvoker::RuntimeSchedulerCallInvoker(
|
||||
std::weak_ptr<RuntimeScheduler> runtimeScheduler)
|
||||
: runtimeScheduler_(runtimeScheduler) {}
|
||||
|
||||
void RuntimeSchedulerCallInvoker::invokeAsync(std::function<void()> &&func) {
|
||||
if (auto runtimeScheduler = runtimeScheduler_.lock()) {
|
||||
runtimeScheduler->scheduleWork(
|
||||
[func = std::move(func)](jsi::Runtime &) { func(); });
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeSchedulerCallInvoker::invokeSync(std::function<void()> &&func) {
|
||||
if (auto runtimeScheduler = runtimeScheduler_.lock()) {
|
||||
runtimeScheduler->executeNowOnTheSameThread(
|
||||
[func = std::move(func)](jsi::Runtime &) { func(); });
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 <ReactCommon/CallInvoker.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Exposes RuntimeScheduler to native modules. All calls invonked on JavaScript
|
||||
* queue from native modules will be funneled through RuntimeScheduler.
|
||||
*/
|
||||
class RuntimeSchedulerCallInvoker : public CallInvoker {
|
||||
public:
|
||||
RuntimeSchedulerCallInvoker(std::weak_ptr<RuntimeScheduler> runtimeScheduler);
|
||||
|
||||
void invokeAsync(std::function<void()> &&func) override;
|
||||
void invokeSync(std::function<void()> &&func) override;
|
||||
|
||||
private:
|
||||
/*
|
||||
* RuntimeScheduler is retained by the runtime. It must not be
|
||||
* retained by anything beyond the runtime.
|
||||
*/
|
||||
std::weak_ptr<RuntimeScheduler> runtimeScheduler_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
#include <react/renderer/core/Constants.h>
|
||||
#include <react/renderer/core/EventQueueProcessor.h>
|
||||
#include <react/renderer/core/LayoutContext.h>
|
||||
#include <react/renderer/debug/SystraceSection.h>
|
||||
|
@ -119,8 +118,6 @@ Scheduler::Scheduler(
|
|||
#ifdef ANDROID
|
||||
removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:remove_outstanding_surfaces_on_destruction_android");
|
||||
Constants::setPropsForwardingEnabled(reactNativeConfig_->getBool(
|
||||
"react_fabric:enable_props_forwarding_android"));
|
||||
#else
|
||||
removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:remove_outstanding_surfaces_on_destruction_ios");
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
@ -31,7 +30,6 @@ allprojects {
|
|||
// All of Detox's artifacts are provided via the npm module
|
||||
url = uri("$rootDir/node_modules/detox/Detox-android")
|
||||
}
|
||||
mavenLocal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
"scripts/compose-source-maps.js",
|
||||
"scripts/find-node.sh",
|
||||
"scripts/fixmacscripts.sh",
|
||||
"scripts/generate-specs.sh",
|
||||
"scripts/generate-specs-cli.js",
|
||||
"scripts/ios-configure-glog.sh",
|
||||
"scripts/launchPackager.bat",
|
||||
|
@ -153,7 +152,7 @@
|
|||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-react-native": "^3.11.0",
|
||||
"eslint-plugin-relay": "1.8.1",
|
||||
"flow-bin": "^0.159.0",
|
||||
"flow-bin": "^0.160.2",
|
||||
"jest": "^26.6.3",
|
||||
"jest-junit": "^10.0.0",
|
||||
"jscodeshift": "^0.11.0",
|
||||
|
|
|
@ -22,7 +22,7 @@ interface NativeCommands {
|
|||
+scrollTo: (viewRef: React.ElementRef<NativeType>, y: Int32, animated: boolean) => void,
|
||||
}
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
const {
|
||||
dispatchCommand
|
||||
|
@ -84,7 +84,7 @@ interface NativeCommands {
|
|||
+scrollTo: (viewRef: React.ElementRef<NativeType>, y: Int32, animated: boolean) => void,
|
||||
}
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
const {
|
||||
dispatchCommand
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "react-native-codegen",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"description": "⚛️ Code generation tools for React Native",
|
||||
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
|
||||
"repository": {
|
||||
|
|
|
@ -177,7 +177,7 @@ function buildViewConfig(
|
|||
switch (extendProps.knownTypeName) {
|
||||
case 'ReactNativeCoreViewProps':
|
||||
imports.add(
|
||||
"const NativeComponentRegistry = require('NativeComponentRegistry');",
|
||||
"const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');",
|
||||
);
|
||||
|
||||
return;
|
||||
|
|
|
@ -16,7 +16,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ArrayPropsNativeComponent';
|
||||
|
||||
|
@ -61,7 +61,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ArrayPropsNativeComponent';
|
||||
|
||||
|
@ -92,7 +92,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'BooleanPropNativeComponent';
|
||||
|
||||
|
@ -123,7 +123,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ColorPropNativeComponent';
|
||||
|
||||
|
@ -156,7 +156,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
const {dispatchCommand} = require(\\"react-native/Libraries/Renderer/shims/ReactNative\\");
|
||||
|
||||
let nativeComponentName = 'CommandNativeComponent';
|
||||
|
@ -195,7 +195,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
const {dispatchCommand} = require(\\"react-native/Libraries/Renderer/shims/ReactNative\\");
|
||||
|
||||
let nativeComponentName = 'CommandNativeComponent';
|
||||
|
@ -237,7 +237,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'DoublePropNativeComponent';
|
||||
|
||||
|
@ -273,7 +273,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'EventsNestedObjectNativeComponent';
|
||||
|
||||
|
@ -314,7 +314,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'EventsNativeComponent';
|
||||
|
||||
|
@ -375,7 +375,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'RCTInterfaceOnlyComponent';
|
||||
|
||||
|
@ -433,7 +433,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ExcludedAndroidComponent';
|
||||
|
||||
|
@ -461,7 +461,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ExcludedAndroidIosComponent';
|
||||
|
||||
|
@ -489,7 +489,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'FloatPropNativeComponent';
|
||||
|
||||
|
@ -525,7 +525,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ImagePropNativeComponent';
|
||||
|
||||
|
@ -558,7 +558,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'InsetsPropNativeComponent';
|
||||
|
||||
|
@ -591,7 +591,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'Int32EnumPropsNativeComponent';
|
||||
|
||||
|
@ -622,7 +622,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'IntegerPropNativeComponent';
|
||||
|
||||
|
@ -655,7 +655,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'RCTInterfaceOnlyComponent';
|
||||
|
||||
|
@ -696,7 +696,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ImageColorPropNativeComponent';
|
||||
|
||||
|
@ -741,7 +741,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'NoPropsNoEventsComponent';
|
||||
|
||||
|
@ -769,7 +769,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ObjectProps';
|
||||
|
||||
|
@ -800,7 +800,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'PointPropNativeComponent';
|
||||
|
||||
|
@ -833,7 +833,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'StringEnumPropsNativeComponent';
|
||||
|
||||
|
@ -864,7 +864,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'StringPropComponent';
|
||||
|
||||
|
@ -896,7 +896,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'MultiFile1NativeComponent';
|
||||
|
||||
|
@ -937,7 +937,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'MultiComponent1NativeComponent';
|
||||
|
||||
|
@ -978,7 +978,7 @@ Map {
|
|||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('NativeComponentRegistry');
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
const {UIManager} = require(\\"react-native\\")
|
||||
|
||||
let nativeComponentName = 'NativeComponentName';
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# react-native-gradle-plugin
|
||||
|
||||
[![Version][version-badge]][package]
|
||||
|
||||
A Gradle Plugin used to support development of React Native applications for Android.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
yarn add react-native-gradle-plugin
|
||||
```
|
||||
|
||||
*Note: We're using `yarn` to install deps. Feel free to change commands to use `npm` 3+ and `npx` if you like*
|
||||
|
||||
[version-badge]: https://img.shields.io/npm/v/react-native-gradle-plugin?style=flat-square
|
||||
[package]: https://www.npmjs.com/package/react-native-gradle-plugin
|
|
@ -20,9 +20,9 @@ repositories {
|
|||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("reactApp") {
|
||||
create("react") {
|
||||
id = "com.facebook.react"
|
||||
implementationClass = "com.facebook.react.ReactAppPlugin"
|
||||
implementationClass = "com.facebook.react.ReactPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "react-native-gradle-plugin",
|
||||
"version": "0.0.1",
|
||||
"description": "⚛️ Gradle Plugin for React Native",
|
||||
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/react-native.git",
|
||||
"directory": "packages/react-native-gradle-plugin"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "./gradlew build",
|
||||
"clean": "./gradlew clean",
|
||||
"test": "./gradlew check"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"settings.gradle.kts",
|
||||
"build.gradle.kts",
|
||||
"gradle",
|
||||
"gradlew",
|
||||
"gradlew.bat",
|
||||
"src",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"react-native-codegen": "*"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
|
@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
|||
* generator is isolated to a single schema, and a single Java package output.
|
||||
*/
|
||||
public final class JavaGenerator {
|
||||
public static String LICENSE_HEADER =
|
||||
public static final String LICENSE_HEADER =
|
||||
"/*\n"
|
||||
+ " * Copyright (c) Facebook, Inc. and its affiliates.\n"
|
||||
+ " *\n"
|
||||
|
|
|
@ -1,153 +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.react.codegen.plugin;
|
||||
|
||||
import com.android.build.gradle.BaseExtension;
|
||||
import com.facebook.react.ReactExtension;
|
||||
import com.facebook.react.codegen.generator.JavaGenerator;
|
||||
import com.facebook.react.tasks.BuildCodegenCLITask;
|
||||
import com.facebook.react.tasks.GenerateCodegenSchemaTask;
|
||||
import com.facebook.react.utils.GradleUtils;
|
||||
import com.facebook.react.utils.PathUtils;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.io.File;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.tasks.Exec;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
/**
|
||||
* A Gradle plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for
|
||||
* more information: https://docs.gradle.org/6.5.1/javadoc/org/gradle/api/Project.html
|
||||
*/
|
||||
public class CodegenPlugin {
|
||||
|
||||
public void apply(final Project project) {
|
||||
final ReactExtension extension =
|
||||
GradleUtils.createOrGet(project.getExtensions(), "react", ReactExtension.class, project);
|
||||
|
||||
// 1. Set up build dir.
|
||||
final File generatedSrcDir = new File(project.getBuildDir(), "generated/source/codegen");
|
||||
final File generatedSchemaFile = new File(generatedSrcDir, "schema.json");
|
||||
|
||||
// 2. Task: produce schema from JS files.
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
TaskProvider<BuildCodegenCLITask> buildCodegenTask =
|
||||
project
|
||||
.getTasks()
|
||||
.register(
|
||||
"buildCodegenCLI",
|
||||
BuildCodegenCLITask.class,
|
||||
task -> {
|
||||
task.getCodegenDir().set(extension.getCodegenDir());
|
||||
String bashWindowsHome = (String) project.findProperty("REACT_WINDOWS_BASH");
|
||||
task.getBashWindowsHome().set(bashWindowsHome);
|
||||
});
|
||||
|
||||
TaskProvider<GenerateCodegenSchemaTask> generateCodegenSchemaTask =
|
||||
project
|
||||
.getTasks()
|
||||
.register(
|
||||
"generateCodegenSchemaFromJavaScript",
|
||||
GenerateCodegenSchemaTask.class,
|
||||
task -> {
|
||||
task.getJsRootDir().set(extension.getJsRootDir());
|
||||
task.getNodeExecutableAndArgs().set(extension.getNodeExecutableAndArgs());
|
||||
task.getCodegenDir().set(extension.getCodegenDir());
|
||||
task.getGeneratedSrcDir().set(generatedSrcDir);
|
||||
task.dependsOn(buildCodegenTask);
|
||||
});
|
||||
|
||||
// 3. Task: generate Java code from schema.
|
||||
project
|
||||
.getTasks()
|
||||
.register(
|
||||
"generateCodegenArtifactsFromSchema",
|
||||
Exec.class,
|
||||
task -> {
|
||||
task.dependsOn(generateCodegenSchemaTask);
|
||||
|
||||
task.getInputs()
|
||||
.files(
|
||||
project.fileTree(
|
||||
ImmutableMap.of("dir", extension.getCodegenDir().getAsFile().get())));
|
||||
task.getInputs()
|
||||
.files(PathUtils.codegenGenerateSchemaCLI(extension).getAbsolutePath());
|
||||
task.getInputs().files(generatedSchemaFile);
|
||||
task.getOutputs().dir(generatedSrcDir);
|
||||
|
||||
if (extension.getUseJavaGenerator().get()) {
|
||||
task.doLast(
|
||||
s -> {
|
||||
generateJavaFromSchemaWithJavaGenerator(
|
||||
generatedSchemaFile,
|
||||
extension.getCodegenJavaPackageName().get(),
|
||||
generatedSrcDir);
|
||||
});
|
||||
}
|
||||
|
||||
ImmutableList<String> execCommands =
|
||||
new ImmutableList.Builder<String>()
|
||||
.add(os.contains("windows") ? "yarn.cmd" : "yarn")
|
||||
.addAll(ImmutableList.copyOf(extension.getNodeExecutableAndArgs().get()))
|
||||
.add(
|
||||
PathUtils.codegenGenerateNativeModuleSpecsCLI(extension)
|
||||
.getAbsolutePath())
|
||||
.add("android")
|
||||
.add(generatedSchemaFile.getAbsolutePath())
|
||||
.add(generatedSrcDir.getAbsolutePath())
|
||||
.add(extension.getLibraryName().get())
|
||||
.add(extension.getCodegenJavaPackageName().get())
|
||||
.build();
|
||||
task.commandLine(execCommands);
|
||||
});
|
||||
|
||||
// 4. Add dependencies & generated sources to the project.
|
||||
// Note: This last step needs to happen after the project has been evaluated.
|
||||
project.afterEvaluate(
|
||||
s -> {
|
||||
// `preBuild` is one of the base tasks automatically registered by Gradle.
|
||||
// This will invoke the codegen before compiling the entire project.
|
||||
Task preBuild = project.getTasks().findByName("preBuild");
|
||||
if (preBuild != null) {
|
||||
preBuild.dependsOn("generateCodegenArtifactsFromSchema");
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally, update the android configuration to include the generated sources. This
|
||||
* equivalent to this DSL:
|
||||
*
|
||||
* <p>android { sourceSets { main { java { srcDirs += "$generatedSrcDir/java" } } } }
|
||||
*
|
||||
* <p>See documentation at
|
||||
* https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.BaseExtension.html.
|
||||
*/
|
||||
BaseExtension android = (BaseExtension) project.getExtensions().getByName("android");
|
||||
android
|
||||
.getSourceSets()
|
||||
.getByName("main")
|
||||
.getJava()
|
||||
.srcDir(new File(generatedSrcDir, "java"));
|
||||
});
|
||||
}
|
||||
|
||||
// Use Java-based generator implementation to produce the source files, instead of using the
|
||||
// JS-based generator.
|
||||
private void generateJavaFromSchemaWithJavaGenerator(
|
||||
final File schemaFile, final String javaPackageName, final File outputDir) {
|
||||
final JavaGenerator generator = new JavaGenerator(schemaFile, javaPackageName, outputDir);
|
||||
try {
|
||||
generator.build();
|
||||
} catch (final Exception ex) {
|
||||
throw new GradleException("Failed to generate Java from schema.", ex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +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.react
|
||||
|
||||
import com.android.build.gradle.AppExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import com.facebook.react.codegen.plugin.CodegenPlugin
|
||||
import com.facebook.react.utils.GradleUtils.createOrGet
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
class ReactAppPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
applyAppPlugin(project)
|
||||
applyCodegenPlugin(project)
|
||||
}
|
||||
|
||||
private fun applyAppPlugin(project: Project) {
|
||||
val config = project.extensions.createOrGet("react", ReactExtension::class.java, project)
|
||||
|
||||
if (config.applyAppPlugin.getOrElse(false)) {
|
||||
project.afterEvaluate {
|
||||
val androidConfiguration = project.extensions.getByType(BaseExtension::class.java)
|
||||
project.configureDevPorts(androidConfiguration)
|
||||
|
||||
val isAndroidLibrary = project.plugins.hasPlugin("com.android.library")
|
||||
val variants =
|
||||
if (isAndroidLibrary) {
|
||||
project.extensions.getByType(LibraryExtension::class.java).libraryVariants
|
||||
} else {
|
||||
project.extensions.getByType(AppExtension::class.java).applicationVariants
|
||||
}
|
||||
variants.all { project.configureReactTasks(variant = it, config = config) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyCodegenPlugin(project: Project) {
|
||||
CodegenPlugin().apply(project)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
import com.android.build.gradle.AppExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
||||
import com.facebook.react.tasks.BuildCodegenCLITask
|
||||
import com.facebook.react.tasks.GenerateCodegenArtifactsTask
|
||||
import com.facebook.react.tasks.GenerateCodegenSchemaTask
|
||||
import java.io.File
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
|
||||
class ReactPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val extension = project.extensions.create("react", ReactExtension::class.java, project)
|
||||
applyAppPlugin(project, extension)
|
||||
applyCodegenPlugin(project, extension)
|
||||
}
|
||||
|
||||
private fun applyAppPlugin(project: Project, config: ReactExtension) {
|
||||
if (config.applyAppPlugin.getOrElse(false)) {
|
||||
project.afterEvaluate {
|
||||
val androidConfiguration = project.extensions.getByType(BaseExtension::class.java)
|
||||
project.configureDevPorts(androidConfiguration)
|
||||
|
||||
val isAndroidLibrary = project.plugins.hasPlugin("com.android.library")
|
||||
val variants =
|
||||
if (isAndroidLibrary) {
|
||||
project.extensions.getByType(LibraryExtension::class.java).libraryVariants
|
||||
} else {
|
||||
project.extensions.getByType(AppExtension::class.java).applicationVariants
|
||||
}
|
||||
variants.all { project.configureReactTasks(variant = it, config = config) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for more
|
||||
* information: https://docs.gradle.org/6.5.1/javadoc/org/gradle/api/Project.html
|
||||
*/
|
||||
private fun applyCodegenPlugin(project: Project, extension: ReactExtension) {
|
||||
// 1. Set up build dir.
|
||||
val generatedSrcDir = File(project.buildDir, "generated/source/codegen")
|
||||
|
||||
val buildCodegenTask =
|
||||
project.tasks.register("buildCodegenCLI", BuildCodegenCLITask::class.java) {
|
||||
it.codegenDir.set(extension.codegenDir)
|
||||
val bashWindowsHome = project.findProperty("REACT_WINDOWS_BASH") as String?
|
||||
it.bashWindowsHome.set(bashWindowsHome)
|
||||
}
|
||||
|
||||
// 2. Task: produce schema from JS files.
|
||||
val generateCodegenSchemaTask =
|
||||
project.tasks.register(
|
||||
"generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) {
|
||||
it.dependsOn(buildCodegenTask)
|
||||
it.jsRootDir.set(extension.jsRootDir)
|
||||
it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
|
||||
it.codegenDir.set(extension.codegenDir)
|
||||
it.generatedSrcDir.set(generatedSrcDir)
|
||||
}
|
||||
|
||||
// 3. Task: generate Java code from schema.
|
||||
val generateCodegenArtifactsTask =
|
||||
project.tasks.register(
|
||||
"generateCodegenArtifactsFromSchema", GenerateCodegenArtifactsTask::class.java) {
|
||||
it.dependsOn(generateCodegenSchemaTask)
|
||||
it.reactRoot.set(extension.reactRoot)
|
||||
it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
|
||||
it.codegenDir.set(extension.codegenDir)
|
||||
it.useJavaGenerator.set(extension.useJavaGenerator)
|
||||
it.codegenJavaPackageName.set(extension.codegenJavaPackageName)
|
||||
it.libraryName.set(extension.libraryName)
|
||||
it.generatedSrcDir.set(generatedSrcDir)
|
||||
}
|
||||
|
||||
// 4. Add dependencies & generated sources to the project.
|
||||
// Note: This last step needs to happen after the project has been evaluated.
|
||||
project.afterEvaluate {
|
||||
|
||||
// `preBuild` is one of the base tasks automatically registered by Gradle.
|
||||
// This will invoke the codegen before compiling the entire project.
|
||||
project.tasks.named("preBuild", Task::class.java).dependsOn(generateCodegenArtifactsTask)
|
||||
|
||||
/**
|
||||
* Finally, update the android configuration to include the generated sources. This equivalent
|
||||
* to this DSL:
|
||||
*
|
||||
* android { sourceSets { main { java { srcDirs += "$generatedSrcDir/java" } } } }
|
||||
*
|
||||
* See documentation at
|
||||
* https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.BaseExtension.html.
|
||||
*/
|
||||
val android = project.extensions.getByName("android") as BaseExtension
|
||||
|
||||
android.sourceSets.getByName("main").java.srcDir(File(generatedSrcDir, "java"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,9 @@ import com.facebook.react.utils.detectedHermesCommand
|
|||
import java.io.File
|
||||
import java.util.*
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
|
||||
private const val REACT_GROUP = "react"
|
||||
|
||||
|
@ -134,6 +136,8 @@ internal fun Project.configureReactTasks(variant: BaseVariant, config: ReactExte
|
|||
is LibraryVariant -> variant.packageLibraryProvider
|
||||
else -> tasks.named("package$targetName")
|
||||
}
|
||||
val stripDebugSymbolsTask: TaskProvider<Task>? = tasks.named("strip${targetName}DebugSymbols")
|
||||
val mergeNativeLibsTask: TaskProvider<Task>? = tasks.named("merge${targetName}NativeLibs")
|
||||
|
||||
val mergeResourcesTask = variant.mergeResourcesProvider
|
||||
val mergeAssetsTask = variant.mergeAssetsProvider
|
||||
|
@ -160,7 +164,25 @@ internal fun Project.configureReactTasks(variant: BaseVariant, config: ReactExte
|
|||
|
||||
packageTask.configure {
|
||||
if (config.enableVmCleanup.get()) {
|
||||
it.doFirst { cleanupVMFiles(enableHermes, isRelease, targetPath) }
|
||||
val libDir = "$buildDir/intermediates/transforms/"
|
||||
val targetVariant = ".*/transforms/[^/]*/$targetPath/.*".toRegex()
|
||||
it.doFirst { cleanupVMFiles(libDir, targetVariant, enableHermes, isRelease) }
|
||||
}
|
||||
}
|
||||
|
||||
stripDebugSymbolsTask?.configure {
|
||||
if (config.enableVmCleanup.get()) {
|
||||
val libDir = "$buildDir/intermediates/stripped_native_libs/${targetPath}/out/lib/"
|
||||
val targetVariant = ".*/stripped_native_libs/$targetPath/out/lib/.*".toRegex()
|
||||
it.doLast { cleanupVMFiles(libDir, targetVariant, enableHermes, isRelease) }
|
||||
}
|
||||
}
|
||||
|
||||
mergeNativeLibsTask?.configure {
|
||||
if (config.enableVmCleanup.get()) {
|
||||
val libDir = "$buildDir/intermediates/merged_native_libs/${targetPath}/out/lib/"
|
||||
val targetVariant = ".*/merged_native_libs/$targetPath/out/lib/.*".toRegex()
|
||||
it.doLast { cleanupVMFiles(libDir, targetVariant, enableHermes, isRelease) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,14 +213,18 @@ internal fun Project.configureReactTasks(variant: BaseVariant, config: ReactExte
|
|||
preBundleTask.dependsOn(currentAssetsCopyTask)
|
||||
}
|
||||
|
||||
private fun Project.cleanupVMFiles(enableHermes: Boolean, isRelease: Boolean, targetPath: String) {
|
||||
private fun Project.cleanupVMFiles(
|
||||
libDir: String,
|
||||
targetVariant: Regex,
|
||||
enableHermes: Boolean,
|
||||
isRelease: Boolean
|
||||
) {
|
||||
// Delete the VM related libraries that this build doesn't need.
|
||||
// The application can manage this manually by setting 'enableVmCleanup: false'
|
||||
//
|
||||
// This should really be done by packaging all Hermes related libs into
|
||||
// two separate HermesDebug and HermesRelease AARs, but until then we'll
|
||||
// kludge it by deleting the .so files out of the /transforms/ directory.
|
||||
val libDir = "$buildDir/intermediates/transforms/"
|
||||
fileTree(libDir) {
|
||||
if (enableHermes) {
|
||||
// For Hermes, delete all the libjsc* files
|
||||
|
@ -208,18 +234,23 @@ private fun Project.cleanupVMFiles(enableHermes: Boolean, isRelease: Boolean, ta
|
|||
// Reduce size by deleting the debugger/inspector
|
||||
it.include("**/libhermes-inspector.so")
|
||||
it.include("**/libhermes-executor-debug.so")
|
||||
it.include("**/libhermes-executor-common-debug.so")
|
||||
} else {
|
||||
// Release libs take precedence and must be removed
|
||||
// to allow debugging
|
||||
it.include("**/libhermes-executor-release.so")
|
||||
it.include("**/libhermes-executor-common-release.so")
|
||||
}
|
||||
} else {
|
||||
// For JSC, delete all the libhermes* files
|
||||
it.include("**/libhermes*.so")
|
||||
// Delete the libjscexecutor from release build
|
||||
if (isRelease) {
|
||||
it.include("**/libjscexecutor.so")
|
||||
}
|
||||
}
|
||||
}
|
||||
.visit { visit ->
|
||||
val targetVariant = ".*/transforms/[^/]*/$targetPath/.*".toRegex()
|
||||
val path = visit.file.absolutePath.replace(File.separatorChar, '/')
|
||||
if (path.matches(targetVariant) && visit.file.isFile) {
|
||||
visit.file.delete()
|
||||
|
|
|
@ -27,10 +27,12 @@ abstract class BuildCodegenCLITask : Exec() {
|
|||
@get:Internal abstract val bashWindowsHome: Property<String>
|
||||
|
||||
@get:InputFiles
|
||||
val input: FileCollection =
|
||||
codegenDir.files("scripts", "src", "package.json", ".babelrc", ".prettierrc")
|
||||
val input: FileCollection by lazy {
|
||||
codegenDir.get().files("scripts", "src", "package.json", ".babelrc", ".prettierrc")
|
||||
}
|
||||
|
||||
@get:OutputFiles val output: FileCollection = codegenDir.files("lib", "node_modules")
|
||||
@get:OutputDirectories
|
||||
val output: FileCollection by lazy { codegenDir.get().files("lib", "node_modules") }
|
||||
|
||||
init {
|
||||
// We need this condition as we want a single instance of BuildCodegenCLITask to execute
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
package com.facebook.react.tasks
|
||||
|
||||
import com.facebook.react.codegen.generator.JavaGenerator
|
||||
import com.facebook.react.utils.windowsAwareYarn
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.file.Directory
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
|
||||
abstract class GenerateCodegenArtifactsTask : Exec() {
|
||||
|
||||
@get:Internal abstract val reactRoot: DirectoryProperty
|
||||
|
||||
@get:Internal abstract val codegenDir: DirectoryProperty
|
||||
|
||||
@get:Internal abstract val generatedSrcDir: DirectoryProperty
|
||||
|
||||
@get:Input abstract val nodeExecutableAndArgs: ListProperty<String>
|
||||
|
||||
@get:Input abstract val useJavaGenerator: Property<Boolean>
|
||||
|
||||
@get:Input abstract val codegenJavaPackageName: Property<String>
|
||||
|
||||
@get:Input abstract val libraryName: Property<String>
|
||||
|
||||
@get:InputFile
|
||||
val combineJsToSchemaCli: Provider<RegularFile> =
|
||||
codegenDir.file("lib/cli/combine/combine-js-to-schema-cli.js")
|
||||
|
||||
@get:InputFile
|
||||
val generatedSchemaFile: Provider<RegularFile> = generatedSrcDir.file("schema.json")
|
||||
|
||||
@get:OutputDirectory val generatedJavaFiles: Provider<Directory> = generatedSrcDir.dir("java")
|
||||
|
||||
@get:OutputDirectory val generatedJniFiles: Provider<Directory> = generatedSrcDir.dir("jni")
|
||||
|
||||
override fun exec() {
|
||||
setupCommandLine()
|
||||
super.exec()
|
||||
}
|
||||
|
||||
internal fun setupCommandLine() {
|
||||
if (useJavaGenerator.getOrElse(false)) {
|
||||
// Use Java-based generator implementation to produce the source files,
|
||||
// instead of using the JS-based generator.
|
||||
try {
|
||||
JavaGenerator(
|
||||
generatedSchemaFile.get().asFile,
|
||||
codegenJavaPackageName.get(),
|
||||
generatedSrcDir.get().asFile)
|
||||
.build()
|
||||
} catch (e: Exception) {
|
||||
throw GradleException("Failed to generate Java from schema.", e)
|
||||
}
|
||||
commandLine("echo", "Used JavaGenerator to generate files instead of generate-specs-cli.js")
|
||||
} else {
|
||||
commandLine(
|
||||
windowsAwareYarn(
|
||||
*nodeExecutableAndArgs.get().toTypedArray(),
|
||||
reactRoot.file("scripts/generate-specs-cli.js").get().asFile.absolutePath,
|
||||
"android",
|
||||
generatedSchemaFile.get().asFile.absolutePath,
|
||||
generatedSrcDir.get().asFile.absolutePath,
|
||||
libraryName.get(),
|
||||
codegenJavaPackageName.get()))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,11 +35,19 @@ abstract class GenerateCodegenSchemaTask : Exec() {
|
|||
val generatedSchemaFile: Provider<RegularFile> = generatedSrcDir.file("schema.json")
|
||||
|
||||
override fun exec() {
|
||||
wipeOutputDir()
|
||||
setupCommandLine()
|
||||
super.exec()
|
||||
}
|
||||
|
||||
internal fun wipeOutputDir() {
|
||||
generatedSrcDir.asFile.get().apply {
|
||||
delete()
|
||||
deleteRecursively()
|
||||
mkdirs()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun setupCommandLine() {
|
||||
commandLine(
|
||||
windowsAwareYarn(
|
||||
*nodeExecutableAndArgs.get().toTypedArray(),
|
||||
|
@ -51,6 +59,5 @@ abstract class GenerateCodegenSchemaTask : Exec() {
|
|||
generatedSchemaFile.get().asFile.absolutePath,
|
||||
jsRootDir.asFile.get().absolutePath,
|
||||
))
|
||||
super.exec()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +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.react.utils
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtensionContainer
|
||||
|
||||
object GradleUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun <T> ExtensionContainer.createOrGet(name: String, type: Class<T>, target: Project): T =
|
||||
this.findByType(type) ?: this.create(name, type, target)
|
||||
}
|
|
@ -122,9 +122,3 @@ internal fun projectPathToLibraryName(projectPath: String): String =
|
|||
.split(':', '-', '_', '.')
|
||||
.joinToString("") { it.capitalize(Locale.ROOT) }
|
||||
.plus("Spec")
|
||||
|
||||
fun codegenGenerateSchemaCLI(config: ReactExtension): File =
|
||||
config.codegenDir.file("lib/cli/combine/combine-js-to-schema-cli.js").get().asFile
|
||||
|
||||
fun codegenGenerateNativeModuleSpecsCLI(config: ReactExtension): File =
|
||||
config.reactRoot.file("scripts/generate-specs-cli.js").get().asFile
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.tasks
|
||||
|
||||
import com.facebook.react.tests.createTestTask
|
||||
import java.io.File
|
||||
import org.gradle.api.tasks.*
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
class BuildCodegenCLITaskTest {
|
||||
|
||||
@get:Rule val tempFolder = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_input_isSetCorrectly() {
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.codegenDir.set(tempFolder.root) }
|
||||
|
||||
assertTrue(task.input.contains(File(tempFolder.root, "scripts")))
|
||||
assertTrue(task.input.contains(File(tempFolder.root, "src")))
|
||||
assertTrue(task.input.contains(File(tempFolder.root, "package.json")))
|
||||
assertTrue(task.input.contains(File(tempFolder.root, ".babelrc")))
|
||||
assertTrue(task.input.contains(File(tempFolder.root, ".prettierrc")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_output_isSetCorrectly() {
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.codegenDir.set(tempFolder.root) }
|
||||
|
||||
assertTrue(task.output.contains(File(tempFolder.root, "lib")))
|
||||
assertTrue(task.output.contains(File(tempFolder.root, "node_modules")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_bashWindowsHome_isSetCorrectly() {
|
||||
val bashPath = tempFolder.newFile("bash").absolutePath
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.bashWindowsHome.set(bashPath) }
|
||||
|
||||
assertEquals(bashPath, task.bashWindowsHome.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_onlyIf_withMissingDirectory_isSatisfied() {
|
||||
File(tempFolder.root, "lib/cli/").apply { mkdirs() }
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.codegenDir.set(tempFolder.root) }
|
||||
|
||||
assertTrue(task.onlyIf.isSatisfiedBy(task))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_onlyIf_withEmptyDirectory_isSatisfied() {
|
||||
File(tempFolder.root, "lib/cli/").apply { mkdirs() }
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.codegenDir.set(tempFolder.root) }
|
||||
|
||||
assertTrue(task.onlyIf.isSatisfiedBy(task))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun buildCodegenCli_onlyIf_withExistingDirtyDirectory_isNotSatisfied() {
|
||||
File(tempFolder.root, "lib/cli/a-file").apply {
|
||||
parentFile.mkdirs()
|
||||
writeText("¯\\_(ツ)_/¯")
|
||||
}
|
||||
val task = createTestTask<BuildCodegenCLITask> { it.codegenDir.set(tempFolder.root) }
|
||||
|
||||
assertFalse(task.onlyIf.isSatisfiedBy(task))
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче