Updates from Mon Feb 22

- [ReactNative] remove docs and website from fbobjc and improve oss_export | Spencer Ahrens
- [ReactNative] Bring back ReactKit proj files | Spencer Ahrens
- [React-Native] Update jstransform/esprima | Christoph Pojer
This commit is contained in:
Christopher Chedeau 2015-02-25 12:36:51 -08:00
parent 72ed849e35
commit 1f8740a9f8
14 changed files with 82 additions and 192 deletions

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:UIExplorer.xcodeproj">
</FileRef>
</Workspace>

View File

@ -4,7 +4,6 @@
#import "RCTInvalidating.h"
#import "RCTJavaScriptExecutor.h"
@class RCTBridge;
@class RCTEventDispatcher;
@class RCTRootView;
@ -27,12 +26,6 @@ static inline NSDictionary *RCTAPIErrorObject(NSString *msg)
return @{@"apiError": msg ?: @""};
}
/**
* This block can be used to instantiate modules that require additional
* init parameters, or additional configuration prior to being used.
*/
typedef NSArray *(^RCTBridgeModuleProviderBlock)(RCTBridge *bridge);
/**
* Async batched bridge used to communicate with the JavaScript application.
*/
@ -41,13 +34,11 @@ typedef NSArray *(^RCTBridgeModuleProviderBlock)(RCTBridge *bridge);
/**
* The designated initializer. This creates a new bridge on top of the specified
* executor. The bridge should then be used for all subsequent communication
* with the JavaScript code running in the executor. Modules will be automatically
* instantiated using the default contructor, but you can optionally pass in a
* module provider block to manually instantiate modules that require additional
* init parameters or configuration.
* with the JavaScript code running in the executor. You can optionally pass in
* a list of module instances to be used instead of the auto-instantiated versions.
*/
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
moduleProvider:(RCTBridgeModuleProviderBlock)block NS_DESIGNATED_INITIALIZER;
moduleInstances:(NSArray *)moduleInstances NS_DESIGNATED_INITIALIZER;
/**
* This method is used to call functions in the JavaScript application context.
@ -69,11 +60,6 @@ typedef NSArray *(^RCTBridgeModuleProviderBlock)(RCTBridge *bridge);
*/
@property (nonatomic, readonly) RCTEventDispatcher *eventDispatcher;
/**
* A dictionary of all registered RCTBridgeModule instances, keyed by moduleName.
*/
@property (nonatomic, copy, readonly) NSDictionary *modules;
/**
* The shadow queue is used to execute callbacks from the JavaScript code. All
* native hooks (e.g. exported module methods) will be executed on the shadow

View File

@ -9,6 +9,7 @@
#import <objc/runtime.h>
#import "RCTConvert.h"
#import "RCTInvalidating.h"
#import "RCTEventDispatcher.h"
#import "RCTLog.h"
#import "RCTSparseArray.h"
@ -100,40 +101,6 @@ static id<RCTBridgeModule> RCTCreateModuleInstance(Class cls, RCTBridge *bridge)
}
}
/**
* This function scans all classes available at runtime and returns an array
* of all JSMethods registered.
*/
static NSArray *RCTJSMethods(void)
{
static NSArray *JSMethods;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSMutableSet *uniqueMethods = [NSMutableSet set];
unsigned int classCount;
Class *classes = objc_copyClassList(&classCount);
for (unsigned int i = 0; i < classCount; i++) {
Class cls = classes[i];
if (!class_getSuperclass(cls)) {
// Class has no superclass - it's probably something weird
continue;
}
if (RCTClassOverridesClassMethod(cls, @selector(JSMethods))) {
[uniqueMethods addObjectsFromArray:[cls JSMethods]];
}
}
free(classes);
JSMethods = [uniqueMethods allObjects];
});
return JSMethods;
}
/**
* This function scans all classes available at runtime and returns an array
* of all classes that implement the RTCBridgeModule protocol.
@ -297,7 +264,7 @@ static NSDictionary *RCTRemoteModulesConfig(NSDictionary *modulesByName)
NSArray *methods = RCTExportedMethodsByModuleID()[moduleID];
NSMutableDictionary *methodsByName = [NSMutableDictionary dictionaryWithCapacity:methods.count];
[methods enumerateObjectsUsingBlock:^(RCTModuleMethod *method, NSUInteger methodID, BOOL *_stop) {
[methods enumerateObjectsUsingBlock:^(RCTModuleMethod *method, NSUInteger methodID, BOOL *stop) {
methodsByName[method.JSMethodName] = @{
@"methodID": @(methodID),
@"type": @"remote",
@ -368,16 +335,38 @@ static NSDictionary *RCTLocalModulesConfig()
static NSMutableDictionary *localModules;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTLocalModuleIDs = [[NSMutableDictionary alloc] init];
RCTLocalMethodIDs = [[NSMutableDictionary alloc] init];
NSMutableArray *JSMethods = [[NSMutableArray alloc] init];
// Add globally used methods
[JSMethods addObjectsFromArray:@[
@"AppRegistry.runApplication",
@"RCTDeviceEventEmitter.emit",
@"RCTEventEmitter.receiveEvent",
@"RCTEventEmitter.receiveTouches",
]];
// NOTE: these methods are currently unused in the OSS project
// @"Dimensions.set",
// @"RCTNativeAppEventEmitter.emit",
// @"ReactIOS.unmountComponentAtNodeAndRemoveContainer",
// Register individual methods from modules
for (Class cls in RCTBridgeModuleClassesByModuleID()) {
if (RCTClassOverridesClassMethod(cls, @selector(JSMethods))) {
[JSMethods addObjectsFromArray:[cls JSMethods]];
}
}
localModules = [[NSMutableDictionary alloc] init];
for (NSString *moduleDotMethod in RCTJSMethods()) {
for (NSString *moduleDotMethod in JSMethods) {
NSArray *parts = [moduleDotMethod componentsSeparatedByString:@"."];
RCTCAssert(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];
@ -388,7 +377,7 @@ static NSDictionary *RCTLocalModulesConfig()
};
localModules[moduleName] = module;
}
// Add method if it doesn't already exist
NSString *methodName = parts[1];
NSMutableDictionary *methods = module[@"methods"];
@ -398,27 +387,27 @@ static NSDictionary *RCTLocalModulesConfig()
@"type": @"local"
};
}
// Add module and method lookup
RCTLocalModuleIDs[moduleDotMethod] = module[@"moduleID"];
RCTLocalMethodIDs[moduleDotMethod] = methods[methodName][@"methodID"];
}
});
return localModules;
}
@implementation RCTBridge
{
RCTSparseArray *_modulesByID;
NSDictionary *_modulesByName;
NSMutableDictionary *_modulesByName;
id<RCTJavaScriptExecutor> _javaScriptExecutor;
}
static id<RCTJavaScriptExecutor> _latestJSExecutor;
- (instancetype)initWithJavaScriptExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
moduleProvider:(RCTBridgeModuleProviderBlock)block
moduleInstances:(NSArray *)moduleInstances
{
if ((self = [super init])) {
_javaScriptExecutor = javaScriptExecutor;
@ -428,39 +417,31 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
// Register passed-in module instances
NSMutableDictionary *preregisteredModules = [[NSMutableDictionary alloc] init];
if (block) {
for (id<RCTBridgeModule> module in block(self)) {
preregisteredModules[RCTModuleNameForClass([module class])] = module;
}
for (id<RCTBridgeModule> module in moduleInstances) {
preregisteredModules[RCTModuleNameForClass([module class])] = module;
}
// Instantiate modules
_modulesByID = [[RCTSparseArray alloc] init];
NSMutableDictionary *modulesByName = [preregisteredModules mutableCopy];
_modulesByName = [[NSMutableDictionary alloc] initWithDictionary:preregisteredModules];
[RCTBridgeModuleClassesByModuleID() enumerateObjectsUsingBlock:^(Class moduleClass, NSUInteger moduleID, BOOL *stop) {
NSString *moduleName = RCTModuleNamesByID[moduleID];
// Check if module instance has already been registered for this name
if ((_modulesByID[moduleID] = modulesByName[moduleName])) {
if (_modulesByName[moduleName] != nil) {
// Preregistered instances takes precedence, no questions asked
if (!preregisteredModules[moduleName]) {
// It's OK to have a name collision as long as the second instance is nil
RCTAssert(RCTCreateModuleInstance(moduleClass, self) == nil,
@"Attempted to register RCTBridgeModule class %@ for the name '%@', \
but name was already registered by class %@", moduleClass,
moduleName, [modulesByName[moduleName] class]);
moduleName, [_modulesByName[moduleName] class]);
}
} else {
// Module name hasn't been used before, so go ahead and instantiate
id<RCTBridgeModule> module = RCTCreateModuleInstance(moduleClass, self);
if (module) {
_modulesByID[moduleID] = modulesByName[moduleName] = module;
}
_modulesByID[moduleID] = _modulesByName[moduleName] = RCTCreateModuleInstance(moduleClass, self);
}
}];
// Store modules
_modulesByName = [modulesByName copy];
// Inject module data into JS context
NSString *configJSON = RCTJSONStringify(@{
@"remoteModuleConfig": RCTRemoteModulesConfig(_modulesByName),
@ -479,14 +460,6 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
return self;
}
- (NSDictionary *)modules
{
RCTAssert(_modulesByName != nil, @"Bridge modules have not yet been initialized. \
You may be trying to access a module too early in the startup procedure.");
return _modulesByName;
}
- (void)dealloc
{
RCTAssert(!self.valid, @"must call -invalidate before -dealloc");
@ -543,7 +516,7 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
[self _invokeAndProcessModule:@"BatchedBridge"
method:@"callFunctionReturnFlushedQueue"
arguments:@[moduleID, methodID, args ?: @[]]];
arguments:@[moduleID, methodID, args]];
}
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete
@ -726,8 +699,8 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
switch (argumentType[0]) {
case ':':
if ([param isKindOfClass:[NSString class]]) {
SEL sel = NSSelectorFromString(param);
[invocation setArgument:&sel atIndex:argIdx];
SEL selector = NSSelectorFromString(param);
[invocation setArgument:&selector atIndex:argIdx];
shouldSet = NO;
}
break;
@ -840,7 +813,7 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
+ (void)log:(NSArray *)objects level:(NSString *)level
{
if (!_latestJSExecutor || ![_latestJSExecutor isValid]) {
RCTLogError(@"ERROR: No valid JS executor to log %@.", objects);
RCTLogError(@"%@", RCTLogFormatString(@"ERROR: No valid JS executor to log %@.", objects));
return;
}
NSMutableArray *args = [NSMutableArray arrayWithObject:level];

View File

@ -2,8 +2,6 @@
#import <Foundation/Foundation.h>
#import "RCTJSMethodRegistrar.h"
@class RCTBridge;
/**
@ -13,9 +11,9 @@
typedef void (^RCTResponseSenderBlock)(NSArray *response);
/**
* Provides the interface needed to register a bridge module.
* Provides minimal interface needed to register a bridge module
*/
@protocol RCTBridgeModule <RCTJSMethodRegistrar>
@protocol RCTBridgeModule <NSObject>
@optional
/**
@ -49,12 +47,15 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
+ (NSDictionary *)constantsToExport;
/**
* Some "constants" are not really constant, and need to be re-generated
* each time the bridge module is created. Support for this feature is
* deprecated and may be going away or changing, but for now you can use
* the -constantsToExport instance method to register these "pseudo-constants".
* 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.
*/
- (NSDictionary *)constantsToExport;
+ (NSArray *)JSMethods;
/**
* Notifies the module that a batch of JS method invocations has just completed.

View File

@ -30,16 +30,10 @@ typedef NS_ENUM(NSInteger, RCTScrollEventType) {
- (instancetype)initWithBridge:(RCTBridge *)bridge;
/**
* Send an application-specific event that does not relate to a specific
* view, e.g. a navigation or data update notification.
* Send a device or application event that does not relate to a specific
* view, e.g. rotation, location, keyboard show/hide, background/awake, etc.
*/
- (void)sendAppEventWithName:(NSString *)name body:(id)body;
/**
* Send a device or iOS event that does not relate to a specific view,
* e.g.rotation, location, keyboard show/hide, background/awake, etc.
*/
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body;
- (void)sendDeviceEventWithName:(NSString *)name body:(NSDictionary *)body;
/**
* Send a user input event. The body dictionary must contain a "target"

View File

@ -7,7 +7,7 @@
@implementation RCTEventDispatcher
{
RCTBridge __weak *_bridge;
RCTBridge *_bridge;
}
- (instancetype)initWithBridge:(RCTBridge *)bridge
@ -18,34 +18,20 @@
return self;
}
+ (NSArray *)JSMethods
{
return @[
@"RCTNativeAppEventEmitter.emit",
@"RCTDeviceEventEmitter.emit",
@"RCTEventEmitter.receiveEvent",
];
}
- (void)sendAppEventWithName:(NSString *)name body:(id)body
{
[_bridge enqueueJSCall:@"RCTNativeAppEventEmitter.emit"
args:body ? @[name, body] : @[name]];
}
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body
- (void)sendDeviceEventWithName:(NSString *)name body:(NSDictionary *)body
{
[_bridge enqueueJSCall:@"RCTDeviceEventEmitter.emit"
args:body ? @[name, body] : @[name]];
}
- (void)sendInputEventWithName:(NSString *)name body:(NSDictionary *)body
{
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:@"RCTEventEmitter.receiveEvent"
args:body ? @[body[@"target"], name, body] : @[body[@"target"], name]];
args:@[body[@"target"], name, body]];
}
- (void)sendTextEventWithType:(RCTTextEventType)type
@ -60,11 +46,9 @@
@"topEndEditing",
};
[self sendInputEventWithName:events[type] body:text ? @{
[self sendInputEventWithName:events[type] body:@{
@"text": text,
@"target": reactTag
} : @{
@"target": reactTag
}];
}

View File

@ -1,24 +0,0 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#import <Foundation/Foundation.h>
@class RCTBridge;
/**
* Provides an interface to register JS methods to be called via the bridge.
*/
@protocol RCTJSMethodRegistrar <NSObject>
@optional
/**
* An array of JavaScript methods that the class 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 registered by another class, it is not necessary to
* register it again, but it is good practice. Registering the same method
* more than once is silently ignored and will not result in an error.
*/
+ (NSArray *)JSMethods;
@end

