Re-introduce {eventName}: true ViewConfig ValidAttributes in Static ViewConfigs

Summary:
# Problem
I removed the {eventName}: true entries from ViewConfigs validAttributes in D33303950 (ca5aaa7663). These entries were iOS-only. I removed them to achieve platform-consistency in native ViewConfigs.

This change broke the onLayout event for all React Native components. So, I reverted D33303950 (ca5aaa7663) for native ViewConfigs server-side. But I never got around to reverting D33303950 (ca5aaa7663) for static ViewConfigs.

# Changes
This diff reverts D33303950 (ca5aaa7663) for Static ViewConfigs, with server-side gating.

Now, these {eventName}: true ViewConfig validAttribute will be inserted into all view configs (static and native) **by default**.

Calling RCTDisableViewConfigEventValidAttributes(YES) on iOS will remove {eventName}: true ViewConfig ValidAttributes entries from Static ViewConfigs. (Previously, this method only removed the entries from native ViewConfigs).

https://www.internalfb.com/code/fbsource/[6615b0675bdf]/fbobjc/Apps/Wilde/FBReactModule2/FBReactModuleAPI/FBReactModuleAPI/Exported/FBReactModule.mm?lines=344

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D33933403

fbshipit-source-id: 17823ed99f97d7851f04e5cdab9c95667df13253
This commit is contained in:
Ramanpreet Nara 2022-02-08 19:09:19 -08:00 коммит произвёл Facebook GitHub Bot
Родитель f89ed90a1e
Коммит 971ba5c26b
9 изменённых файлов: 155 добавлений и 4 удалений

Просмотреть файл

@ -11,6 +11,7 @@
import type {ScrollViewNativeProps as Props} from './ScrollViewNativeComponentType';
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';
import {ConditionallyIgnoredEventHandlers} from '../../NativeComponent/ViewConfigIgnore';
import Platform from '../../Utilities/Platform';
const RCTScrollViewViewConfig =
@ -138,6 +139,14 @@ const RCTScrollViewViewConfig =
snapToOffsets: true,
snapToStart: true,
zoomScale: true,
...ConditionallyIgnoredEventHandlers({
onScrollBeginDrag: true,
onMomentumScrollEnd: true,
onScrollEndDrag: true,
onMomentumScrollBegin: true,
onScrollToTop: true,
onScroll: true,
}),
},
};

Просмотреть файл

@ -9,6 +9,7 @@
*/
import type {PartialViewConfig} from '../../Renderer/shims/ReactNativeTypes';
import {ConditionallyIgnoredEventHandlers} from '../../NativeComponent/ViewConfigIgnore';
type PartialViewConfigWithoutName = $Rest<
PartialViewConfig,
@ -147,6 +148,15 @@ const RCTTextInputViewConfig = {
clearTextOnFocus: true,
showSoftInputOnFocus: true,
autoFocus: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
onSelectionChange: true,
onContentSizeChange: true,
onScroll: true,
onChangeSync: true,
onKeyPressSync: true,
onTextInput: true,
}),
},
};

Просмотреть файл

@ -12,6 +12,7 @@ import type {ResolvedAssetSource} from './AssetSourceResolver';
import type {ImageProps} from './ImageProps';
import type {ViewProps} from '../Components/View/ViewPropTypes';
import * as NativeComponentRegistry from '../NativeComponent/NativeComponentRegistry';
import {ConditionallyIgnoredEventHandlers} from '../NativeComponent/ViewConfigIgnore';
import type {HostComponent} from '../Renderer/shims/ReactNativeTypes';
import type {
ColorValue,
@ -125,6 +126,14 @@ const ImageViewViewConfig =
tintColor: {
process: require('../StyleSheet/processColor'),
},
...ConditionallyIgnoredEventHandlers({
onLoadStart: true,
onLoad: true,
onLoadEnd: true,
onProgress: true,
onError: true,
onPartialLoad: true,
}),
},
};

Просмотреть файл

@ -11,7 +11,10 @@
import {Platform} from 'react-native';
import type {PartialViewConfig} from '../Renderer/shims/ReactNativeTypes';
import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes';
import {DynamicallyInjectedByGestureHandler} from './ViewConfigIgnore';
import {
DynamicallyInjectedByGestureHandler,
ConditionallyIgnoredEventHandlers,
} from './ViewConfigIgnore';
type PartialViewConfigWithoutName = $Rest<
PartialViewConfig,
@ -446,6 +449,14 @@ const PlatformBaseViewConfig: PartialViewConfigWithoutName =
direction: true,
style: ReactNativeStyleAttributes,
...ConditionallyIgnoredEventHandlers({
onLayout: true,
onMagicTap: true,
onAccessibilityAction: true,
onAccessibilityEscape: true,
onAccessibilityTap: true,
}),
},
};

Просмотреть файл

