Cleanup and simplify view config generation

Reviewed By: fkgozali

Differential Revision: D4083308

fbshipit-source-id: 42ca797a8faede68bd031e84cf1c33a3e3ade37f
This commit is contained in:
Pieter De Baets 2016-10-27 06:54:26 -07:00 committed by Facebook Github Bot
parent af3f656d97
commit 19ab84ffb7
3 changed files with 76 additions and 88 deletions

View File

@ -11,19 +11,19 @@
*/ */
'use strict'; 'use strict';
var ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
var UIManager = require('UIManager'); const UIManager = require('UIManager');
var UnimplementedView = require('UnimplementedView'); const UnimplementedView = require('UnimplementedView');
var createReactNativeComponentClass = require('react/lib/createReactNativeComponentClass'); const createReactNativeComponentClass = require('react/lib/createReactNativeComponentClass');
var insetsDiffer = require('insetsDiffer'); const insetsDiffer = require('insetsDiffer');
var matricesDiffer = require('matricesDiffer'); const matricesDiffer = require('matricesDiffer');
var pointsDiffer = require('pointsDiffer'); const pointsDiffer = require('pointsDiffer');
var processColor = require('processColor'); const processColor = require('processColor');
var resolveAssetSource = require('resolveAssetSource'); const resolveAssetSource = require('resolveAssetSource');
var sizesDiffer = require('sizesDiffer'); const sizesDiffer = require('sizesDiffer');
var verifyPropTypes = require('verifyPropTypes'); const verifyPropTypes = require('verifyPropTypes');
var warning = require('fbjs/lib/warning'); const warning = require('fbjs/lib/warning');
/** /**
* Used to create React components that directly wrap native component * Used to create React components that directly wrap native component
@ -47,29 +47,34 @@ function requireNativeComponent(
componentInterface?: ?ComponentInterface, componentInterface?: ?ComponentInterface,
extraConfig?: ?{nativeOnly?: Object}, extraConfig?: ?{nativeOnly?: Object},
): Function { ): Function {
var viewConfig = UIManager[viewName]; const viewConfig = UIManager[viewName];
if (!viewConfig || !viewConfig.NativeProps) { if (!viewConfig || !viewConfig.NativeProps) {
warning(false, 'Native component for "%s" does not exist', viewName); warning(false, 'Native component for "%s" does not exist', viewName);
return UnimplementedView; return UnimplementedView;
} }
var nativeProps = {
...UIManager.RCTView.NativeProps,
...viewConfig.NativeProps,
};
viewConfig.uiViewClassName = viewName; viewConfig.uiViewClassName = viewName;
viewConfig.validAttributes = {}; viewConfig.validAttributes = {};
viewConfig.propTypes = componentInterface && componentInterface.propTypes; viewConfig.propTypes = componentInterface && componentInterface.propTypes;
for (var key in nativeProps) {
var useAttribute = false;
var attribute = {};
var differ = TypeToDifferMap[nativeProps[key]]; // The ViewConfig doesn't contain any props inherited from the view manager's
// superclass, so we manually merge in the RCTView ones. Other inheritance
// patterns are currenty not supported.
const nativeProps = {
...UIManager.RCTView.NativeProps,
...viewConfig.NativeProps,
};
for (const key in nativeProps) {
let useAttribute = false;
const attribute = {};
const differ = TypeToDifferMap[nativeProps[key]];
if (differ) { if (differ) {
attribute.diff = differ; attribute.diff = differ;
useAttribute = true; useAttribute = true;
} }
var processor = TypeToProcessorMap[nativeProps[key]]; const processor = TypeToProcessorMap[nativeProps[key]];
if (processor) { if (processor) {
attribute.process = processor; attribute.process = processor;
useAttribute = true; useAttribute = true;
@ -92,6 +97,7 @@ function requireNativeComponent(
extraConfig && extraConfig.nativeOnly extraConfig && extraConfig.nativeOnly
); );
} }
return createReactNativeComponentClass(viewConfig); return createReactNativeComponentClass(viewConfig);
} }

View File

@ -1472,22 +1472,19 @@ RCT_EXPORT_METHOD(clearJSResponder)
- (NSDictionary<NSString *, id> *)constantsToExport - (NSDictionary<NSString *, id> *)constantsToExport
{ {
NSMutableDictionary<NSString *, NSDictionary *> *allJSConstants = [NSMutableDictionary new]; NSMutableDictionary<NSString *, NSDictionary *> *constants = [NSMutableDictionary new];
NSMutableDictionary<NSString *, NSDictionary *> *directEvents = [NSMutableDictionary new]; NSMutableDictionary<NSString *, NSDictionary *> *directEvents = [NSMutableDictionary new];
NSMutableDictionary<NSString *, NSDictionary *> *bubblingEvents = [NSMutableDictionary new]; NSMutableDictionary<NSString *, NSDictionary *> *bubblingEvents = [NSMutableDictionary new];
[_componentDataByName enumerateKeysAndObjectsUsingBlock: [_componentDataByName enumerateKeysAndObjectsUsingBlock:^(NSString *name, RCTComponentData *componentData, __unused BOOL *stop) {
^(NSString *name, RCTComponentData *componentData, __unused BOOL *stop) { NSMutableDictionary<NSString *, id> *moduleConstants = [NSMutableDictionary new];
NSMutableDictionary<NSString *, id> *constantsNamespace =
[NSMutableDictionary dictionaryWithDictionary:allJSConstants[name]];
// Add manager class // Add manager class
constantsNamespace[@"Manager"] = RCTBridgeModuleNameForClass(componentData.managerClass); moduleConstants[@"Manager"] = RCTBridgeModuleNameForClass(componentData.managerClass);
// Add native props // Add native props
NSDictionary<NSString *, id> *viewConfig = [componentData viewConfig]; NSDictionary<NSString *, id> *viewConfig = [componentData viewConfig];
constantsNamespace[@"NativeProps"] = viewConfig[@"propTypes"]; moduleConstants[@"NativeProps"] = viewConfig[@"propTypes"];
// Add direct events // Add direct events
for (NSString *eventName in viewConfig[@"directEvents"]) { for (NSString *eventName in viewConfig[@"directEvents"]) {
@ -1519,19 +1516,19 @@ RCT_EXPORT_METHOD(clearJSResponder)
} }
} }
allJSConstants[name] = constantsNamespace; RCTAssert(!constants[name], @"UIManager already has constants for %@", componentData.name);
constants[name] = moduleConstants;
}]; }];
#if !TARGET_OS_TV #if !TARGET_OS_TV
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation]; _currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];
#endif #endif
[allJSConstants addEntriesFromDictionary:@{
@"customBubblingEventTypes": bubblingEvents,
@"customDirectEventTypes": directEvents,
@"Dimensions": RCTExportedDimensions(NO)
}];
return allJSConstants; constants[@"customBubblingEventTypes"] = bubblingEvents;
constants[@"customDirectEventTypes"] = directEvents;
constants[@"Dimensions"] = RCTExportedDimensions(NO);
return constants;
} }
static NSDictionary *RCTExportedDimensions(BOOL rotateBounds) static NSDictionary *RCTExportedDimensions(BOOL rotateBounds)

View File

@ -400,44 +400,31 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
NSMutableArray<NSString *> *directEvents = [NSMutableArray new]; NSMutableArray<NSString *> *directEvents = [NSMutableArray new];
if (RCTClassOverridesInstanceMethod(_managerClass, @selector(customDirectEventTypes))) { if (RCTClassOverridesInstanceMethod(_managerClass, @selector(customDirectEventTypes))) {
NSArray<NSString *> *events = [self.manager customDirectEventTypes]; NSArray<NSString *> *events = [self.manager customDirectEventTypes];
#pragma clang diagnostic pop
if (RCT_DEBUG) {
RCTAssert(!events || [events isKindOfClass:[NSArray class]],
@"customDirectEventTypes must return an array, but %@ returned %@",
_managerClass, [events class]);
}
for (NSString *event in events) { for (NSString *event in events) {
[directEvents addObject:RCTNormalizeInputEventName(event)]; [directEvents addObject:RCTNormalizeInputEventName(event)];
} }
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSMutableArray<NSString *> *bubblingEvents = [NSMutableArray new]; NSMutableArray<NSString *> *bubblingEvents = [NSMutableArray new];
if (RCTClassOverridesInstanceMethod(_managerClass, @selector(customBubblingEventTypes))) { if (RCTClassOverridesInstanceMethod(_managerClass, @selector(customBubblingEventTypes))) {
#pragma clang diagnostic pop
NSArray<NSString *> *events = [self.manager customBubblingEventTypes]; NSArray<NSString *> *events = [self.manager customBubblingEventTypes];
if (RCT_DEBUG) {
RCTAssert(!events || [events isKindOfClass:[NSArray class]],
@"customBubblingEventTypes must return an array, but %@ returned %@",
_managerClass, [events class]);
}
for (NSString *event in events) { for (NSString *event in events) {
[bubblingEvents addObject:RCTNormalizeInputEventName(event)]; [bubblingEvents addObject:RCTNormalizeInputEventName(event)];
} }
} }
#pragma clang diagnostic pop
unsigned int count = 0; unsigned int count = 0;
NSMutableDictionary *propTypes = [NSMutableDictionary new]; NSMutableDictionary *propTypes = [NSMutableDictionary new];
Method *methods = class_copyMethodList(object_getClass(_managerClass), &count); Method *methods = class_copyMethodList(object_getClass(_managerClass), &count);
for (unsigned int i = 0; i < count; i++) { for (unsigned int i = 0; i < count; i++) {
Method method = methods[i]; SEL selector = method_getName(methods[i]);
SEL selector = method_getName(method); const char *selectorName = sel_getName(selector);
NSString *methodName = NSStringFromSelector(selector); if (strncmp(selectorName, "propConfig_", strlen("propConfig_")) != 0) {
if ([methodName hasPrefix:@"propConfig"]) { continue;
NSRange nameRange = [methodName rangeOfString:@"_"]; }
if (nameRange.length) {
NSString *name = [methodName substringFromIndex:nameRange.location + 1]; NSString *name = @(selectorName + strlen("propConfig_"));
NSString *type = ((NSArray<NSString *> *(*)(id, SEL))objc_msgSend)(_managerClass, selector)[0]; NSString *type = ((NSArray<NSString *> *(*)(id, SEL))objc_msgSend)(_managerClass, selector)[0];
if (RCT_DEBUG && propTypes[name] && ![propTypes[name] isEqualToString:type]) { if (RCT_DEBUG && propTypes[name] && ![propTypes[name] isEqualToString:type]) {
RCTLogError(@"Property '%@' of component '%@' redefined from '%@' " RCTLogError(@"Property '%@' of component '%@' redefined from '%@' "
@ -454,11 +441,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
propTypes[name] = type; propTypes[name] = type;
} }
} }
}
}
free(methods); free(methods);
if (RCT_DEBUG) { #if RCT_DEBUG
for (NSString *event in directEvents) { for (NSString *event in directEvents) {
if ([bubblingEvents containsObject:event]) { if ([bubblingEvents containsObject:event]) {
RCTLogError(@"Component '%@' registered '%@' as both a bubbling event " RCTLogError(@"Component '%@' registered '%@' as both a bubbling event "
@ -471,12 +456,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
"and a direct event", _name, event); "and a direct event", _name, event);
} }
} }
} #endif
return @{ return @{
@"propTypes" : propTypes, @"propTypes": propTypes,
@"directEvents" : directEvents, @"directEvents": directEvents,
@"bubblingEvents" : bubblingEvents, @"bubblingEvents": bubblingEvents,
}; };
} }