View File

@ -81,20 +81,9 @@ static Class _globalExecutorClass;
object:nil];
}
+ (NSArray *)JSMethods
{
return @[
@"AppRegistry.runApplication",
@"ReactIOS.unmountComponentAtNodeAndRemoveContainer"
];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_bridge enqueueJSCall:@"ReactIOS.unmountComponentAtNodeAndRemoveContainer"
args:@[self.reactTag]];
}
- (void)bundleFinishedLoading:(NSError *)error
@ -136,7 +125,7 @@ static Class _globalExecutorClass;
// Choose local executor if specified, followed by global, followed by default
_executor = [[_executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class] alloc] init];
_bridge = [[RCTBridge alloc] initWithJavaScriptExecutor:_executor moduleProvider:nil];
_bridge = [[RCTBridge alloc] initWithJavaScriptExecutor:_executor moduleInstances:nil];
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
[self addGestureRecognizer:_touchHandler];

View File

@ -108,9 +108,4 @@
return [[[self class] allocWithZone:zone] initWithSparseArray:self];
}
- (NSString *)description
{
return [[super description] stringByAppendingString:[_storage description]];
}
@end

View File

@ -137,11 +137,6 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
}
+ (NSArray *)JSMethods
{
return @[@"RCTEventEmitter.receiveTouches"];
}
/**
* Constructs information about touch events to send across the serialized
* boundary. This data should be compliant with W3C `Touch` objects. This data

View File

@ -2,7 +2,6 @@
#import "RCTTiming.h"
#import "RCTAssert.h"
#import "RCTBridge.h"
#import "RCTLog.h"
#import "RCTSparseArray.h"
@ -12,7 +11,7 @@
@property (nonatomic, strong, readonly) NSDate *target;
@property (nonatomic, assign, readonly) BOOL repeats;
@property (nonatomic, copy, readonly) NSNumber *callbackID;
@property (nonatomic, strong, readonly) NSNumber *callbackID;
@property (nonatomic, assign, readonly) NSTimeInterval interval;
@end
@ -173,12 +172,12 @@
if (jsSchedulingOverhead < 0) {
RCTLogWarn(@"jsSchedulingOverhead (%ims) should be positive", (int)(jsSchedulingOverhead * 1000));
}
NSTimeInterval targetTime = interval - jsSchedulingOverhead;
if (interval < 0.018) { // Make sure short intervals run each frame
interval = 0;
}
RCTTimer *timer = [[RCTTimer alloc] initWithCallbackID:callbackID
interval:interval
targetTime:targetTime

View File

@ -137,7 +137,6 @@
13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ReactKit.h"; sourceTree = "<group>"; };
13E067541A70F44B002CDEE1 /* UIView+ReactKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ReactKit.m"; sourceTree = "<group>"; };
13ED13891A80C9D40050A8F9 /* RCTPointerEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPointerEvents.h; sourceTree = "<group>"; };
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSMethodRegistrar.h; sourceTree = "<group>"; };
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = "<group>"; };
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = "<group>"; };
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = "<group>"; };
@ -321,7 +320,6 @@
137029521A69923600575408 /* RCTImageDownloader.m */,
83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */,
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */,
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */,
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */,
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */,
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,

View File

@ -12,9 +12,7 @@
"/node_modules/",
"/packager/"
],
"testFileExtensions": [
"js"
]
"testFileExtensions": ["js"]
},
"scripts": {
"test": "jest",
@ -47,8 +45,7 @@
"underscore": "1.7.0",
"wordwrap": "0.0.2",
"worker-farm": "1.1.0",
"yargs": "1.3.2",
"joi": "~5.1.0"
"yargs": "1.3.2"
},
"devDependencies": {
"jest-cli": "0.2.1",

View File

@ -4,11 +4,7 @@
"description": "",
"main": "index.js",
"jest": {
"unmockedModulePathPatterns": [
"source-map"
],
"testPathIgnorePatterns": [
"JSAppServer/node_modules"
]
"unmockedModulePathPatterns": ["source-map"],
"testPathIgnorePatterns": ["JSAppServer/node_modules"]
}
}