Merge up to 7b9490b4b1
Merge up to commit where view configs are refactored
This commit is contained in:
Коммит
5067981821
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,5 +1,21 @@
|
|||
# Changelog
|
||||
|
||||
## v0.67.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix error "mockModal is not a function" ([507b05f4c0](https://github.com/facebook/react-native/commit/507b05f4c02b46109f483a2b79c924a775fd7bd3) by [@AntoineDoubovetzky](https://github.com/AntoineDoubovetzky))
|
||||
|
||||
#### Android specific
|
||||
|
||||
- Fix potential crash if ReactRootView does not have insets attached. ([6239e2f5ce](https://github.com/facebook/react-native/commit/6239e2f5ce82f7c2e683eb4699b9ce3ff1b58ac5) by [@enahum](https://github.com/enahum))
|
||||
- Upgrading OkHttp from 4.9.1 to 4.9.2 to fix CVE-2021-0341. ([e896d21](https://github.com/facebook/react-native/commit/e896d21ced3c0c917c2fc0044d2b93b44df9a081) by [@owjsub](https://github.com/owjsub))
|
||||
|
||||
#### iOS specific
|
||||
|
||||
- Fix `Time.h` patch not being applied when running `pod install --project-directory=ios` ([60cef850bd](https://github.com/facebook/react-native/commit/60cef850bd3fd12c32ee1196bd19a559592d1465) by [@tido64](https://github.com/tido64))
|
||||
- Find-node.sh now respects .nvmrc ([35bcf934b1](https://github.com/facebook/react-native/commit/35bcf934b186e581d100d43e563044300759557f) by [@igrayson](https://github.com/igrayson))
|
||||
|
||||
## v0.67.1
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -19,6 +19,7 @@ const {shouldUseNativeDriver} = require('../NativeAnimatedHelper');
|
|||
|
||||
import type {PlatformConfig} from '../AnimatedPlatformConfig';
|
||||
import type {AnimationConfig, EndCallback} from './Animation';
|
||||
import type {RgbaValue} from '../nodes/AnimatedColor';
|
||||
|
||||
import AnimatedColor from '../nodes/AnimatedColor';
|
||||
|
||||
|
@ -33,13 +34,7 @@ export type TimingAnimationConfig = {
|
|||
...
|
||||
}
|
||||
| AnimatedValueXY
|
||||
| {
|
||||
r: number,
|
||||
g: number,
|
||||
b: number,
|
||||
a: number,
|
||||
...
|
||||
}
|
||||
| RgbaValue
|
||||
| AnimatedColor
|
||||
| AnimatedInterpolation,
|
||||
easing?: (value: number) => number,
|
||||
|
|
|
@ -15,11 +15,12 @@ import AnimatedWithChildren from './AnimatedWithChildren';
|
|||
import normalizeColor from '../../StyleSheet/normalizeColor';
|
||||
import {processColorObject} from '../../StyleSheet/PlatformColorValueTypes';
|
||||
|
||||
import type {PlatformConfig} from '../AnimatedPlatformConfig';
|
||||
import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
||||
import type {NativeColorValue} from '../../StyleSheet/PlatformColorValueTypes';
|
||||
|
||||
type ColorListenerCallback = (value: string) => mixed;
|
||||
type RgbaValue = {
|
||||
export type RgbaValue = {
|
||||
+r: number,
|
||||
+g: number,
|
||||
+b: number,
|
||||
|
@ -263,4 +264,22 @@ export default class AnimatedColor extends AnimatedWithChildren {
|
|||
this.a.__removeChild(this);
|
||||
super.__detach();
|
||||
}
|
||||
|
||||
__makeNative(platformConfig: ?PlatformConfig) {
|
||||
this.r.__makeNative(platformConfig);
|
||||
this.g.__makeNative(platformConfig);
|
||||
this.b.__makeNative(platformConfig);
|
||||
this.a.__makeNative(platformConfig);
|
||||
super.__makeNative(platformConfig);
|
||||
}
|
||||
|
||||
__getNativeConfig(): {...} {
|
||||
return {
|
||||
type: 'color',
|
||||
r: this.r.__getNativeTag(),
|
||||
g: this.g.__getNativeTag(),
|
||||
b: this.b.__getNativeTag(),
|
||||
a: this.a.__getNativeTag(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import type {
|
|||
} from '../View/ViewAccessibility';
|
||||
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
|
||||
import usePressability from '../../Pressability/usePressability';
|
||||
import {normalizeRect, type RectOrSize} from '../../StyleSheet/Rect';
|
||||
import {type RectOrSize} from '../../StyleSheet/Rect';
|
||||
import type {
|
||||
LayoutEvent,
|
||||
MouseEvent,
|
||||
|
@ -233,6 +233,7 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
|||
delayLongPress,
|
||||
disabled,
|
||||
focusable,
|
||||
hitSlop,
|
||||
onHoverIn,
|
||||
onHoverOut,
|
||||
onLongPress,
|
||||
|
@ -259,8 +260,6 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
|||
|
||||
const [pressed, setPressed] = usePressState(testOnly_pressed === true);
|
||||
|
||||
const hitSlop = normalizeRect(props.hitSlop);
|
||||
|
||||
const accessibilityState =
|
||||
disabled != null
|
||||
? {...props.accessibilityState, disabled}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule PlatformViewPropTypes
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
// TODO(macOS GH#774)
|
||||
|
||||
'use strict';
|
||||
|
||||
export type PlatformViewPropTypes = {};
|
|
@ -1,374 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {ViewConfig} from '../../Renderer/shims/ReactNativeTypes';
|
||||
import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid';
|
||||
import ReactNativeViewViewConfigMacOS from './ReactNativeViewViewConfigMacOS'; // TODO(macOS GH#774)
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
const ReactNativeViewConfig: ViewConfig = {
|
||||
uiViewClassName: 'RCTView',
|
||||
baseModuleName: null,
|
||||
Manager: 'ViewManager',
|
||||
Commands: {},
|
||||
Constants: {},
|
||||
bubblingEventTypes: {
|
||||
...ReactNativeViewViewConfigAndroid.bubblingEventTypes,
|
||||
topBlur: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onBlur',
|
||||
captured: 'onBlurCapture',
|
||||
},
|
||||
},
|
||||
topChange: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onChange',
|
||||
captured: 'onChangeCapture',
|
||||
},
|
||||
},
|
||||
topEndEditing: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onEndEditing',
|
||||
captured: 'onEndEditingCapture',
|
||||
},
|
||||
},
|
||||
topFocus: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onFocus',
|
||||
captured: 'onFocusCapture',
|
||||
},
|
||||
},
|
||||
topKeyPress: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onKeyPress',
|
||||
captured: 'onKeyPressCapture',
|
||||
},
|
||||
},
|
||||
topPress: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onPress',
|
||||
captured: 'onPressCapture',
|
||||
},
|
||||
},
|
||||
topSubmitEditing: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onSubmitEditing',
|
||||
captured: 'onSubmitEditingCapture',
|
||||
},
|
||||
},
|
||||
topTouchCancel: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchCancel',
|
||||
captured: 'onTouchCancelCapture',
|
||||
},
|
||||
},
|
||||
topTouchEnd: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchEnd',
|
||||
captured: 'onTouchEndCapture',
|
||||
},
|
||||
},
|
||||
topTouchMove: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchMove',
|
||||
captured: 'onTouchMoveCapture',
|
||||
},
|
||||
},
|
||||
topTouchStart: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchStart',
|
||||
captured: 'onTouchStartCapture',
|
||||
},
|
||||
},
|
||||
},
|
||||
directEventTypes: {
|
||||
...ReactNativeViewViewConfigAndroid.directEventTypes,
|
||||
...ReactNativeViewViewConfigMacOS.directEventTypes, // TODO(macOS GH#774)
|
||||
topAccessibilityAction: {
|
||||
registrationName: 'onAccessibilityAction',
|
||||
},
|
||||
topAccessibilityEscape: {
|
||||
registrationName: 'onAccessibilityEscape',
|
||||
},
|
||||
topAccessibilityTap: {
|
||||
registrationName: 'onAccessibilityTap',
|
||||
},
|
||||
topLayout: {
|
||||
registrationName: 'onLayout',
|
||||
},
|
||||
topMagicTap: {
|
||||
registrationName: 'onMagicTap',
|
||||
},
|
||||
topKeyUp: {
|
||||
registrationName: 'onKeyUp',
|
||||
},
|
||||
topKeyDown: {
|
||||
registrationName: 'onKeyDown',
|
||||
},
|
||||
topPointerEnter: {
|
||||
registrationName: 'pointerenter',
|
||||
},
|
||||
topPointerLeave: {
|
||||
registrationName: 'pointerleave',
|
||||
},
|
||||
topPointerMove: {
|
||||
registrationName: 'pointermove',
|
||||
},
|
||||
// Events for react-native-gesture-handler (T45765076)
|
||||
// Remove once this library can handle JS View Configs
|
||||
onGestureHandlerEvent: {
|
||||
registrationName: 'onGestureHandlerEvent',
|
||||
},
|
||||
onGestureHandlerStateChange: {
|
||||
registrationName: 'onGestureHandlerStateChange',
|
||||
},
|
||||
},
|
||||
validAttributes: {
|
||||
...ReactNativeViewViewConfigAndroid.validAttributes,
|
||||
...ReactNativeViewViewConfigMacOS.validAttributes, // TODO(macOS GH#774)
|
||||
accessibilityActions: true,
|
||||
accessibilityElementsHidden: true,
|
||||
accessibilityHint: true,
|
||||
accessibilityIgnoresInvertColors: true,
|
||||
accessibilityLabel: true,
|
||||
accessibilityLiveRegion: true,
|
||||
accessibilityRole: true,
|
||||
accessibilityState: true,
|
||||
accessibilityValue: true,
|
||||
accessibilityViewIsModal: true,
|
||||
accessible: true,
|
||||
alignContent: true,
|
||||
alignItems: true,
|
||||
alignSelf: true,
|
||||
aspectRatio: true,
|
||||
backfaceVisibility: true,
|
||||
backgroundColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderBottomColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderBottomEndRadius: true,
|
||||
borderBottomLeftRadius: true,
|
||||
borderBottomRightRadius: true,
|
||||
borderBottomStartRadius: true,
|
||||
borderBottomWidth: true,
|
||||
borderColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderEndColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderEndWidth: true,
|
||||
borderLeftColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderLeftWidth: true,
|
||||
borderRadius: true,
|
||||
borderRightColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderRightWidth: true,
|
||||
borderStartColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderStartWidth: true,
|
||||
borderStyle: true,
|
||||
borderTopColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderTopEndRadius: true,
|
||||
borderTopLeftRadius: true,
|
||||
borderTopRightRadius: true,
|
||||
borderTopStartRadius: true,
|
||||
borderTopWidth: true,
|
||||
borderWidth: true,
|
||||
bottom: true,
|
||||
clickable: true,
|
||||
collapsable: true,
|
||||
direction: true,
|
||||
display: true,
|
||||
elevation: true,
|
||||
end: true,
|
||||
flex: true,
|
||||
flexBasis: true,
|
||||
flexDirection: true,
|
||||
flexGrow: true,
|
||||
flexShrink: true,
|
||||
flexWrap: true,
|
||||
height: true,
|
||||
hitSlop: {diff: require('../../Utilities/differ/insetsDiffer')},
|
||||
importantForAccessibility: true,
|
||||
justifyContent: true,
|
||||
left: true,
|
||||
margin: true,
|
||||
marginBottom: true,
|
||||
marginEnd: true,
|
||||
marginHorizontal: true,
|
||||
marginLeft: true,
|
||||
marginRight: true,
|
||||
marginStart: true,
|
||||
marginTop: true,
|
||||
marginVertical: true,
|
||||
maxHeight: true,
|
||||
maxWidth: true,
|
||||
minHeight: true,
|
||||
minWidth: true,
|
||||
nativeID: true,
|
||||
needsOffscreenAlphaCompositing: true,
|
||||
onAccessibilityAction: true,
|
||||
onAccessibilityEscape: true,
|
||||
onAccessibilityTap: true,
|
||||
pointerenter: true,
|
||||
pointerleave: true,
|
||||
pointermove: true,
|
||||
onLayout: true,
|
||||
onMagicTap: true,
|
||||
opacity: true,
|
||||
overflow: true,
|
||||
padding: true,
|
||||
paddingBottom: true,
|
||||
paddingEnd: true,
|
||||
paddingHorizontal: true,
|
||||
paddingLeft: true,
|
||||
paddingRight: true,
|
||||
paddingStart: true,
|
||||
paddingTop: true,
|
||||
paddingVertical: true,
|
||||
pointerEvents: true,
|
||||
position: true,
|
||||
removeClippedSubviews: true,
|
||||
renderToHardwareTextureAndroid: true,
|
||||
right: true,
|
||||
rotation: true,
|
||||
scaleX: true,
|
||||
scaleY: true,
|
||||
shadowColor: {process: require('../../StyleSheet/processColor')},
|
||||
shadowOffset: {diff: require('../../Utilities/differ/sizesDiffer')},
|
||||
shadowOpacity: true,
|
||||
shadowRadius: true,
|
||||
shouldRasterizeIOS: true,
|
||||
start: true,
|
||||
style: {
|
||||
alignContent: true,
|
||||
alignItems: true,
|
||||
alignSelf: true,
|
||||
aspectRatio: true,
|
||||
backfaceVisibility: true,
|
||||
backgroundColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderBottomColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderBottomEndRadius: true,
|
||||
borderBottomLeftRadius: true,
|
||||
borderBottomRightRadius: true,
|
||||
borderBottomStartRadius: true,
|
||||
borderBottomWidth: true,
|
||||
borderColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderEndColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderEndWidth: true,
|
||||
borderLeftColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderLeftWidth: true,
|
||||
borderRadius: true,
|
||||
borderRightColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderRightWidth: true,
|
||||
borderStartColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderStartWidth: true,
|
||||
borderStyle: true,
|
||||
borderTopColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderTopEndRadius: true,
|
||||
borderTopLeftRadius: true,
|
||||
borderTopRightRadius: true,
|
||||
borderTopStartRadius: true,
|
||||
borderTopWidth: true,
|
||||
borderWidth: true,
|
||||
bottom: true,
|
||||
color: {process: require('../../StyleSheet/processColor')},
|
||||
cursor: true,
|
||||
decomposedMatrix: true,
|
||||
direction: true,
|
||||
display: true,
|
||||
elevation: true,
|
||||
end: true,
|
||||
flex: true,
|
||||
flexBasis: true,
|
||||
flexDirection: true,
|
||||
flexGrow: true,
|
||||
flexShrink: true,
|
||||
flexWrap: true,
|
||||
fontFamily: true,
|
||||
fontSize: true,
|
||||
fontStyle: true,
|
||||
fontVariant: true,
|
||||
fontWeight: true,
|
||||
apple_fontSmoothing: true, // TODO(OSS Candidate ISS#2710739)
|
||||
height: true,
|
||||
includeFontPadding: true,
|
||||
justifyContent: true,
|
||||
left: true,
|
||||
letterSpacing: true,
|
||||
lineHeight: true,
|
||||
margin: true,
|
||||
marginBottom: true,
|
||||
marginEnd: true,
|
||||
marginHorizontal: true,
|
||||
marginLeft: true,
|
||||
marginRight: true,
|
||||
marginStart: true,
|
||||
marginTop: true,
|
||||
marginVertical: true,
|
||||
maxHeight: true,
|
||||
maxWidth: true,
|
||||
minHeight: true,
|
||||
minWidth: true,
|
||||
opacity: true,
|
||||
overflow: true,
|
||||
overlayColor: {process: require('../../StyleSheet/processColor')},
|
||||
padding: true,
|
||||
paddingBottom: true,
|
||||
paddingEnd: true,
|
||||
paddingHorizontal: true,
|
||||
paddingLeft: true,
|
||||
paddingRight: true,
|
||||
paddingStart: true,
|
||||
paddingTop: true,
|
||||
paddingVertical: true,
|
||||
position: true,
|
||||
resizeMode: true,
|
||||
right: true,
|
||||
rotation: true,
|
||||
scaleX: true,
|
||||
scaleY: true,
|
||||
shadowColor: {process: require('../../StyleSheet/processColor')},
|
||||
shadowOffset: {diff: require('../../Utilities/differ/sizesDiffer')},
|
||||
shadowOpacity: true,
|
||||
shadowRadius: true,
|
||||
start: true,
|
||||
textAlign: true,
|
||||
textAlignVertical: true,
|
||||
textDecorationColor: {process: require('../../StyleSheet/processColor')},
|
||||
textDecorationLine: true,
|
||||
textDecorationStyle: true,
|
||||
textShadowColor: {process: require('../../StyleSheet/processColor')},
|
||||
textShadowOffset: true,
|
||||
textShadowRadius: true,
|
||||
textTransform: true,
|
||||
tintColor: {process: require('../../StyleSheet/processColor')},
|
||||
top: true,
|
||||
transform:
|
||||
Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS GH#774)
|
||||
? {diff: require('../../Utilities/differ/matricesDiffer')}
|
||||
: {process: require('../../StyleSheet/processTransform')},
|
||||
transformMatrix: true,
|
||||
translateX: true,
|
||||
translateY: true,
|
||||
width: true,
|
||||
writingDirection: true,
|
||||
zIndex: true,
|
||||
},
|
||||
testID: true,
|
||||
top: true,
|
||||
transform:
|
||||
Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS GH#774)
|
||||
? {diff: require('../../Utilities/differ/matricesDiffer')}
|
||||
: {process: require('../../StyleSheet/processTransform')},
|
||||
translateX: true,
|
||||
translateY: true,
|
||||
validKeysDown: true,
|
||||
validKeysUp: true,
|
||||
nextKeyViewTag: true, // TODO(macOS GH#768)
|
||||
width: true,
|
||||
zIndex: true,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactNativeViewConfig;
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactNativeViewViewConfigAndroid = {
|
||||
uiViewClassName: 'RCTView',
|
||||
bubblingEventTypes: {
|
||||
topSelect: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onSelect',
|
||||
captured: 'onSelectCapture',
|
||||
},
|
||||
},
|
||||
topAssetDidLoad: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onAssetDidLoad',
|
||||
captured: 'onAssetDidLoadCapture',
|
||||
},
|
||||
},
|
||||
},
|
||||
directEventTypes: {
|
||||
topClick: {
|
||||
registrationName: 'onClick',
|
||||
},
|
||||
topContentSizeChange: {
|
||||
registrationName: 'onContentSizeChange',
|
||||
},
|
||||
topLoadingError: {
|
||||
registrationName: 'onLoadingError',
|
||||
},
|
||||
topLoadingFinish: {
|
||||
registrationName: 'onLoadingFinish',
|
||||
},
|
||||
topLoadingStart: {
|
||||
registrationName: 'onLoadingStart',
|
||||
},
|
||||
topMessage: {
|
||||
registrationName: 'onMessage',
|
||||
},
|
||||
topMomentumScrollBegin: {
|
||||
registrationName: 'onMomentumScrollBegin',
|
||||
},
|
||||
topMomentumScrollEnd: {
|
||||
registrationName: 'onMomentumScrollEnd',
|
||||
},
|
||||
topScroll: {
|
||||
registrationName: 'onScroll',
|
||||
},
|
||||
topScrollBeginDrag: {
|
||||
registrationName: 'onScrollBeginDrag',
|
||||
},
|
||||
topScrollEndDrag: {
|
||||
registrationName: 'onScrollEndDrag',
|
||||
},
|
||||
topSelectionChange: {
|
||||
registrationName: 'onSelectionChange',
|
||||
},
|
||||
onAssetDidLoad: {
|
||||
registrationName: 'onAssetDidLoad',
|
||||
},
|
||||
},
|
||||
validAttributes: {
|
||||
hasTVPreferredFocus: true,
|
||||
focusable: true,
|
||||
nativeBackgroundAndroid: true,
|
||||
nativeForegroundAndroid: true,
|
||||
nextFocusDown: true,
|
||||
nextFocusForward: true,
|
||||
nextFocusLeft: true,
|
||||
nextFocusRight: true,
|
||||
nextFocusUp: true,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ReactNativeViewViewConfigAndroid;
|
|
@ -10,18 +10,75 @@
|
|||
|
||||
import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';
|
||||
import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes';
|
||||
import Platform from '../../Utilities/Platform';
|
||||
import codegenNativeCommands from '../../Utilities/codegenNativeCommands';
|
||||
import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid';
|
||||
import {type ViewProps as Props} from './ViewPropTypes';
|
||||
import Platform from '../../Utilities/Platform';
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
const ViewPartialViewConfig =
|
||||
Platform.OS === 'android'
|
||||
? {
|
||||
uiViewClassName: 'RCTView',
|
||||
validAttributes: {
|
||||
// ReactClippingViewManager @ReactProps
|
||||
removeClippedSubviews: true,
|
||||
|
||||
// ReactViewManager @ReactProps
|
||||
accessible: true,
|
||||
hasTVPreferredFocus: true,
|
||||
nextFocusDown: true,
|
||||
nextFocusForward: true,
|
||||
nextFocusLeft: true,
|
||||
nextFocusRight: true,
|
||||
nextFocusUp: true,
|
||||
|
||||
borderRadius: true,
|
||||
borderTopLeftRadius: true,
|
||||
borderTopRightRadius: true,
|
||||
borderBottomRightRadius: true,
|
||||
borderBottomLeftRadius: true,
|
||||
borderTopStartRadius: true,
|
||||
borderTopEndRadius: true,
|
||||
borderBottomStartRadius: true,
|
||||
borderBottomEndRadius: true,
|
||||
|
||||
borderStyle: true,
|
||||
hitSlop: true,
|
||||
pointerEvents: true,
|
||||
nativeBackgroundAndroid: true,
|
||||
nativeForegroundAndroid: true,
|
||||
needsOffscreenAlphaCompositing: true,
|
||||
|
||||
borderWidth: true,
|
||||
borderLeftWidth: true,
|
||||
borderRightWidth: true,
|
||||
borderTopWidth: true,
|
||||
borderBottomWidth: true,
|
||||
borderStartWidth: true,
|
||||
borderEndWidth: true,
|
||||
|
||||
borderColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderLeftColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderRightColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderTopColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderBottomColor: {
|
||||
process: require('../../StyleSheet/processColor'),
|
||||
},
|
||||
borderStartColor: {process: require('../../StyleSheet/processColor')},
|
||||
borderEndColor: {process: require('../../StyleSheet/processColor')},
|
||||
|
||||
focusable: true,
|
||||
overflow: true,
|
||||
backfaceVisibility: true,
|
||||
},
|
||||
}
|
||||
: {
|
||||
uiViewClassName: 'RCTView',
|
||||
};
|
||||
|
||||
const ViewNativeComponent: HostComponent<Props> =
|
||||
NativeComponentRegistry.get<Props>('RCTView', () =>
|
||||
Platform.OS === 'android'
|
||||
? ReactNativeViewViewConfigAndroid
|
||||
: {uiViewClassName: 'RCTView'},
|
||||
);
|
||||
NativeComponentRegistry.get<Props>('RCTView', () => ViewPartialViewConfig);
|
||||
|
||||
interface NativeCommands {
|
||||
+hotspotUpdate: (
|
||||
|
|
|
@ -20,7 +20,7 @@ import type {
|
|||
ScrollEvent, // TODO(macOS GH#774)
|
||||
KeyEvent, // TODO(macOS GH#774)
|
||||
} from '../../Types/CoreEventTypes';
|
||||
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
|
||||
import type {EdgeInsetsOrSizeProp} from '../../StyleSheet/EdgeInsetsPropType';
|
||||
import type {Node} from 'react';
|
||||
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
|
||||
import type {
|
||||
|
@ -597,7 +597,7 @@ export type ViewProps = $ReadOnly<{|
|
|||
*
|
||||
* See https://reactnative.dev/docs/view#hitslop
|
||||
*/
|
||||
hitSlop?: ?EdgeInsetsProp,
|
||||
hitSlop?: ?EdgeInsetsOrSizeProp,
|
||||
|
||||
/**
|
||||
* Controls whether the `View` can be the target of touch events.
|
||||
|
|
|
@ -58,12 +58,13 @@ if (__DEV__) {
|
|||
isWebSocketOpen = true;
|
||||
});
|
||||
|
||||
const viewConfig = require('../Components/View/ReactNativeViewViewConfig');
|
||||
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
|
||||
|
||||
reactDevTools.connectToDevTools({
|
||||
isAppActive,
|
||||
resolveRNStyle: require('../StyleSheet/flattenStyle'),
|
||||
nativeStyleEditorValidAttributes: Object.keys(
|
||||
viewConfig.validAttributes.style,
|
||||
ReactNativeStyleAttributes,
|
||||
),
|
||||
websocket: ws,
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ const React = require('react');
|
|||
const ReactNative = require('../Renderer/shims/ReactNative');
|
||||
const StyleSheet = require('../StyleSheet/StyleSheet');
|
||||
const View = require('../Components/View/View');
|
||||
const ReactNativeStyleAttributes = require('../Components/View/ReactNativeStyleAttributes');
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
|
@ -47,10 +48,7 @@ const renderers = findRenderers();
|
|||
// Required for React DevTools to view/edit React Native styles in Flipper.
|
||||
// Flipper doesn't inject these values when initializing DevTools.
|
||||
hook.resolveRNStyle = require('../StyleSheet/flattenStyle');
|
||||
const viewConfig = require('../Components/View/ReactNativeViewViewConfig');
|
||||
hook.nativeStyleEditorValidAttributes = Object.keys(
|
||||
viewConfig.validAttributes.style,
|
||||
);
|
||||
hook.nativeStyleEditorValidAttributes = Object.keys(ReactNativeStyleAttributes);
|
||||
|
||||
function findRenderers(): $ReadOnlyArray<ReactRenderer> {
|
||||
const allRenderers = Array.from(hook.renderers.values());
|
||||
|
|
|
@ -0,0 +1,506 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import {Platform} from 'react-native';
|
||||
import type {PartialViewConfig} from '../Renderer/shims/ReactNativeTypes';
|
||||
import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes';
|
||||
import {DynamicallyInjectedByGestureHandler} from './ViewConfigIgnore';
|
||||
|
||||
type PartialViewConfigWithoutName = $Rest<
|
||||
PartialViewConfig,
|
||||
{uiViewClassName: string},
|
||||
>;
|
||||
|
||||
const PlatformBaseViewConfig: PartialViewConfigWithoutName =
|
||||
Platform.OS === 'android'
|
||||
? /**
|
||||
* On Android, Props are derived from a ViewManager and its ShadowNode.
|
||||
*
|
||||
* Where did we find these base platform props from?
|
||||
* - Nearly all component ViewManagers descend from BaseViewManager.
|
||||
* - BaseViewManagers' ShadowNodes descend from LayoutShadowNode.
|
||||
*
|
||||
* So, these ViewConfigs are generated from LayoutShadowNode and BaseViewManager.
|
||||
*/
|
||||
{
|
||||
directEventTypes: {
|
||||
topAccessibilityAction: {
|
||||
registrationName: 'onAccessibilityAction',
|
||||
},
|
||||
topPointerEnter: {
|
||||
registrationName: 'pointerenter',
|
||||
},
|
||||
topPointerLeave: {
|
||||
registrationName: 'pointerleave',
|
||||
},
|
||||
topPointerMove: {
|
||||
registrationName: 'pointermove',
|
||||
},
|
||||
onGestureHandlerEvent: DynamicallyInjectedByGestureHandler({
|
||||
registrationName: 'onGestureHandlerEvent',
|
||||
}),
|
||||
onGestureHandlerStateChange: DynamicallyInjectedByGestureHandler({
|
||||
registrationName: 'onGestureHandlerStateChange',
|
||||
}),
|
||||
|
||||
// Direct events from UIManagerModuleConstants.java
|
||||
topContentSizeChange: {
|
||||
registrationName: 'onContentSizeChange',
|
||||
},
|
||||
topScrollBeginDrag: {
|
||||
registrationName: 'onScrollBeginDrag',
|
||||
},
|
||||
topMessage: {
|
||||
registrationName: 'onMessage',
|
||||
},
|
||||
topSelectionChange: {
|
||||
registrationName: 'onSelectionChange',
|
||||
},
|
||||
topLoadingFinish: {
|
||||
registrationName: 'onLoadingFinish',
|
||||
},
|
||||
topMomentumScrollEnd: {
|
||||
registrationName: 'onMomentumScrollEnd',
|
||||
},
|
||||
topClick: {
|
||||
registrationName: 'onClick',
|
||||
},
|
||||
topLoadingStart: {
|
||||
registrationName: 'onLoadingStart',
|
||||
},
|
||||
topLoadingError: {
|
||||
registrationName: 'onLoadingError',
|
||||
},
|
||||
topMomentumScrollBegin: {
|
||||
registrationName: 'onMomentumScrollBegin',
|
||||
},
|
||||
topScrollEndDrag: {
|
||||
registrationName: 'onScrollEndDrag',
|
||||
},
|
||||
topScroll: {
|
||||
registrationName: 'onScroll',
|
||||
},
|
||||
topLayout: {
|
||||
registrationName: 'onLayout',
|
||||
},
|
||||
},
|
||||
bubblingEventTypes: {
|
||||
// Bubbling events from UIManagerModuleConstants.java
|
||||
topChange: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onChangeCapture',
|
||||
bubbled: 'onChange',
|
||||
},
|
||||
},
|
||||
topSelect: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onSelectCapture',
|
||||
bubbled: 'onSelect',
|
||||
},
|
||||
},
|
||||
topTouchEnd: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onTouchEndCapture',
|
||||
bubbled: 'onTouchEnd',
|
||||
},
|
||||
},
|
||||
topTouchCancel: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onTouchCancelCapture',
|
||||
bubbled: 'onTouchCancel',
|
||||
},
|
||||
},
|
||||
topTouchStart: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onTouchStartCapture',
|
||||
bubbled: 'onTouchStart',
|
||||
},
|
||||
},
|
||||
topTouchMove: {
|
||||
phasedRegistrationNames: {
|
||||
captured: 'onTouchMoveCapture',
|
||||
bubbled: 'onTouchMove',
|
||||
},
|
||||
},
|
||||
},
|
||||
validAttributes: {
|
||||
// @ReactProps from BaseViewManager
|
||||
backgroundColor: {process: require('../StyleSheet/processColor')},
|
||||
transform: true,
|
||||
opacity: true,
|
||||
elevation: true,
|
||||
shadowColor: {process: require('../StyleSheet/processColor')},
|
||||
zIndex: true,
|
||||
renderToHardwareTextureAndroid: true,
|
||||
testID: true,
|
||||
nativeID: true,
|
||||
accessibilityLabelledBy: true,
|
||||
accessibilityLabel: true,
|
||||
accessibilityHint: true,
|
||||
accessibilityRole: true,
|
||||
accessibilityState: true,
|
||||
accessibilityActions: true,
|
||||
accessibilityValue: true,
|
||||
importantForAccessibility: true,
|
||||
rotation: true,
|
||||
scaleX: true,
|
||||
scaleY: true,
|
||||
translateX: true,
|
||||
translateY: true,
|
||||
accessibilityLiveRegion: true,
|
||||
|
||||
// @ReactProps from LayoutShadowNode
|
||||
width: true,
|
||||
minWidth: true,
|
||||
collapsable: true,
|
||||
maxWidth: true,
|
||||
height: true,
|
||||
minHeight: true,
|
||||
maxHeight: true,
|
||||
flex: true,
|
||||
flexGrow: true,
|
||||
flexShrink: true,
|
||||
flexBasis: true,
|
||||
aspectRatio: true,
|
||||
flexDirection: true,
|
||||
flexWrap: true,
|
||||
alignSelf: true,
|
||||
alignItems: true,
|
||||
alignContent: true,
|
||||
justifyContent: true,
|
||||
overflow: true,
|
||||
display: true,
|
||||
|
||||
margin: true,
|
||||
marginVertical: true,
|
||||
marginHorizontal: true,
|
||||
marginStart: true,
|
||||
marginEnd: true,
|
||||
marginTop: true,
|
||||
marginBottom: true,
|
||||
marginLeft: true,
|
||||
marginRight: true,
|
||||
|
||||
padding: true,
|
||||
paddingVertical: true,
|
||||
paddingHorizontal: true,
|
||||
paddingStart: true,
|
||||
paddingEnd: true,
|
||||
paddingTop: true,
|
||||
paddingBottom: true,
|
||||
paddingLeft: true,
|
||||
paddingRight: true,
|
||||
|
||||
borderWidth: true,
|
||||
borderStartWidth: true,
|
||||
borderEndWidth: true,
|
||||
borderTopWidth: true,
|
||||
borderBottomWidth: true,
|
||||
borderLeftWidth: true,
|
||||
borderRightWidth: true,
|
||||
|
||||
start: true,
|
||||
end: true,
|
||||
left: true,
|
||||
right: true,
|
||||
top: true,
|
||||
bottom: true,
|
||||
|
||||
position: true,
|
||||
onLayout: true,
|
||||
|
||||
pointerenter: true,
|
||||
pointerleave: true,
|
||||
pointermove: true,
|
||||
|
||||
style: ReactNativeStyleAttributes,
|
||||
},
|
||||
}
|
||||
: /**
|
||||
* On iOS, ViewManagers define all of a component's props.
|
||||
* All ViewManagers extend RCTViewManager, and RCTViewManager declares
|
||||
* these props.
|
||||
*/
|
||||
{
|
||||
bubblingEventTypes: {
|
||||
// Generic Events
|
||||
topPress: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onPress',
|
||||
captured: 'onPressCapture',
|
||||
},
|
||||
},
|
||||
topChange: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onChange',
|
||||
captured: 'onChangeCapture',
|
||||
},
|
||||
},
|
||||
topFocus: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onFocus',
|
||||
captured: 'onFocusCapture',
|
||||
},
|
||||
},
|
||||
topBlur: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onBlur',
|
||||
captured: 'onBlurCapture',
|
||||
},
|
||||
},
|
||||
topSubmitEditing: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onSubmitEditing',
|
||||
captured: 'onSubmitEditingCapture',
|
||||
},
|
||||
},
|
||||
topEndEditing: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onEndEditing',
|
||||
captured: 'onEndEditingCapture',
|
||||
},
|
||||
},
|
||||
topKeyPress: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onKeyPress',
|
||||
captured: 'onKeyPressCapture',
|
||||
},
|
||||
},
|
||||
|
||||
// Touch Events
|
||||
topTouchStart: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchStart',
|
||||
captured: 'onTouchStartCapture',
|
||||
},
|
||||
},
|
||||
topTouchMove: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchMove',
|
||||
captured: 'onTouchMoveCapture',
|
||||
},
|
||||
},
|
||||
topTouchCancel: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchCancel',
|
||||
captured: 'onTouchCancelCapture',
|
||||
},
|
||||
},
|
||||
topTouchEnd: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: 'onTouchEnd',
|
||||
captured: 'onTouchEndCapture',
|
||||
},
|
||||
},
|
||||
},
|
||||
directEventTypes: {
|
||||
topAccessibilityAction: {
|
||||
registrationName: 'onAccessibilityAction',
|
||||
},
|
||||
topAccessibilityTap: {
|
||||
registrationName: 'onAccessibilityTap',
|
||||
},
|
||||
topMagicTap: {
|
||||
registrationName: 'onMagicTap',
|
||||
},
|
||||
topAccessibilityEscape: {
|
||||
registrationName: 'onAccessibilityEscape',
|
||||
},
|
||||
topLayout: {
|
||||
registrationName: 'onLayout',
|
||||
},
|
||||
onGestureHandlerEvent: DynamicallyInjectedByGestureHandler({
|
||||
registrationName: 'onGestureHandlerEvent',
|
||||
}),
|
||||
onGestureHandlerStateChange: DynamicallyInjectedByGestureHandler({
|
||||
registrationName: 'onGestureHandlerStateChange',
|
||||
}),
|
||||
// [macOS
|
||||
...(Platform.OS === 'macos' && {
|
||||
topDoubleClick: {
|
||||
registrationName: 'onDoubleClick',
|
||||
},
|
||||
topDragEnter: {
|
||||
registrationName: 'onDragEnter',
|
||||
},
|
||||
topDragLeave: {
|
||||
registrationName: 'onDragLeave',
|
||||
},
|
||||
topDrop: {
|
||||
registrationName: 'onDrop',
|
||||
},
|
||||
topKeyUp: {
|
||||
registrationName: 'onKeyUp',
|
||||
},
|
||||
topKeyDown: {
|
||||
registrationName: 'onKeyDown',
|
||||
},
|
||||
topMouseEnter: {
|
||||
registrationName: 'onMouseEnter',
|
||||
},
|
||||
topMouseLeave: {
|
||||
registrationName: 'onMouseLeave',
|
||||
},
|
||||
}),
|
||||
// macOS]
|
||||
},
|
||||
validAttributes: {
|
||||
// View Props
|
||||
accessible: true,
|
||||
accessibilityActions: true,
|
||||
accessibilityLabel: true,
|
||||
accessibilityHint: true,
|
||||
accessibilityValue: true,
|
||||
accessibilityViewIsModal: true,
|
||||
accessibilityElementsHidden: true,
|
||||
accessibilityIgnoresInvertColors: true,
|
||||
apple_fontSmoothing: true, // TODO(OSS Candidate ISS#2710739)
|
||||
testID: true,
|
||||
backgroundColor: {process: require('../StyleSheet/processColor')},
|
||||
backfaceVisibility: true,
|
||||
opacity: true,
|
||||
shadowColor: {process: require('../StyleSheet/processColor')},
|
||||
shadowOffset: {diff: require('../Utilities/differ/sizesDiffer')},
|
||||
shadowOpacity: true,
|
||||
shadowRadius: true,
|
||||
needsOffscreenAlphaCompositing: true,
|
||||
overflow: true,
|
||||
shouldRasterizeIOS: true,
|
||||
transform: {diff: require('../Utilities/differ/matricesDiffer')},
|
||||
accessibilityRole: true,
|
||||
accessibilityState: true,
|
||||
nativeID: true,
|
||||
pointerEvents: true,
|
||||
removeClippedSubviews: true,
|
||||
borderRadius: true,
|
||||
borderColor: {process: require('../StyleSheet/processColor')},
|
||||
borderWidth: true,
|
||||
borderStyle: true,
|
||||
hitSlop: {diff: require('../Utilities/differ/insetsDiffer')},
|
||||
collapsable: true,
|
||||
|
||||
borderTopWidth: true,
|
||||
borderTopColor: {process: require('../StyleSheet/processColor')},
|
||||
borderRightWidth: true,
|
||||
borderRightColor: {process: require('../StyleSheet/processColor')},
|
||||
borderBottomWidth: true,
|
||||
borderBottomColor: {process: require('../StyleSheet/processColor')},
|
||||
borderLeftWidth: true,
|
||||
borderLeftColor: {process: require('../StyleSheet/processColor')},
|
||||
borderStartWidth: true,
|
||||
borderStartColor: {process: require('../StyleSheet/processColor')},
|
||||
borderEndWidth: true,
|
||||
borderEndColor: {process: require('../StyleSheet/processColor')},
|
||||
|
||||
borderTopLeftRadius: true,
|
||||
borderTopRightRadius: true,
|
||||
borderTopStartRadius: true,
|
||||
borderTopEndRadius: true,
|
||||
borderBottomLeftRadius: true,
|
||||
borderBottomRightRadius: true,
|
||||
borderBottomStartRadius: true,
|
||||
borderBottomEndRadius: true,
|
||||
display: true,
|
||||
zIndex: true,
|
||||
|
||||
// ShadowView properties
|
||||
top: true,
|
||||
right: true,
|
||||
start: true,
|
||||
end: true,
|
||||
bottom: true,
|
||||
left: true,
|
||||
|
||||
width: true,
|
||||
height: true,
|
||||
|
||||
minWidth: true,
|
||||
maxWidth: true,
|
||||
minHeight: true,
|
||||
maxHeight: true,
|
||||
|
||||
// Also declared as ViewProps
|
||||
// borderTopWidth: true,
|
||||
// borderRightWidth: true,
|
||||
// borderBottomWidth: true,
|
||||
// borderLeftWidth: true,
|
||||
// borderStartWidth: true,
|
||||
// borderEndWidth: true,
|
||||
// borderWidth: true,
|
||||
|
||||
marginTop: true,
|
||||
marginRight: true,
|
||||
marginBottom: true,
|
||||
marginLeft: true,
|
||||
marginStart: true,
|
||||
marginEnd: true,
|
||||
marginVertical: true,
|
||||
marginHorizontal: true,
|
||||
margin: true,
|
||||
|
||||
paddingTop: true,
|
||||
paddingRight: true,
|
||||
paddingBottom: true,
|
||||
paddingLeft: true,
|
||||
paddingStart: true,
|
||||
paddingEnd: true,
|
||||
paddingVertical: true,
|
||||
paddingHorizontal: true,
|
||||
padding: true,
|
||||
|
||||
flex: true,
|
||||
flexGrow: true,
|
||||
flexShrink: true,
|
||||
flexBasis: true,
|
||||
flexDirection: true,
|
||||
flexWrap: true,
|
||||
justifyContent: true,
|
||||
alignItems: true,
|
||||
alignSelf: true,
|
||||
alignContent: true,
|
||||
position: true,
|
||||
aspectRatio: true,
|
||||
|
||||
// Also declared as ViewProps
|
||||
// overflow: true,
|
||||
// display: true,
|
||||
|
||||
direction: true,
|
||||
|
||||
style: ReactNativeStyleAttributes,
|
||||
|
||||
// [macOS
|
||||
...(Platform.OS === 'macos' && {
|
||||
acceptsFirstMouse: true,
|
||||
accessibilityTraits: true,
|
||||
cursor: true,
|
||||
draggedTypes: true,
|
||||
enableFocusRing: true,
|
||||
nextKeyViewTag: true,
|
||||
onBlur: true,
|
||||
onClick: true,
|
||||
onDoubleClick: true,
|
||||
onDragEnter: true,
|
||||
onDragLeave: true,
|
||||
onDrop: true,
|
||||
onFocus: true,
|
||||
onKeyDown: true,
|
||||
onKeyUp: true,
|
||||
onMouseEnter: true,
|
||||
onMouseLeave: true,
|
||||
tooltip: true,
|
||||
validKeysDown: true,
|
||||
validKeysUp: true,
|
||||
}),
|
||||
// macOS]
|
||||
},
|
||||
};
|
||||
|
||||
export default PlatformBaseViewConfig;
|
|
@ -13,6 +13,7 @@ import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
|
|||
import getNativeComponentAttributes from '../ReactNative/getNativeComponentAttributes';
|
||||
// $FlowFixMe[nonstrict-import]
|
||||
import {createViewConfig} from './ViewConfig';
|
||||
import {isIgnored} from './ViewConfigIgnore';
|
||||
|
||||
type Difference =
|
||||
| {
|
||||
|
@ -183,7 +184,10 @@ function accumulateDifferences(
|
|||
}
|
||||
|
||||
for (const staticKey in staticObject) {
|
||||
if (!nativeObject.hasOwnProperty(staticKey)) {
|
||||
if (
|
||||
!nativeObject.hasOwnProperty(staticKey) &&
|
||||
!isIgnored(staticObject[staticKey])
|
||||
) {
|
||||
differences.push({
|
||||
path: [...path, staticKey],
|
||||
type: 'unexpected',
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
* @format
|
||||
*/
|
||||
|
||||
import ReactNativeViewViewConfig from '../Components/View/ReactNativeViewViewConfig';
|
||||
import type {
|
||||
PartialViewConfig,
|
||||
ViewConfig,
|
||||
} from '../Renderer/shims/ReactNativeTypes';
|
||||
import PlatformBaseViewConfig from './PlatformBaseViewConfig';
|
||||
|
||||
/**
|
||||
* Creates a complete `ViewConfig` from a `PartialViewConfig`.
|
||||
|
@ -24,16 +24,16 @@ export function createViewConfig(
|
|||
uiViewClassName: partialViewConfig.uiViewClassName,
|
||||
Commands: {},
|
||||
bubblingEventTypes: composeIndexers(
|
||||
ReactNativeViewViewConfig.bubblingEventTypes,
|
||||
PlatformBaseViewConfig.bubblingEventTypes,
|
||||
partialViewConfig.bubblingEventTypes,
|
||||
),
|
||||
directEventTypes: composeIndexers(
|
||||
ReactNativeViewViewConfig.directEventTypes,
|
||||
PlatformBaseViewConfig.directEventTypes,
|
||||
partialViewConfig.directEventTypes,
|
||||
),
|
||||
validAttributes: composeIndexers(
|
||||
// $FlowFixMe[incompatible-call] `style` property confuses Flow.
|
||||
ReactNativeViewViewConfig.validAttributes,
|
||||
PlatformBaseViewConfig.validAttributes,
|
||||
// $FlowFixMe[incompatible-call] `style` property confuses Flow.
|
||||
partialViewConfig.validAttributes,
|
||||
),
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
const ignoredViewConfigProps = new WeakSet<{...}>();
|
||||
|
||||
/**
|
||||
* Decorates ViewConfig values that are dynamically injected by the library,
|
||||
* react-native-gesture-handler. (T45765076)
|
||||
*/
|
||||
export function DynamicallyInjectedByGestureHandler<T: {...}>(object: T): T {
|
||||
ignoredViewConfigProps.add(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
export function isIgnored(value: mixed): boolean {
|
||||
if (typeof value === 'object' && value != null) {
|
||||
return ignoredViewConfigProps.has(value);
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -10,18 +10,14 @@
|
|||
|
||||
import normalizeColor from '../StyleSheet/normalizeColor';
|
||||
import type {ColorValue} from '../StyleSheet/StyleSheet';
|
||||
import {normalizeRect, type RectOrSize} from '../StyleSheet/Rect';
|
||||
|
||||
import View from '../Components/View/View';
|
||||
import * as React from 'react';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
color: ColorValue,
|
||||
hitSlop: ?$ReadOnly<{|
|
||||
bottom?: ?number,
|
||||
left?: ?number,
|
||||
right?: ?number,
|
||||
top?: ?number,
|
||||
|}>,
|
||||
hitSlop: ?RectOrSize,
|
||||
|}>;
|
||||
|
||||
/**
|
||||
|
@ -39,16 +35,16 @@ type Props = $ReadOnly<{|
|
|||
* );
|
||||
*
|
||||
*/
|
||||
export function PressabilityDebugView({color, hitSlop}: Props): React.Node {
|
||||
export function PressabilityDebugView(props: Props): React.Node {
|
||||
if (__DEV__) {
|
||||
if (isEnabled()) {
|
||||
const normalizedColor = normalizeColor(color);
|
||||
const normalizedColor = normalizeColor(props.color);
|
||||
if (typeof normalizedColor !== 'number') {
|
||||
return null;
|
||||
}
|
||||
const baseColor =
|
||||
'#' + (normalizedColor ?? 0).toString(16).padStart(8, '0');
|
||||
|
||||
const hitSlop = normalizeRect(props.hitSlop);
|
||||
return (
|
||||
<View
|
||||
pointerEvents="none"
|
||||
|
|
|
@ -18,14 +18,16 @@ module.exports = {
|
|||
'getViewManagerConfig is unavailable in Bridgeless, use hasViewManagerConfig instead. viewManagerName: ' +
|
||||
viewManagerName,
|
||||
);
|
||||
if (viewManagerName === 'RCTVirtualText') {
|
||||
if (
|
||||
viewManagerName === 'RCTVirtualText' ||
|
||||
viewManagerName === 'RCTShimmeringView'
|
||||
) {
|
||||
return {};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
hasViewManagerConfig: (viewManagerName: string): boolean => {
|
||||
const staticViewConfigsEnabled = global.__fbStaticViewConfig === true;
|
||||
if (staticViewConfigsEnabled) {
|
||||
if (global.__nativeComponentRegistry__hasComponent) {
|
||||
return unstable_hasComponent(viewManagerName);
|
||||
} else {
|
||||
return (
|
||||
|
|
|
@ -34,7 +34,6 @@ export interface UIManagerJSInterface extends Spec {
|
|||
const UIManager: UIManagerJSInterface =
|
||||
global.RN$Bridgeless === true
|
||||
? require('./DummyUIManager')
|
||||
: require('./UIManagerInjection').default.unstable_UIManager ??
|
||||
require('./PaperUIManager');
|
||||
: require('./PaperUIManager');
|
||||
|
||||
module.exports = UIManager;
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {UIManagerJSInterface} from './UIManager';
|
||||
|
||||
export default {
|
||||
unstable_UIManager: (null: ?UIManagerJSInterface),
|
||||
};
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import type {Rect} from './Rect';
|
||||
import type {Rect, RectOrSize} from './Rect';
|
||||
|
||||
// TODO: allow all EdgeInsets-like property to be set using a single number
|
||||
// and unify EdgeInsetsProp with EdgeInsetsOrSizeProp
|
||||
export type EdgeInsetsProp = Rect;
|
||||
export type EdgeInsetsOrSizeProp = RectOrSize;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
import ReactNativeViewViewConfig from '../Components/View/ReactNativeViewViewConfig';
|
||||
import PlatformBaseViewConfig from '../NativeComponent/PlatformBaseViewConfig';
|
||||
import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
|
||||
|
||||
const IGNORED_KEYS = ['transform', 'hitSlop'];
|
||||
|
@ -109,7 +109,7 @@ export function getConfigWithoutViewProps(
|
|||
}
|
||||
|
||||
return Object.keys(viewConfig[propName])
|
||||
.filter(prop => !ReactNativeViewViewConfig[propName][prop])
|
||||
.filter(prop => !PlatformBaseViewConfig[propName][prop])
|
||||
.reduce((obj, prop) => {
|
||||
obj[prop] = viewConfig[propName][prop];
|
||||
return obj;
|
||||
|
|
|
@ -97,8 +97,6 @@ import com.facebook.react.surface.ReactStage;
|
|||
import com.facebook.react.turbomodule.core.TurboModuleManager;
|
||||
import com.facebook.react.turbomodule.core.TurboModuleManagerDelegate;
|
||||
import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry;
|
||||
import com.facebook.react.uimanager.ComponentNameResolver;
|
||||
import com.facebook.react.uimanager.ComponentNameResolverManager;
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||
import com.facebook.react.uimanager.ReactRoot;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
|
@ -168,7 +166,6 @@ public class ReactInstanceManager {
|
|||
private final DevSupportManager mDevSupportManager;
|
||||
private final boolean mUseDeveloperSupport;
|
||||
private final boolean mRequireActivity;
|
||||
private @Nullable ComponentNameResolverManager mComponentNameResolverManager;
|
||||
private final @Nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener;
|
||||
private final Object mReactContextLock = new Object();
|
||||
private @Nullable volatile ReactContext mCurrentReactContext;
|
||||
|
@ -770,7 +767,6 @@ public class ReactInstanceManager {
|
|||
synchronized (mPackages) {
|
||||
mViewManagerNames = null;
|
||||
}
|
||||
mComponentNameResolverManager = null;
|
||||
FLog.d(ReactConstants.TAG, "ReactInstanceManager has been destroyed");
|
||||
}
|
||||
|
||||
|
@ -1399,23 +1395,6 @@ public class ReactInstanceManager {
|
|||
if (Systrace.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JS_VM_CALLS)) {
|
||||
catalystInstance.setGlobalVariable("__RCTProfileIsProfiling", "true");
|
||||
}
|
||||
if (ReactFeatureFlags.enableExperimentalStaticViewConfigs) {
|
||||
mComponentNameResolverManager =
|
||||
new ComponentNameResolverManager(
|
||||
catalystInstance.getRuntimeExecutor(),
|
||||
new ComponentNameResolver() {
|
||||
@Override
|
||||
public String[] getComponentNames() {
|
||||
List<String> viewManagerNames = getViewManagerNames();
|
||||
if (viewManagerNames == null) {
|
||||
FLog.e(TAG, "No ViewManager names found");
|
||||
return new String[0];
|
||||
}
|
||||
return viewManagerNames.toArray(new String[0]);
|
||||
}
|
||||
});
|
||||
catalystInstance.setGlobalVariable("__fbStaticViewConfig", "true");
|
||||
}
|
||||
|
||||
ReactMarker.logMarker(ReactMarkerConstants.PRE_RUN_JS_BUNDLE_START);
|
||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "runJSBundle");
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.view.Surface;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -826,9 +827,12 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
|||
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();
|
||||
WindowInsets insets = getRootView().getRootWindowInsets();
|
||||
if (insets != null) {
|
||||
DisplayCutout displayCutout = insets.getDisplayCutout();
|
||||
if (displayCutout != null) {
|
||||
notchHeight = displayCutout.getSafeInsetTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
final int heightDiff =
|
||||
|
|
|
@ -28,6 +28,7 @@ rn_android_library(
|
|||
react_native_target("java/com/facebook/react/modules/core:core"),
|
||||
react_native_target("java/com/facebook/react/uimanager:uimanager"),
|
||||
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
|
||||
react_native_target("java/com/facebook/react/views/view:view"),
|
||||
],
|
||||
exported_deps = [react_native_root_target(":FBReactNativeSpec")],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and 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.animated;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.views.view.ColorUtil;
|
||||
|
||||
/** Animated node that represents a color. */
|
||||
/*package*/ class ColorAnimatedNode extends AnimatedNode {
|
||||
|
||||
private final NativeAnimatedNodesManager mNativeAnimatedNodesManager;
|
||||
private final int mRNodeId;
|
||||
private final int mGNodeId;
|
||||
private final int mBNodeId;
|
||||
private final int mANodeId;
|
||||
private int mColor;
|
||||
|
||||
public ColorAnimatedNode(
|
||||
ReadableMap config, NativeAnimatedNodesManager nativeAnimatedNodesManager) {
|
||||
mNativeAnimatedNodesManager = nativeAnimatedNodesManager;
|
||||
mRNodeId = config.getInt("r");
|
||||
mGNodeId = config.getInt("g");
|
||||
mBNodeId = config.getInt("b");
|
||||
mANodeId = config.getInt("a");
|
||||
|
||||
// TODO (T110930421): Support platform color
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return mColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
AnimatedNode rNode = mNativeAnimatedNodesManager.getNodeById(mRNodeId);
|
||||
AnimatedNode gNode = mNativeAnimatedNodesManager.getNodeById(mGNodeId);
|
||||
AnimatedNode bNode = mNativeAnimatedNodesManager.getNodeById(mBNodeId);
|
||||
AnimatedNode aNode = mNativeAnimatedNodesManager.getNodeById(mANodeId);
|
||||
|
||||
double r = ((ValueAnimatedNode) rNode).getValue();
|
||||
double g = ((ValueAnimatedNode) gNode).getValue();
|
||||
double b = ((ValueAnimatedNode) bNode).getValue();
|
||||
double a = ((ValueAnimatedNode) aNode).getValue();
|
||||
|
||||
mColor = ColorUtil.normalize(r, g, b, a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String prettyPrint() {
|
||||
return "ColorAnimatedNode["
|
||||
+ mTag
|
||||
+ "]: r: "
|
||||
+ mRNodeId
|
||||
+ " g: "
|
||||
+ mGNodeId
|
||||
+ " b: "
|
||||
+ mBNodeId
|
||||
+ " a: "
|
||||
+ mANodeId;
|
||||
}
|
||||
}
|
|
@ -129,6 +129,8 @@ import java.util.Queue;
|
|||
node = new StyleAnimatedNode(config, this);
|
||||
} else if ("value".equals(type)) {
|
||||
node = new ValueAnimatedNode(config);
|
||||
} else if ("color".equals(type)) {
|
||||
node = new ColorAnimatedNode(config, this);
|
||||
} else if ("props".equals(type)) {
|
||||
node = new PropsAnimatedNode(config, this);
|
||||
} else if ("interpolation".equals(type)) {
|
||||
|
|
|
@ -105,6 +105,8 @@ import java.util.Map;
|
|||
} else {
|
||||
mPropMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
|
||||
}
|
||||
} else if (node instanceof ColorAnimatedNode) {
|
||||
mPropMap.putInt(entry.getKey(), ((ColorAnimatedNode) node).getColor());
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported type of node used in property node " + node.getClass());
|
||||
|
|
|
@ -43,6 +43,8 @@ import java.util.Map;
|
|||
((TransformAnimatedNode) node).collectViewUpdates(propsMap);
|
||||
} else if (node instanceof ValueAnimatedNode) {
|
||||
propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
|
||||
} else if (node instanceof ColorAnimatedNode) {
|
||||
propsMap.putInt(entry.getKey(), ((ColorAnimatedNode) node).getColor());
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported type of node used in property node " + node.getClass());
|
||||
|
|
|
@ -64,9 +64,6 @@ public class ReactFeatureFlags {
|
|||
/** This feature flag enables logs for Fabric */
|
||||
public static boolean enableFabricLogs = false;
|
||||
|
||||
/** Enables Static ViewConfig in RN Android native code. */
|
||||
public static boolean enableExperimentalStaticViewConfigs = false;
|
||||
|
||||
public static boolean enableRuntimeScheduler = false;
|
||||
|
||||
public static boolean enableRuntimeSchedulerInTurboModule = false;
|
||||
|
|
|
@ -405,7 +405,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
|||
|
||||
ViewManagerPropertyUpdater.clear();
|
||||
|
||||
// When using ReactFeatureFlags.enableExperimentalStaticViewConfigs enabled, FabriUIManager is
|
||||
// When using StaticViewConfigs is enabled, FabriUIManager is
|
||||
// responsible for initializing and deallocating EventDispatcher.
|
||||
// TODO T83943316: Remove this IF once StaticViewConfigs are enabled by default
|
||||
if (mShouldDeallocateEventDispatcher) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.content.Context;
|
|||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.view.WindowManager;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
@ -184,12 +185,23 @@ public class StatusBarModule extends NativeStatusBarManagerAndroidSpec {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public void run() {
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@TargetApi(Build.VERSION_CODES.R)
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
WindowInsetsController insetsController = activity.getWindow().getInsetsController();
|
||||
if ("dark-content".equals(style)) {
|
||||
// dark-content means dark icons on a light status bar
|
||||
insetsController.setSystemBarsAppearance(
|
||||
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
|
||||
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
|
||||
} else {
|
||||
insetsController.setSystemBarsAppearance(
|
||||
0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
View decorView = activity.getWindow().getDecorView();
|
||||
int systemUiVisibilityFlags = decorView.getSystemUiVisibility();
|
||||
if ("dark-content".equals(style)) {
|
||||
|
@ -199,7 +211,7 @@ public class StatusBarModule extends NativeStatusBarManagerAndroidSpec {
|
|||
}
|
||||
decorView.setSystemUiVisibility(systemUiVisibilityFlags);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import com.facebook.react.bridge.UiThreadUtil;
|
|||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
|
@ -288,16 +287,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule
|
|||
@Deprecated
|
||||
@Override
|
||||
public void preInitializeViewManagers(List<String> viewManagerNames) {
|
||||
if (ReactFeatureFlags.enableExperimentalStaticViewConfigs) {
|
||||
for (String viewManagerName : viewManagerNames) {
|
||||
mUIImplementation.resolveViewManager(viewManagerName);
|
||||
}
|
||||
// When Static view configs are enabled it is not necessary to pre-compute the constants for
|
||||
// viewManagers, although the pre-initialization of viewManager objects is still necessary
|
||||
// for performance reasons.
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, WritableMap> constantsMap = new ArrayMap<>();
|
||||
for (String viewManagerName : viewManagerNames) {
|
||||
WritableMap constants = computeConstantsForViewManager(viewManagerName);
|
||||
|
|
|
@ -39,6 +39,7 @@ public class ColorUtil {
|
|||
/**
|
||||
* Gets the opacity from a color. Inspired by Android ColorDrawable.
|
||||
*
|
||||
* @param color color to get opacity from
|
||||
* @return opacity expressed by one of PixelFormat constants
|
||||
*/
|
||||
public static int getOpacityFromColor(int color) {
|
||||
|
@ -51,4 +52,22 @@ public class ColorUtil {
|
|||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts individual {r, g, b, a} channel values to a single integer representation of the color
|
||||
* as 0xAARRGGBB.
|
||||
*
|
||||
* @param r red channel value, [0, 255]
|
||||
* @param g green channel value, [0, 255]
|
||||
* @param b blue channel value, [0, 255]
|
||||
* @param a alpha channel value, [0, 1]
|
||||
* @return integer representation of the color as 0xAARRGGBB
|
||||
*/
|
||||
public static int normalize(double r, double g, double b, double a) {
|
||||
return (clamp255(a * 255) << 24) | (clamp255(r) << 16) | (clamp255(g) << 8) | clamp255(b);
|
||||
}
|
||||
|
||||
private static int clamp255(double value) {
|
||||
return Math.max(0, Math.min(255, (int) Math.round(value)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,12 @@ load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "r
|
|||
|
||||
rn_robolectric_test(
|
||||
name = "views",
|
||||
# TODO Disabled temporarily until Yoga linking is fixed t14964130
|
||||
# TODO (T110934492): Disabled temporarily until tests are fixed
|
||||
# srcs = glob(['**/*.java']),
|
||||
srcs = glob(["image/*.java"]),
|
||||
srcs = glob([
|
||||
"image/*.java",
|
||||
"view/*.java",
|
||||
]),
|
||||
contacts = ["oncall+fbandroid_sheriff@xmail.facebook.com"],
|
||||
deps = [
|
||||
YOGA_TARGET,
|
||||
|
|
|
@ -44,4 +44,13 @@ public class ColorUtilTest {
|
|||
assertEquals(PixelFormat.OPAQUE, ColorUtil.getOpacityFromColor(0xFF123456));
|
||||
assertEquals(PixelFormat.OPAQUE, ColorUtil.getOpacityFromColor(0xFFFFFFFF));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalize() {
|
||||
assertEquals(0x800B1621, ColorUtil.normalize(11, 22, 33, 0.5));
|
||||
assertEquals(0x00000000, ColorUtil.normalize(0, 0, 0, 0));
|
||||
assertEquals(0xFFFFFFFF, ColorUtil.normalize(255, 255, 255, 1));
|
||||
assertEquals(0xFF00FFFF, ColorUtil.normalize(-1, 256, 255, 1.1));
|
||||
assertEquals(0x000001FF, ColorUtil.normalize(0.4, 0.5, 255.4, -1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ class MultipleCommandsPendingException : public std::runtime_error {
|
|||
": a step or resume is already pending") {}
|
||||
};
|
||||
|
||||
class UserCallbackException : public std::runtime_error {
|
||||
public:
|
||||
UserCallbackException(const std::exception &e)
|
||||
: std::runtime_error(std::string("callback exception: ") + e.what()) {}
|
||||
};
|
||||
|
||||
} // namespace inspector
|
||||
} // namespace hermes
|
||||
} // namespace facebook
|
||||
|
|
|
@ -589,8 +589,11 @@ void Inspector::executeIfEnabledOnExecutor(
|
|||
|
||||
state_->pushPendingFunc(
|
||||
[wrappedFunc = std::move(wrappedFunc), promise]() mutable {
|
||||
wrappedFunc();
|
||||
promise->setValue();
|
||||
if (auto userCallbackException = runUserCallback(wrappedFunc)) {
|
||||
promise->setException(*userCallbackException);
|
||||
} else {
|
||||
promise->setValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include <folly/Executor.h>
|
||||
#include <folly/Optional.h>
|
||||
#include <folly/Unit.h>
|
||||
#include <folly/futures/Future.h>
|
||||
#include <hermes/DebuggerAPI.h>
|
||||
#include <hermes/hermes.h>
|
||||
#include <hermes/inspector/AsyncPauseState.h>
|
||||
#include <hermes/inspector/Exceptions.h>
|
||||
#include <hermes/inspector/RuntimeAdapter.h>
|
||||
|
||||
namespace facebook {
|
||||
|
@ -363,6 +365,18 @@ class Inspector : public facebook::hermes::debugger::EventObserver,
|
|||
std::unique_ptr<folly::Executor> executor_;
|
||||
};
|
||||
|
||||
/// Helper function that guards user code execution in a try-catch block.
|
||||
template <typename C, typename... A>
|
||||
folly::Optional<UserCallbackException> runUserCallback(C &cb, A &&...arg) {
|
||||
try {
|
||||
cb(std::forward<A>(arg)...);
|
||||
} catch (const std::exception &e) {
|
||||
return UserCallbackException(e);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace inspector
|
||||
} // namespace hermes
|
||||
} // namespace facebook
|
||||
|
|
|
@ -249,10 +249,14 @@ std::pair<NextStatePtr, CommandPtr> InspectorState::Running::didPause(
|
|||
} else if (reason == debugger::PauseReason::EvalComplete) {
|
||||
assert(pendingEvalPromise_);
|
||||
|
||||
pendingEvalResultTransformer_(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
pendingEvalPromise_->setValue(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
if (auto userCallbackException = runUserCallback(
|
||||
pendingEvalResultTransformer_,
|
||||
inspector_.debugger_.getProgramState().getEvalResult())) {
|
||||
pendingEvalPromise_->setException(*userCallbackException);
|
||||
} else {
|
||||
pendingEvalPromise_->setValue(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
}
|
||||
pendingEvalPromise_.reset();
|
||||
} else if (
|
||||
reason == debugger::PauseReason::Breakpoint &&
|
||||
|
@ -364,10 +368,14 @@ std::pair<NextStatePtr, CommandPtr> InspectorState::Paused::didPause(
|
|||
break;
|
||||
case debugger::PauseReason::EvalComplete: {
|
||||
assert(pendingEvalPromise_);
|
||||
pendingEvalResultTransformer_(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
pendingEvalPromise_->setValue(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
if (auto userCallbackException = runUserCallback(
|
||||
pendingEvalResultTransformer_,
|
||||
inspector_.debugger_.getProgramState().getEvalResult())) {
|
||||
pendingEvalPromise_->setException(*userCallbackException);
|
||||
} else {
|
||||
pendingEvalPromise_->setValue(
|
||||
inspector_.debugger_.getProgramState().getEvalResult());
|
||||
}
|
||||
pendingEvalPromise_.reset();
|
||||
} break;
|
||||
case debugger::PauseReason::ScriptLoaded:
|
||||
|
|
|
@ -72,28 +72,8 @@ void RuntimeScheduler::executeNowOnTheSameThread(
|
|||
runtimeExecutor_,
|
||||
[this, callback = std::move(callback)](jsi::Runtime &runtime) {
|
||||
shouldYield_ = false;
|
||||
auto task = jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
jsi::PropNameID::forUtf8(runtime, ""),
|
||||
3,
|
||||
[callback = std::move(callback)](
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &,
|
||||
jsi::Value const *arguments,
|
||||
size_t) -> jsi::Value {
|
||||
callback(runtime);
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
|
||||
// We are about to trigger work loop. Setting `isCallbackScheduled_` to
|
||||
// true prevents unnecessary call to `runtimeExecutor`.
|
||||
isWorkLoopScheduled_ = true;
|
||||
this->scheduleTask(
|
||||
SchedulerPriority::ImmediatePriority, std::move(task));
|
||||
isWorkLoopScheduled_ = false;
|
||||
|
||||
isSynchronous_ = true;
|
||||
startWorkLoop(runtime);
|
||||
callback(runtime);
|
||||
isSynchronous_ = false;
|
||||
});
|
||||
|
||||
|
@ -103,6 +83,37 @@ void RuntimeScheduler::executeNowOnTheSameThread(
|
|||
scheduleWorkLoopIfNecessary();
|
||||
}
|
||||
|
||||
void RuntimeScheduler::callImmediates(jsi::Runtime &runtime) {
|
||||
auto previousPriority = currentPriority_;
|
||||
try {
|
||||
while (!taskQueue_.empty()) {
|
||||
auto topPriorityTask = taskQueue_.top();
|
||||
auto now = now_();
|
||||
auto didUserCallbackTimeout = topPriorityTask->expirationTime <= now;
|
||||
|
||||
if (!didUserCallbackTimeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPriority_ = topPriorityTask->priority;
|
||||
auto result = topPriorityTask->execute(runtime);
|
||||
|
||||
if (result.isObject() && result.getObject(runtime).isFunction(runtime)) {
|
||||
topPriorityTask->callback =
|
||||
result.getObject(runtime).getFunction(runtime);
|
||||
} else {
|
||||
if (taskQueue_.top() == topPriorityTask) {
|
||||
taskQueue_.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (jsi::JSError &error) {
|
||||
handleFatalError(runtime, error);
|
||||
}
|
||||
|
||||
currentPriority_ = previousPriority;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
void RuntimeScheduler::scheduleWorkLoopIfNecessary() const {
|
||||
|
@ -124,17 +135,11 @@ void RuntimeScheduler::startWorkLoop(jsi::Runtime &runtime) const {
|
|||
auto now = now_();
|
||||
auto didUserCallbackTimeout = topPriorityTask->expirationTime <= now;
|
||||
|
||||
// This task hasn't expired and we need to yield.
|
||||
auto shouldBreakBecauseYield = !didUserCallbackTimeout && shouldYield_;
|
||||
|
||||
// This task hasn't expired but we are in synchronous mode and need to
|
||||
// only execute the necessary minimum.
|
||||
auto shouldBreakBecauseSynchronous =
|
||||
!didUserCallbackTimeout && isSynchronous_;
|
||||
|
||||
if (shouldBreakBecauseYield || shouldBreakBecauseSynchronous) {
|
||||
if (!didUserCallbackTimeout && getShouldYield()) {
|
||||
// This currentTask hasn't expired, and we need to yield.
|
||||
break;
|
||||
}
|
||||
|
||||
currentPriority_ = topPriorityTask->priority;
|
||||
auto result = topPriorityTask->execute(runtime);
|
||||
|
||||
|
|
|
@ -96,6 +96,17 @@ class RuntimeScheduler final {
|
|||
*/
|
||||
RuntimeSchedulerTimePoint now() const noexcept;
|
||||
|
||||
/*
|
||||
* Immediate is a task that is expired and should have been already executed
|
||||
* or has priority set to Immediate. Designed to be called in the event
|
||||
* pipeline after an event is dispatched to React. React may schedule events
|
||||
* with immediate priority which need to be handled before the next event is
|
||||
* sent to React.
|
||||
*
|
||||
* Thread synchronization must be enforced externally.
|
||||
*/
|
||||
void callImmediates(jsi::Runtime &runtime);
|
||||
|
||||
private:
|
||||
mutable std::priority_queue<
|
||||
std::shared_ptr<Task>,
|
||||
|
|
|
@ -517,7 +517,7 @@ TEST_F(RuntimeSchedulerTest, sameThreadTaskCreatesImmediatePriorityTask) {
|
|||
std::thread t1([this, &didRunSynchronousTask, &didRunSubsequentTask]() {
|
||||
runtimeScheduler_->executeNowOnTheSameThread(
|
||||
[this, &didRunSynchronousTask, &didRunSubsequentTask](
|
||||
jsi::Runtime &rt) {
|
||||
jsi::Runtime &runtime) {
|
||||
didRunSynchronousTask = true;
|
||||
|
||||
auto callback = createHostFunctionFromLambda(
|
||||
|
@ -529,6 +529,8 @@ TEST_F(RuntimeSchedulerTest, sameThreadTaskCreatesImmediatePriorityTask) {
|
|||
|
||||
runtimeScheduler_->scheduleTask(
|
||||
SchedulerPriority::ImmediatePriority, std::move(callback));
|
||||
|
||||
runtimeScheduler_->callImmediates(runtime);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -553,7 +555,7 @@ TEST_F(RuntimeSchedulerTest, sameThreadTaskCreatesLowPriorityTask) {
|
|||
std::thread t1([this, &didRunSynchronousTask, &didRunSubsequentTask]() {
|
||||
runtimeScheduler_->executeNowOnTheSameThread(
|
||||
[this, &didRunSynchronousTask, &didRunSubsequentTask](
|
||||
jsi::Runtime &rt) {
|
||||
jsi::Runtime &runtime) {
|
||||
didRunSynchronousTask = true;
|
||||
|
||||
auto callback = createHostFunctionFromLambda(
|
||||
|
@ -565,6 +567,9 @@ TEST_F(RuntimeSchedulerTest, sameThreadTaskCreatesLowPriorityTask) {
|
|||
|
||||
runtimeScheduler_->scheduleTask(
|
||||
SchedulerPriority::LowPriority, std::move(callback));
|
||||
runtimeScheduler_->callImmediates(runtime);
|
||||
|
||||
EXPECT_FALSE(didRunSubsequentTask);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <react/renderer/debug/SystraceSection.h>
|
||||
#include <react/renderer/mounting/MountingOverrideDelegate.h>
|
||||
#include <react/renderer/mounting/ShadowViewMutation.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#include <react/renderer/templateprocessor/UITemplateProcessor.h>
|
||||
#include <react/renderer/uimanager/UIManager.h>
|
||||
#include <react/renderer/uimanager/UIManagerBinding.h>
|
||||
|
@ -49,7 +49,23 @@ Scheduler::Scheduler(
|
|||
auto eventOwnerBox = std::make_shared<EventBeat::OwnerBox>();
|
||||
eventOwnerBox->owner = eventDispatcher_;
|
||||
|
||||
auto eventPipe = [uiManager](
|
||||
#ifdef ANDROID
|
||||
auto enableCallImmediates = reactNativeConfig_->getBool(
|
||||
"react_native_new_architecture:enable_call_immediates_android");
|
||||
#else
|
||||
auto enableCallImmediates = reactNativeConfig_->getBool(
|
||||
"react_native_new_architecture:enable_call_immediates_ios");
|
||||
#endif
|
||||
|
||||
auto weakRuntimeScheduler =
|
||||
contextContainer_->find<std::weak_ptr<RuntimeScheduler>>(
|
||||
"RuntimeScheduler");
|
||||
auto runtimeScheduler =
|
||||
(enableCallImmediates && weakRuntimeScheduler.hasValue())
|
||||
? weakRuntimeScheduler.value().lock()
|
||||
: nullptr;
|
||||
|
||||
auto eventPipe = [uiManager, runtimeScheduler = runtimeScheduler.get()](
|
||||
jsi::Runtime &runtime,
|
||||
const EventTarget *eventTarget,
|
||||
const std::string &type,
|
||||
|
@ -61,6 +77,9 @@ Scheduler::Scheduler(
|
|||
runtime, eventTarget, type, priority, payloadFactory);
|
||||
},
|
||||
runtime);
|
||||
if (runtimeScheduler) {
|
||||
runtimeScheduler->callImmediates(runtime);
|
||||
}
|
||||
};
|
||||
|
||||
auto statePipe = [uiManager](StateUpdate const &stateUpdate) {
|
||||
|
|
|
@ -130,9 +130,8 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL
|
|||
`.trim();
|
||||
};
|
||||
|
||||
// If static view configs are enabled, get whether the native component exists
|
||||
// in the app binary using hasViewManagerConfig() instead of getViewManagerConfig().
|
||||
// Old getViewManagerConfig() checks for the existance of the native Paper view manager.
|
||||
// Check whether the native component exists in the app binary.
|
||||
// Old getViewManagerConfig() checks for the existance of the native Paper view manager. Not available in Bridgeless.
|
||||
// New hasViewManagerConfig() queries Fabric’s native component registry directly.
|
||||
const DeprecatedComponentNameCheckTemplate = ({
|
||||
componentName,
|
||||
|
@ -142,8 +141,7 @@ const DeprecatedComponentNameCheckTemplate = ({
|
|||
paperComponentNameDeprecated: string,
|
||||
}) =>
|
||||
`
|
||||
const staticViewConfigsEnabled = global.__fbStaticViewConfig === true;
|
||||
if (staticViewConfigsEnabled) {
|
||||
if (global.__nativeComponentRegistry__hasComponent) {
|
||||
if (UIManager.hasViewManagerConfig('${componentName}')) {
|
||||
nativeComponentName = '${componentName}';
|
||||
} else if (UIManager.hasViewManagerConfig('${paperComponentNameDeprecated}')) {
|
||||
|
|
|
@ -1046,8 +1046,7 @@ const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/
|
|||
const {UIManager} = require(\\"react-native\\")
|
||||
|
||||
let nativeComponentName = 'NativeComponentName';
|
||||
const staticViewConfigsEnabled = global.__fbStaticViewConfig === true;
|
||||
if (staticViewConfigsEnabled) {
|
||||
if (global.__nativeComponentRegistry__hasComponent) {
|
||||
if (UIManager.hasViewManagerConfig('NativeComponentName')) {
|
||||
nativeComponentName = 'NativeComponentName';
|
||||
} else if (UIManager.hasViewManagerConfig('DeprecatedNativeComponentName')) {
|
||||
|
|
|
@ -23,7 +23,7 @@ const {
|
|||
|
||||
const colors = ['#ff0000', '#00ff00', '#0000ff', 'rgba(0, 0, 0, 0.4)'];
|
||||
|
||||
const barStyles = ['default', 'light-content'];
|
||||
const barStyles = ['default', 'light-content', 'dark-content'];
|
||||
|
||||
const showHideTransitions = ['fade', 'slide'];
|
||||
|
||||
|
@ -129,11 +129,16 @@ class StatusBarStyleExample extends React.Component<{...}, $FlowFixMeState> {
|
|||
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<View style={styles.wrapper}>
|
||||
<Text>(default is dark for iOS, light for Android)</Text>
|
||||
</View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this._onChangeAnimated}>
|
||||
<View style={styles.button}>
|
||||
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
|
||||
<Text>
|
||||
animated (ios only): {this.state.animated ? 'true' : 'false'}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
|
@ -288,6 +293,9 @@ class StatusBarStaticIOSExample extends React.Component<{...}> {
|
|||
<Text>setBarStyle('default', true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<View style={styles.wrapper}>
|
||||
<Text>(default is dark for iOS, light for Android)</Text>
|
||||
</View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
|
@ -342,6 +350,36 @@ class StatusBarStaticAndroidExample extends React.Component<{...}> {
|
|||
<Text>setHidden(false)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBarStyle('light-content');
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBarStyle('light-content')</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBarStyle('dark-content');
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBarStyle('dark-content')</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
StatusBar.setBarStyle('default');
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>setBarStyle('default')</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<View style={styles.wrapper}>
|
||||
<Text>(default is dark for iOS, light for Android)</Text>
|
||||
</View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
|
@ -448,7 +486,6 @@ exports.examples = [
|
|||
render(): React.Node {
|
||||
return <StatusBarStyleExample />;
|
||||
},
|
||||
platform: 'ios',
|
||||
},
|
||||
{
|
||||
title: 'StatusBar network activity indicator',
|
||||
|
|
Загрузка…
Ссылка в новой задаче