2015-02-03 updates
- Add back providesModule transform to JSAppServer | Joseph Savona - [ReactKit] fix open source performance issue | John Harper - [ReactKit] improve ReactIOSEventEmitter logics | Andrew Rasmussen - [reactkit] fix web view JS executor and bind it to Command-d | John Harper - Removed hardcoded RCTModuleIDs | Nick Lockwood - [ReactKit] Animated GIF support | Alex Akers - [ReactKit] Update RCTBridge to support non-`id` argument types | Alex Akers - [reactkit] fix typo in RCTCopyProperty() change | John Harper - [reactkit] fix shadow view crash on missing properties | John Harper - [reactkit] fix transform keypath | John Harper
This commit is contained in:
parent
ccd8f184af
commit
6153fffb30
|
@ -9,6 +9,7 @@
|
||||||
var React = require('react-native');
|
var React = require('react-native');
|
||||||
var {
|
var {
|
||||||
Bundler,
|
Bundler,
|
||||||
|
Image,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
TouchableHighlight,
|
TouchableHighlight,
|
||||||
|
@ -118,13 +119,22 @@ var Cell = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
imageContents() {
|
||||||
|
switch (this.props.player) {
|
||||||
|
case 1:
|
||||||
|
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-277623.gif';
|
||||||
|
case 2:
|
||||||
|
return 'http://www.picgifs.com/alphabets/alphabets/children-5/alphabets-children-5-730492.gif';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<TouchableHighlight onPress={this.props.onPress} underlayColor={'clear'} activeOpacity={0.5}>
|
<TouchableHighlight onPress={this.props.onPress} underlayColor={'clear'} activeOpacity={0.5}>
|
||||||
<View style={[styles.cell, this.cellStyle()]}>
|
<View style={[styles.cell, this.cellStyle()]}>
|
||||||
<Text style={[styles.cellText, this.textStyle()]}>
|
<Image source={{uri: this.imageContents()}} />
|
||||||
{this.textContents()}
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
);
|
);
|
||||||
|
|
|
@ -169,12 +169,20 @@ var ReactIOSEventEmitter = merge(ReactEventEmitterMixin, {
|
||||||
var target = nativeEvent.target;
|
var target = nativeEvent.target;
|
||||||
if (target !== null && target !== undefined) {
|
if (target !== null && target !== undefined) {
|
||||||
if (target < ReactIOSTagHandles.tagsStartAt) {
|
if (target < ReactIOSTagHandles.tagsStartAt) {
|
||||||
|
// When we get multiple touches at the same time, only the first touch
|
||||||
|
// actually has a view attached to it. The rest of the touches do not.
|
||||||
|
// This is presumably because iOS doesn't want to send touch events to
|
||||||
|
// two views for a single multi touch. Therefore this warning is only
|
||||||
|
// appropriate when it happens to the first touch. (hence jj === 0)
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
|
if (jj === 0) {
|
||||||
warning(
|
warning(
|
||||||
false,
|
false,
|
||||||
'A view is reporting that a touch occured on tag zero.'
|
'A view is reporting that a touch occured on tag zero.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
rootNodeID = NodeHandle.getRootNodeID(target);
|
rootNodeID = NodeHandle.getRootNodeID(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,12 +37,14 @@ function createStrictShapeTypeChecker(shapeTypes) {
|
||||||
var allKeys = merge(props[propName], shapeTypes);
|
var allKeys = merge(props[propName], shapeTypes);
|
||||||
for (var key in allKeys) {
|
for (var key in allKeys) {
|
||||||
var checker = shapeTypes[key];
|
var checker = shapeTypes[key];
|
||||||
|
if (!checker) {
|
||||||
invariant(
|
invariant(
|
||||||
checker,
|
false,
|
||||||
`Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` +
|
`Invalid props.${propName} key \`${key}\` supplied to \`${componentName}\`.` +
|
||||||
`\nBad object: ` + JSON.stringify(props[propName], null, ' ') +
|
`\nBad object: ` + JSON.stringify(props[propName], null, ' ') +
|
||||||
`\nValid keys: ` + JSON.stringify(Object.keys(shapeTypes), null, ' ')
|
`\nValid keys: ` + JSON.stringify(Object.keys(shapeTypes), null, ' ')
|
||||||
);
|
);
|
||||||
|
}
|
||||||
var error = checker(propValue, key, componentName, location);
|
var error = checker(propValue, key, componentName, location);
|
||||||
if (error) {
|
if (error) {
|
||||||
invariant(
|
invariant(
|
||||||
|
|
|
@ -33,10 +33,9 @@ static inline NSDictionary *RCTAPIErrorObject(NSString *msg)
|
||||||
*/
|
*/
|
||||||
@interface RCTBridge : NSObject <RCTInvalidating>
|
@interface RCTBridge : NSObject <RCTInvalidating>
|
||||||
|
|
||||||
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
|
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor;
|
||||||
javaScriptModulesConfig:(NSDictionary *)javaScriptModulesConfig;
|
|
||||||
|
|
||||||
- (void)enqueueJSCall:(NSUInteger)moduleID methodID:(NSUInteger)methodID args:(NSArray *)args;
|
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
|
||||||
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
||||||
|
|
||||||
@property (nonatomic, readonly) RCTEventDispatcher *eventDispatcher;
|
@property (nonatomic, readonly) RCTEventDispatcher *eventDispatcher;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#import "RCTInvalidating.h"
|
#import "RCTInvalidating.h"
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTModuleIDs.h"
|
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,19 +35,6 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) {
|
||||||
RCTBridgeFieldFlushDateMillis
|
RCTBridgeFieldFlushDateMillis
|
||||||
};
|
};
|
||||||
|
|
||||||
static NSString *RCTModuleName(Class moduleClass)
|
|
||||||
{
|
|
||||||
if ([moduleClass respondsToSelector:@selector(moduleName)]) {
|
|
||||||
|
|
||||||
return [moduleClass moduleName];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Default implementation, works in most cases
|
|
||||||
return NSStringFromClass(moduleClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSDictionary *RCTNativeModuleClasses(void)
|
static NSDictionary *RCTNativeModuleClasses(void)
|
||||||
{
|
{
|
||||||
static NSMutableDictionary *modules;
|
static NSMutableDictionary *modules;
|
||||||
|
@ -73,7 +59,7 @@ static NSDictionary *RCTNativeModuleClasses(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get module name
|
// Get module name
|
||||||
NSString *moduleName = RCTModuleName(cls);
|
NSString *moduleName = [cls respondsToSelector:@selector(moduleName)] ? [cls moduleName] : NSStringFromClass(cls);
|
||||||
|
|
||||||
// Check module name is unique
|
// Check module name is unique
|
||||||
id existingClass = modules[moduleName];
|
id existingClass = modules[moduleName];
|
||||||
|
@ -90,23 +76,22 @@ static NSDictionary *RCTNativeModuleClasses(void)
|
||||||
@implementation RCTBridge
|
@implementation RCTBridge
|
||||||
{
|
{
|
||||||
NSMutableDictionary *_moduleInstances;
|
NSMutableDictionary *_moduleInstances;
|
||||||
NSDictionary *_javaScriptModulesConfig;
|
NSMutableDictionary *_moduleIDLookup;
|
||||||
|
NSMutableDictionary *_methodIDLookup;
|
||||||
id<RCTJavaScriptExecutor> _javaScriptExecutor;
|
id<RCTJavaScriptExecutor> _javaScriptExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
|
|
||||||
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
|
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
|
||||||
javaScriptModulesConfig:(NSDictionary *)javaScriptModulesConfig
|
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
_javaScriptExecutor = javaScriptExecutor;
|
_javaScriptExecutor = javaScriptExecutor;
|
||||||
_latestJSExecutor = _javaScriptExecutor;
|
_latestJSExecutor = _javaScriptExecutor;
|
||||||
_eventDispatcher = [[RCTEventDispatcher alloc] initWithBridge:self];
|
_eventDispatcher = [[RCTEventDispatcher alloc] initWithBridge:self];
|
||||||
_javaScriptModulesConfig = javaScriptModulesConfig;
|
|
||||||
_shadowQueue = dispatch_queue_create("com.facebook.ReactKit.ShadowQueue", DISPATCH_QUEUE_SERIAL);
|
_shadowQueue = dispatch_queue_create("com.facebook.ReactKit.ShadowQueue", DISPATCH_QUEUE_SERIAL);
|
||||||
|
|
||||||
// Register modules
|
// Instantiate modules
|
||||||
_moduleInstances = [[NSMutableDictionary alloc] init];
|
_moduleInstances = [[NSMutableDictionary alloc] init];
|
||||||
[RCTNativeModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *moduleName, Class moduleClass, BOOL *stop) {
|
[RCTNativeModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *moduleName, Class moduleClass, BOOL *stop) {
|
||||||
if (_moduleInstances[moduleName] == nil) {
|
if (_moduleInstances[moduleName] == nil) {
|
||||||
|
@ -118,6 +103,8 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
_moduleIDLookup = [[NSMutableDictionary alloc] init];
|
||||||
|
_methodIDLookup = [[NSMutableDictionary alloc] init];
|
||||||
[self doneRegisteringModules];
|
[self doneRegisteringModules];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +155,18 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
/**
|
/**
|
||||||
* Like JS::call, for objective-c.
|
* Like JS::call, for objective-c.
|
||||||
*/
|
*/
|
||||||
- (void)enqueueJSCall:(NSUInteger)moduleID methodID:(NSUInteger)methodID args:(NSArray *)args
|
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||||
{
|
{
|
||||||
RCTAssertMainThread();
|
NSNumber *moduleID = _moduleIDLookup[moduleDotMethod];
|
||||||
[self _invokeRemoteJSModule:moduleID methodID:methodID args:args];
|
RCTAssert(moduleID, @"Module '%@' not registered.",
|
||||||
|
[[moduleDotMethod componentsSeparatedByString:@"."] firstObject]);
|
||||||
|
|
||||||
|
NSNumber *methodID = _methodIDLookup[moduleDotMethod];
|
||||||
|
RCTAssert(methodID, @"Method '%@' not registered.", moduleDotMethod);
|
||||||
|
|
||||||
|
[self _invokeAndProcessModule:@"BatchedBridge"
|
||||||
|
method:@"callFunctionReturnFlushedQueue"
|
||||||
|
arguments:@[moduleID, methodID, args]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete
|
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete
|
||||||
|
@ -217,13 +212,6 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
callback:processResponse];
|
callback:processResponse];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_invokeRemoteJSModule:(NSUInteger)moduleID methodID:(NSUInteger)methodID args:(NSArray *)args
|
|
||||||
{
|
|
||||||
[self _invokeAndProcessModule:@"BatchedBridge"
|
|
||||||
method:@"callFunctionReturnFlushedQueue"
|
|
||||||
arguments:@[@(moduleID), @(methodID), args]];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO (#5906496): Have responses piggy backed on a round trip with ObjC->JS requests.
|
* TODO (#5906496): Have responses piggy backed on a round trip with ObjC->JS requests.
|
||||||
*/
|
*/
|
||||||
|
@ -334,19 +322,19 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSInvocation *invocation = [RCTBridge invocationForAdditionalArguments:methodArity];
|
|
||||||
|
|
||||||
// TODO: we should just store module instances by index, since that's how we look them up anyway
|
// TODO: we should just store module instances by index, since that's how we look them up anyway
|
||||||
id target = strongSelf->_moduleInstances[moduleName];
|
id target = strongSelf->_moduleInstances[moduleName];
|
||||||
RCTAssert(target != nil, @"No module found for name '%@'", moduleName);
|
RCTAssert(target != nil, @"No module found for name '%@'", moduleName);
|
||||||
|
|
||||||
[invocation setArgument:&target atIndex:0];
|
|
||||||
|
|
||||||
SEL selector = method.selector;
|
SEL selector = method.selector;
|
||||||
|
|
||||||
|
NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector];
|
||||||
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
|
||||||
|
[invocation setArgument:&target atIndex:0];
|
||||||
[invocation setArgument:&selector atIndex:1];
|
[invocation setArgument:&selector atIndex:1];
|
||||||
|
|
||||||
// Retain used blocks until after invocation completes.
|
// Retain used blocks until after invocation completes.
|
||||||
NSMutableArray *blocks = [NSMutableArray array];
|
NS_VALID_UNTIL_END_OF_SCOPE NSMutableArray *blocks = [NSMutableArray array];
|
||||||
|
|
||||||
[params enumerateObjectsUsingBlock:^(id param, NSUInteger idx, BOOL *stop) {
|
[params enumerateObjectsUsingBlock:^(id param, NSUInteger idx, BOOL *stop) {
|
||||||
if ([param isEqual:[NSNull null]]) {
|
if ([param isEqual:[NSNull null]]) {
|
||||||
|
@ -357,7 +345,57 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
param = block;
|
param = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
[invocation setArgument:¶m atIndex:idx + 2];
|
NSUInteger argIdx = idx + 2;
|
||||||
|
|
||||||
|
BOOL shouldSet = YES;
|
||||||
|
const char *argumentType = [methodSignature getArgumentTypeAtIndex:argIdx];
|
||||||
|
switch (argumentType[0]) {
|
||||||
|
case ':':
|
||||||
|
if ([param isKindOfClass:[NSString class]]) {
|
||||||
|
SEL selector = NSSelectorFromString(param);
|
||||||
|
[invocation setArgument:&selector atIndex:argIdx];
|
||||||
|
shouldSet = NO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
if ([param isKindOfClass:[NSString class]]) {
|
||||||
|
const char *string = [param UTF8String];
|
||||||
|
[invocation setArgument:&string atIndex:argIdx];
|
||||||
|
shouldSet = NO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define CASE(_value, _type, _selector) \
|
||||||
|
case _value: \
|
||||||
|
if ([param respondsToSelector:@selector(_selector)]) { \
|
||||||
|
_type value = [param _selector]; \
|
||||||
|
[invocation setArgument:&value atIndex:argIdx]; \
|
||||||
|
shouldSet = NO; \
|
||||||
|
} \
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE('c', char, charValue)
|
||||||
|
CASE('C', unsigned char, unsignedCharValue)
|
||||||
|
CASE('s', short, shortValue)
|
||||||
|
CASE('S', unsigned short, unsignedShortValue)
|
||||||
|
CASE('i', int, intValue)
|
||||||
|
CASE('I', unsigned int, unsignedIntValue)
|
||||||
|
CASE('l', long, longValue)
|
||||||
|
CASE('L', unsigned long, unsignedLongValue)
|
||||||
|
CASE('q', long long, longLongValue)
|
||||||
|
CASE('Q', unsigned long long, unsignedLongLongValue)
|
||||||
|
CASE('f', float, floatValue)
|
||||||
|
CASE('d', double, doubleValue)
|
||||||
|
CASE('B', BOOL, boolValue)
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSet) {
|
||||||
|
[invocation setArgument:¶m atIndex:argIdx];
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@try {
|
@try {
|
||||||
|
@ -366,10 +404,6 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
RCTLogMustFix(@"Exception thrown while invoking %@ on target %@ with params %@: %@", method.JSMethodName, target, params, exception);
|
RCTLogMustFix(@"Exception thrown while invoking %@ on target %@ with params %@: %@", method.JSMethodName, target, params, exception);
|
||||||
}
|
}
|
||||||
@finally {
|
|
||||||
// Force `blocks` to remain alive until here.
|
|
||||||
blocks = nil;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -412,16 +446,71 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
return invocation;
|
return invocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray *)JSMethods
|
||||||
|
{
|
||||||
|
NSMutableArray *methods = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
// Add globally used methods
|
||||||
|
[methods addObjectsFromArray:@[
|
||||||
|
@"Bundler.runApplication",
|
||||||
|
@"RCTEventEmitter.receiveEvent",
|
||||||
|
@"RCTEventEmitter.receiveTouches",
|
||||||
|
]];
|
||||||
|
|
||||||
|
// NOTE: these methods are currently unused in the OSS project
|
||||||
|
// @"Dimensions.set",
|
||||||
|
// @"RCTDeviceEventEmitter.emit",
|
||||||
|
// @"RCTNativeAppEventEmitter.emit",
|
||||||
|
// @"ReactIOS.unmountComponentAtNodeAndRemoveContainer",
|
||||||
|
|
||||||
|
// Register individual methods from modules
|
||||||
|
for (Class cls in RCTNativeModuleClasses().allValues) {
|
||||||
|
if (RCTClassOverridesClassMethod(cls, @selector(JSMethods))) {
|
||||||
|
[methods addObjectsFromArray:[cls JSMethods]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)doneRegisteringModules
|
- (void)doneRegisteringModules
|
||||||
{
|
{
|
||||||
|
// TODO: everything in this method can actually be determined
|
||||||
|
// statically from just the class, and can therefore be cached
|
||||||
|
// in a dispatch_once instead of being repeated every time we
|
||||||
|
// reload or create a new RootView.
|
||||||
|
|
||||||
RCTAssertMainThread();
|
RCTAssertMainThread();
|
||||||
RCTAssert(_javaScriptModulesConfig != nil, @"JS module config not loaded in APP");
|
|
||||||
|
|
||||||
NSMutableDictionary *objectsToInject = [NSMutableDictionary dictionary];
|
/**
|
||||||
|
* This constructs the remote modules configuration data structure,
|
||||||
|
* which represents the native modules and methods that will be called
|
||||||
|
* by JS. A numeric ID is assigned to each module and method, which will
|
||||||
|
* be used to communicate via the bridge. The structure of each
|
||||||
|
* module is as follows:
|
||||||
|
*
|
||||||
|
* "ModuleName1": {
|
||||||
|
* "moduleID": 0,
|
||||||
|
* "methods": {
|
||||||
|
* "methodName1": {
|
||||||
|
* "methodID": 0,
|
||||||
|
* "type": "remote"
|
||||||
|
* },
|
||||||
|
* "methodName2": {
|
||||||
|
* "methodID": 1,
|
||||||
|
* "type": "remote"
|
||||||
|
* },
|
||||||
|
* etc...
|
||||||
|
* },
|
||||||
|
* "constants": {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* etc...
|
||||||
|
*/
|
||||||
|
|
||||||
// Dictionary of { moduleName0: { moduleID: 0, methods: { methodName0: { methodID: 0, type: remote }, methodName1: { ... }, ... }, ... }
|
|
||||||
NSUInteger moduleCount = RCTExportedMethodsByModule().count;
|
NSUInteger moduleCount = RCTExportedMethodsByModule().count;
|
||||||
NSMutableDictionary *moduleConfigs = [NSMutableDictionary dictionaryWithCapacity:RCTExportedMethodsByModule().count];
|
NSMutableDictionary *remoteModules = [NSMutableDictionary dictionaryWithCapacity:RCTExportedMethodsByModule().count];
|
||||||
for (NSUInteger i = 0; i < moduleCount; i++) {
|
for (NSUInteger i = 0; i < moduleCount; i++) {
|
||||||
NSString *moduleName = RCTExportedModuleNameAtSortedIndex(i);
|
NSString *moduleName = RCTExportedModuleNameAtSortedIndex(i);
|
||||||
NSArray *rawMethods = RCTExportedMethodsByModule()[moduleName];
|
NSArray *rawMethods = RCTExportedMethodsByModule()[moduleName];
|
||||||
|
@ -433,37 +522,89 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
|
|
||||||
NSMutableDictionary *moduleConfig = [NSMutableDictionary dictionary];
|
NSDictionary *module = @{
|
||||||
moduleConfig[@"moduleID"] = @(i);
|
@"moduleID": @(i),
|
||||||
moduleConfig[@"methods"] = methods;
|
@"methods": methods
|
||||||
|
|
||||||
id target = [_moduleInstances objectForKey:moduleName];
|
|
||||||
if ([target respondsToSelector:@selector(constantsToExport)]) {
|
|
||||||
moduleConfig[@"constants"] = [target constantsToExport];
|
|
||||||
}
|
|
||||||
moduleConfigs[moduleName] = moduleConfig;
|
|
||||||
}
|
|
||||||
NSDictionary *batchedBridgeConfig = @{
|
|
||||||
@"remoteModuleConfig": moduleConfigs,
|
|
||||||
@"localModulesConfig": _javaScriptModulesConfig
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NSString *configJSON = RCTJSONStringify(batchedBridgeConfig, NULL);
|
id target = _moduleInstances[moduleName];
|
||||||
objectsToInject[@"__fbBatchedBridgeConfig"] = configJSON;
|
if (RCTClassOverridesClassMethod([target class], @selector(constantsToExport))) {
|
||||||
|
module = [module mutableCopy];
|
||||||
|
((NSMutableDictionary *)module)[@"constants"] = [[target class] constantsToExport];
|
||||||
|
}
|
||||||
|
remoteModules[moduleName] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As above, but for local modules/methods, which represent JS classes
|
||||||
|
* and methods that will be called by the native code via the bridge.
|
||||||
|
* Structure is essentially the same as for remote modules:
|
||||||
|
*
|
||||||
|
* "ModuleName1": {
|
||||||
|
* "moduleID": 0,
|
||||||
|
* "methods": {
|
||||||
|
* "methodName1": {
|
||||||
|
* "methodID": 0,
|
||||||
|
* "type": "local"
|
||||||
|
* },
|
||||||
|
* "methodName2": {
|
||||||
|
* "methodID": 1,
|
||||||
|
* "type": "local"
|
||||||
|
* },
|
||||||
|
* etc...
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* etc...
|
||||||
|
*/
|
||||||
|
|
||||||
|
NSMutableDictionary *localModules = [[NSMutableDictionary alloc] init];
|
||||||
|
for (NSString *moduleDotMethod in [self JSMethods]) {
|
||||||
|
|
||||||
|
NSArray *parts = [moduleDotMethod componentsSeparatedByString:@"."];
|
||||||
|
RCTAssert(parts.count == 2, @"'%@' is not a valid JS method definition - expected 'Module.method' format.", moduleDotMethod);
|
||||||
|
|
||||||
|
// Add module if it doesn't already exist
|
||||||
|
NSString *moduleName = parts[0];
|
||||||
|
NSDictionary *module = localModules[moduleName];
|
||||||
|
if (!module) {
|
||||||
|
module = @{
|
||||||
|
@"moduleID": @(localModules.count),
|
||||||
|
@"methods": [[NSMutableDictionary alloc] init]
|
||||||
|
};
|
||||||
|
localModules[moduleName] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add method if it doesn't already exist
|
||||||
|
NSString *methodName = parts[1];
|
||||||
|
NSMutableDictionary *methods = module[@"methods"];
|
||||||
|
if (!methods[methodName]) {
|
||||||
|
methods[methodName] = @{
|
||||||
|
@"methodID": @(methods.count),
|
||||||
|
@"type": @"local"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add module and method lookup
|
||||||
|
_moduleIDLookup[moduleDotMethod] = module[@"moduleID"];
|
||||||
|
_methodIDLookup[moduleDotMethod] = methods[methodName][@"methodID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject module data into JS context
|
||||||
|
*/
|
||||||
|
NSString *configJSON = RCTJSONStringify(@{
|
||||||
|
@"remoteModuleConfig": remoteModules,
|
||||||
|
@"localModulesConfig": localModules
|
||||||
|
}, NULL);
|
||||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||||
[objectsToInject enumerateKeysAndObjectsUsingBlock:^(NSString *objectName, NSString *script, BOOL *stop) {
|
[_javaScriptExecutor injectJSONText:configJSON asGlobalObjectNamed:@"__fbBatchedBridgeConfig" callback:^(id err) {
|
||||||
[_javaScriptExecutor injectJSONText:script asGlobalObjectNamed:objectName callback:^(id err) {
|
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
}];
|
}];
|
||||||
}];
|
|
||||||
|
|
||||||
for (NSUInteger i = 0, count = objectsToInject.count; i < count; i++) {
|
|
||||||
if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)) != 0) {
|
if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)) != 0) {
|
||||||
RCTLogMustFix(@"JavaScriptExecutor take too long to inject JSON object");
|
RCTLogMustFix(@"JavaScriptExecutor take too long to inject JSON object");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
- (void)registerRootView:(RCTRootView *)rootView
|
- (void)registerRootView:(RCTRootView *)rootView
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
+ (UIColor *)UIColor:(id)json;
|
+ (UIColor *)UIColor:(id)json;
|
||||||
+ (CGColorRef)CGColor:(id)json;
|
+ (CGColorRef)CGColor:(id)json;
|
||||||
|
|
||||||
|
+ (CAKeyframeAnimation *)GIF:(id)json;
|
||||||
+ (UIImage *)UIImage:(id)json;
|
+ (UIImage *)UIImage:(id)json;
|
||||||
+ (CGImageRef)CGImage:(id)json;
|
+ (CGImageRef)CGImage:(id)json;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
|
|
||||||
|
#import <ImageIO/ImageIO.h>
|
||||||
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
|
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
|
|
||||||
CGFloat const RCTDefaultFontSize = 14;
|
CGFloat const RCTDefaultFontSize = 14;
|
||||||
|
@ -426,6 +429,83 @@ RCT_STRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]
|
||||||
return [self UIColor:json].CGColor;
|
return [self UIColor:json].CGColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (CAKeyframeAnimation *)GIF:(id)json
|
||||||
|
{
|
||||||
|
CGImageSourceRef imageSource;
|
||||||
|
if ([json isKindOfClass:[NSString class]]) {
|
||||||
|
NSString *path = json;
|
||||||
|
if (path.length == 0) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSURL *fileURL = [path isAbsolutePath] ? [NSURL fileURLWithPath:path] : [[NSBundle mainBundle] URLForResource:path withExtension:nil];
|
||||||
|
imageSource = CGImageSourceCreateWithURL((CFURLRef)fileURL, NULL);
|
||||||
|
} else if ([json isKindOfClass:[NSData class]]) {
|
||||||
|
NSData *data = json;
|
||||||
|
if (data.length == 0) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageSource = CGImageSourceCreateWithData((CFDataRef)data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UTTypeConformsTo(CGImageSourceGetType(imageSource), kUTTypeGIF)) {
|
||||||
|
CFRelease(imageSource);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(imageSource, NULL);
|
||||||
|
NSUInteger loopCount = [properties[(id)kCGImagePropertyGIFDictionary][(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
|
||||||
|
|
||||||
|
size_t imageCount = CGImageSourceGetCount(imageSource);
|
||||||
|
NSTimeInterval duration = 0;
|
||||||
|
NSMutableArray *delays = [NSMutableArray arrayWithCapacity:imageCount];
|
||||||
|
NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount];
|
||||||
|
for (size_t i = 0; i < imageCount; i++) {
|
||||||
|
CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
|
||||||
|
NSDictionary *frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, i, NULL);
|
||||||
|
NSDictionary *frameGIFProperties = frameProperties[(id)kCGImagePropertyGIFDictionary];
|
||||||
|
|
||||||
|
const NSTimeInterval kDelayTimeIntervalDefault = 0.1;
|
||||||
|
NSNumber *delayTime = frameGIFProperties[(id)kCGImagePropertyGIFUnclampedDelayTime] ?: frameGIFProperties[(id)kCGImagePropertyGIFDelayTime];
|
||||||
|
if (delayTime == nil) {
|
||||||
|
if (i == 0) {
|
||||||
|
delayTime = @(kDelayTimeIntervalDefault);
|
||||||
|
} else {
|
||||||
|
delayTime = delays[i - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const NSTimeInterval kDelayTimeIntervalMinimum = 0.02;
|
||||||
|
if (delayTime.floatValue < (float)kDelayTimeIntervalMinimum - FLT_EPSILON) {
|
||||||
|
delayTime = @(kDelayTimeIntervalDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
duration += delayTime.doubleValue;
|
||||||
|
delays[i] = delayTime;
|
||||||
|
images[i] = (__bridge_transfer id)image;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(imageSource);
|
||||||
|
|
||||||
|
NSMutableArray *keyTimes = [NSMutableArray arrayWithCapacity:delays.count];
|
||||||
|
NSTimeInterval runningDuration = 0;
|
||||||
|
for (NSNumber *delayNumber in delays) {
|
||||||
|
[keyTimes addObject:@(runningDuration / duration)];
|
||||||
|
runningDuration += delayNumber.doubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[keyTimes addObject:@1.0];
|
||||||
|
|
||||||
|
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
|
||||||
|
animation.calculationMode = kCAAnimationDiscrete;
|
||||||
|
animation.repeatCount = loopCount == 0 ? HUGE_VALF : loopCount;
|
||||||
|
animation.keyTimes = keyTimes;
|
||||||
|
animation.values = images;
|
||||||
|
animation.duration = duration;
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
+ (UIImage *)UIImage:(id)json
|
+ (UIImage *)UIImage:(id)json
|
||||||
{
|
{
|
||||||
if (![json isKindOfClass:[NSString class]]) {
|
if (![json isKindOfClass:[NSString class]]) {
|
||||||
|
|
|
@ -33,9 +33,11 @@ typedef NS_ENUM(NSInteger, RCTScrollEventType) {
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an arbitrary event type
|
* Send a named event. For most purposes, use the an
|
||||||
|
* event type of RCTEventTypeDefault, the other types
|
||||||
|
* are used internally by the React framework.
|
||||||
*/
|
*/
|
||||||
- (void)sendRawEventWithType:(NSString *)eventType body:(NSDictionary *)body;
|
- (void)sendEventWithName:(NSString *)name body:(NSDictionary *)body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an array of touch events
|
* Send an array of touch events
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
|
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTModuleIDs.h"
|
|
||||||
#import "UIView+ReactKit.h"
|
#import "UIView+ReactKit.h"
|
||||||
|
|
||||||
@implementation RCTEventDispatcher
|
@implementation RCTEventDispatcher
|
||||||
|
@ -19,39 +18,13 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)touchEvents
|
- (void)sendEventWithName:(NSString *)name body:(NSDictionary *)body
|
||||||
{
|
{
|
||||||
static NSArray *events;
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
events = @[
|
|
||||||
@"topTouchStart",
|
|
||||||
@"topTouchMove",
|
|
||||||
@"topTouchEnd",
|
|
||||||
@"topTouchCancel",
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendRawEventWithType:(NSString *)eventType body:(NSDictionary *)body
|
|
||||||
{
|
|
||||||
static NSSet *touchEvents;
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
touchEvents = [NSSet setWithArray:[self touchEvents]];
|
|
||||||
});
|
|
||||||
|
|
||||||
RCTAssert(![touchEvents containsObject:eventType], @"Touch events must be"
|
|
||||||
"sent via the sendTouchEventWithOrderedTouches: method, not sendRawEventWithType:");
|
|
||||||
|
|
||||||
RCTAssert([body[@"target"] isKindOfClass:[NSNumber class]],
|
RCTAssert([body[@"target"] isKindOfClass:[NSNumber class]],
|
||||||
@"Event body dictionary must include a 'target' property containing a react tag");
|
@"Event body dictionary must include a 'target' property containing a react tag");
|
||||||
|
|
||||||
[_bridge enqueueJSCall:RCTModuleIDReactIOSEventEmitter
|
[_bridge enqueueJSCall:@"RCTEventEmitter.receiveEvent"
|
||||||
methodID:RCTEventEmitterReceiveEvent
|
args:@[body[@"target"], name, body]];
|
||||||
args:@[body[@"target"], eventType, body]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,30 +42,32 @@
|
||||||
touches:(NSArray *)touches
|
touches:(NSArray *)touches
|
||||||
changedIndexes:(NSArray *)changedIndexes
|
changedIndexes:(NSArray *)changedIndexes
|
||||||
{
|
{
|
||||||
|
static NSString *events[] = {
|
||||||
|
@"topTouchStart",
|
||||||
|
@"topTouchMove",
|
||||||
|
@"topTouchEnd",
|
||||||
|
@"topTouchCancel",
|
||||||
|
};
|
||||||
|
|
||||||
RCTAssert(touches.count, @"No touches in touchEventArgsForOrderedTouches");
|
RCTAssert(touches.count, @"No touches in touchEventArgsForOrderedTouches");
|
||||||
|
|
||||||
[_bridge enqueueJSCall:RCTModuleIDReactIOSEventEmitter
|
[_bridge enqueueJSCall:@"RCTEventEmitter.receiveTouches"
|
||||||
methodID:RCTEventEmitterReceiveTouches
|
args:@[events[type], touches, changedIndexes]];
|
||||||
args:@[[self touchEvents][type], touches, changedIndexes]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendTextEventWithType:(RCTTextEventType)type
|
- (void)sendTextEventWithType:(RCTTextEventType)type
|
||||||
reactTag:(NSNumber *)reactTag
|
reactTag:(NSNumber *)reactTag
|
||||||
text:(NSString *)text
|
text:(NSString *)text
|
||||||
{
|
{
|
||||||
static NSArray *events;
|
static NSString *events[] = {
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
events = @[
|
|
||||||
@"topFocus",
|
@"topFocus",
|
||||||
@"topBlur",
|
@"topBlur",
|
||||||
@"topChange",
|
@"topChange",
|
||||||
@"topSubmitEditing",
|
@"topSubmitEditing",
|
||||||
@"topEndEditing",
|
@"topEndEditing",
|
||||||
];
|
};
|
||||||
});
|
|
||||||
|
|
||||||
[self sendRawEventWithType:events[type] body:@{
|
[self sendEventWithName:events[type] body:@{
|
||||||
@"text": text,
|
@"text": text,
|
||||||
@"target": reactTag
|
@"target": reactTag
|
||||||
}];
|
}];
|
||||||
|
@ -111,18 +86,14 @@
|
||||||
scrollView:(UIScrollView *)scrollView
|
scrollView:(UIScrollView *)scrollView
|
||||||
userData:(NSDictionary *)userData
|
userData:(NSDictionary *)userData
|
||||||
{
|
{
|
||||||
static NSArray *events;
|
static NSString *events[] = {
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
events = @[
|
|
||||||
@"topScrollBeginDrag",
|
@"topScrollBeginDrag",
|
||||||
@"topScroll",
|
@"topScroll",
|
||||||
@"topScrollEndDrag",
|
@"topScrollEndDrag",
|
||||||
@"topMomentumScrollBegin",
|
@"topMomentumScrollBegin",
|
||||||
@"topMomentumScrollEnd",
|
@"topMomentumScrollEnd",
|
||||||
@"topScrollAnimationEnd",
|
@"topScrollAnimationEnd",
|
||||||
];
|
};
|
||||||
});
|
|
||||||
|
|
||||||
NSDictionary *body = @{
|
NSDictionary *body = @{
|
||||||
@"contentOffset": @{
|
@"contentOffset": @{
|
||||||
|
@ -147,7 +118,7 @@
|
||||||
body = mutableBody;
|
body = mutableBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self sendRawEventWithType:events[type] body:body];
|
[self sendEventWithName:events[type] body:body];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern NSString *RCTExportedModuleNameAtSortedIndex(NSUInteger index);
|
||||||
extern NSDictionary *RCTExportedMethodsByModule(void);
|
extern NSDictionary *RCTExportedMethodsByModule(void);
|
||||||
|
|
||||||
extern BOOL RCTSetProperty(id target, NSString *keypath, id value);
|
extern BOOL RCTSetProperty(id target, NSString *keypath, id value);
|
||||||
|
extern BOOL RCTCopyProperty(id target, id source, NSString *keypath);
|
||||||
extern BOOL RCTCallSetter(id target, SEL setter, id value);
|
extern BOOL RCTCallSetter(id target, SEL setter, id value);
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -66,9 +67,22 @@ _RCTExportSectionName))) static const RCTExportEntry __rct_export_entry__ = { __
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects constants into JS. These constants are made accessible via
|
* Injects constants into JS. These constants are made accessible via
|
||||||
* NativeModules.moduleName.X.
|
* NativeModules.moduleName.X. Note that this method is not inherited when you
|
||||||
|
* subclass a module, and you should not call [super constantsToExport] when
|
||||||
|
* implementing it.
|
||||||
*/
|
*/
|
||||||
- (NSDictionary *)constantsToExport;
|
+ (NSDictionary *)constantsToExport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of JavaScript methods that the module will call via the
|
||||||
|
* -[RCTBridge enqueueJSCall:args:] method. Each method should be specified
|
||||||
|
* as a string of the form "JSModuleName.jsMethodName". Attempting to call a
|
||||||
|
* method that has not been registered will result in an error. If a method
|
||||||
|
* has already been regsistered by another module, it is not necessary to
|
||||||
|
* register it again, but it is good pratice. Registering the same method
|
||||||
|
* more than once is silently ignored and will not result in an error.
|
||||||
|
*/
|
||||||
|
+ (NSArray *)JSMethods;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the module that a batch of JS method invocations has just completed.
|
* Notifies the module that a batch of JS method invocations has just completed.
|
||||||
|
@ -84,9 +98,18 @@ _RCTExportSectionName))) static const RCTExportEntry __rct_export_entry__ = { __
|
||||||
@protocol RCTNativeViewModule <NSObject>
|
@protocol RCTNativeViewModule <NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instantiates a native view to be managed by the module.
|
* Designated initializer for view modules. The event dispatched can either be
|
||||||
|
* used directly by the module, or passed on to instantiated views for event handling.
|
||||||
*/
|
*/
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method instantiates a native view to be managed by the module. The method
|
||||||
|
* will be called many times, and should return a fresh instance each time. The
|
||||||
|
* view module MUST NOT cache the returned view and return the same instance
|
||||||
|
* for subsequent calls.
|
||||||
|
*/
|
||||||
|
- (UIView *)view;
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
|
@ -98,7 +121,8 @@ _RCTExportSectionName))) static const RCTExportEntry __rct_export_entry__ = { __
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instantiates a shadow view to be managed by the module. If omitted,
|
* This method instantiates a shadow view to be managed by the module. If omitted,
|
||||||
* an ordinary RCTShadowView instance will be created.
|
* an ordinary RCTShadowView instance will be created. As with the -view method,
|
||||||
|
* the -shadowView method should return a fresh instance each time it is called.
|
||||||
*/
|
*/
|
||||||
- (RCTShadowView *)shadowView;
|
- (RCTShadowView *)shadowView;
|
||||||
|
|
||||||
|
@ -164,8 +188,11 @@ RCT_REMAP_VIEW_PROPERTY(name, name)
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* Note that this method is not inherited when you subclass a view module, and
|
||||||
|
* you should not call [super customBubblingEventTypes] when implementing it.
|
||||||
*/
|
*/
|
||||||
- (NSDictionary *)customBubblingEventTypes;
|
+ (NSDictionary *)customBubblingEventTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a dictionary of config data passed to JS that defines eligible events
|
* Returns a dictionary of config data passed to JS that defines eligible events
|
||||||
|
@ -177,14 +204,19 @@ RCT_REMAP_VIEW_PROPERTY(name, name)
|
||||||
* @"registrationName": @"onTwirl"
|
* @"registrationName": @"onTwirl"
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* Note that this method is not inherited when you subclass a view module, and
|
||||||
|
* you should not call [super customDirectEventTypes] when implementing it.
|
||||||
*/
|
*/
|
||||||
- (NSDictionary *)customDirectEventTypes;
|
+ (NSDictionary *)customDirectEventTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects constants into JS. These constants are made accessible via
|
* Injects constants into JS. These constants are made accessible via
|
||||||
* NativeModules.moduleName.X.
|
* NativeModules.moduleName.X. Note that this method is not inherited when you
|
||||||
|
* subclass a view module, and you should not call [super constantsToExport]
|
||||||
|
* when implementing it.
|
||||||
*/
|
*/
|
||||||
- (NSDictionary *)constantsToExport;
|
+ (NSDictionary *)constantsToExport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To deprecate, hopefully
|
* To deprecate, hopefully
|
||||||
|
|
|
@ -349,6 +349,36 @@ BOOL RCTSetProperty(id target, NSString *keypath, id value)
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL RCTCopyProperty(id target, id source, NSString *keypath)
|
||||||
|
{
|
||||||
|
// Split keypath
|
||||||
|
NSArray *parts = [keypath componentsSeparatedByString:@"."];
|
||||||
|
NSString *key = [parts lastObject];
|
||||||
|
for (NSUInteger i = 0; i < parts.count - 1; i++) {
|
||||||
|
source = [source valueForKey:parts[i]];
|
||||||
|
target = [target valueForKey:parts[i]];
|
||||||
|
if (!source || !target) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check class for property definition
|
||||||
|
if (!class_getProperty([source class], [key UTF8String])) {
|
||||||
|
// Check if setter exists
|
||||||
|
SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:",
|
||||||
|
[[key substringToIndex:1] uppercaseString],
|
||||||
|
[key substringFromIndex:1]]);
|
||||||
|
|
||||||
|
if (![source respondsToSelector:setter]
|
||||||
|
|| ![target respondsToSelector:setter]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[target setValue:[source valueForKey:key] forKey:key];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL RCTCallSetter(id target, SEL setter, id value)
|
BOOL RCTCallSetter(id target, SEL setter, id value)
|
||||||
{
|
{
|
||||||
// Get property name
|
// Get property name
|
||||||
|
|
|
@ -2,12 +2,16 @@
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
typedef void (^RCTDataDownloadBlock)(NSData *data, NSError *error);
|
||||||
typedef void (^RCTImageDownloadBlock)(UIImage *image, NSError *error);
|
typedef void (^RCTImageDownloadBlock)(UIImage *image, NSError *error);
|
||||||
|
|
||||||
@interface RCTImageDownloader : NSObject
|
@interface RCTImageDownloader : NSObject
|
||||||
|
|
||||||
+ (instancetype)sharedInstance;
|
+ (instancetype)sharedInstance;
|
||||||
|
|
||||||
|
- (id)downloadDataForURL:(NSURL *)url
|
||||||
|
block:(RCTDataDownloadBlock)block;
|
||||||
|
|
||||||
- (id)downloadImageForURL:(NSURL *)url
|
- (id)downloadImageForURL:(NSURL *)url
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale
|
||||||
|
|
|
@ -18,6 +18,20 @@
|
||||||
return sharedInstance;
|
return sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)downloadDataForURL:(NSURL *)url
|
||||||
|
block:(RCTDataDownloadBlock)block
|
||||||
|
{
|
||||||
|
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||||
|
// Dispatch back to main thread
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
block(data, error);
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
|
||||||
|
[task resume];
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
- (id)downloadImageForURL:(NSURL *)url
|
- (id)downloadImageForURL:(NSURL *)url
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
scale:(CGFloat)scale
|
scale:(CGFloat)scale
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All of this will be replaced with an auto-generated bridge.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTJSModuleIDs) {
|
|
||||||
RCTModuleIDReactIOSEventEmitter,
|
|
||||||
RCTModuleIDJSTimers, // JS timer tracking module
|
|
||||||
RCTModuleIDReactIOS,
|
|
||||||
RCTModuleIDBundler,
|
|
||||||
RCTModuleIDDimensions,
|
|
||||||
RCTModuleIDDeviceEventEmitter,
|
|
||||||
RCTModuleIDNativeAppEventEmitter,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JS module `RCTIOSEventEmitter`.
|
|
||||||
*/
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTEventEmitterRemoteMethodIDs) {
|
|
||||||
RCTEventEmitterReceiveEvent = 0,
|
|
||||||
RCTEventEmitterReceiveTouches
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTKeyCode) {
|
|
||||||
RCTKeyCodeBackspace = 8,
|
|
||||||
RCTKeyCodeReturn = 13,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JS timer tracking module.
|
|
||||||
*/
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTJSTimersMethodIDs) {
|
|
||||||
RCTJSTimersCallTimers = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTReactIOSMethodIDs) {
|
|
||||||
RCTReactIOSUnmountComponentAtNodeAndRemoveContainer = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTBundlerMethodIDs) {
|
|
||||||
RCTBundlerRunApplication = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTDimensionsMethodIDs) {
|
|
||||||
RCTDimensionsSet = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, RCTDeviceEventEmitterMethodIDs) {
|
|
||||||
RCTDeviceEventEmitterEmit = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface RCTModuleIDs : NSObject
|
|
||||||
|
|
||||||
+ (NSDictionary *)config;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
||||||
|
|
||||||
#import "RCTModuleIDs.h"
|
|
||||||
|
|
||||||
@implementation RCTModuleIDs
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures invocations from IOS -> JS. Simply passes the name of the key in
|
|
||||||
* the configuration object `require('ReactIOSEventEmitter')`.
|
|
||||||
*/
|
|
||||||
+ (NSDictionary *)config
|
|
||||||
{
|
|
||||||
return @{
|
|
||||||
@"Dimensions": @{
|
|
||||||
@"moduleID": @(RCTModuleIDDimensions),
|
|
||||||
@"methods": @{
|
|
||||||
@"set": @{
|
|
||||||
@"methodID": @(RCTDimensionsSet),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"RCTDeviceEventEmitter": @{
|
|
||||||
@"moduleID": @(RCTModuleIDDeviceEventEmitter),
|
|
||||||
@"methods": @{
|
|
||||||
@"emit": @{
|
|
||||||
@"methodID": @(RCTDeviceEventEmitterEmit),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"RCTEventEmitter": @{
|
|
||||||
@"moduleID": @(RCTModuleIDReactIOSEventEmitter),
|
|
||||||
@"methods": @{
|
|
||||||
@"receiveEvent": @{
|
|
||||||
@"methodID": @(RCTEventEmitterReceiveEvent),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
@"receiveTouches": @{
|
|
||||||
@"methodID": @(RCTEventEmitterReceiveTouches),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"RCTNativeAppEventEmitter": @{
|
|
||||||
@"moduleID": @(RCTModuleIDNativeAppEventEmitter),
|
|
||||||
@"methods": @{
|
|
||||||
@"emit": @{
|
|
||||||
@"methodID": @(RCTDeviceEventEmitterEmit),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"RCTJSTimers": @{
|
|
||||||
@"moduleID": @(RCTModuleIDJSTimers),
|
|
||||||
@"methods": @{
|
|
||||||
// Last argument is the callback.
|
|
||||||
@"callTimers": @{
|
|
||||||
@"methodID": @(RCTJSTimersCallTimers),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"ReactIOS": @{
|
|
||||||
@"moduleID": @(RCTModuleIDReactIOS),
|
|
||||||
@"methods": @{
|
|
||||||
@"unmountComponentAtNodeAndRemoveContainer": @{
|
|
||||||
@"methodID": @(RCTReactIOSUnmountComponentAtNodeAndRemoveContainer),
|
|
||||||
@"type": @"local"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@"Bundler": @{
|
|
||||||
@"moduleID": @(RCTModuleIDBundler),
|
|
||||||
@"methods": @{
|
|
||||||
@"runApplication": @{
|
|
||||||
@"methodID": @(RCTBundlerRunApplication),
|
|
||||||
@"type": @"local"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
#import "RCTContextExecutor.h"
|
#import "RCTContextExecutor.h"
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
#import "RCTJavaScriptAppEngine.h"
|
#import "RCTJavaScriptAppEngine.h"
|
||||||
#import "RCTModuleIDs.h"
|
|
||||||
#import "RCTTouchHandler.h"
|
#import "RCTTouchHandler.h"
|
||||||
#import "RCTUIManager.h"
|
#import "RCTUIManager.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "RCTViewManager.h"
|
#import "RCTViewManager.h"
|
||||||
|
#import "RCTWebViewExecutor.h"
|
||||||
#import "UIView+ReactKit.h"
|
#import "UIView+ReactKit.h"
|
||||||
#import "RCTKeyCommands.h"
|
#import "RCTKeyCommands.h"
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ NSString *const RCTRootViewReloadNotification = @"RCTRootViewReloadNotification"
|
||||||
RCTTouchHandler *_touchHandler;
|
RCTTouchHandler *_touchHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL _useWebExec;
|
||||||
|
|
||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -34,6 +36,13 @@ NSString *const RCTRootViewReloadNotification = @"RCTRootViewReloadNotification"
|
||||||
action:^(UIKeyCommand *command) {
|
action:^(UIKeyCommand *command) {
|
||||||
[self reloadAll];
|
[self reloadAll];
|
||||||
}];
|
}];
|
||||||
|
// Cmd-D reloads using the web view executor, allows attaching from Safari dev tools.
|
||||||
|
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"d"
|
||||||
|
modifierFlags:UIKeyModifierCommand
|
||||||
|
action:^(UIKeyCommand *command) {
|
||||||
|
_useWebExec = YES;
|
||||||
|
[self reloadAll];
|
||||||
|
}];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -98,8 +107,8 @@ NSString *const RCTRootViewReloadNotification = @"RCTRootViewReloadNotification"
|
||||||
@"rootTag": self.reactTag ?: @0,
|
@"rootTag": self.reactTag ?: @0,
|
||||||
@"initialProps": self.initialProperties ?: @{},
|
@"initialProps": self.initialProperties ?: @{},
|
||||||
};
|
};
|
||||||
[_bridge enqueueJSCall:RCTModuleIDBundler
|
|
||||||
methodID:RCTBundlerRunApplication
|
[_bridge enqueueJSCall:@"Bundler.runApplication"
|
||||||
args:@[moduleName, appParameters]];
|
args:@[moduleName, appParameters]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,9 +132,13 @@ NSString *const RCTRootViewReloadNotification = @"RCTRootViewReloadNotification"
|
||||||
[_executor invalidate];
|
[_executor invalidate];
|
||||||
[_bridge invalidate];
|
[_bridge invalidate];
|
||||||
|
|
||||||
|
if (!_useWebExec) {
|
||||||
_executor = [[RCTContextExecutor alloc] init];
|
_executor = [[RCTContextExecutor alloc] init];
|
||||||
_bridge = [[RCTBridge alloc] initWithJavaScriptExecutor:_executor
|
} else {
|
||||||
javaScriptModulesConfig:[RCTModuleIDs config]];
|
_executor = [[RCTWebViewExecutor alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
_bridge = [[RCTBridge alloc] initWithJavaScriptExecutor:_executor];
|
||||||
|
|
||||||
_appEngine = [[RCTJavaScriptAppEngine alloc] initWithBridge:_bridge];
|
_appEngine = [[RCTJavaScriptAppEngine alloc] initWithBridge:_bridge];
|
||||||
_touchHandler = [[RCTTouchHandler alloc] initWithEventDispatcher:_bridge.eventDispatcher rootView:self];
|
_touchHandler = [[RCTTouchHandler alloc] initWithEventDispatcher:_bridge.eventDispatcher rootView:self];
|
||||||
|
@ -165,22 +178,4 @@ NSString *const RCTRootViewReloadNotification = @"RCTRootViewReloadNotification"
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTRootViewReloadNotification object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTRootViewReloadNotification object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Key commands
|
|
||||||
|
|
||||||
- (NSArray *)keyCommands
|
|
||||||
{
|
|
||||||
return @[
|
|
||||||
|
|
||||||
// Reload
|
|
||||||
[UIKeyCommand keyCommandWithInput:@"r"
|
|
||||||
modifierFlags:UIKeyModifierCommand
|
|
||||||
action:@selector(reload)]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)canBecomeFirstResponder
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
|
|
||||||
@interface RCTSparseArray : NSObject <NSCopying>
|
@interface RCTSparseArray : NSObject <NSCopying>
|
||||||
|
|
||||||
- (instancetype)init;
|
- (instancetype)initWithCapacity:(NSUInteger)capacity NS_DESIGNATED_INITIALIZER;
|
||||||
- (instancetype)initWithCapacity:(NSUInteger)capacity;
|
- (instancetype)initWithSparseArray:(RCTSparseArray *)sparseArray NS_DESIGNATED_INITIALIZER;
|
||||||
- (instancetype)initWithSparseArray:(RCTSparseArray *)sparseArray;
|
|
||||||
|
|
||||||
+ (instancetype)sparseArray;
|
+ (instancetype)sparseArray;
|
||||||
+ (instancetype)sparseArrayWithCapacity:(NSUInteger)capacity;
|
+ (instancetype)sparseArrayWithCapacity:(NSUInteger)capacity;
|
||||||
|
|
|
@ -28,14 +28,6 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithStorage:(NSDictionary *)storage
|
|
||||||
{
|
|
||||||
if ((self = [super init])) {
|
|
||||||
_storage = [storage copy];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)sparseArray
|
+ (instancetype)sparseArray
|
||||||
{
|
{
|
||||||
return [[self alloc] init];
|
return [[self alloc] init];
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "UIView+ReactKit.h"
|
#import "UIView+ReactKit.h"
|
||||||
|
|
||||||
|
// TODO: this class behaves a lot like a module, and could be implemented as a
|
||||||
|
// module if we were to assume that modules and RootViews had a 1:1 relationship
|
||||||
|
|
||||||
@implementation RCTTouchHandler
|
@implementation RCTTouchHandler
|
||||||
{
|
{
|
||||||
__weak UIView *_rootView;
|
__weak UIView *_rootView;
|
||||||
|
@ -27,11 +30,6 @@
|
||||||
NSMutableArray *_touchViews;
|
NSMutableArray *_touchViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
|
||||||
{
|
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithTarget:(id)target action:(SEL)action
|
- (instancetype)initWithTarget:(id)target action:(SEL)action
|
||||||
{
|
{
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
|
|
|
@ -20,8 +20,9 @@ id RCTJSONParse(NSString *jsonString, NSError **error);
|
||||||
// Get MD5 hash of a string
|
// Get MD5 hash of a string
|
||||||
NSString *RCTMD5Hash(NSString *string);
|
NSString *RCTMD5Hash(NSString *string);
|
||||||
|
|
||||||
// Get screen scale in a thread-safe way
|
// Get screen metrics in a thread-safe way
|
||||||
CGFloat RCTScreenScale(void);
|
CGFloat RCTScreenScale(void);
|
||||||
|
CGSize RCTScreenSize(void);
|
||||||
|
|
||||||
// Round float coordinates to nearest whole screen pixel (not point)
|
// Round float coordinates to nearest whole screen pixel (not point)
|
||||||
CGFloat RCTRoundPixelValue(CGFloat value);
|
CGFloat RCTRoundPixelValue(CGFloat value);
|
||||||
|
@ -34,3 +35,7 @@ NSTimeInterval RCTTGetAbsoluteTime(void);
|
||||||
// Method swizzling
|
// Method swizzling
|
||||||
void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
|
void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
|
||||||
void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
|
void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
|
||||||
|
|
||||||
|
// Module subclass support
|
||||||
|
BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
|
||||||
|
BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
||||||
|
|
|
@ -35,7 +35,7 @@ NSString *RCTMD5Hash(NSString *string)
|
||||||
|
|
||||||
CGFloat RCTScreenScale()
|
CGFloat RCTScreenScale()
|
||||||
{
|
{
|
||||||
static CGFloat scale = -1;
|
static CGFloat scale;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
if (![NSThread isMainThread]) {
|
if (![NSThread isMainThread]) {
|
||||||
|
@ -50,6 +50,23 @@ CGFloat RCTScreenScale()
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGSize RCTScreenSize()
|
||||||
|
{
|
||||||
|
static CGSize size;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
if (![NSThread isMainThread]) {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
size = [UIScreen mainScreen].bounds.size;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
size = [UIScreen mainScreen].bounds.size;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
CGFloat RCTRoundPixelValue(CGFloat value)
|
CGFloat RCTRoundPixelValue(CGFloat value)
|
||||||
{
|
{
|
||||||
CGFloat scale = RCTScreenScale();
|
CGFloat scale = RCTScreenScale();
|
||||||
|
@ -120,3 +137,24 @@ void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement)
|
||||||
method_exchangeImplementations(originalMethod, replacementMethod);
|
method_exchangeImplementations(originalMethod, replacementMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL RCTClassOverridesClassMethod(Class cls, SEL selector)
|
||||||
|
{
|
||||||
|
return RCTClassOverridesInstanceMethod(object_getClass(cls), selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector)
|
||||||
|
{
|
||||||
|
unsigned int numberOfMethods;
|
||||||
|
Method *methods = class_copyMethodList(cls, &numberOfMethods);
|
||||||
|
for (unsigned int i = 0; i < numberOfMethods; i++)
|
||||||
|
{
|
||||||
|
if (method_getName(methods[i]) == selector)
|
||||||
|
{
|
||||||
|
free(methods);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,11 @@ static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)init
|
||||||
|
{
|
||||||
|
return [self initWithWebView:[[UIWebView alloc] init]];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)isValid
|
- (BOOL)isValid
|
||||||
{
|
{
|
||||||
return _webView != nil;
|
return _webView != nil;
|
||||||
|
@ -98,7 +103,13 @@ static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...)
|
||||||
sourceURL:(NSURL *)url
|
sourceURL:(NSURL *)url
|
||||||
onComplete:(RCTJavaScriptCompleteBlock)onComplete
|
onComplete:(RCTJavaScriptCompleteBlock)onComplete
|
||||||
{
|
{
|
||||||
RCTAssertMainThread();
|
if (![NSThread isMainThread]) {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
[self executeApplicationScript:script sourceURL:url onComplete:onComplete];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RCTAssert(onComplete != nil, @"");
|
RCTAssert(onComplete != nil, @"");
|
||||||
_onApplicationScriptLoaded = onComplete;
|
_onApplicationScriptLoaded = onComplete;
|
||||||
|
|
||||||
|
@ -137,26 +148,12 @@ static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...)
|
||||||
*/
|
*/
|
||||||
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block
|
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block
|
||||||
{
|
{
|
||||||
if (![NSThread isMainThread]) {
|
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_MSEC);
|
||||||
[self performSelectorOnMainThread:@selector(executeBlockOnJavaScriptQueue:)
|
|
||||||
withObject:block
|
|
||||||
waitUntilDone:YES];
|
|
||||||
} else {
|
|
||||||
[self performSelector:@selector(_onMainThreadExecuteBlockAfterDelay:)
|
|
||||||
withObject:block afterDelay:0.001 // This can't be zero!
|
|
||||||
inModes:@[NSDefaultRunLoopMode, UITrackingRunLoopMode]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
dispatch_after(when, dispatch_get_main_queue(), ^{
|
||||||
* This timing delay is needed to avoid crashes in WebKit when setting a
|
|
||||||
* breakpoint or `debugger` statement and debugging via the remote Safari
|
|
||||||
* inspector.
|
|
||||||
*/
|
|
||||||
- (void)_onMainThreadExecuteBlockAfterDelay:(dispatch_block_t)block
|
|
||||||
{
|
|
||||||
RCTAssertMainThread();
|
RCTAssertMainThread();
|
||||||
block();
|
block();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTModuleIDs.h"
|
|
||||||
#import "RCTSparseArray.h"
|
#import "RCTSparseArray.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
|
@ -55,6 +54,11 @@
|
||||||
id _updateTimer;
|
id _updateTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)JSMethods
|
||||||
|
{
|
||||||
|
return @[@"RCTJSTimers.callTimers"];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -143,7 +147,7 @@
|
||||||
|
|
||||||
// call timers that need to be called
|
// call timers that need to be called
|
||||||
if ([timersToCall count] > 0) {
|
if ([timersToCall count] > 0) {
|
||||||
[_bridge enqueueJSCall:RCTModuleIDJSTimers methodID:RCTJSTimersCallTimers args:@[timersToCall]];
|
[_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[timersToCall]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,14 +159,14 @@
|
||||||
* Date.now() from JS and then subtracting that from the current time here.
|
* Date.now() from JS and then subtracting that from the current time here.
|
||||||
*/
|
*/
|
||||||
- (void)createTimer:(NSNumber *)callbackID
|
- (void)createTimer:(NSNumber *)callbackID
|
||||||
duration:(NSNumber *)jsDuration
|
duration:(double)jsDuration
|
||||||
jsSchedulingTime:(NSNumber *)jsSchedulingTime
|
jsSchedulingTime:(double)jsSchedulingTime
|
||||||
repeats:(NSNumber *)repeats
|
repeats:(BOOL)repeats
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
RCT_EXPORT();
|
||||||
|
|
||||||
NSTimeInterval interval = jsDuration.doubleValue / 1000;
|
NSTimeInterval interval = jsDuration / 1000;
|
||||||
NSTimeInterval jsCreationTimeSinceUnixEpoch = jsSchedulingTime.doubleValue / 1000;
|
NSTimeInterval jsCreationTimeSinceUnixEpoch = jsSchedulingTime / 1000;
|
||||||
NSTimeInterval currentTimeSinceUnixEpoch = [[NSDate date] timeIntervalSince1970];
|
NSTimeInterval currentTimeSinceUnixEpoch = [[NSDate date] timeIntervalSince1970];
|
||||||
NSTimeInterval jsSchedulingOverhead = currentTimeSinceUnixEpoch - jsCreationTimeSinceUnixEpoch;
|
NSTimeInterval jsSchedulingOverhead = currentTimeSinceUnixEpoch - jsCreationTimeSinceUnixEpoch;
|
||||||
if (jsSchedulingOverhead < 0) {
|
if (jsSchedulingOverhead < 0) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
@protocol RCTScrollableProtocol;
|
@protocol RCTScrollableProtocol;
|
||||||
@protocol RCTViewNodeProtocol;
|
@protocol RCTViewNodeProtocol;
|
||||||
|
|
||||||
@interface RCTUIManager : NSObject <RCTInvalidating, RCTNativeModule>
|
@interface RCTUIManager : NSObject <RCTNativeModule, RCTInvalidating>
|
||||||
|
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
||||||
|
|
||||||
|
|
|
@ -34,26 +34,6 @@ static void RCTTraverseViewNodes(id<RCTViewNodeProtocol> view, react_view_node_b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSString *RCTModuleName(Class moduleClass)
|
|
||||||
{
|
|
||||||
if ([moduleClass respondsToSelector:@selector(moduleName)]) {
|
|
||||||
|
|
||||||
return [moduleClass moduleName];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Default implementation, works in most cases
|
|
||||||
NSString *className = NSStringFromClass(moduleClass);
|
|
||||||
if ([className hasPrefix:@"RCTUI"]) {
|
|
||||||
className = [className substringFromIndex:@"RCT".length];
|
|
||||||
}
|
|
||||||
if ([className hasSuffix:@"Manager"]) {
|
|
||||||
className = [className substringToIndex:className.length - @"Manager".length];
|
|
||||||
}
|
|
||||||
return className;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSDictionary *RCTViewModuleClasses(void)
|
static NSDictionary *RCTViewModuleClasses(void)
|
||||||
{
|
{
|
||||||
static NSMutableDictionary *modules;
|
static NSMutableDictionary *modules;
|
||||||
|
@ -78,7 +58,7 @@ static NSDictionary *RCTViewModuleClasses(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get module name
|
// Get module name
|
||||||
NSString *moduleName = RCTModuleName(cls);
|
NSString *moduleName = [cls respondsToSelector:@selector(moduleName)] ? [cls moduleName] : NSStringFromClass(cls);
|
||||||
|
|
||||||
// Check module name is unique
|
// Check module name is unique
|
||||||
id existingClass = modules[moduleName];
|
id existingClass = modules[moduleName];
|
||||||
|
@ -131,7 +111,7 @@ static NSDictionary *RCTViewModuleClasses(void)
|
||||||
// Instantiate view managers
|
// Instantiate view managers
|
||||||
NSMutableDictionary *viewManagers = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *viewManagers = [[NSMutableDictionary alloc] init];
|
||||||
[RCTViewModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *moduleName, Class moduleClass, BOOL *stop) {
|
[RCTViewModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *moduleName, Class moduleClass, BOOL *stop) {
|
||||||
viewManagers[moduleName] = [[moduleClass alloc] init];
|
viewManagers[moduleName] = [[moduleClass alloc] initWithEventDispatcher:_bridge.eventDispatcher];
|
||||||
}];
|
}];
|
||||||
_viewManagers = viewManagers;
|
_viewManagers = viewManagers;
|
||||||
|
|
||||||
|
@ -535,11 +515,6 @@ static NSDictionary *RCTViewModuleClasses(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView *)viewForViewManager:(id <RCTNativeViewModule>)manager
|
|
||||||
{
|
|
||||||
return [manager viewWithEventDispatcher:_bridge.eventDispatcher];
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL RCTCallPropertySetter(SEL setter, id value, id view, id defaultView, id <RCTNativeViewModule>manager)
|
static BOOL RCTCallPropertySetter(SEL setter, id value, id view, id defaultView, id <RCTNativeViewModule>manager)
|
||||||
{
|
{
|
||||||
// TODO: cache respondsToSelector tests
|
// TODO: cache respondsToSelector tests
|
||||||
|
@ -581,7 +556,9 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
|
|
||||||
if (obj == [NSNull null]) {
|
if (obj == [NSNull null]) {
|
||||||
// Copy property from default view to current
|
// Copy property from default view to current
|
||||||
RCTSetProperty(shadowView, key, [defaultView valueForKey:key]);
|
// Note: not just doing `[defaultView valueForKey:key]`, the
|
||||||
|
// key may not exist, in which case we'd get an exception.
|
||||||
|
RCTCopyProperty(shadowView, defaultView, key);
|
||||||
} else {
|
} else {
|
||||||
RCTSetProperty(shadowView, key, obj);
|
RCTSetProperty(shadowView, key, obj);
|
||||||
}
|
}
|
||||||
|
@ -619,10 +596,10 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
// Note the default is setup after the props are read for the first time ever
|
// Note the default is setup after the props are read for the first time ever
|
||||||
// for this className - this is ok because we only use the default for restoring
|
// for this className - this is ok because we only use the default for restoring
|
||||||
// defaults, which never happens on first creation.
|
// defaults, which never happens on first creation.
|
||||||
uiManager->_defaultViews[moduleName] = [uiManager viewForViewManager:manager];
|
uiManager->_defaultViews[moduleName] = [manager view];
|
||||||
}
|
}
|
||||||
|
|
||||||
UIView *view = [uiManager viewForViewManager:manager];
|
UIView *view = [manager view];
|
||||||
if (view) {
|
if (view) {
|
||||||
// Set required properties
|
// Set required properties
|
||||||
view.reactTag = reactTag;
|
view.reactTag = reactTag;
|
||||||
|
@ -1013,7 +990,7 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)allBubblingEventTypesConfigs
|
+ (NSDictionary *)allBubblingEventTypesConfigs
|
||||||
{
|
{
|
||||||
NSMutableDictionary *customBubblingEventTypesConfigs = [@{
|
NSMutableDictionary *customBubblingEventTypesConfigs = [@{
|
||||||
// Bubble dispatched events
|
// Bubble dispatched events
|
||||||
|
@ -1103,20 +1080,20 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
},
|
},
|
||||||
} mutableCopy];
|
} mutableCopy];
|
||||||
|
|
||||||
for (id <RCTNativeViewModule> viewManager in _viewManagers.allValues) {
|
[RCTViewModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *name, Class cls, BOOL *stop) {
|
||||||
NSDictionary *bubblingEvents = [viewManager respondsToSelector:@selector(customBubblingEventTypes)]? [viewManager customBubblingEventTypes] : nil;
|
if (RCTClassOverridesClassMethod(cls, @selector(customBubblingEventTypes))) {
|
||||||
if (bubblingEvents) {
|
NSDictionary *eventTypes = [cls customBubblingEventTypes];
|
||||||
for (NSString *eventName in bubblingEvents) {
|
for (NSString *eventName in eventTypes) {
|
||||||
RCTCAssert(!customBubblingEventTypesConfigs[eventName], @"Event %@ registered multiple times.", eventName);
|
RCTCAssert(!customBubblingEventTypesConfigs[eventName], @"Event '%@' registered multiple times.", eventName);
|
||||||
}
|
|
||||||
[customBubblingEventTypesConfigs addEntriesFromDictionary:bubblingEvents];
|
|
||||||
}
|
}
|
||||||
|
[customBubblingEventTypesConfigs addEntriesFromDictionary:eventTypes];
|
||||||
}
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
return customBubblingEventTypesConfigs;
|
return customBubblingEventTypesConfigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)allDirectEventTypesConfigs
|
+ (NSDictionary *)allDirectEventTypesConfigs
|
||||||
{
|
{
|
||||||
NSMutableDictionary *customDirectEventTypes = [@{
|
NSMutableDictionary *customDirectEventTypes = [@{
|
||||||
@"topScrollBeginDrag": @{
|
@"topScrollBeginDrag": @{
|
||||||
|
@ -1154,22 +1131,21 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
},
|
},
|
||||||
} mutableCopy];
|
} mutableCopy];
|
||||||
|
|
||||||
for (id <RCTNativeViewModule> viewManager in _viewManagers.allValues) {
|
[RCTViewModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *name, Class cls, BOOL *stop) {
|
||||||
NSDictionary *bubblingEvents = [viewManager respondsToSelector:@selector(customDirectEventTypes)] ? [viewManager customDirectEventTypes] : nil;
|
if (RCTClassOverridesClassMethod(cls, @selector(customDirectEventTypes))) {
|
||||||
if (bubblingEvents) {
|
NSDictionary *eventTypes = [cls customDirectEventTypes];
|
||||||
for (NSString *eventName in bubblingEvents) {
|
for (NSString *eventName in eventTypes) {
|
||||||
RCTCAssert(!customDirectEventTypes[eventName], @"Event %@ registered multiple times.", eventName);
|
RCTCAssert(!customDirectEventTypes[eventName], @"Event '%@' registered multiple times.", eventName);
|
||||||
}
|
|
||||||
[customDirectEventTypes addEntriesFromDictionary:bubblingEvents];
|
|
||||||
}
|
}
|
||||||
|
[customDirectEventTypes addEntriesFromDictionary:eventTypes];
|
||||||
}
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
return customDirectEventTypes;
|
return customDirectEventTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)constantsToExport
|
+ (NSDictionary *)constantsToExport
|
||||||
{
|
{
|
||||||
UIScreen *screen = [UIScreen mainScreen];
|
|
||||||
NSMutableDictionary *allJSConstants = [@{
|
NSMutableDictionary *allJSConstants = [@{
|
||||||
@"customBubblingEventTypes": [self allBubblingEventTypesConfigs],
|
@"customBubblingEventTypes": [self allBubblingEventTypesConfigs],
|
||||||
@"customDirectEventTypes": [self allDirectEventTypesConfigs],
|
@"customDirectEventTypes": [self allDirectEventTypesConfigs],
|
||||||
|
@ -1180,13 +1156,13 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
},
|
},
|
||||||
@"Dimensions": @{
|
@"Dimensions": @{
|
||||||
@"window": @{
|
@"window": @{
|
||||||
@"width": @(screen.bounds.size.width),
|
@"width": @(RCTScreenSize().width),
|
||||||
@"height": @(screen.bounds.size.height),
|
@"height": @(RCTScreenSize().height),
|
||||||
@"scale": @(screen.scale),
|
@"scale": @(RCTScreenScale()),
|
||||||
},
|
},
|
||||||
@"modalFullscreenView": @{
|
@"modalFullscreenView": @{
|
||||||
@"width": @(screen.bounds.size.width),
|
@"width": @(RCTScreenSize().width),
|
||||||
@"height": @(screen.bounds.size.height),
|
@"height": @(RCTScreenSize().width),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@"StyleConstants": @{
|
@"StyleConstants": @{
|
||||||
|
@ -1224,12 +1200,15 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
},
|
},
|
||||||
} mutableCopy];
|
} mutableCopy];
|
||||||
|
|
||||||
[_viewManagers enumerateKeysAndObjectsUsingBlock:^(NSString *name, id <RCTNativeViewModule> viewManager, BOOL *stop) {
|
[RCTViewModuleClasses() enumerateKeysAndObjectsUsingBlock:^(NSString *name, Class cls, BOOL *stop) {
|
||||||
NSDictionary *constants = [viewManager respondsToSelector:@selector(constantsToExport)] ? [viewManager constantsToExport] : nil;
|
// TODO: should these be inherited?
|
||||||
if (constants) {
|
NSDictionary *constants = RCTClassOverridesClassMethod(cls, @selector(constantsToExport)) ? [cls constantsToExport] : nil;
|
||||||
RCTAssert(allJSConstants[name] == nil , @"Cannot redefine constant namespace: %@", name);
|
if ([constants count]) {
|
||||||
|
NSMutableDictionary *namespace = [NSMutableDictionary dictionaryWithDictionary:allJSConstants[name]];
|
||||||
|
RCTAssert(namespace[@"Constants"] == nil , @"Cannot redefine Constants in namespace: %@", name);
|
||||||
// add an additional 'Constants' namespace for each class
|
// add an additional 'Constants' namespace for each class
|
||||||
allJSConstants[name] = @{@"Constants": constants};
|
namespace[@"Constants"] = constants;
|
||||||
|
allJSConstants[name] = [namespace copy];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */; };
|
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */; };
|
||||||
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
|
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
|
||||||
83CBBA871A60202500E9B192 /* RCTJavaScriptAppEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA861A60202500E9B192 /* RCTJavaScriptAppEngine.m */; };
|
83CBBA871A60202500E9B192 /* RCTJavaScriptAppEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA861A60202500E9B192 /* RCTJavaScriptAppEngine.m */; };
|
||||||
83CBBA8B1A60204600E9B192 /* RCTModuleIDs.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA8A1A60204600E9B192 /* RCTModuleIDs.m */; };
|
|
||||||
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
|
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
|
||||||
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
|
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
|
||||||
83EEC2EE1A604AB200C39218 /* RCTModuleMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 83EEC2ED1A604AB200C39218 /* RCTModuleMethod.m */; };
|
83EEC2EE1A604AB200C39218 /* RCTModuleMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 83EEC2ED1A604AB200C39218 /* RCTModuleMethod.m */; };
|
||||||
|
@ -162,8 +161,6 @@
|
||||||
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventDispatcher.m; sourceTree = "<group>"; };
|
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventDispatcher.m; sourceTree = "<group>"; };
|
||||||
83CBBA851A60202500E9B192 /* RCTJavaScriptAppEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptAppEngine.h; sourceTree = "<group>"; };
|
83CBBA851A60202500E9B192 /* RCTJavaScriptAppEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptAppEngine.h; sourceTree = "<group>"; };
|
||||||
83CBBA861A60202500E9B192 /* RCTJavaScriptAppEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJavaScriptAppEngine.m; sourceTree = "<group>"; };
|
83CBBA861A60202500E9B192 /* RCTJavaScriptAppEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJavaScriptAppEngine.m; sourceTree = "<group>"; };
|
||||||
83CBBA891A60204600E9B192 /* RCTModuleIDs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTModuleIDs.h; sourceTree = "<group>"; };
|
|
||||||
83CBBA8A1A60204600E9B192 /* RCTModuleIDs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleIDs.m; sourceTree = "<group>"; };
|
|
||||||
83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTouchHandler.h; sourceTree = "<group>"; };
|
83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTouchHandler.h; sourceTree = "<group>"; };
|
||||||
83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchHandler.m; sourceTree = "<group>"; };
|
83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchHandler.m; sourceTree = "<group>"; };
|
||||||
83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = "<group>"; };
|
83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = "<group>"; };
|
||||||
|
@ -329,8 +326,6 @@
|
||||||
83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */,
|
83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */,
|
||||||
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,
|
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,
|
||||||
83CBBA4E1A601E3B00E9B192 /* RCTLog.m */,
|
83CBBA4E1A601E3B00E9B192 /* RCTLog.m */,
|
||||||
83CBBA891A60204600E9B192 /* RCTModuleIDs.h */,
|
|
||||||
83CBBA8A1A60204600E9B192 /* RCTModuleIDs.m */,
|
|
||||||
83CBBA581A601E9000E9B192 /* RCTRedBox.h */,
|
83CBBA581A601E9000E9B192 /* RCTRedBox.h */,
|
||||||
83CBBA591A601E9000E9B192 /* RCTRedBox.m */,
|
83CBBA591A601E9000E9B192 /* RCTRedBox.m */,
|
||||||
83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */,
|
83CBBA961A6020BB00E9B192 /* RCTTouchHandler.h */,
|
||||||
|
@ -439,7 +434,6 @@
|
||||||
13E067591A70F44B002CDEE1 /* UIView+ReactKit.m in Sources */,
|
13E067591A70F44B002CDEE1 /* UIView+ReactKit.m in Sources */,
|
||||||
137029531A69923600575408 /* RCTImageDownloader.m in Sources */,
|
137029531A69923600575408 /* RCTImageDownloader.m in Sources */,
|
||||||
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */,
|
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */,
|
||||||
83CBBA8B1A60204600E9B192 /* RCTModuleIDs.m in Sources */,
|
|
||||||
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */,
|
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */,
|
||||||
13B080071A6947C200A75B9A /* RCTShadowRawText.m in Sources */,
|
13B080071A6947C200A75B9A /* RCTShadowRawText.m in Sources */,
|
||||||
13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */,
|
13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */,
|
||||||
|
@ -555,6 +549,7 @@
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
OTHER_LDFLAGS = "-ObjC";
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
@ -564,6 +559,7 @@
|
||||||
83CBBA411A601D0F00E9B192 /* Release */ = {
|
83CBBA411A601D0F00E9B192 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
OTHER_LDFLAGS = "-ObjC";
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
@implementation RCTNavItemManager
|
@implementation RCTNavItemManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTNavItem alloc] initWithFrame:CGRectZero];
|
return [[RCTNavItem alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(title)
|
RCT_EXPORT_VIEW_PROPERTY(title)
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
@property (nonatomic, strong) UIView *reactNavSuperviewLink;
|
@property (nonatomic, strong) UIView *reactNavSuperviewLink;
|
||||||
@property (nonatomic, assign) NSInteger requestedTopOfStack;
|
@property (nonatomic, assign) NSInteger requestedTopOfStack;
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
||||||
eventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a JavaScript navigation and prevents `UIKit` from navigating until
|
* Schedules a JavaScript navigation and prevents `UIKit` from navigating until
|
||||||
|
|
|
@ -126,7 +126,17 @@ NSInteger kNeverProgressed = -10000;
|
||||||
*/
|
*/
|
||||||
@implementation RCTNavigationController
|
@implementation RCTNavigationController
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||||
|
{
|
||||||
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
|
||||||
|
{
|
||||||
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController
|
||||||
{
|
{
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
}
|
}
|
||||||
|
@ -137,7 +147,7 @@ NSInteger kNeverProgressed = -10000;
|
||||||
*/
|
*/
|
||||||
- (instancetype)initWithScrollCallback:(dispatch_block_t)callback
|
- (instancetype)initWithScrollCallback:(dispatch_block_t)callback
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super initWithNibName:nil bundle:nil])) {
|
||||||
_scrollCallback = callback;
|
_scrollCallback = callback;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -265,11 +275,14 @@ NSInteger kNeverProgressed = -10000;
|
||||||
|
|
||||||
@implementation RCTNavigator
|
@implementation RCTNavigator
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)frame
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
eventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:frame];
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
if (self) {
|
}
|
||||||
|
|
||||||
|
- (id)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
||||||
|
{
|
||||||
|
if ((self = [super initWithFrame:CGRectZero])) {
|
||||||
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(reportNavigationProgress:)];
|
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(reportNavigationProgress:)];
|
||||||
_mostRecentProgress = kNeverProgressed;
|
_mostRecentProgress = kNeverProgressed;
|
||||||
_dummyView = [[UIView alloc] initWithFrame:CGRectZero];
|
_dummyView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
|
@ -311,24 +324,15 @@ NSInteger kNeverProgressed = -10000;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_mostRecentProgress = nextProgress;
|
_mostRecentProgress = nextProgress;
|
||||||
[_eventDispatcher sendRawEventWithType:@"topNavigationProgress"
|
[_eventDispatcher sendEventWithName:@"topNavigationProgress" body:@{
|
||||||
body:@{@"fromIndex": @(_currentlyTransitioningFrom),
|
@"fromIndex": @(_currentlyTransitioningFrom),
|
||||||
@"toIndex": @(_currentlyTransitioningTo),
|
@"toIndex": @(_currentlyTransitioningTo),
|
||||||
@"progress": @(nextProgress),
|
@"progress": @(nextProgress),
|
||||||
@"target": self.reactTag}];
|
@"target": self.reactTag
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame
|
|
||||||
{
|
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init
|
|
||||||
{
|
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
_navigationController.delegate = nil;
|
_navigationController.delegate = nil;
|
||||||
|
@ -438,9 +442,10 @@ NSInteger kNeverProgressed = -10000;
|
||||||
|
|
||||||
- (void)handleTopOfStackChanged
|
- (void)handleTopOfStackChanged
|
||||||
{
|
{
|
||||||
[_eventDispatcher sendRawEventWithType:@"topNavigateBack"
|
[_eventDispatcher sendEventWithName:@"topNavigateBack" body:@{
|
||||||
body:@{@"target":self.reactTag,
|
@"target":self.reactTag,
|
||||||
@"stackLength":@(_navigationController.viewControllers.count)}];
|
@"stackLength":@(_navigationController.viewControllers.count)
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dispatchFakeScrollEvent
|
- (void)dispatchFakeScrollEvent
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
@implementation RCTNavigatorManager
|
@implementation RCTNavigatorManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTNavigator alloc] initWithFrame:CGRectZero eventDispatcher:eventDispatcher];
|
return [[RCTNavigator alloc] initWithEventDispatcher:self.eventDispatcher];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack)
|
RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#import "RCTImageDownloader.h"
|
#import "RCTImageDownloader.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
|
#import "RCTConvert.h"
|
||||||
|
|
||||||
@implementation RCTNetworkImageView
|
@implementation RCTNetworkImageView
|
||||||
{
|
{
|
||||||
|
@ -52,6 +53,19 @@
|
||||||
self.layer.contentsScale = _defaultImage.scale;
|
self.layer.contentsScale = _defaultImage.scale;
|
||||||
self.layer.contents = (__bridge id)_defaultImage.CGImage;
|
self.layer.contents = (__bridge id)_defaultImage.CGImage;
|
||||||
}
|
}
|
||||||
|
if ([imageURL.pathExtension caseInsensitiveCompare:@"gif"] == NSOrderedSame) {
|
||||||
|
_downloadToken = [_imageDownloader downloadDataForURL:imageURL block:^(NSData *data, NSError *error) {
|
||||||
|
if (data) {
|
||||||
|
CAKeyframeAnimation *animation = [RCTConvert GIF:data];
|
||||||
|
CGImageRef firstFrame = (__bridge CGImageRef)animation.values.firstObject;
|
||||||
|
self.layer.bounds = CGRectMake(0, 0, CGImageGetWidth(firstFrame), CGImageGetHeight(firstFrame));
|
||||||
|
self.layer.contentsScale = 1.0;
|
||||||
|
self.layer.contentsGravity = kCAGravityResizeAspect;
|
||||||
|
[self.layer addAnimation:animation forKey:@"contents"];
|
||||||
|
}
|
||||||
|
// TODO: handle errors
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
_downloadToken = [_imageDownloader downloadImageForURL:imageURL size:self.bounds.size scale:RCTScreenScale() block:^(UIImage *image, NSError *error) {
|
_downloadToken = [_imageDownloader downloadImageForURL:imageURL size:self.bounds.size scale:RCTScreenScale() block:^(UIImage *image, NSError *error) {
|
||||||
if (image) {
|
if (image) {
|
||||||
self.layer.contentsScale = image.scale;
|
self.layer.contentsScale = image.scale;
|
||||||
|
@ -61,6 +75,7 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setImageURL:(NSURL *)imageURL
|
- (void)setImageURL:(NSURL *)imageURL
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
@implementation RCTNetworkImageViewManager
|
@implementation RCTNetworkImageViewManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
RCTNetworkImageView *view = [[RCTNetworkImageView alloc] initWithFrame:CGRectZero imageDownloader:[RCTImageDownloader sharedInstance]];
|
RCTNetworkImageView *view = [[RCTNetworkImageView alloc] initWithFrame:CGRectZero imageDownloader:[RCTImageDownloader sharedInstance]];
|
||||||
view.contentMode = UIViewContentModeScaleAspectFill;
|
view.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
@implementation RCTRawTextManager
|
@implementation RCTRawTextManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[UIView alloc] init];
|
return [[UIView alloc] init];
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,6 @@
|
||||||
@property (nonatomic, assign) BOOL centerContent;
|
@property (nonatomic, assign) BOOL centerContent;
|
||||||
@property (nonatomic, copy) NSArray *stickyHeaderIndices;
|
@property (nonatomic, copy) NSArray *stickyHeaderIndices;
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame eventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTUIManager.h"
|
#import "RCTUIManager.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
#import "UIView+ReactKit.h"
|
#import "UIView+ReactKit.h"
|
||||||
|
|
||||||
CGFloat const ZINDEX_DEFAULT = 0;
|
CGFloat const ZINDEX_DEFAULT = 0;
|
||||||
|
@ -122,6 +123,7 @@ CGFloat const ZINDEX_STICKY_HEADER = 50;
|
||||||
*/
|
*/
|
||||||
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
|
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
|
||||||
{
|
{
|
||||||
|
//TODO: shouldn't this call super if _shouldDisableScrollInteraction returns NO?
|
||||||
return ![self _shouldDisableScrollInteraction];
|
return ![self _shouldDisableScrollInteraction];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,9 +262,14 @@ CGFloat const ZINDEX_STICKY_HEADER = 50;
|
||||||
|
|
||||||
@synthesize nativeMainScrollDelegate = _nativeMainScrollDelegate;
|
@synthesize nativeMainScrollDelegate = _nativeMainScrollDelegate;
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame eventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
||||||
|
{
|
||||||
|
if ((self = [super initWithFrame:CGRectZero])) {
|
||||||
|
|
||||||
_eventDispatcher = eventDispatcher;
|
_eventDispatcher = eventDispatcher;
|
||||||
_scrollView = [[RCTCustomScrollView alloc] initWithFrame:CGRectZero];
|
_scrollView = [[RCTCustomScrollView alloc] initWithFrame:CGRectZero];
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
@implementation RCTScrollViewManager
|
@implementation RCTScrollViewManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTScrollView alloc] initWithFrame:CGRectZero eventDispatcher:eventDispatcher];
|
return [[RCTScrollView alloc] initWithEventDispatcher:self.eventDispatcher];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(alwaysBounceHorizontal)
|
RCT_EXPORT_VIEW_PROPERTY(alwaysBounceHorizontal)
|
||||||
|
@ -36,7 +36,7 @@ RCT_EXPORT_VIEW_PROPERTY(contentInset);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets);
|
RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(contentOffset);
|
RCT_EXPORT_VIEW_PROPERTY(contentOffset);
|
||||||
|
|
||||||
- (NSDictionary *)constantsToExport
|
+ (NSDictionary *)constantsToExport
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
@{
|
@{
|
||||||
|
|
|
@ -9,14 +9,26 @@
|
||||||
|
|
||||||
@implementation RCTStaticImageManager
|
@implementation RCTStaticImageManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTStaticImage alloc] init];
|
return [[RCTStaticImage alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_REMAP_VIEW_PROPERTY(src, image)
|
|
||||||
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode)
|
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode)
|
||||||
|
|
||||||
|
- (void)set_src:(id)json forView:(RCTStaticImage *)view withDefaultView:(RCTStaticImage *)defaultView
|
||||||
|
{
|
||||||
|
if (json) {
|
||||||
|
if ([json isKindOfClass:[NSString class]] && [[json pathExtension] caseInsensitiveCompare:@"gif"] == NSOrderedSame) {
|
||||||
|
[view.layer addAnimation:[RCTConvert GIF:json] forKey:@"contents"];
|
||||||
|
} else {
|
||||||
|
view.image = [RCTConvert UIImage:json];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view.image = defaultView.image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)set_capInsets:(id)json forView:(RCTStaticImage *)view withDefaultView:(RCTStaticImage *)defaultView
|
- (void)set_capInsets:(id)json forView:(RCTStaticImage *)view withDefaultView:(RCTStaticImage *)defaultView
|
||||||
{
|
{
|
||||||
view.capInsets = json ? [RCTConvert UIEdgeInsets:json] : defaultView.capInsets;
|
view.capInsets = json ? [RCTConvert UIEdgeInsets:json] : defaultView.capInsets;
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
@property (nonatomic, assign) BOOL autoCorrect;
|
@property (nonatomic, assign) BOOL autoCorrect;
|
||||||
@property (nonatomic, assign) UIEdgeInsets paddingEdgeInsets; // TODO: contentInset
|
@property (nonatomic, assign) UIEdgeInsets paddingEdgeInsets; // TODO: contentInset
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame eventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
BOOL _jsRequestingFirstResponder;
|
BOOL _jsRequestingFirstResponder;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
RCT_NOT_DESIGNATED_INITIALIZER();
|
RCT_NOT_DESIGNATED_INITIALIZER();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame eventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frame])) {
|
if ((self = [super initWithFrame:CGRectZero])) {
|
||||||
|
|
||||||
_eventDispatcher = eventDispatcher;
|
_eventDispatcher = eventDispatcher;
|
||||||
[self addTarget:self action:@selector(_textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
|
[self addTarget:self action:@selector(_textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
@implementation RCTTextFieldManager
|
@implementation RCTTextFieldManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTTextField alloc] initWithFrame:CGRectZero eventDispatcher:eventDispatcher];
|
return [[RCTTextField alloc] initWithEventDispatcher:self.eventDispatcher];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(caretHidden)
|
RCT_EXPORT_VIEW_PROPERTY(caretHidden)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
@implementation RCTTextManager
|
@implementation RCTTextManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
UILabel *label = [[UILabel alloc] init];
|
UILabel *label = [[UILabel alloc] init];
|
||||||
label.numberOfLines = 0;
|
label.numberOfLines = 0;
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
@implementation RCTUIActivityIndicatorViewManager
|
@implementation RCTUIActivityIndicatorViewManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
|
return [[UIActivityIndicatorView alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(activityIndicatorViewStyle)
|
RCT_EXPORT_VIEW_PROPERTY(activityIndicatorViewStyle)
|
||||||
|
@ -28,7 +28,7 @@ RCT_EXPORT_VIEW_PROPERTY(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)constantsToExport
|
+ (NSDictionary *)constantsToExport
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
@{
|
@{
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
#import "RCTExport.h"
|
#import "RCTExport.h"
|
||||||
|
|
||||||
|
@class RCTEventDispatcher;
|
||||||
|
|
||||||
@interface RCTUIViewManager : NSObject <RCTNativeViewModule>
|
@interface RCTUIViewManager : NSObject <RCTNativeViewModule>
|
||||||
|
|
||||||
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
@property (nonatomic, readonly) RCTEventDispatcher *eventDispatcher;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -3,13 +3,38 @@
|
||||||
#import "RCTUIViewManager.h"
|
#import "RCTUIViewManager.h"
|
||||||
|
|
||||||
#import "RCTConvert.h"
|
#import "RCTConvert.h"
|
||||||
|
#import "RCTEventDispatcher.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTShadowView.h"
|
#import "RCTShadowView.h"
|
||||||
#import "RCTView.h"
|
#import "RCTView.h"
|
||||||
|
|
||||||
@implementation RCTUIViewManager
|
@implementation RCTUIViewManager
|
||||||
|
{
|
||||||
|
__weak RCTEventDispatcher *_eventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
||||||
|
{
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_eventDispatcher = eventDispatcher;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)moduleName
|
||||||
|
{
|
||||||
|
// Default implementation, works in most cases
|
||||||
|
NSString *name = NSStringFromClass(self);
|
||||||
|
if ([name hasPrefix:@"RCTUI"]) {
|
||||||
|
name = [name substringFromIndex:@"RCT".length];
|
||||||
|
}
|
||||||
|
if ([name hasSuffix:@"Manager"]) {
|
||||||
|
name = [name substringToIndex:name.length - @"Manager".length];
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[UIView alloc] init];
|
return [[UIView alloc] init];
|
||||||
}
|
}
|
||||||
|
@ -29,7 +54,7 @@ RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius)
|
||||||
RCT_REMAP_VIEW_PROPERTY(borderColor, layer.borderColor);
|
RCT_REMAP_VIEW_PROPERTY(borderColor, layer.borderColor);
|
||||||
RCT_REMAP_VIEW_PROPERTY(borderRadius, layer.cornerRadius)
|
RCT_REMAP_VIEW_PROPERTY(borderRadius, layer.cornerRadius)
|
||||||
RCT_REMAP_VIEW_PROPERTY(borderWidth, layer.borderWidth)
|
RCT_REMAP_VIEW_PROPERTY(borderWidth, layer.borderWidth)
|
||||||
RCT_REMAP_VIEW_PROPERTY(transformMatrix, view.layer.transform)
|
RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform)
|
||||||
|
|
||||||
- (void)set_overflow:(id)json
|
- (void)set_overflow:(id)json
|
||||||
forView:(UIView *)view
|
forView:(UIView *)view
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
|
|
||||||
@implementation RCTViewManager
|
@implementation RCTViewManager
|
||||||
|
|
||||||
- (UIView *)viewWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTView alloc] init];
|
return [[RCTView alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel)
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(pointerEvents)
|
RCT_EXPORT_VIEW_PROPERTY(pointerEvents)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
|
|
||||||
- (void)rightButtonTapped
|
- (void)rightButtonTapped
|
||||||
{
|
{
|
||||||
[_eventDispatcher sendRawEventWithType:@"topNavRightButtonTap" body:@{@"target":_navItem.reactTag}];
|
[_eventDispatcher sendEventWithName:@"topNavRightButtonTap" body:@{@"target":_navItem.reactTag}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didMoveToParentViewController:(UIViewController *)parent
|
- (void)didMoveToParentViewController:(UIViewController *)parent
|
||||||
|
|
Loading…
Reference in New Issue