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:
Родитель
f89ed90a1e
Коммит
971ba5c26b
|
@ -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,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче