From 8f3e1884265b32caa5d8530cba7a4338ae567eb7 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 10 Dec 2021 23:18:19 -0800 Subject: [PATCH] Fix Static View Config for RCTView Summary: - Fix the StaticViewConfig violations for RCTView Changelog: [Internal] Reviewed By: yungsters Differential Revision: D32187835 fbshipit-source-id: c8c926817a9245b1e8671e5a2e8965ab7ffecace --- .../View/ReactNativeViewViewConfig.js | 148 +++++++++++------- .../View/ReactNativeViewViewConfigAndroid.js | 83 ---------- .../Components/View/ViewNativeComponent.js | 10 +- .../StaticViewConfigValidator.js | 6 +- Libraries/NativeComponent/ViewConfigIgnore.js | 27 ++++ 5 files changed, 125 insertions(+), 149 deletions(-) delete mode 100644 Libraries/Components/View/ReactNativeViewViewConfigAndroid.js create mode 100644 Libraries/NativeComponent/ViewConfigIgnore.js diff --git a/Libraries/Components/View/ReactNativeViewViewConfig.js b/Libraries/Components/View/ReactNativeViewViewConfig.js index 6406b6ec7f..e50061ba73 100644 --- a/Libraries/Components/View/ReactNativeViewViewConfig.js +++ b/Libraries/Components/View/ReactNativeViewViewConfig.js @@ -9,17 +9,54 @@ */ import type {ViewConfig} from '../../Renderer/shims/ReactNativeTypes'; -import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid'; +import {DynamicallyInjectedByGestureHandler} from '../../NativeComponent/ViewConfigIgnore'; import {Platform} from 'react-native'; -const ReactNativeViewConfig: ViewConfig = { - uiViewClassName: 'RCTView', - baseModuleName: null, - Manager: 'ViewManager', - Commands: {}, - Constants: {}, +const ReactNativeViewViewConfigAndroid = { + bubblingEventTypes: {}, + directEventTypes: { + topAccessibilityAction: { + registrationName: 'onAccessibilityAction', + }, + topPointerEnter: { + registrationName: 'pointerenter', + }, + topPointerLeave: { + registrationName: 'pointerleave', + }, + topPointerMove: { + registrationName: 'pointermove', + }, + }, + validAttributes: { + elevation: true, + hasTVPreferredFocus: true, + focusable: true, + nativeBackgroundAndroid: true, + nativeForegroundAndroid: true, + nextFocusDown: true, + nextFocusForward: true, + nextFocusLeft: true, + nextFocusRight: true, + nextFocusUp: true, + renderToHardwareTextureAndroid: true, + translateX: true, + scaleX: true, + scaleY: true, + importantForAccessibility: true, + accessibilityLiveRegion: true, + rotation: true, + translateY: true, + transform: true, + hitSlop: true, + pointerenter: true, + pointerleave: true, + pointermove: true, + }, +}; + +const ReactNativeViewViewConfigIOS = { bubblingEventTypes: { - ...ReactNativeViewViewConfigAndroid.bubblingEventTypes, topBlur: { phasedRegistrationNames: { bubbled: 'onBlur', @@ -88,7 +125,6 @@ const ReactNativeViewConfig: ViewConfig = { }, }, directEventTypes: { - ...ReactNativeViewViewConfigAndroid.directEventTypes, topAccessibilityAction: { registrationName: 'onAccessibilityAction', }, @@ -104,36 +140,56 @@ const ReactNativeViewConfig: ViewConfig = { topMagicTap: { registrationName: 'onMagicTap', }, - 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, - accessibilityActions: true, accessibilityElementsHidden: true, - accessibilityHint: true, accessibilityIgnoresInvertColors: true, + accessibilityViewIsModal: true, + direction: true, + onAccessibilityAction: true, + onAccessibilityEscape: true, + onAccessibilityTap: true, + onMagicTap: true, + shadowOffset: {diff: require('../../Utilities/differ/sizesDiffer')}, + shadowOpacity: true, + shadowRadius: true, + shouldRasterizeIOS: true, + transform: {diff: require('../../Utilities/differ/matricesDiffer')}, + hitSlop: {diff: require('../../Utilities/differ/insetsDiffer')}, + }, +}; + +const PlatformSpecificViewConfig = + Platform.OS === 'android' + ? ReactNativeViewViewConfigAndroid + : ReactNativeViewViewConfigIOS; + +const ReactNativeViewConfig: ViewConfig = { + uiViewClassName: 'RCTView', + baseModuleName: null, + Manager: 'ViewManager', + Commands: {}, + Constants: {}, + bubblingEventTypes: PlatformSpecificViewConfig.bubblingEventTypes, + directEventTypes: { + ...PlatformSpecificViewConfig.directEventTypes, + // Events for react-native-gesture-handler (T45765076) + // Remove once this library can handle JS View Configs + onGestureHandlerEvent: DynamicallyInjectedByGestureHandler({ + registrationName: 'onGestureHandlerEvent', + }), + onGestureHandlerStateChange: DynamicallyInjectedByGestureHandler({ + registrationName: 'onGestureHandlerStateChange', + }), + }, + validAttributes: { + ...PlatformSpecificViewConfig.validAttributes, + accessibilityActions: true, + accessibilityHint: true, accessibilityLabel: true, - accessibilityLiveRegion: true, accessibilityRole: true, accessibilityState: true, accessibilityValue: true, - accessibilityViewIsModal: true, accessible: true, alignContent: true, alignItems: true, @@ -166,11 +222,8 @@ const ReactNativeViewConfig: ViewConfig = { borderTopWidth: true, borderWidth: true, bottom: true, - clickable: true, collapsable: true, - direction: true, display: true, - elevation: true, end: true, flex: true, flexBasis: true, @@ -179,8 +232,6 @@ const ReactNativeViewConfig: ViewConfig = { flexShrink: true, flexWrap: true, height: true, - hitSlop: {diff: require('../../Utilities/differ/insetsDiffer')}, - importantForAccessibility: true, justifyContent: true, left: true, margin: true, @@ -201,11 +252,7 @@ const ReactNativeViewConfig: ViewConfig = { onAccessibilityAction: true, onAccessibilityEscape: true, onAccessibilityTap: true, - pointerenter: true, - pointerleave: true, - pointermove: true, onLayout: true, - onMagicTap: true, opacity: true, overflow: true, padding: true, @@ -220,16 +267,8 @@ const ReactNativeViewConfig: ViewConfig = { 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, @@ -333,10 +372,9 @@ const ReactNativeViewConfig: ViewConfig = { textTransform: true, tintColor: {process: require('../../StyleSheet/processColor')}, top: true, - transform: - Platform.OS === 'ios' - ? {diff: require('../../Utilities/differ/matricesDiffer')} - : {process: require('../../StyleSheet/processTransform')}, + transform: { + process: require('../../StyleSheet/processTransform'), + }, transformMatrix: true, translateX: true, translateY: true, @@ -346,12 +384,6 @@ const ReactNativeViewConfig: ViewConfig = { }, testID: true, top: true, - transform: - Platform.OS === 'ios' - ? {diff: require('../../Utilities/differ/matricesDiffer')} - : {process: require('../../StyleSheet/processTransform')}, - translateX: true, - translateY: true, width: true, zIndex: true, }, diff --git a/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js b/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js deleted file mode 100644 index ad2542dfa2..0000000000 --- a/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +++ /dev/null @@ -1,83 +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. - * - * @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; diff --git a/Libraries/Components/View/ViewNativeComponent.js b/Libraries/Components/View/ViewNativeComponent.js index a38c2a0a3b..1ec0745f3f 100644 --- a/Libraries/Components/View/ViewNativeComponent.js +++ b/Libraries/Components/View/ViewNativeComponent.js @@ -10,18 +10,14 @@ 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 * as React from 'react'; const ViewNativeComponent: HostComponent = - NativeComponentRegistry.get('RCTView', () => - Platform.OS === 'android' - ? ReactNativeViewViewConfigAndroid - : {uiViewClassName: 'RCTView'}, - ); + NativeComponentRegistry.get('RCTView', () => ({ + uiViewClassName: 'RCTView', + })); interface NativeCommands { +hotspotUpdate: ( diff --git a/Libraries/NativeComponent/StaticViewConfigValidator.js b/Libraries/NativeComponent/StaticViewConfigValidator.js index 6aa70649a5..ddc229472d 100644 --- a/Libraries/NativeComponent/StaticViewConfigValidator.js +++ b/Libraries/NativeComponent/StaticViewConfigValidator.js @@ -9,6 +9,7 @@ */ import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes'; +import {isIgnored} from './ViewConfigIgnore'; type Difference = | { @@ -144,7 +145,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', diff --git a/Libraries/NativeComponent/ViewConfigIgnore.js b/Libraries/NativeComponent/ViewConfigIgnore.js new file mode 100644 index 0000000000..8df7c83a06 --- /dev/null +++ b/Libraries/NativeComponent/ViewConfigIgnore.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +const ignoredViewConfigProps = new WeakSet<{...}>(); + +/** + * Decorates ViewConfig values that are dynamically injected by the library, + * react-native-gesture-handler. (T45765076) + */ +export function DynamicallyInjectedByGestureHandler(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; +}