@ -8,6 +8,8 @@
* @format
*/
import Platform from '../Utilities/Platform';
const ignoredViewConfigProps = new WeakSet<{...}>();
/**
@ -19,6 +21,32 @@ export function DynamicallyInjectedByGestureHandler<T: {...}>(object: T): T {
return object;
}
/**
* On iOS, ViewManager events declarations generate {eventName}: true entries
* in ViewConfig valueAttributes. In our Static ViewConfig infra, we generate
* these {eventName}: true entries during runtime by inspecting a ViewConfig's
* bubblingEventTypes, and directEventTypes.
*
* However, not all event declarations generate these {eventName}: true entries.
* So, the ViewConfig infra generates extra {eventName}: true entries for some
* events. These extra entries are harmless. So, the logic below makes the ViewConfig
* Validator ignore all extra {eventName}: true entries in static ViewConfig
* validAttributes.
*
* TODO(T110872225): Remove this logic
*/
export function ConditionallyIgnoredEventHandlers<T: {[name: string]: true}>(
value: T,
): T | void {
if (
Platform.OS === 'ios' &&
!(global.RN$ViewConfigEventValidAttributesDisabled === true)
) {
return value;
}
return undefined;
}
export function isIgnored(value: mixed): boolean {
if (typeof value === 'object' && value != null) {
return ignoredViewConfigProps.has(value);

Просмотреть файл

@ -24,6 +24,10 @@ interface NativeCommands {
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {
ConditionallyIgnoredEventHandlers
} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
const {
dispatchCommand
} = require(\\"react-native/Libraries/Renderer/shims/ReactNative\\");
@ -45,7 +49,11 @@ export const __INTERNAL_VIEW_CONFIG = {
}
},
validAttributes: {
boolean_default_true_optional_both: true
boolean_default_true_optional_both: true,
...ConditionallyIgnoredEventHandlers({
onDirectEventDefinedInlineNull: true,
onBubblingEventDefinedInlineNull: true
})
}
};
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
@ -85,6 +93,10 @@ interface NativeCommands {
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {
ConditionallyIgnoredEventHandlers
} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
const {
dispatchCommand
} = require(\\"react-native/Libraries/Renderer/shims/ReactNative\\");
@ -106,7 +118,11 @@ export const __INTERNAL_VIEW_CONFIG = {
}
},
validAttributes: {
boolean_default_true_optional_both: true
boolean_default_true_optional_both: true,
...ConditionallyIgnoredEventHandlers({
onDirectEventDefinedInlineNull: true,
onBubblingEventDefinedInlineNull: true
})
}
};
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);

Просмотреть файл

@ -200,6 +200,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'EventNestedObjectPropsNativeComponentView';
@ -218,6 +219,10 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
disabled: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
}),
},
};
@ -243,6 +248,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'EventPropsNativeComponentView';
@ -289,6 +295,15 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
disabled: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
onEventDirect: true,
onEventDirectWithPaperName: true,
onOrientationChange: true,
onEnd: true,
onEventBubblingWithPaperName: true,
}),
},
};
@ -426,6 +441,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'RCTInterfaceOnlyComponent';
@ -444,6 +460,10 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
title: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
}),
},
};

Просмотреть файл

@ -171,6 +171,23 @@ function normalizeInputEventName(name) {
return name;
}
// Replicates the behavior of viewConfig in RCTComponentData.m
function getValidAttributesForEvents(events, imports) {
imports.add(
"const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');",
);
const validAttributes = j.objectExpression(
events.map(eventType => {
return j.property('init', j.identifier(eventType.name), j.literal(true));
}),
);
return j.callExpression(j.identifier('ConditionallyIgnoredEventHandlers'), [
validAttributes,
]);
}
function generateBubblingEventInfo(event, nameOveride) {
return j.property(
'init',
@ -243,6 +260,13 @@ function buildViewConfig(
getReactDiffProcessValue(schemaProp.typeAnnotation),
);
}),
...(componentEvents.length > 0
? [
j.spreadProperty(
getValidAttributesForEvents(componentEvents, imports),
),
]
: []),
]);
const bubblingEventNames = component.events

Просмотреть файл

@ -295,6 +295,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'EventsNestedObjectNativeComponent';
@ -313,6 +314,10 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
disabled: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
}),
},
};
@ -338,6 +343,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'EventsNativeComponent';
@ -373,6 +379,13 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
disabled: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
onEventDirect: true,
onOrientationChange: true,
onEnd: true,
}),
},
};
@ -398,6 +411,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'RCTInterfaceOnlyComponent';
@ -420,7 +434,12 @@ export const __INTERNAL_VIEW_CONFIG = {
},
},
validAttributes: {},
validAttributes: {
...ConditionallyIgnoredEventHandlers({
onChange: true,
onDire tChange: true,
}),
},
};
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
@ -688,6 +707,7 @@ Map {
'use strict';
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');
let nativeComponentName = 'RCTInterfaceOnlyComponent';
@ -706,6 +726,10 @@ export const __INTERNAL_VIEW_CONFIG = {
validAttributes: {
accessibilityHint: true,
...ConditionallyIgnoredEventHandlers({
onChange: true,
}),
},
};