yeet
This commit is contained in:
167
node_modules/react-native/React/Base/RCTAssert.h
generated
vendored
Normal file
167
node_modules/react-native/React/Base/RCTAssert.h
generated
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
/*
|
||||
* Defined in RCTUtils.m
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTIsMainQueue(void);
|
||||
|
||||
/**
|
||||
* This is the main assert macro that you should use. Asserts should be compiled out
|
||||
* in production builds. You can customize the assert behaviour by setting a custom
|
||||
* assert handler through `RCTSetAssertFunction`.
|
||||
*/
|
||||
#ifndef NS_BLOCK_ASSERTIONS
|
||||
#define RCTAssert(condition, ...) \
|
||||
do { \
|
||||
if ((condition) == 0) { \
|
||||
_RCTAssertFormat(#condition, __FILE__, __LINE__, __func__, __VA_ARGS__); \
|
||||
if (RCT_NSASSERT) { \
|
||||
[[NSAssertionHandler currentHandler] handleFailureInFunction:(NSString * _Nonnull) @(__func__) \
|
||||
file:(NSString * _Nonnull) @(__FILE__) \
|
||||
lineNumber:__LINE__ \
|
||||
description:__VA_ARGS__]; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
#else
|
||||
#define RCTAssert(condition, ...) \
|
||||
do { \
|
||||
} while (false)
|
||||
#endif
|
||||
RCT_EXTERN void _RCTAssertFormat(const char *, const char *, int, const char *, NSString *, ...)
|
||||
NS_FORMAT_FUNCTION(5, 6);
|
||||
|
||||
/**
|
||||
* Report a fatal condition when executing. These calls will _NOT_ be compiled out
|
||||
* in production, and crash the app by default. You can customize the fatal behaviour
|
||||
* by setting a custom fatal handler through `RCTSetFatalHandler` and
|
||||
* `RCTSetFatalExceptionHandler`.
|
||||
*/
|
||||
RCT_EXTERN void RCTFatal(NSError *error);
|
||||
RCT_EXTERN void RCTFatalException(NSException *exception);
|
||||
|
||||
/**
|
||||
* The default error domain to be used for React errors.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTErrorDomain;
|
||||
|
||||
/**
|
||||
* JS Stack trace provided as part of an NSError's userInfo
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJSStackTraceKey;
|
||||
|
||||
/**
|
||||
* Raw JS Stack trace string provided as part of an NSError's userInfo
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJSRawStackTraceKey;
|
||||
|
||||
/**
|
||||
* Name of fatal exceptions generated by RCTFatal
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTFatalExceptionName;
|
||||
|
||||
/**
|
||||
* A block signature to be used for custom assertion handling.
|
||||
*/
|
||||
typedef void (^RCTAssertFunction)(
|
||||
NSString *condition,
|
||||
NSString *fileName,
|
||||
NSNumber *lineNumber,
|
||||
NSString *function,
|
||||
NSString *message);
|
||||
|
||||
typedef void (^RCTFatalHandler)(NSError *error);
|
||||
typedef void (^RCTFatalExceptionHandler)(NSException *exception);
|
||||
|
||||
/**
|
||||
* Convenience macro for asserting that a parameter is non-nil/non-zero.
|
||||
*/
|
||||
#define RCTAssertParam(name) RCTAssert(name, @"'%s' is a required parameter", #name)
|
||||
|
||||
/**
|
||||
* Convenience macro for asserting that we're running on main queue.
|
||||
*/
|
||||
#define RCTAssertMainQueue() RCTAssert(RCTIsMainQueue(), @"This function must be called on the main queue")
|
||||
|
||||
/**
|
||||
* Convenience macro for asserting that we're running off the main queue.
|
||||
*/
|
||||
#define RCTAssertNotMainQueue() RCTAssert(!RCTIsMainQueue(), @"This function must not be called on the main queue")
|
||||
|
||||
/**
|
||||
* These methods get and set the current assert function called by the RCTAssert
|
||||
* macros. You can use these to replace the standard behavior with custom assert
|
||||
* functionality.
|
||||
*/
|
||||
RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction);
|
||||
RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);
|
||||
|
||||
/**
|
||||
* This appends additional code to the existing assert function, without
|
||||
* replacing the existing functionality. Useful if you just want to forward
|
||||
* assert info to an extra service without changing the default behavior.
|
||||
*/
|
||||
RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
|
||||
|
||||
/**
|
||||
* This method temporarily overrides the assert function while performing the
|
||||
* specified block. This is useful for testing purposes (to detect if a given
|
||||
* function asserts something) or to suppress or override assertions temporarily.
|
||||
*/
|
||||
RCT_EXTERN void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction);
|
||||
|
||||
/**
|
||||
* These methods get and set the current fatal handler called by the `RCTFatal`
|
||||
* and `RCTFatalException` methods.
|
||||
*/
|
||||
RCT_EXTERN void RCTSetFatalHandler(RCTFatalHandler fatalHandler);
|
||||
RCT_EXTERN RCTFatalHandler RCTGetFatalHandler(void);
|
||||
RCT_EXTERN void RCTSetFatalExceptionHandler(RCTFatalExceptionHandler fatalExceptionHandler);
|
||||
RCT_EXTERN RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void);
|
||||
|
||||
/**
|
||||
* Get the current thread's name (or the current queue, if in debug mode)
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTCurrentThreadName(void);
|
||||
|
||||
/**
|
||||
* Helper to get generate exception message from NSError
|
||||
*/
|
||||
RCT_EXTERN NSString *
|
||||
RCTFormatError(NSString *message, NSArray<NSDictionary<NSString *, id> *> *stacktrace, NSUInteger maxMessageLength);
|
||||
|
||||
/**
|
||||
* Formats a JS stack trace for logging.
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTFormatStackTrace(NSArray<NSDictionary<NSString *, id> *> *stackTrace);
|
||||
|
||||
/**
|
||||
* Convenience macro to assert which thread is currently running (DEBUG mode only)
|
||||
*/
|
||||
#if DEBUG
|
||||
|
||||
#define RCTAssertThread(thread, format...) \
|
||||
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") RCTAssert( \
|
||||
[(id)thread isKindOfClass:[NSString class]] \
|
||||
? [RCTCurrentThreadName() isEqualToString:(NSString *)thread] \
|
||||
: [(id)thread isKindOfClass:[NSThread class]] ? [NSThread currentThread] == (NSThread *)thread \
|
||||
: dispatch_get_current_queue() == (dispatch_queue_t)thread, \
|
||||
format); \
|
||||
_Pragma("clang diagnostic pop")
|
||||
|
||||
#else
|
||||
|
||||
#define RCTAssertThread(thread, format...) \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
#endif
|
231
node_modules/react-native/React/Base/RCTAssert.m
generated
vendored
Normal file
231
node_modules/react-native/React/Base/RCTAssert.m
generated
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
NSString *const RCTErrorDomain = @"RCTErrorDomain";
|
||||
NSString *const RCTJSStackTraceKey = @"RCTJSStackTraceKey";
|
||||
NSString *const RCTJSRawStackTraceKey = @"RCTJSRawStackTraceKey";
|
||||
NSString *const RCTFatalExceptionName = @"RCTFatalException";
|
||||
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";
|
||||
|
||||
static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";
|
||||
|
||||
RCTAssertFunction RCTCurrentAssertFunction = nil;
|
||||
RCTFatalHandler RCTCurrentFatalHandler = nil;
|
||||
RCTFatalExceptionHandler RCTCurrentFatalExceptionHandler = nil;
|
||||
|
||||
NSException *_RCTNotImplementedException(SEL, Class);
|
||||
NSException *_RCTNotImplementedException(SEL cmd, Class cls)
|
||||
{
|
||||
NSString *msg = [NSString stringWithFormat:
|
||||
@"%s is not implemented "
|
||||
"for the class %@",
|
||||
sel_getName(cmd),
|
||||
cls];
|
||||
return [NSException exceptionWithName:@"RCTNotDesignatedInitializerException" reason:msg userInfo:nil];
|
||||
}
|
||||
|
||||
void RCTSetAssertFunction(RCTAssertFunction assertFunction)
|
||||
{
|
||||
RCTCurrentAssertFunction = assertFunction;
|
||||
}
|
||||
|
||||
RCTAssertFunction RCTGetAssertFunction(void)
|
||||
{
|
||||
return RCTCurrentAssertFunction;
|
||||
}
|
||||
|
||||
void RCTAddAssertFunction(RCTAssertFunction assertFunction)
|
||||
{
|
||||
RCTAssertFunction existing = RCTCurrentAssertFunction;
|
||||
if (existing) {
|
||||
RCTCurrentAssertFunction =
|
||||
^(NSString *condition, NSString *fileName, NSNumber *lineNumber, NSString *function, NSString *message) {
|
||||
existing(condition, fileName, lineNumber, function, message);
|
||||
assertFunction(condition, fileName, lineNumber, function, message);
|
||||
};
|
||||
} else {
|
||||
RCTCurrentAssertFunction = assertFunction;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the topmost stacked assert function for the current thread, which
|
||||
* may not be the same as the current value of RCTCurrentAssertFunction.
|
||||
*/
|
||||
static RCTAssertFunction RCTGetLocalAssertFunction()
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSArray<RCTAssertFunction> *functionStack = threadDictionary[RCTAssertFunctionStack];
|
||||
RCTAssertFunction assertFunction = functionStack.lastObject;
|
||||
if (assertFunction) {
|
||||
return assertFunction;
|
||||
}
|
||||
return RCTCurrentAssertFunction;
|
||||
}
|
||||
|
||||
void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction)
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSMutableArray<RCTAssertFunction> *functionStack = threadDictionary[RCTAssertFunctionStack];
|
||||
if (!functionStack) {
|
||||
functionStack = [NSMutableArray new];
|
||||
threadDictionary[RCTAssertFunctionStack] = functionStack;
|
||||
}
|
||||
[functionStack addObject:assertFunction];
|
||||
block();
|
||||
[functionStack removeLastObject];
|
||||
}
|
||||
|
||||
NSString *RCTCurrentThreadName(void)
|
||||
{
|
||||
NSThread *thread = [NSThread currentThread];
|
||||
NSString *threadName = RCTIsMainQueue() || thread.isMainThread ? @"main" : thread.name;
|
||||
if (threadName.length == 0) {
|
||||
const char *label = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
|
||||
if (label && strlen(label) > 0) {
|
||||
threadName = @(label);
|
||||
} else {
|
||||
threadName = [NSString stringWithFormat:@"%p", thread];
|
||||
}
|
||||
}
|
||||
return threadName;
|
||||
}
|
||||
|
||||
void _RCTAssertFormat(
|
||||
const char *condition,
|
||||
const char *fileName,
|
||||
int lineNumber,
|
||||
const char *function,
|
||||
NSString *format,
|
||||
...)
|
||||
{
|
||||
RCTAssertFunction assertFunction = RCTGetLocalAssertFunction();
|
||||
if (assertFunction) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
va_end(args);
|
||||
|
||||
assertFunction(@(condition), @(fileName), @(lineNumber), @(function), message);
|
||||
}
|
||||
}
|
||||
|
||||
void RCTFatal(NSError *error)
|
||||
{
|
||||
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@", error.localizedDescription);
|
||||
|
||||
RCTFatalHandler fatalHandler = RCTGetFatalHandler();
|
||||
if (fatalHandler) {
|
||||
fatalHandler(error);
|
||||
} else {
|
||||
#if DEBUG
|
||||
@try {
|
||||
#endif
|
||||
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, error.localizedDescription];
|
||||
|
||||
// Truncate the localized description to 175 characters to avoid wild screen overflows
|
||||
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 175);
|
||||
|
||||
// Attach an untruncated copy of the description to the userInfo, in case it is needed
|
||||
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
|
||||
[userInfo setObject:RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], -1)
|
||||
forKey:RCTUntruncatedMessageKey];
|
||||
|
||||
// Expected resulting exception information:
|
||||
// name: RCTFatalException: <underlying error description>
|
||||
// reason: <underlying error description plus JS stack trace, truncated to 175 characters>
|
||||
// userInfo: <underlying error userinfo, plus untruncated description plus JS stack trace>
|
||||
@throw [[NSException alloc] initWithName:name reason:message userInfo:userInfo];
|
||||
#if DEBUG
|
||||
} @catch (NSException *e) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void RCTSetFatalHandler(RCTFatalHandler fatalHandler)
|
||||
{
|
||||
RCTCurrentFatalHandler = fatalHandler;
|
||||
}
|
||||
|
||||
RCTFatalHandler RCTGetFatalHandler(void)
|
||||
{
|
||||
return RCTCurrentFatalHandler;
|
||||
}
|
||||
|
||||
NSString *
|
||||
RCTFormatError(NSString *message, NSArray<NSDictionary<NSString *, id> *> *stackTrace, NSUInteger maxMessageLength)
|
||||
{
|
||||
if (maxMessageLength > 0 && message.length > maxMessageLength) {
|
||||
message = [[message substringToIndex:maxMessageLength] stringByAppendingString:@"..."];
|
||||
}
|
||||
|
||||
NSString *prettyStack = RCTFormatStackTrace(stackTrace);
|
||||
|
||||
return [NSString
|
||||
stringWithFormat:@"%@%@%@", message, prettyStack ? @", stack:\n" : @"", prettyStack ? prettyStack : @""];
|
||||
}
|
||||
|
||||
NSString *RCTFormatStackTrace(NSArray<NSDictionary<NSString *, id> *> *stackTrace)
|
||||
{
|
||||
if (stackTrace) {
|
||||
NSMutableString *prettyStack = [NSMutableString string];
|
||||
|
||||
NSRegularExpression *regex =
|
||||
[NSRegularExpression regularExpressionWithPattern:@"\\b((?:seg-\\d+(?:_\\d+)?|\\d+)\\.js)"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:NULL];
|
||||
for (NSDictionary<NSString *, id> *frame in stackTrace) {
|
||||
NSString *fileName = [frame[@"file"] lastPathComponent];
|
||||
NSTextCheckingResult *match =
|
||||
fileName != nil ? [regex firstMatchInString:fileName options:0 range:NSMakeRange(0, fileName.length)] : nil;
|
||||
if (match) {
|
||||
fileName = [NSString stringWithFormat:@"%@:", [fileName substringWithRange:match.range]];
|
||||
} else {
|
||||
fileName = @"";
|
||||
}
|
||||
|
||||
[prettyStack
|
||||
appendFormat:@"%@@%@%@:%@\n", frame[@"methodName"], fileName, frame[@"lineNumber"], frame[@"column"]];
|
||||
}
|
||||
|
||||
return prettyStack;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
void RCTFatalException(NSException *exception)
|
||||
{
|
||||
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@: %@", exception.name, exception.reason);
|
||||
|
||||
RCTFatalExceptionHandler fatalExceptionHandler = RCTGetFatalExceptionHandler();
|
||||
if (fatalExceptionHandler) {
|
||||
fatalExceptionHandler(exception);
|
||||
} else {
|
||||
#if DEBUG
|
||||
@try {
|
||||
#endif
|
||||
@throw exception;
|
||||
#if DEBUG
|
||||
} @catch (NSException *e) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void RCTSetFatalExceptionHandler(RCTFatalExceptionHandler fatalExceptionHandler)
|
||||
{
|
||||
RCTCurrentFatalExceptionHandler = fatalExceptionHandler;
|
||||
}
|
||||
|
||||
RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void)
|
||||
{
|
||||
return RCTCurrentFatalExceptionHandler;
|
||||
}
|
149
node_modules/react-native/React/Base/RCTBridge+Private.h
generated
vendored
Normal file
149
node_modules/react-native/React/Base/RCTBridge+Private.h
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
@class RCTModuleData;
|
||||
@protocol RCTJavaScriptExecutor;
|
||||
|
||||
RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
|
||||
RCT_EXTERN void RCTRegisterModule(Class);
|
||||
|
||||
@interface RCTBridge ()
|
||||
|
||||
// Private designated initializer
|
||||
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
|
||||
bundleURL:(NSURL *)bundleURL
|
||||
moduleProvider:(RCTBridgeModuleListProvider)block
|
||||
launchOptions:(NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
// Used for the profiler flow events between JS and native
|
||||
@property (nonatomic, assign) int64_t flowID;
|
||||
@property (nonatomic, assign) CFMutableDictionaryRef flowIDMap;
|
||||
@property (nonatomic, strong) NSLock *flowIDMapLock;
|
||||
|
||||
// Used by RCTDevMenu
|
||||
@property (nonatomic, copy) NSString *bridgeDescription;
|
||||
|
||||
+ (instancetype)currentBridge;
|
||||
+ (void)setCurrentBridge:(RCTBridge *)bridge;
|
||||
|
||||
/**
|
||||
* Bridge setup code - creates an instance of RCTBachedBridge. Exposed for
|
||||
* test only
|
||||
*/
|
||||
- (void)setUp;
|
||||
|
||||
/**
|
||||
* This method is used to invoke a callback that was registered in the
|
||||
* JavaScript application context. Safe to call from any thread.
|
||||
*/
|
||||
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args;
|
||||
|
||||
/**
|
||||
* This property is mostly used on the main thread, but may be touched from
|
||||
* a background thread if the RCTBridge happens to deallocate on a background
|
||||
* thread. Therefore, we want all writes to it to be seen atomically.
|
||||
*/
|
||||
@property (atomic, strong) RCTBridge *batchedBridge;
|
||||
|
||||
/**
|
||||
* The block that creates the modules' instances to be added to the bridge.
|
||||
* Exposed for RCTCxxBridge
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) RCTBridgeModuleListProvider moduleProvider;
|
||||
|
||||
/**
|
||||
* Used by RCTDevMenu to override the `hot` param of the current bundleURL.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) NSURL *bundleURL;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTBridge (RCTCxxBridge)
|
||||
|
||||
/**
|
||||
* Used by RCTModuleData
|
||||
*/
|
||||
|
||||
@property (nonatomic, weak, readonly) RCTBridge *parentBridge;
|
||||
|
||||
/**
|
||||
* Used by RCTModuleData
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL moduleSetupComplete;
|
||||
|
||||
/**
|
||||
* Called on the child bridge to run the executor and start loading.
|
||||
*/
|
||||
- (void)start;
|
||||
|
||||
/**
|
||||
* Used by RCTModuleData to register the module for frame updates after it is
|
||||
* lazily initialized.
|
||||
*/
|
||||
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData;
|
||||
|
||||
/**
|
||||
* Dispatch work to a module's queue - this is also suports the fake RCTJSThread
|
||||
* queue. Exposed for the RCTProfiler
|
||||
*/
|
||||
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* Get the module data for a given module name. Used by UIManager to implement
|
||||
* the `dispatchViewManagerCommand` method.
|
||||
*/
|
||||
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName;
|
||||
|
||||
/**
|
||||
* Registers additional classes with the ModuleRegistry.
|
||||
*/
|
||||
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)newModules;
|
||||
|
||||
/**
|
||||
* Updates the ModuleRegistry with a pre-initialized instance.
|
||||
*/
|
||||
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance;
|
||||
|
||||
/**
|
||||
* Systrace profiler toggling methods exposed for the RCTDevMenu
|
||||
*/
|
||||
- (void)startProfiling;
|
||||
- (void)stopProfiling:(void (^)(NSData *))callback;
|
||||
|
||||
/**
|
||||
* Synchronously call a specific native module's method and return the result
|
||||
*/
|
||||
- (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(NSArray *)params;
|
||||
|
||||
/**
|
||||
* Hook exposed for RCTLog to send logs to JavaScript when not running in JSC
|
||||
*/
|
||||
- (void)logMessage:(NSString *)message level:(NSString *)level;
|
||||
|
||||
/**
|
||||
* Allow super fast, one time, timers to skip the queue and be directly executed
|
||||
*/
|
||||
- (void)_immediatelyCallTimer:(NSNumber *)timer;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTBridge (Inspector)
|
||||
|
||||
@property (nonatomic, readonly, getter=isInspectable) BOOL inspectable;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTCxxBridge : RCTBridge
|
||||
|
||||
// TODO(cjhopman): this seems unsafe unless we require that it is only called on the main js queue.
|
||||
@property (nonatomic, readonly) void *runtime;
|
||||
|
||||
- (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
297
node_modules/react-native/React/Base/RCTBridge.h
generated
vendored
Normal file
297
node_modules/react-native/React/Base/RCTBridge.h
generated
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTFrameUpdate.h>
|
||||
#import <React/RCTInvalidating.h>
|
||||
|
||||
@class JSValue;
|
||||
@class RCTBridge;
|
||||
@class RCTEventDispatcher;
|
||||
@class RCTPerformanceLogger;
|
||||
|
||||
/**
|
||||
* This notification fires when the bridge initializes.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJavaScriptWillStartLoadingNotification;
|
||||
|
||||
/**
|
||||
* This notification fires when the bridge starts executing the JS bundle.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJavaScriptWillStartExecutingNotification;
|
||||
|
||||
/**
|
||||
* This notification fires when the bridge has finished loading the JS bundle.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJavaScriptDidLoadNotification;
|
||||
|
||||
/**
|
||||
* This notification fires when the bridge failed to load the JS bundle. The
|
||||
* `error` key can be used to determine the error that occurred.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification;
|
||||
|
||||
/**
|
||||
* This notification fires each time a native module is instantiated. The
|
||||
* `module` key will contain a reference to the newly-created module instance.
|
||||
* Note that this notification may be fired before the module is available via
|
||||
* the `[bridge moduleForClass:]` method.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTDidInitializeModuleNotification;
|
||||
|
||||
/**
|
||||
* This notification fires each time a module is setup after it is initialized. The
|
||||
* `RCTDidSetupModuleNotificationModuleNameKey` key will contain a reference to the module name and
|
||||
* `RCTDidSetupModuleNotificationSetupTimeKey` will contain the setup time in ms.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTDidSetupModuleNotification;
|
||||
|
||||
/**
|
||||
* Key for the module name (NSString) in the
|
||||
* RCTDidSetupModuleNotification userInfo dictionary.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationModuleNameKey;
|
||||
|
||||
/**
|
||||
* Key for the setup time (NSNumber) in the
|
||||
* RCTDidSetupModuleNotification userInfo dictionary.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationSetupTimeKey;
|
||||
|
||||
/**
|
||||
* DEPRECATED - Use RCTReloadCommand instead. This notification fires just before the bridge starts
|
||||
* processing a request to reload.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeWillReloadNotification;
|
||||
|
||||
/**
|
||||
* This notification fires whenever a fast refresh happens.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeFastRefreshNotification;
|
||||
|
||||
/**
|
||||
* This notification fires just before the bridge begins downloading a script
|
||||
* from the packager.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeWillDownloadScriptNotification;
|
||||
|
||||
/**
|
||||
* This notification fires just after the bridge finishes downloading a script
|
||||
* from the packager.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotification;
|
||||
|
||||
/**
|
||||
* This notification fires right after the bridge is about to invalidate NativeModule
|
||||
* instances during teardown. Handle this notification to perform additional invalidation.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeWillInvalidateModulesNotification;
|
||||
|
||||
/**
|
||||
* This notification fires right after the bridge finishes invalidating NativeModule
|
||||
* instances during teardown. Handle this notification to perform additional invalidation.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeDidInvalidateModulesNotification;
|
||||
|
||||
/**
|
||||
* This notification fires right before the bridge starting invalidation process.
|
||||
* Handle this notification to perform additional invalidation.
|
||||
* The notification can be issued on any thread.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeWillBeInvalidatedNotification;
|
||||
|
||||
/**
|
||||
* Key for the RCTSource object in the RCTBridgeDidDownloadScriptNotification
|
||||
* userInfo dictionary.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey;
|
||||
|
||||
/**
|
||||
* Key for the reload reason in the RCTBridgeWillReloadNotification userInfo dictionary.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationReasonKey;
|
||||
|
||||
/**
|
||||
* Key for the bridge description (NSString_ in the
|
||||
* RCTBridgeDidDownloadScriptNotification userInfo dictionary.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey;
|
||||
|
||||
/**
|
||||
* This block can be used to instantiate modules that require additional
|
||||
* init parameters, or additional configuration prior to being used.
|
||||
* The bridge will call this block to instantiate the modules, and will
|
||||
* be responsible for invalidating/releasing them when the bridge is destroyed.
|
||||
* For this reason, the block should always return new module instances, and
|
||||
* module instances should not be shared between bridges.
|
||||
*/
|
||||
typedef NSArray<id<RCTBridgeModule>> * (^RCTBridgeModuleListProvider)(void);
|
||||
|
||||
/**
|
||||
* This function returns the module name for a given class.
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
* Check/set if JSI-bound NativeModule is enabled. By default it's off.
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTTurboModuleEnabled(void);
|
||||
RCT_EXTERN void RCTEnableTurboModule(BOOL enabled);
|
||||
|
||||
/**
|
||||
* Async batched bridge used to communicate with the JavaScript application.
|
||||
*/
|
||||
@interface RCTBridge : NSObject <RCTInvalidating>
|
||||
|
||||
/**
|
||||
* Creates a new bridge with a custom RCTBridgeDelegate.
|
||||
*
|
||||
* All the interaction with the JavaScript context should be done using the bridge
|
||||
* instance of the RCTBridgeModules. Modules will be automatically instantiated
|
||||
* using the default contructor, but you can optionally pass in an array of
|
||||
* pre-initialized module instances if they require additional init parameters
|
||||
* or configuration.
|
||||
*/
|
||||
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use initWithDelegate:launchOptions: instead
|
||||
*
|
||||
* 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 an
|
||||
* array of pre-initialized module instances if they require additional init
|
||||
* parameters or configuration.
|
||||
*/
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleProvider:(RCTBridgeModuleListProvider)block
|
||||
launchOptions:(NSDictionary *)launchOptions;
|
||||
|
||||
/**
|
||||
* This method is used to call functions in the JavaScript application context.
|
||||
* It is primarily intended for use by modules that require two-way communication
|
||||
* with the JavaScript code. Safe to call from any thread.
|
||||
*/
|
||||
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
|
||||
- (void)enqueueJSCall:(NSString *)module
|
||||
method:(NSString *)method
|
||||
args:(NSArray *)args
|
||||
completion:(dispatch_block_t)completion;
|
||||
|
||||
/**
|
||||
* This method registers the file path of an additional JS segment by its ID.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path;
|
||||
|
||||
/**
|
||||
* Retrieve a bridge module instance by name or class. Note that modules are
|
||||
* lazily instantiated, so calling these methods for the first time with a given
|
||||
* module name/class may cause the class to be synchronously instantiated,
|
||||
* potentially blocking both the calling thread and main thread for a short time.
|
||||
*
|
||||
* Note: This method does NOT lazily load the particular module if it's not yet loaded.
|
||||
*/
|
||||
- (id)moduleForName:(NSString *)moduleName;
|
||||
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
|
||||
// Note: This method lazily load the module as necessary.
|
||||
- (id)moduleForClass:(Class)moduleClass;
|
||||
|
||||
/**
|
||||
* When a NativeModule performs a lookup for a TurboModule, we need to query
|
||||
* the lookupDelegate.
|
||||
*/
|
||||
- (void)setRCTTurboModuleLookupDelegate:(id<RCTTurboModuleLookupDelegate>)turboModuleLookupDelegate;
|
||||
|
||||
/**
|
||||
* Convenience method for retrieving all modules conforming to a given protocol.
|
||||
* Modules will be synchronously instantiated if they haven't already been,
|
||||
* potentially blocking both the calling thread and main thread for a short time.
|
||||
*/
|
||||
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol;
|
||||
|
||||
/**
|
||||
* Test if a module has been initialized. Use this prior to calling
|
||||
* `moduleForClass:` or `moduleForName:` if you do not want to cause the module
|
||||
* to be instantiated if it hasn't been already.
|
||||
*/
|
||||
- (BOOL)moduleIsInitialized:(Class)moduleClass;
|
||||
|
||||
/**
|
||||
* All registered bridge module classes.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSArray<Class> *moduleClasses;
|
||||
|
||||
/**
|
||||
* URL of the script that was loaded into the bridge.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSURL *bundleURL;
|
||||
|
||||
/**
|
||||
* The class of the executor currently being used. Changes to this value will
|
||||
* take effect after the bridge is reloaded.
|
||||
*/
|
||||
@property (nonatomic, strong) Class executorClass;
|
||||
|
||||
/**
|
||||
* The delegate provided during the bridge initialization
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) id<RCTBridgeDelegate> delegate;
|
||||
|
||||
/**
|
||||
* The launch options that were used to initialize the bridge.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
|
||||
|
||||
/**
|
||||
* Use this to check if the bridge is currently loading.
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
|
||||
|
||||
/**
|
||||
* Use this to check if the bridge has been invalidated.
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isValid) BOOL valid;
|
||||
|
||||
/**
|
||||
* Link to the Performance Logger that logs React Native perf events.
|
||||
*/
|
||||
@property (nonatomic, readonly, strong) RCTPerformanceLogger *performanceLogger;
|
||||
|
||||
/**
|
||||
* Reload the bundle and reset executor & modules. Safe to call from any thread.
|
||||
*/
|
||||
- (void)reload __deprecated_msg("Use RCTReloadCommand instead");
|
||||
|
||||
/**
|
||||
* Reload the bundle and reset executor & modules. Safe to call from any thread.
|
||||
*/
|
||||
- (void)reloadWithReason:(NSString *)reason __deprecated_msg("Use RCTReloadCommand instead");
|
||||
|
||||
/**
|
||||
* Handle notifications for a fast refresh. Safe to call from any thread.
|
||||
*/
|
||||
- (void)onFastRefresh;
|
||||
|
||||
/**
|
||||
* Inform the bridge, and anything subscribing to it, that it should reload.
|
||||
*/
|
||||
- (void)requestReload __deprecated_msg("Use RCTReloadCommand instead");
|
||||
|
||||
/**
|
||||
* Says whether bridge has started receiving calls from javascript.
|
||||
*/
|
||||
- (BOOL)isBatchActive;
|
||||
|
||||
@end
|
391
node_modules/react-native/React/Base/RCTBridge.m
generated
vendored
Normal file
391
node_modules/react-native/React/Base/RCTBridge.m
generated
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
#import "RCTInspectorDevServerHelper.h"
|
||||
#endif
|
||||
#import "RCTLog.h"
|
||||
#import "RCTModuleData.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTReloadCommand.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
NSString *const RCTJavaScriptWillStartLoadingNotification = @"RCTJavaScriptWillStartLoadingNotification";
|
||||
NSString *const RCTJavaScriptWillStartExecutingNotification = @"RCTJavaScriptWillStartExecutingNotification";
|
||||
NSString *const RCTJavaScriptDidLoadNotification = @"RCTJavaScriptDidLoadNotification";
|
||||
NSString *const RCTJavaScriptDidFailToLoadNotification = @"RCTJavaScriptDidFailToLoadNotification";
|
||||
NSString *const RCTDidInitializeModuleNotification = @"RCTDidInitializeModuleNotification";
|
||||
NSString *const RCTDidSetupModuleNotification = @"RCTDidSetupModuleNotification";
|
||||
NSString *const RCTDidSetupModuleNotificationModuleNameKey = @"moduleName";
|
||||
NSString *const RCTDidSetupModuleNotificationSetupTimeKey = @"setupTime";
|
||||
NSString *const RCTBridgeWillReloadNotification = @"RCTBridgeWillReloadNotification";
|
||||
NSString *const RCTBridgeFastRefreshNotification = @"RCTBridgeFastRefreshNotification";
|
||||
NSString *const RCTBridgeWillDownloadScriptNotification = @"RCTBridgeWillDownloadScriptNotification";
|
||||
NSString *const RCTBridgeDidDownloadScriptNotification = @"RCTBridgeDidDownloadScriptNotification";
|
||||
NSString *const RCTBridgeWillInvalidateModulesNotification = @"RCTBridgeWillInvalidateModulesNotification";
|
||||
NSString *const RCTBridgeDidInvalidateModulesNotification = @"RCTBridgeDidInvalidateModulesNotification";
|
||||
NSString *const RCTBridgeWillBeInvalidatedNotification = @"RCTBridgeWillBeInvalidatedNotification";
|
||||
NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey = @"source";
|
||||
NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey = @"bridgeDescription";
|
||||
|
||||
static NSMutableArray<Class> *RCTModuleClasses;
|
||||
static dispatch_queue_t RCTModuleClassesSyncQueue;
|
||||
NSArray<Class> *RCTGetModuleClasses(void)
|
||||
{
|
||||
__block NSArray<Class> *result;
|
||||
dispatch_sync(RCTModuleClassesSyncQueue, ^{
|
||||
result = [RCTModuleClasses copy];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given class as a bridge module. All modules must be registered
|
||||
* prior to the first bridge initialization.
|
||||
*/
|
||||
void RCTRegisterModule(Class);
|
||||
void RCTRegisterModule(Class moduleClass)
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
RCTModuleClasses = [NSMutableArray new];
|
||||
RCTModuleClassesSyncQueue =
|
||||
dispatch_queue_create("com.facebook.react.ModuleClassesSyncQueue", DISPATCH_QUEUE_CONCURRENT);
|
||||
});
|
||||
|
||||
RCTAssert(
|
||||
[moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
|
||||
@"%@ does not conform to the RCTBridgeModule protocol",
|
||||
moduleClass);
|
||||
|
||||
// Register module
|
||||
dispatch_barrier_async(RCTModuleClassesSyncQueue, ^{
|
||||
[RCTModuleClasses addObject:moduleClass];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the module name for a given class.
|
||||
*/
|
||||
NSString *RCTBridgeModuleNameForClass(Class cls)
|
||||
{
|
||||
#if RCT_DEBUG
|
||||
RCTAssert(
|
||||
[cls conformsToProtocol:@protocol(RCTBridgeModule)],
|
||||
@"Bridge module `%@` does not conform to RCTBridgeModule",
|
||||
cls);
|
||||
#endif
|
||||
|
||||
NSString *name = [cls moduleName];
|
||||
if (name.length == 0) {
|
||||
name = NSStringFromClass(cls);
|
||||
}
|
||||
|
||||
return RCTDropReactPrefixes(name);
|
||||
}
|
||||
|
||||
static BOOL turboModuleEnabled = NO;
|
||||
BOOL RCTTurboModuleEnabled(void)
|
||||
{
|
||||
#if RCT_DEBUG
|
||||
// TODO(T53341772): Allow TurboModule for test environment. Right now this breaks RNTester tests if enabled.
|
||||
if (RCTRunningInTestEnvironment()) {
|
||||
return NO;
|
||||
}
|
||||
#endif
|
||||
return turboModuleEnabled;
|
||||
}
|
||||
|
||||
void RCTEnableTurboModule(BOOL enabled)
|
||||
{
|
||||
turboModuleEnabled = enabled;
|
||||
}
|
||||
|
||||
@interface RCTBridge () <RCTReloadListener>
|
||||
@end
|
||||
|
||||
@implementation RCTBridge {
|
||||
NSURL *_delegateBundleURL;
|
||||
}
|
||||
|
||||
dispatch_queue_t RCTJSThread;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
// Set up JS thread
|
||||
RCTJSThread = (id)kCFNull;
|
||||
});
|
||||
}
|
||||
|
||||
static RCTBridge *RCTCurrentBridgeInstance = nil;
|
||||
|
||||
/**
|
||||
* The last current active bridge instance. This is set automatically whenever
|
||||
* the bridge is accessed. It can be useful for static functions or singletons
|
||||
* that need to access the bridge for purposes such as logging, but should not
|
||||
* be relied upon to return any particular instance, due to race conditions.
|
||||
*/
|
||||
+ (instancetype)currentBridge
|
||||
{
|
||||
return RCTCurrentBridgeInstance;
|
||||
}
|
||||
|
||||
+ (void)setCurrentBridge:(RCTBridge *)currentBridge
|
||||
{
|
||||
RCTCurrentBridgeInstance = currentBridge;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
return [self initWithDelegate:delegate bundleURL:nil moduleProvider:nil launchOptions:launchOptions];
|
||||
}
|
||||
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleProvider:(RCTBridgeModuleListProvider)block
|
||||
launchOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
return [self initWithDelegate:nil bundleURL:bundleURL moduleProvider:block launchOptions:launchOptions];
|
||||
}
|
||||
|
||||
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
|
||||
bundleURL:(NSURL *)bundleURL
|
||||
moduleProvider:(RCTBridgeModuleListProvider)block
|
||||
launchOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_delegate = delegate;
|
||||
_bundleURL = bundleURL;
|
||||
_moduleProvider = block;
|
||||
_launchOptions = [launchOptions copy];
|
||||
|
||||
[self setUp];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
/**
|
||||
* This runs only on the main thread, but crashes the subclass
|
||||
* RCTAssertMainQueue();
|
||||
*/
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)setRCTTurboModuleLookupDelegate:(id<RCTTurboModuleLookupDelegate>)turboModuleLookupDelegate
|
||||
{
|
||||
[self.batchedBridge setRCTTurboModuleLookupDelegate:turboModuleLookupDelegate];
|
||||
}
|
||||
|
||||
- (void)didReceiveReloadCommand
|
||||
{
|
||||
[self reloadWithReason:@"Command"];
|
||||
}
|
||||
|
||||
- (NSArray<Class> *)moduleClasses
|
||||
{
|
||||
return self.batchedBridge.moduleClasses;
|
||||
}
|
||||
|
||||
- (id)moduleForName:(NSString *)moduleName
|
||||
{
|
||||
return [self.batchedBridge moduleForName:moduleName];
|
||||
}
|
||||
|
||||
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
|
||||
{
|
||||
return [self.batchedBridge moduleForName:moduleName lazilyLoadIfNecessary:lazilyLoad];
|
||||
}
|
||||
|
||||
- (id)moduleForClass:(Class)moduleClass
|
||||
{
|
||||
id module = [self.batchedBridge moduleForClass:moduleClass];
|
||||
if (!module) {
|
||||
module = [self moduleForName:RCTBridgeModuleNameForClass(moduleClass)];
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol
|
||||
{
|
||||
NSMutableArray *modules = [NSMutableArray new];
|
||||
for (Class moduleClass in [self.moduleClasses copy]) {
|
||||
if ([moduleClass conformsToProtocol:protocol]) {
|
||||
id module = [self moduleForClass:moduleClass];
|
||||
if (module) {
|
||||
[modules addObject:module];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [modules copy];
|
||||
}
|
||||
|
||||
- (BOOL)moduleIsInitialized:(Class)moduleClass
|
||||
{
|
||||
return [self.batchedBridge moduleIsInitialized:moduleClass];
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED - please use RCTReloadCommand.
|
||||
*/
|
||||
- (void)reload
|
||||
{
|
||||
[self reloadWithReason:@"Unknown from bridge"];
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED - please use RCTReloadCommand.
|
||||
*/
|
||||
- (void)reloadWithReason:(NSString *)reason
|
||||
{
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
// Disable debugger to resume the JsVM & avoid thread locks while reloading
|
||||
[RCTInspectorDevServerHelper disableDebugger];
|
||||
#endif
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillReloadNotification object:self userInfo:nil];
|
||||
|
||||
/**
|
||||
* Any thread
|
||||
*/
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// WARNING: Invalidation is async, so it may not finish before re-setting up the bridge,
|
||||
// causing some issues. TODO: revisit this post-Fabric/TurboModule.
|
||||
[self invalidate];
|
||||
// Reload is a special case, do not preserve launchOptions and treat reload as a fresh start
|
||||
self->_launchOptions = nil;
|
||||
[self setUp];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)onFastRefresh
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeFastRefreshNotification object:self];
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED - please use RCTReloadCommand.
|
||||
*/
|
||||
- (void)requestReload
|
||||
{
|
||||
[self reloadWithReason:@"Requested from bridge"];
|
||||
}
|
||||
|
||||
- (Class)bridgeClass
|
||||
{
|
||||
return [RCTCxxBridge class];
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
RCT_PROFILE_BEGIN_EVENT(0, @"-[RCTBridge setUp]", nil);
|
||||
|
||||
_performanceLogger = [RCTPerformanceLogger new];
|
||||
[_performanceLogger markStartForTag:RCTPLBridgeStartup];
|
||||
[_performanceLogger markStartForTag:RCTPLTTI];
|
||||
|
||||
Class bridgeClass = self.bridgeClass;
|
||||
|
||||
// Only update bundleURL from delegate if delegate bundleURL has changed
|
||||
NSURL *previousDelegateURL = _delegateBundleURL;
|
||||
_delegateBundleURL = [self.delegate sourceURLForBridge:self];
|
||||
if (_delegateBundleURL && ![_delegateBundleURL isEqual:previousDelegateURL]) {
|
||||
_bundleURL = _delegateBundleURL;
|
||||
}
|
||||
|
||||
// Sanitize the bundle URL
|
||||
_bundleURL = [RCTConvert NSURL:_bundleURL.absoluteString];
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
RCTRegisterReloadCommandListener(self);
|
||||
RCTReloadCommandSetBundleURL(self->_bundleURL);
|
||||
});
|
||||
|
||||
self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
|
||||
[self.batchedBridge start];
|
||||
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
|
||||
- (BOOL)isLoading
|
||||
{
|
||||
return self.batchedBridge.loading;
|
||||
}
|
||||
|
||||
- (BOOL)isValid
|
||||
{
|
||||
return self.batchedBridge.valid;
|
||||
}
|
||||
|
||||
- (BOOL)isBatchActive
|
||||
{
|
||||
return [_batchedBridge isBatchActive];
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillBeInvalidatedNotification object:self];
|
||||
|
||||
RCTBridge *batchedBridge = self.batchedBridge;
|
||||
self.batchedBridge = nil;
|
||||
|
||||
if (batchedBridge) {
|
||||
RCTExecuteOnMainQueue(^{
|
||||
[batchedBridge invalidate];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance
|
||||
{
|
||||
[self.batchedBridge updateModuleWithInstance:instance];
|
||||
}
|
||||
|
||||
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules
|
||||
{
|
||||
[self.batchedBridge registerAdditionalModuleClasses:modules];
|
||||
}
|
||||
|
||||
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||
{
|
||||
NSArray<NSString *> *ids = [moduleDotMethod componentsSeparatedByString:@"."];
|
||||
NSString *module = ids[0];
|
||||
NSString *method = ids[1];
|
||||
[self enqueueJSCall:module method:method args:args completion:NULL];
|
||||
}
|
||||
|
||||
- (void)enqueueJSCall:(NSString *)module
|
||||
method:(NSString *)method
|
||||
args:(NSArray *)args
|
||||
completion:(dispatch_block_t)completion
|
||||
{
|
||||
[self.batchedBridge enqueueJSCall:module method:method args:args completion:completion];
|
||||
}
|
||||
|
||||
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args
|
||||
{
|
||||
[self.batchedBridge enqueueCallback:cbID args:args];
|
||||
}
|
||||
|
||||
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
|
||||
{
|
||||
[self.batchedBridge registerSegmentWithId:segmentId path:path];
|
||||
}
|
||||
|
||||
@end
|
79
node_modules/react-native/React/Base/RCTBridgeDelegate.h
generated
vendored
Normal file
79
node_modules/react-native/React/Base/RCTBridgeDelegate.h
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTJavaScriptLoader.h>
|
||||
|
||||
@class RCTBridge;
|
||||
@protocol RCTBridgeModule;
|
||||
|
||||
@protocol RCTBridgeDelegate <NSObject>
|
||||
|
||||
/**
|
||||
* The location of the JavaScript source file. When running from the packager
|
||||
* this should be an absolute URL, e.g. `http://localhost:8081/index.ios.bundle`.
|
||||
* When running from a locally bundled JS file, this should be a `file://` url
|
||||
* pointing to a path inside the app resources, e.g. `file://.../main.jsbundle`.
|
||||
*/
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* The bridge initializes any registered RCTBridgeModules automatically, however
|
||||
* if you wish to instantiate your own module instances, you can return them
|
||||
* from this method.
|
||||
*
|
||||
* Note: You should always return a new instance for each call, rather than
|
||||
* returning the same instance each time the bridge is reloaded. Module instances
|
||||
* should not be shared between bridges, and this may cause unexpected behavior.
|
||||
*
|
||||
* It is also possible to override standard modules with your own implementations
|
||||
* by returning a class with the same `moduleName` from this method, but this is
|
||||
* not recommended in most cases - if the module methods and behavior do not
|
||||
* match exactly, it may lead to bugs or crashes.
|
||||
*/
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge;
|
||||
|
||||
/**
|
||||
* Configure whether the JSCExecutor created should use the system JSC API or
|
||||
* alternative hooks provided. When returning YES from this method, you must have
|
||||
* previously called facebook::react::setCustomJSCWrapper.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
- (BOOL)shouldBridgeUseCustomJSC:(RCTBridge *)bridge;
|
||||
|
||||
/**
|
||||
* The bridge will call this method when a module been called from JS
|
||||
* cannot be found among registered modules.
|
||||
* It should return YES if the module with name 'moduleName' was registered
|
||||
* in the implementation, and the system must attempt to look for it again among registered.
|
||||
* If the module was not registered, return NO to prevent further searches.
|
||||
*/
|
||||
- (BOOL)bridge:(RCTBridge *)bridge didNotFindModule:(NSString *)moduleName;
|
||||
|
||||
/**
|
||||
* The bridge will automatically attempt to load the JS source code from the
|
||||
* location specified by the `sourceURLForBridge:` method, however, if you want
|
||||
* to handle loading the JS yourself, you can do so by implementing this method.
|
||||
*/
|
||||
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||
onComplete:(RCTSourceLoadBlock)loadCallback;
|
||||
|
||||
/**
|
||||
* Similar to loadSourceForBridge:onProgress:onComplete: but without progress
|
||||
* reporting.
|
||||
*/
|
||||
- (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback;
|
||||
|
||||
/**
|
||||
* Retrieve the list of lazy-native-modules names for the given bridge.
|
||||
*/
|
||||
- (NSDictionary<NSString *, Class> *)extraLazyModuleClassesForBridge:(RCTBridge *)bridge;
|
||||
|
||||
@end
|
37
node_modules/react-native/React/Base/RCTBridgeMethod.h
generated
vendored
Normal file
37
node_modules/react-native/React/Base/RCTBridgeMethod.h
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, RCTFunctionType) {
|
||||
RCTFunctionTypeNormal,
|
||||
RCTFunctionTypePromise,
|
||||
RCTFunctionTypeSync,
|
||||
};
|
||||
|
||||
static inline const char *RCTFunctionDescriptorFromType(RCTFunctionType type)
|
||||
{
|
||||
switch (type) {
|
||||
case RCTFunctionTypeNormal:
|
||||
return "async";
|
||||
case RCTFunctionTypePromise:
|
||||
return "promise";
|
||||
case RCTFunctionTypeSync:
|
||||
return "sync";
|
||||
}
|
||||
};
|
||||
|
||||
@protocol RCTBridgeMethod <NSObject>
|
||||
|
||||
@property (nonatomic, readonly) const char *JSMethodName;
|
||||
@property (nonatomic, readonly) RCTFunctionType functionType;
|
||||
|
||||
- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments;
|
||||
|
||||
@end
|
371
node_modules/react-native/React/Base/RCTBridgeModule.h
generated
vendored
Normal file
371
node_modules/react-native/React/Base/RCTBridgeModule.h
generated
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
@class RCTBridge;
|
||||
@protocol RCTBridgeMethod;
|
||||
|
||||
/**
|
||||
* The type of a block that is capable of sending a response to a bridged
|
||||
* operation. Use this for returning callback methods to JS.
|
||||
*/
|
||||
typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
||||
|
||||
/**
|
||||
* The type of a block that is capable of sending an error response to a
|
||||
* bridged operation. Use this for returning error information to JS.
|
||||
*/
|
||||
typedef void (^RCTResponseErrorBlock)(NSError *error);
|
||||
|
||||
/**
|
||||
* Block that bridge modules use to resolve the JS promise waiting for a result.
|
||||
* Nil results are supported and are converted to JS's undefined value.
|
||||
*/
|
||||
typedef void (^RCTPromiseResolveBlock)(id result);
|
||||
|
||||
/**
|
||||
* Block that bridge modules use to reject the JS promise waiting for a result.
|
||||
* The error may be nil but it is preferable to pass an NSError object for more
|
||||
* precise error messages.
|
||||
*/
|
||||
typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
|
||||
|
||||
/**
|
||||
* This constant can be returned from +methodQueue to force module
|
||||
* methods to be called on the JavaScript thread. This can have serious
|
||||
* implications for performance, so only use this if you're sure it's what
|
||||
* you need.
|
||||
*
|
||||
* NOTE: RCTJSThread is not a real libdispatch queue
|
||||
*/
|
||||
RCT_EXTERN dispatch_queue_t RCTJSThread;
|
||||
|
||||
RCT_EXTERN_C_BEGIN
|
||||
|
||||
typedef struct RCTMethodInfo {
|
||||
const char *const jsName;
|
||||
const char *const objcName;
|
||||
const BOOL isSync;
|
||||
} RCTMethodInfo;
|
||||
|
||||
RCT_EXTERN_C_END
|
||||
|
||||
/**
|
||||
* Provides the interface needed to register a bridge module.
|
||||
*/
|
||||
@protocol RCTBridgeModule <NSObject>
|
||||
|
||||
/**
|
||||
* Place this macro in your class implementation to automatically register
|
||||
* your module with the bridge when it loads. The optional js_name argument
|
||||
* will be used as the JS module name. If omitted, the JS module name will
|
||||
* match the Objective-C class name.
|
||||
*/
|
||||
#define RCT_EXPORT_MODULE(js_name) \
|
||||
RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+(NSString *)moduleName \
|
||||
{ \
|
||||
return @ #js_name; \
|
||||
} \
|
||||
+(void)load \
|
||||
{ \
|
||||
RCTRegisterModule(self); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module
|
||||
* registration. Useful for registering swift classes that forbids use of load
|
||||
* Used in RCT_EXTERN_REMAP_MODULE
|
||||
*/
|
||||
#define RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) \
|
||||
RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+(NSString *)moduleName \
|
||||
{ \
|
||||
return @ #js_name; \
|
||||
} \
|
||||
__attribute__((constructor)) static void RCT_CONCAT(initialize_, objc_name)() \
|
||||
{ \
|
||||
RCTRegisterModule([objc_name class]); \
|
||||
}
|
||||
|
||||
/**
|
||||
* To improve startup performance users may want to generate their module lists
|
||||
* at build time and hook the delegate to merge with the runtime list. This
|
||||
* macro takes the place of the above for those cases by omitting the +load
|
||||
* generation.
|
||||
*
|
||||
*/
|
||||
#define RCT_EXPORT_PRE_REGISTERED_MODULE(js_name) \
|
||||
+(NSString *)moduleName \
|
||||
{ \
|
||||
return @ #js_name; \
|
||||
}
|
||||
|
||||
// Implemented by RCT_EXPORT_MODULE
|
||||
+ (NSString *)moduleName;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* A reference to the RCTBridge. Useful for modules that require access
|
||||
* to bridge features, such as sending events or making JS calls. This
|
||||
* will be set automatically by the bridge when it initializes the module.
|
||||
* To implement this in your module, just add `@synthesize bridge = _bridge;`
|
||||
* If using Swift, add `@objc var bridge: RCTBridge!` to your module.
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) RCTBridge *bridge;
|
||||
|
||||
/**
|
||||
* The queue that will be used to call all exported methods. If omitted, this
|
||||
* will call on a default background queue, which is avoids blocking the main
|
||||
* thread.
|
||||
*
|
||||
* If the methods in your module need to interact with UIKit methods, they will
|
||||
* probably need to call those on the main thread, as most of UIKit is main-
|
||||
* thread-only. You can tell React Native to call your module methods on the
|
||||
* main thread by returning a reference to the main queue, like this:
|
||||
*
|
||||
* - (dispatch_queue_t)methodQueue
|
||||
* {
|
||||
* return dispatch_get_main_queue();
|
||||
* }
|
||||
*
|
||||
* If you don't want to specify the queue yourself, but you need to use it
|
||||
* inside your class (e.g. if you have internal methods that need to dispatch
|
||||
* onto that queue), you can just add `@synthesize methodQueue = _methodQueue;`
|
||||
* and the bridge will populate the methodQueue property for you automatically
|
||||
* when it initializes the module.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue;
|
||||
|
||||
/**
|
||||
* Wrap the parameter line of your method implementation with this macro to
|
||||
* expose it to JS. By default the exposed method will match the first part of
|
||||
* the Objective-C method selector name (up to the first colon). Use
|
||||
* RCT_REMAP_METHOD to specify the JS name of the method.
|
||||
*
|
||||
* For example, in ModuleName.m:
|
||||
*
|
||||
* - (void)doSomething:(NSString *)aString withA:(NSInteger)a andB:(NSInteger)b
|
||||
* { ... }
|
||||
*
|
||||
* becomes
|
||||
*
|
||||
* RCT_EXPORT_METHOD(doSomething:(NSString *)aString
|
||||
* withA:(NSInteger)a
|
||||
* andB:(NSInteger)b)
|
||||
* { ... }
|
||||
*
|
||||
* and is exposed to JavaScript as `NativeModules.ModuleName.doSomething`.
|
||||
*
|
||||
* ## Promises
|
||||
*
|
||||
* Bridge modules can also define methods that are exported to JavaScript as
|
||||
* methods that return a Promise, and are compatible with JS async functions.
|
||||
*
|
||||
* Declare the last two parameters of your native method to be a resolver block
|
||||
* and a rejecter block. The resolver block must precede the rejecter block.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* RCT_EXPORT_METHOD(doSomethingAsync:(NSString *)aString
|
||||
* resolver:(RCTPromiseResolveBlock)resolve
|
||||
* rejecter:(RCTPromiseRejectBlock)reject
|
||||
* { ... }
|
||||
*
|
||||
* Calling `NativeModules.ModuleName.doSomethingAsync(aString)` from
|
||||
* JavaScript will return a promise that is resolved or rejected when your
|
||||
* native method implementation calls the respective block.
|
||||
*
|
||||
*/
|
||||
#define RCT_EXPORT_METHOD(method) RCT_REMAP_METHOD(, method)
|
||||
|
||||
/**
|
||||
* Same as RCT_EXPORT_METHOD but the method is called from JS
|
||||
* synchronously **on the JS thread**, possibly returning a result.
|
||||
*
|
||||
* WARNING: in the vast majority of cases, you should use RCT_EXPORT_METHOD which
|
||||
* allows your native module methods to be called asynchronously: calling
|
||||
* methods synchronously can have strong performance penalties and introduce
|
||||
* threading-related bugs to your native modules.
|
||||
*
|
||||
* The return type must be of object type (id) and should be serializable
|
||||
* to JSON. This means that the hook can only return nil or JSON values
|
||||
* (e.g. NSNumber, NSString, NSArray, NSDictionary).
|
||||
*
|
||||
* Calling these methods when running under the websocket executor
|
||||
* is currently not supported.
|
||||
*/
|
||||
#define RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(method) RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(id, method)
|
||||
|
||||
#define RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(returnType, method) \
|
||||
RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(, returnType, method)
|
||||
|
||||
/**
|
||||
* Similar to RCT_EXPORT_METHOD but lets you set the JS name of the exported
|
||||
* method. Example usage:
|
||||
*
|
||||
* RCT_REMAP_METHOD(executeQueryWithParameters,
|
||||
* executeQuery:(NSString *)query parameters:(NSDictionary *)parameters)
|
||||
* { ... }
|
||||
*/
|
||||
#define RCT_REMAP_METHOD(js_name, method) \
|
||||
_RCT_EXTERN_REMAP_METHOD(js_name, method, NO) \
|
||||
-(void)method RCT_DYNAMIC;
|
||||
|
||||
/**
|
||||
* Similar to RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD but lets you set
|
||||
* the JS name of the exported method. Example usage:
|
||||
*
|
||||
* RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(executeQueryWithParameters,
|
||||
* executeQuery:(NSString *)query parameters:(NSDictionary *)parameters)
|
||||
* { ... }
|
||||
*/
|
||||
#define RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(js_name, returnType, method) \
|
||||
_RCT_EXTERN_REMAP_METHOD(js_name, method, YES) \
|
||||
-(returnType)method RCT_DYNAMIC;
|
||||
|
||||
/**
|
||||
* Use this macro in a private Objective-C implementation file to automatically
|
||||
* register an external module with the bridge when it loads. This allows you to
|
||||
* register Swift or private Objective-C classes with the bridge.
|
||||
*
|
||||
* For example if one wanted to export a Swift class to the bridge:
|
||||
*
|
||||
* MyModule.swift:
|
||||
*
|
||||
* @objc(MyModule) class MyModule: NSObject {
|
||||
*
|
||||
* @objc func doSomething(string: String! withFoo a: Int, bar b: Int) { ... }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* MyModuleExport.m:
|
||||
*
|
||||
* #import <React/RCTBridgeModule.h>
|
||||
*
|
||||
* @interface RCT_EXTERN_MODULE(MyModule, NSObject)
|
||||
*
|
||||
* RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b)
|
||||
*
|
||||
* @end
|
||||
*
|
||||
* This will now expose MyModule and the method to JavaScript via
|
||||
* `NativeModules.MyModule.doSomething`
|
||||
*/
|
||||
#define RCT_EXTERN_MODULE(objc_name, objc_supername) RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername)
|
||||
|
||||
/**
|
||||
* Like RCT_EXTERN_MODULE, but allows setting a custom JavaScript name.
|
||||
*/
|
||||
#define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \
|
||||
objc_name: \
|
||||
objc_supername @ \
|
||||
end @interface objc_name(RCTExternModule)<RCTBridgeModule> \
|
||||
@end \
|
||||
@implementation objc_name (RCTExternModule) \
|
||||
RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name)
|
||||
|
||||
/**
|
||||
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
|
||||
* of an external module.
|
||||
*/
|
||||
#define RCT_EXTERN_METHOD(method) _RCT_EXTERN_REMAP_METHOD(, method, NO)
|
||||
|
||||
/**
|
||||
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
|
||||
* of an external module that should be invoked synchronously.
|
||||
*/
|
||||
#define RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(method) _RCT_EXTERN_REMAP_METHOD(, method, YES)
|
||||
|
||||
/**
|
||||
* Like RCT_EXTERN_REMAP_METHOD, but allows setting a custom JavaScript name
|
||||
* and also whether this method is synchronous.
|
||||
*/
|
||||
#define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
|
||||
+(const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) \
|
||||
{ \
|
||||
static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
|
||||
return &config; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Most modules can be used from any thread. All of the modules exported non-sync method will be called on its
|
||||
* methodQueue, and the module will be constructed lazily when its first invoked. Some modules have main need to access
|
||||
* information that's main queue only (e.g. most UIKit classes). Since we don't want to dispatch synchronously to the
|
||||
* main thread to this safely, we construct these modules and export their constants ahead-of-time.
|
||||
*
|
||||
* Note that when set to false, the module constructor will be called from any thread.
|
||||
*
|
||||
* This requirement is currently inferred by checking if the module has a custom initializer or if there's exported
|
||||
* constants. In the future, we'll stop automatically inferring this and instead only rely on this method.
|
||||
*/
|
||||
+ (BOOL)requiresMainQueueSetup;
|
||||
|
||||
/**
|
||||
* Injects methods into JS. Entries in this array are used in addition to any
|
||||
* methods defined using the macros above. This method is called only once,
|
||||
* before registration.
|
||||
*/
|
||||
- (NSArray<id<RCTBridgeMethod>> *)methodsToExport;
|
||||
|
||||
/**
|
||||
* Injects constants into JS. These constants are made accessible via NativeModules.ModuleName.X. It is only called once
|
||||
* for the lifetime of the bridge, so it is not suitable for returning dynamic values, but may be used for long-lived
|
||||
* values such as session keys, that are regenerated only as part of a reload of the entire React application.
|
||||
*
|
||||
* If you implement this method and do not implement `requiresMainQueueSetup`, you will trigger deprecated logic
|
||||
* that eagerly initializes your module on bridge startup. In the future, this behaviour will be changed to default
|
||||
* to initializing lazily, and even modules with constants will be initialized lazily.
|
||||
*/
|
||||
- (NSDictionary *)constantsToExport;
|
||||
|
||||
/**
|
||||
* Notifies the module that a batch of JS method invocations has just completed.
|
||||
*/
|
||||
- (void)batchDidComplete;
|
||||
|
||||
/**
|
||||
* Notifies the module that the active batch of JS method invocations has been
|
||||
* partially flushed.
|
||||
*
|
||||
* This occurs before -batchDidComplete, and more frequently.
|
||||
*/
|
||||
- (void)partialBatchDidFlush;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* A protocol that allows TurboModules to do lookup on other TurboModules.
|
||||
* Calling these methods may cause a module to be synchronously instantiated.
|
||||
*/
|
||||
@protocol RCTTurboModuleLookupDelegate <NSObject>
|
||||
- (id)moduleForName:(const char *)moduleName;
|
||||
|
||||
/**
|
||||
* Rationale:
|
||||
* When TurboModules lookup other modules by name, we first check the TurboModule
|
||||
* registry to see if a TurboModule exists with the respective name. In this case,
|
||||
* we don't want a RedBox to be raised if the TurboModule isn't found.
|
||||
*
|
||||
* This method is deprecated and will be deleted after the migration from
|
||||
* TurboModules to TurboModules is complete.
|
||||
*/
|
||||
- (id)moduleForName:(const char *)moduleName warnOnLookupFailure:(BOOL)warnOnLookupFailure;
|
||||
- (BOOL)moduleIsInitialized:(const char *)moduleName;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
* A protocol to declare that a class supports TurboModule.
|
||||
* This may be removed in the future.
|
||||
* See RCTTurboModule.h for actual signature.
|
||||
*/
|
||||
@protocol RCTTurboModule;
|
110
node_modules/react-native/React/Base/RCTBundleURLProvider.h
generated
vendored
Normal file
110
node_modules/react-native/React/Base/RCTBundleURLProvider.h
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern NSString *const RCTBundleURLProviderUpdatedNotification;
|
||||
|
||||
extern const NSUInteger kRCTBundleURLProviderDefaultPort;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
@interface RCTBundleURLProvider : NSObject
|
||||
|
||||
/**
|
||||
* Set default settings on NSUserDefaults.
|
||||
*/
|
||||
- (void)setDefaults;
|
||||
|
||||
/**
|
||||
* Reset every settings to default.
|
||||
*/
|
||||
- (void)resetToDefaults;
|
||||
|
||||
/**
|
||||
* Return the server host. If its a development build and there's no jsLocation defined,
|
||||
* it will return the server host IP address
|
||||
*/
|
||||
- (NSString *)packagerServerHost;
|
||||
|
||||
#if RCT_DEV
|
||||
- (BOOL)isPackagerRunning:(NSString *)host;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the jsBundleURL for a given bundle entrypoint and
|
||||
* the fallback offline JS bundle if the packager is not running.
|
||||
*/
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackURLProvider:(NSURL * (^)(void))fallbackURLProvider;
|
||||
|
||||
/**
|
||||
* Returns the jsBundleURL for a given bundle entrypoint and
|
||||
* the fallback offline JS bundle if the packager is not running.
|
||||
* if resourceName or extension are nil, "main" and "jsbundle" will be
|
||||
* used, respectively.
|
||||
*/
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
||||
fallbackResource:(NSString *)resourceName
|
||||
fallbackExtension:(NSString *)extension;
|
||||
|
||||
/**
|
||||
* Returns the jsBundleURL for a given bundle entrypoint and
|
||||
* the fallback offline JS bundle if the packager is not running.
|
||||
*/
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackResource:(NSString *)resourceName;
|
||||
|
||||
/**
|
||||
* Returns the jsBundleURL for a given bundle entrypoint and
|
||||
* the fallback offline JS bundle. If resourceName or extension
|
||||
* are nil, "main" and "jsbundle" will be used, respectively.
|
||||
*/
|
||||
- (NSURL *)jsBundleURLForFallbackResource:(NSString *)resourceName fallbackExtension:(NSString *)extension;
|
||||
|
||||
/**
|
||||
* Returns the resourceURL for a given bundle entrypoint and
|
||||
* the fallback offline resource file if the packager is not running.
|
||||
*/
|
||||
- (NSURL *)resourceURLForResourceRoot:(NSString *)root
|
||||
resourceName:(NSString *)name
|
||||
resourceExtension:(NSString *)extension
|
||||
offlineBundle:(NSBundle *)offlineBundle;
|
||||
|
||||
/**
|
||||
* The IP address or hostname of the packager.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *jsLocation;
|
||||
|
||||
@property (nonatomic, assign) BOOL enableLiveReload;
|
||||
@property (nonatomic, assign) BOOL enableMinification;
|
||||
@property (nonatomic, assign) BOOL enableDev;
|
||||
|
||||
+ (instancetype)sharedSettings;
|
||||
|
||||
/**
|
||||
Given a hostname for the packager and a bundle root, returns the URL to the js bundle. Generally you should use the
|
||||
instance method -jsBundleURLForBundleRoot:fallbackResource: which includes logic to guess if the packager is running
|
||||
and fall back to a pre-packaged bundle if it is not.
|
||||
*/
|
||||
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
||||
packagerHost:(NSString *)packagerHost
|
||||
enableDev:(BOOL)enableDev
|
||||
enableMinification:(BOOL)enableMinification;
|
||||
|
||||
/**
|
||||
* Given a hostname for the packager and a resource path (including "/"), return the URL to the resource.
|
||||
* In general, please use the instance method to decide if the packager is running and fallback to the pre-packaged
|
||||
* resource if it is not: -resourceURLForResourceRoot:resourceName:resourceExtension:offlineBundle:
|
||||
*/
|
||||
+ (NSURL *)resourceURLForResourcePath:(NSString *)path packagerHost:(NSString *)packagerHost query:(NSString *)query;
|
||||
|
||||
@end
|
261
node_modules/react-native/React/Base/RCTBundleURLProvider.m
generated
vendored
Normal file
261
node_modules/react-native/React/Base/RCTBundleURLProvider.m
generated
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTBundleURLProvider.h"
|
||||
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTDefines.h"
|
||||
|
||||
NSString *const RCTBundleURLProviderUpdatedNotification = @"RCTBundleURLProviderUpdatedNotification";
|
||||
|
||||
const NSUInteger kRCTBundleURLProviderDefaultPort = RCT_METRO_PORT;
|
||||
|
||||
static NSString *const kRCTJsLocationKey = @"RCT_jsLocation";
|
||||
// This option is no longer exposed in the dev menu UI.
|
||||
// It was renamed in D15958697 so it doesn't get stuck with no way to turn it off:
|
||||
static NSString *const kRCTEnableLiveReloadKey = @"RCT_enableLiveReload_LEGACY";
|
||||
static NSString *const kRCTEnableDevKey = @"RCT_enableDev";
|
||||
static NSString *const kRCTEnableMinificationKey = @"RCT_enableMinification";
|
||||
|
||||
@implementation RCTBundleURLProvider
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self setDefaults];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)defaults
|
||||
{
|
||||
return @{
|
||||
kRCTEnableLiveReloadKey : @NO,
|
||||
kRCTEnableDevKey : @YES,
|
||||
kRCTEnableMinificationKey : @NO,
|
||||
};
|
||||
}
|
||||
|
||||
- (void)settingsUpdated
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBundleURLProviderUpdatedNotification object:self];
|
||||
}
|
||||
|
||||
- (void)setDefaults
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:[self defaults]];
|
||||
}
|
||||
|
||||
- (void)resetToDefaults
|
||||
{
|
||||
for (NSString *key in [[self defaults] allKeys]) {
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
|
||||
}
|
||||
[self setDefaults];
|
||||
[self settingsUpdated];
|
||||
}
|
||||
|
||||
static NSURL *serverRootWithHostPort(NSString *hostPort)
|
||||
{
|
||||
if ([hostPort rangeOfString:@":"].location != NSNotFound) {
|
||||
return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/", hostPort]];
|
||||
}
|
||||
return [NSURL
|
||||
URLWithString:[NSString
|
||||
stringWithFormat:@"http://%@:%lu/", hostPort, (unsigned long)kRCTBundleURLProviderDefaultPort]];
|
||||
}
|
||||
|
||||
#if RCT_DEV
|
||||
- (BOOL)isPackagerRunning:(NSString *)host
|
||||
{
|
||||
NSURL *url = [serverRootWithHostPort(host) URLByAppendingPathComponent:@"status"];
|
||||
|
||||
NSURLSession *session = [NSURLSession sharedSession];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
||||
__block NSURLResponse *response;
|
||||
__block NSData *data;
|
||||
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
[[session dataTaskWithRequest:request
|
||||
completionHandler:^(NSData *d, NSURLResponse *res, __unused NSError *err) {
|
||||
data = d;
|
||||
response = res;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}] resume];
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
NSString *status = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
return [status isEqualToString:@"packager-status:running"];
|
||||
}
|
||||
|
||||
- (NSString *)guessPackagerHost
|
||||
{
|
||||
static NSString *ipGuess;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *ipPath = [[NSBundle mainBundle] pathForResource:@"ip" ofType:@"txt"];
|
||||
ipGuess =
|
||||
[[NSString stringWithContentsOfFile:ipPath encoding:NSUTF8StringEncoding
|
||||
error:nil] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
||||
});
|
||||
|
||||
NSString *host = ipGuess ?: @"localhost";
|
||||
if ([self isPackagerRunning:host]) {
|
||||
return host;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (NSString *)packagerServerHost
|
||||
{
|
||||
NSString *location = [self jsLocation];
|
||||
if (location != nil) {
|
||||
return location;
|
||||
}
|
||||
#if RCT_DEV
|
||||
NSString *host = [self guessPackagerHost];
|
||||
if (host) {
|
||||
return host;
|
||||
}
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackURLProvider:(NSURL * (^)(void))fallbackURLProvider
|
||||
{
|
||||
NSString *packagerServerHost = [self packagerServerHost];
|
||||
if (!packagerServerHost) {
|
||||
return fallbackURLProvider();
|
||||
} else {
|
||||
return [RCTBundleURLProvider jsBundleURLForBundleRoot:bundleRoot
|
||||
packagerHost:packagerServerHost
|
||||
enableDev:[self enableDev]
|
||||
enableMinification:[self enableMinification]];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
||||
fallbackResource:(NSString *)resourceName
|
||||
fallbackExtension:(NSString *)extension
|
||||
{
|
||||
return [self jsBundleURLForBundleRoot:bundleRoot
|
||||
fallbackURLProvider:^NSURL * {
|
||||
return [self jsBundleURLForFallbackResource:resourceName fallbackExtension:extension];
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackResource:(NSString *)resourceName
|
||||
{
|
||||
return [self jsBundleURLForBundleRoot:bundleRoot fallbackResource:resourceName fallbackExtension:nil];
|
||||
}
|
||||
|
||||
- (NSURL *)jsBundleURLForFallbackResource:(NSString *)resourceName fallbackExtension:(NSString *)extension
|
||||
{
|
||||
resourceName = resourceName ?: @"main";
|
||||
extension = extension ?: @"jsbundle";
|
||||
return [[NSBundle mainBundle] URLForResource:resourceName withExtension:extension];
|
||||
}
|
||||
|
||||
- (NSURL *)resourceURLForResourceRoot:(NSString *)root
|
||||
resourceName:(NSString *)name
|
||||
resourceExtension:(NSString *)extension
|
||||
offlineBundle:(NSBundle *)offlineBundle
|
||||
{
|
||||
NSString *packagerServerHost = [self packagerServerHost];
|
||||
if (!packagerServerHost) {
|
||||
// Serve offline bundle (local file)
|
||||
NSBundle *bundle = offlineBundle ?: [NSBundle mainBundle];
|
||||
return [bundle URLForResource:name withExtension:extension];
|
||||
}
|
||||
NSString *path = [NSString stringWithFormat:@"/%@/%@.%@", root, name, extension];
|
||||
return [[self class] resourceURLForResourcePath:path packagerHost:packagerServerHost query:nil];
|
||||
}
|
||||
|
||||
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
||||
packagerHost:(NSString *)packagerHost
|
||||
enableDev:(BOOL)enableDev
|
||||
enableMinification:(BOOL)enableMinification
|
||||
{
|
||||
NSString *path = [NSString stringWithFormat:@"/%@.bundle", bundleRoot];
|
||||
// When we support only iOS 8 and above, use queryItems for a better API.
|
||||
NSString *query = [NSString stringWithFormat:@"platform=ios&dev=%@&minify=%@",
|
||||
enableDev ? @"true" : @"false",
|
||||
enableMinification ? @"true" : @"false"];
|
||||
return [[self class] resourceURLForResourcePath:path packagerHost:packagerHost query:query];
|
||||
}
|
||||
|
||||
+ (NSURL *)resourceURLForResourcePath:(NSString *)path packagerHost:(NSString *)packagerHost query:(NSString *)query
|
||||
{
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHostPort(packagerHost)
|
||||
resolvingAgainstBaseURL:NO];
|
||||
components.path = path;
|
||||
if (query != nil) {
|
||||
components.query = query;
|
||||
}
|
||||
return components.URL;
|
||||
}
|
||||
|
||||
- (void)updateValue:(id)object forKey:(NSString *)key
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
[self settingsUpdated];
|
||||
}
|
||||
|
||||
- (BOOL)enableDev
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableDevKey];
|
||||
}
|
||||
|
||||
- (BOOL)enableLiveReload
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableLiveReloadKey];
|
||||
}
|
||||
|
||||
- (BOOL)enableMinification
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableMinificationKey];
|
||||
}
|
||||
|
||||
- (NSString *)jsLocation
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults] stringForKey:kRCTJsLocationKey];
|
||||
}
|
||||
|
||||
- (void)setEnableDev:(BOOL)enableDev
|
||||
{
|
||||
[self updateValue:@(enableDev) forKey:kRCTEnableDevKey];
|
||||
}
|
||||
|
||||
- (void)setEnableLiveReload:(BOOL)enableLiveReload
|
||||
{
|
||||
[self updateValue:@(enableLiveReload) forKey:kRCTEnableLiveReloadKey];
|
||||
}
|
||||
|
||||
- (void)setJsLocation:(NSString *)jsLocation
|
||||
{
|
||||
[self updateValue:jsLocation forKey:kRCTJsLocationKey];
|
||||
}
|
||||
|
||||
- (void)setEnableMinification:(BOOL)enableMinification
|
||||
{
|
||||
[self updateValue:@(enableMinification) forKey:kRCTEnableMinificationKey];
|
||||
}
|
||||
|
||||
+ (instancetype)sharedSettings
|
||||
{
|
||||
static RCTBundleURLProvider *sharedInstance;
|
||||
static dispatch_once_t once_token;
|
||||
dispatch_once(&once_token, ^{
|
||||
sharedInstance = [RCTBundleURLProvider new];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
@end
|
23
node_modules/react-native/React/Base/RCTComponentEvent.h
generated
vendored
Normal file
23
node_modules/react-native/React/Base/RCTComponentEvent.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Generic untyped event for Components. Used internally by RCTDirectEventBlock and
|
||||
* RCTBubblingEventBlock, for other use cases prefer using a class that implements
|
||||
* RCTEvent to have a type safe way to initialize it.
|
||||
*/
|
||||
@interface RCTComponentEvent : NSObject <RCTEvent>
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag body:(NSDictionary *)body;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@end
|
49
node_modules/react-native/React/Base/RCTComponentEvent.m
generated
vendored
Normal file
49
node_modules/react-native/React/Base/RCTComponentEvent.m
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTComponentEvent.h"
|
||||
|
||||
#import "RCTAssert.h"
|
||||
|
||||
@implementation RCTComponentEvent {
|
||||
NSArray *_arguments;
|
||||
}
|
||||
|
||||
@synthesize eventName = _eventName;
|
||||
@synthesize viewTag = _viewTag;
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag body:(NSDictionary *)body
|
||||
{
|
||||
if (self = [super init]) {
|
||||
NSMutableDictionary *mutableBody = [NSMutableDictionary dictionaryWithDictionary:body];
|
||||
mutableBody[@"target"] = viewTag;
|
||||
|
||||
_eventName = RCTNormalizeInputEventName(name);
|
||||
_viewTag = viewTag;
|
||||
_arguments = @[ _viewTag, _eventName, mutableBody ];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
- (NSArray *)arguments
|
||||
{
|
||||
return _arguments;
|
||||
}
|
||||
|
||||
- (BOOL)canCoalesce
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString *)moduleDotMethod
|
||||
{
|
||||
return @"RCTEventEmitter.receiveEvent";
|
||||
}
|
||||
|
||||
@end
|
11
node_modules/react-native/React/Base/RCTConstants.h
generated
vendored
Normal file
11
node_modules/react-native/React/Base/RCTConstants.h
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
|
||||
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;
|
11
node_modules/react-native/React/Base/RCTConstants.m
generated
vendored
Normal file
11
node_modules/react-native/React/Base/RCTConstants.m
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTConstants.h"
|
||||
|
||||
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
|
||||
NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey = @"traitCollection";
|
263
node_modules/react-native/React/Base/RCTConvert.h
generated
vendored
Normal file
263
node_modules/react-native/React/Base/RCTConvert.h
generated
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTAnimationType.h>
|
||||
#import <React/RCTBorderStyle.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTPointerEvents.h>
|
||||
#import <React/RCTTextDecorationLineType.h>
|
||||
#import <yoga/Yoga.h>
|
||||
#if TARGET_OS_IPHONE && WEBKIT_IOS_10_APIS_AVAILABLE
|
||||
#import <WebKit/WebKit.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class provides a collection of conversion functions for mapping
|
||||
* JSON objects to native types and classes. These are useful when writing
|
||||
* custom RCTViewManager setter methods.
|
||||
*/
|
||||
@interface RCTConvert : NSObject
|
||||
|
||||
+ (id)id:(id)json;
|
||||
|
||||
+ (BOOL)BOOL:(id)json;
|
||||
+ (double)double:(id)json;
|
||||
+ (float)float:(id)json;
|
||||
+ (int)int:(id)json;
|
||||
|
||||
+ (int64_t)int64_t:(id)json;
|
||||
+ (uint64_t)uint64_t:(id)json;
|
||||
|
||||
+ (NSInteger)NSInteger:(id)json;
|
||||
+ (NSUInteger)NSUInteger:(id)json;
|
||||
|
||||
+ (NSArray *)NSArray:(id)json;
|
||||
+ (NSDictionary *)NSDictionary:(id)json;
|
||||
+ (NSString *)NSString:(id)json;
|
||||
+ (NSNumber *)NSNumber:(id)json;
|
||||
|
||||
+ (NSSet *)NSSet:(id)json;
|
||||
+ (NSData *)NSData:(id)json;
|
||||
+ (NSIndexSet *)NSIndexSet:(id)json;
|
||||
|
||||
+ (NSURLRequestCachePolicy)NSURLRequestCachePolicy:(id)json;
|
||||
+ (NSURL *)NSURL:(id)json;
|
||||
+ (NSURLRequest *)NSURLRequest:(id)json;
|
||||
|
||||
typedef NSURL RCTFileURL;
|
||||
+ (RCTFileURL *)RCTFileURL:(id)json;
|
||||
|
||||
+ (NSDate *)NSDate:(id)json;
|
||||
+ (NSLocale *)NSLocale:(id)json;
|
||||
+ (NSTimeZone *)NSTimeZone:(id)json;
|
||||
+ (NSTimeInterval)NSTimeInterval:(id)json;
|
||||
|
||||
+ (NSLineBreakMode)NSLineBreakMode:(id)json;
|
||||
+ (NSTextAlignment)NSTextAlignment:(id)json;
|
||||
+ (NSUnderlineStyle)NSUnderlineStyle:(id)json;
|
||||
+ (NSWritingDirection)NSWritingDirection:(id)json;
|
||||
+ (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
|
||||
+ (UITextFieldViewMode)UITextFieldViewMode:(id)json;
|
||||
+ (UIKeyboardType)UIKeyboardType:(id)json;
|
||||
+ (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
|
||||
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
|
||||
#if !TARGET_OS_TV
|
||||
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IPHONE && WEBKIT_IOS_10_APIS_AVAILABLE
|
||||
+ (WKDataDetectorTypes)WKDataDetectorTypes:(id)json;
|
||||
#endif
|
||||
|
||||
+ (UIViewContentMode)UIViewContentMode:(id)json;
|
||||
#if !TARGET_OS_TV
|
||||
+ (UIBarStyle)UIBarStyle:(id)json;
|
||||
#endif
|
||||
|
||||
+ (CGFloat)CGFloat:(id)json;
|
||||
+ (CGPoint)CGPoint:(id)json;
|
||||
+ (CGSize)CGSize:(id)json;
|
||||
+ (CGRect)CGRect:(id)json;
|
||||
+ (UIEdgeInsets)UIEdgeInsets:(id)json;
|
||||
|
||||
+ (CGLineCap)CGLineCap:(id)json;
|
||||
+ (CGLineJoin)CGLineJoin:(id)json;
|
||||
|
||||
+ (CGAffineTransform)CGAffineTransform:(id)json;
|
||||
|
||||
+ (UIColor *)UIColor:(id)json;
|
||||
+ (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
|
||||
|
||||
+ (YGValue)YGValue:(id)json;
|
||||
|
||||
+ (NSArray<NSArray *> *)NSArrayArray:(id)json;
|
||||
+ (NSArray<NSString *> *)NSStringArray:(id)json;
|
||||
+ (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
|
||||
+ (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
|
||||
+ (NSArray<NSURL *> *)NSURLArray:(id)json;
|
||||
+ (NSArray<RCTFileURL *> *)RCTFileURLArray:(id)json;
|
||||
+ (NSArray<NSNumber *> *)NSNumberArray:(id)json;
|
||||
+ (NSArray<UIColor *> *)UIColorArray:(id)json;
|
||||
|
||||
typedef NSArray CGColorArray;
|
||||
+ (CGColorArray *)CGColorArray:(id)json;
|
||||
|
||||
/**
|
||||
* Convert a JSON object to a Plist-safe equivalent by stripping null values.
|
||||
*/
|
||||
typedef id NSPropertyList;
|
||||
+ (NSPropertyList)NSPropertyList:(id)json;
|
||||
|
||||
typedef BOOL css_backface_visibility_t;
|
||||
+ (YGOverflow)YGOverflow:(id)json;
|
||||
+ (YGDisplay)YGDisplay:(id)json;
|
||||
+ (css_backface_visibility_t)css_backface_visibility_t:(id)json;
|
||||
+ (YGFlexDirection)YGFlexDirection:(id)json;
|
||||
+ (YGJustify)YGJustify:(id)json;
|
||||
+ (YGAlign)YGAlign:(id)json;
|
||||
+ (YGPositionType)YGPositionType:(id)json;
|
||||
+ (YGWrap)YGWrap:(id)json;
|
||||
+ (YGDirection)YGDirection:(id)json;
|
||||
|
||||
+ (RCTPointerEvents)RCTPointerEvents:(id)json;
|
||||
+ (RCTAnimationType)RCTAnimationType:(id)json;
|
||||
+ (RCTBorderStyle)RCTBorderStyle:(id)json;
|
||||
+ (RCTTextDecorationLineType)RCTTextDecorationLineType:(id)json;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTConvert (Deprecated)
|
||||
|
||||
/**
|
||||
* Use lightweight generics syntax instead, e.g. NSArray<NSString *>
|
||||
*/
|
||||
typedef NSArray NSArrayArray __deprecated_msg("Use NSArray<NSArray *>");
|
||||
typedef NSArray NSStringArray __deprecated_msg("Use NSArray<NSString *>");
|
||||
typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray<NSArray<NSString *> *>");
|
||||
typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray<NSDictionary *>");
|
||||
typedef NSArray NSURLArray __deprecated_msg("Use NSArray<NSURL *>");
|
||||
typedef NSArray RCTFileURLArray __deprecated_msg("Use NSArray<RCTFileURL *>");
|
||||
typedef NSArray NSNumberArray __deprecated_msg("Use NSArray<NSNumber *>");
|
||||
typedef NSArray UIColorArray __deprecated_msg("Use NSArray<UIColor *>");
|
||||
|
||||
/**
|
||||
* Synchronous image loading is generally a bad idea for performance reasons.
|
||||
* If you need to pass image references, try to use `RCTImageSource` and then
|
||||
* `RCTImageLoader` instead of converting directly to a UIImage.
|
||||
*/
|
||||
+ (UIImage *)UIImage:(id)json;
|
||||
+ (CGImageRef)CGImage:(id)json CF_RETURNS_NOT_RETAINED;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Underlying implementations of RCT_XXX_CONVERTER macros. Ignore these.
|
||||
*/
|
||||
RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
|
||||
RCT_EXTERN NSNumber *RCTConvertMultiEnumValue(const char *, NSDictionary *, NSNumber *, id);
|
||||
RCT_EXTERN NSArray *RCTConvertArrayValue(SEL, id);
|
||||
|
||||
/**
|
||||
* This macro is used for logging conversion errors. This is just used to
|
||||
* avoid repeating the same boilerplate for every error message.
|
||||
*/
|
||||
#define RCTLogConvertError(json, typeName) \
|
||||
RCTLogError(@"JSON value '%@' of type %@ cannot be converted to %@", json, [json classForCoder], typeName)
|
||||
|
||||
/**
|
||||
* This macro is used for creating simple converter functions that just call
|
||||
* the specified getter method on the json value.
|
||||
*/
|
||||
#define RCT_CONVERTER(type, name, getter) RCT_CUSTOM_CONVERTER(type, name, [json getter])
|
||||
|
||||
/**
|
||||
* This macro is used for creating converter functions with arbitrary logic.
|
||||
*/
|
||||
#define RCT_CUSTOM_CONVERTER(type, name, code) \
|
||||
+(type)name : (id)json RCT_DYNAMIC \
|
||||
{ \
|
||||
if (!RCT_DEBUG) { \
|
||||
return code; \
|
||||
} else { \
|
||||
@try { \
|
||||
return code; \
|
||||
} @catch (__unused NSException * e) { \
|
||||
RCTLogConvertError(json, @ #type); \
|
||||
json = nil; \
|
||||
return code; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* This macro is similar to RCT_CONVERTER, but specifically geared towards
|
||||
* numeric types. It will handle string input correctly, and provides more
|
||||
* detailed error reporting if an invalid value is passed in.
|
||||
*/
|
||||
#define RCT_NUMBER_CONVERTER(type, getter) \
|
||||
RCT_CUSTOM_CONVERTER(type, type, [RCT_DEBUG ? [self NSNumber:json] : json getter])
|
||||
|
||||
/**
|
||||
* When using RCT_ENUM_CONVERTER in ObjC, the compiler is OK with us returning
|
||||
* the underlying NSInteger/NSUInteger. In ObjC++, this is a type mismatch and
|
||||
* we need to explicitly cast the return value to expected enum return type.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define _RCT_CAST(type, expr) static_cast<type>(expr)
|
||||
#else
|
||||
#define _RCT_CAST(type, expr) expr
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This macro is used for creating converters for enum types.
|
||||
*/
|
||||
#define RCT_ENUM_CONVERTER(type, values, default, getter) \
|
||||
+(type)type : (id)json RCT_DYNAMIC \
|
||||
{ \
|
||||
static NSDictionary *mapping; \
|
||||
static dispatch_once_t onceToken; \
|
||||
dispatch_once(&onceToken, ^{ \
|
||||
mapping = values; \
|
||||
}); \
|
||||
return _RCT_CAST(type, [RCTConvertEnumValue(#type, mapping, @(default), json) getter]); \
|
||||
}
|
||||
|
||||
/**
|
||||
* This macro is used for creating converters for enum types for
|
||||
* multiple enum values combined with | operator
|
||||
*/
|
||||
#define RCT_MULTI_ENUM_CONVERTER(type, values, default, getter) \
|
||||
+(type)type : (id)json RCT_DYNAMIC \
|
||||
{ \
|
||||
static NSDictionary *mapping; \
|
||||
static dispatch_once_t onceToken; \
|
||||
dispatch_once(&onceToken, ^{ \
|
||||
mapping = values; \
|
||||
}); \
|
||||
return _RCT_CAST(type, [RCTConvertMultiEnumValue(#type, mapping, @(default), json) getter]); \
|
||||
}
|
||||
|
||||
/**
|
||||
* This macro is used for creating explicitly-named converter functions
|
||||
* for typed arrays.
|
||||
*/
|
||||
#define RCT_ARRAY_CONVERTER_NAMED(type, name) \
|
||||
+(NSArray<type *> *)name##Array : (id)json RCT_DYNAMIC \
|
||||
{ \
|
||||
return RCTConvertArrayValue(@selector(name:), json); \
|
||||
}
|
||||
|
||||
/**
|
||||
* This macro is used for creating converter functions for typed arrays.
|
||||
* RCT_ARRAY_CONVERTER_NAMED may be used when type contains characters
|
||||
* which are disallowed in selector names.
|
||||
*/
|
||||
#define RCT_ARRAY_CONVERTER(type) RCT_ARRAY_CONVERTER_NAMED(type, type)
|
1241
node_modules/react-native/React/Base/RCTConvert.m
generated
vendored
Normal file
1241
node_modules/react-native/React/Base/RCTConvert.m
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
18
node_modules/react-native/React/Base/RCTCxxConvert.h
generated
vendored
Normal file
18
node_modules/react-native/React/Base/RCTCxxConvert.h
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* This class provides a collection of conversion functions for mapping
|
||||
* JSON objects to cxx types. Extensible via categories.
|
||||
* Convert methods are expected to return cxx objects wraped in RCTManagedPointer.
|
||||
*/
|
||||
|
||||
@interface RCTCxxConvert : NSObject
|
||||
|
||||
@end
|
12
node_modules/react-native/React/Base/RCTCxxConvert.m
generated
vendored
Normal file
12
node_modules/react-native/React/Base/RCTCxxConvert.m
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTCxxConvert.h"
|
||||
|
||||
@implementation RCTCxxConvert
|
||||
|
||||
@end
|
149
node_modules/react-native/React/Base/RCTDefines.h
generated
vendored
Normal file
149
node_modules/react-native/React/Base/RCTDefines.h
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#if __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Make global functions usable in C++
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
#define RCT_EXTERN extern "C" __attribute__((visibility("default")))
|
||||
#define RCT_EXTERN_C_BEGIN extern "C" {
|
||||
#define RCT_EXTERN_C_END }
|
||||
#else
|
||||
#define RCT_EXTERN extern __attribute__((visibility("default")))
|
||||
#define RCT_EXTERN_C_BEGIN
|
||||
#define RCT_EXTERN_C_END
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The RCT_DEBUG macro can be used to exclude error checking and logging code
|
||||
* from release builds to improve performance and reduce binary size.
|
||||
*/
|
||||
#ifndef RCT_DEBUG
|
||||
#if DEBUG
|
||||
#define RCT_DEBUG 1
|
||||
#else
|
||||
#define RCT_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The RCT_DEV macro can be used to enable or disable development tools
|
||||
* such as the debug executors, dev menu, red box, etc.
|
||||
*/
|
||||
#ifndef RCT_DEV
|
||||
#if DEBUG
|
||||
#define RCT_DEV 1
|
||||
#else
|
||||
#define RCT_DEV 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RCT_DEV_MENU can be used to toggle the dev menu separately from RCT_DEV.
|
||||
* By default though, it will inherit from RCT_DEV.
|
||||
*/
|
||||
#ifndef RCT_DEV_MENU
|
||||
#define RCT_DEV_MENU RCT_DEV
|
||||
#endif
|
||||
|
||||
#ifndef RCT_ENABLE_INSPECTOR
|
||||
#if RCT_DEV && __has_include(<React/RCTInspectorDevServerHelper.h>)
|
||||
#define RCT_ENABLE_INSPECTOR 1
|
||||
#else
|
||||
#define RCT_ENABLE_INSPECTOR 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_PACKAGER_CONNECTION
|
||||
#if RCT_DEV && (__has_include("RCTPackagerConnection.h") || __has_include(<React/RCTPackagerConnection.h>))
|
||||
#define ENABLE_PACKAGER_CONNECTION 1
|
||||
#else
|
||||
#define ENABLE_PACKAGER_CONNECTION 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if RCT_DEV
|
||||
#define RCT_IF_DEV(...) __VA_ARGS__
|
||||
#else
|
||||
#define RCT_IF_DEV(...)
|
||||
#endif
|
||||
|
||||
#ifndef RCT_PROFILE
|
||||
#define RCT_PROFILE RCT_DEV
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Add the default Metro packager port number
|
||||
*/
|
||||
#ifndef RCT_METRO_PORT
|
||||
#define RCT_METRO_PORT 8081
|
||||
#else
|
||||
// test if RCT_METRO_PORT is empty
|
||||
#define RCT_METRO_PORT_DO_EXPAND(VAL) VAL##1
|
||||
#define RCT_METRO_PORT_EXPAND(VAL) RCT_METRO_PORT_DO_EXPAND(VAL)
|
||||
#if !defined(RCT_METRO_PORT) || (RCT_METRO_PORT_EXPAND(RCT_METRO_PORT) == 1)
|
||||
// Only here if RCT_METRO_PORT is not defined
|
||||
// OR RCT_METRO_PORT is the empty string
|
||||
#undef RCT_METRO_PORT
|
||||
#define RCT_METRO_PORT 8081
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Add the default packager name
|
||||
*/
|
||||
#ifndef RCT_PACKAGER_NAME
|
||||
#define RCT_PACKAGER_NAME @"Metro"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* By default, only raise an NSAssertion in debug mode
|
||||
* (custom assert functions will still be called).
|
||||
*/
|
||||
#ifndef RCT_NSASSERT
|
||||
#define RCT_NSASSERT RCT_DEBUG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Concat two literals. Supports macro expansions,
|
||||
* e.g. RCT_CONCAT(foo, __FILE__).
|
||||
*/
|
||||
#define RCT_CONCAT2(A, B) A##B
|
||||
#define RCT_CONCAT(A, B) RCT_CONCAT2(A, B)
|
||||
|
||||
/**
|
||||
* This attribute is used for static analysis.
|
||||
*/
|
||||
#if !defined RCT_DYNAMIC
|
||||
#if __has_attribute(objc_dynamic)
|
||||
#define RCT_DYNAMIC __attribute__((objc_dynamic))
|
||||
#else
|
||||
#define RCT_DYNAMIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Throw an assertion for unimplemented methods.
|
||||
*/
|
||||
#define RCT_NOT_IMPLEMENTED(method) \
|
||||
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wmissing-method-return-type\"") \
|
||||
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
|
||||
RCT_EXTERN NSException *_RCTNotImplementedException(SEL, Class); \
|
||||
method NS_UNAVAILABLE \
|
||||
{ \
|
||||
@throw _RCTNotImplementedException(_cmd, [self class]); \
|
||||
} \
|
||||
_Pragma("clang diagnostic pop")
|
||||
|
||||
/**
|
||||
* Check if WebKit iOS 10.0 APIs are available.
|
||||
*/
|
||||
#define WEBKIT_IOS_10_APIS_AVAILABLE __has_include(<WebKit/WKAudiovisualMediaTypes.h>)
|
20
node_modules/react-native/React/Base/RCTDisplayLink.h
generated
vendored
Normal file
20
node_modules/react-native/React/Base/RCTDisplayLink.h
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol RCTBridgeModule;
|
||||
@class RCTModuleData;
|
||||
|
||||
@interface RCTDisplayLink : NSObject
|
||||
|
||||
- (instancetype)init;
|
||||
- (void)invalidate;
|
||||
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData;
|
||||
- (void)addToRunLoop:(NSRunLoop *)runLoop;
|
||||
|
||||
@end
|
153
node_modules/react-native/React/Base/RCTDisplayLink.m
generated
vendored
Normal file
153
node_modules/react-native/React/Base/RCTDisplayLink.m
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTDisplayLink.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/CADisplayLink.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "RCTFrameUpdate.h"
|
||||
#import "RCTModuleData.h"
|
||||
#import "RCTProfile.h"
|
||||
|
||||
#define RCTAssertRunLoop() \
|
||||
RCTAssert(_runLoop == [NSRunLoop currentRunLoop], @"This method must be called on the CADisplayLink run loop")
|
||||
|
||||
@implementation RCTDisplayLink {
|
||||
CADisplayLink *_jsDisplayLink;
|
||||
NSMutableSet<RCTModuleData *> *_frameUpdateObservers;
|
||||
NSRunLoop *_runLoop;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_frameUpdateObservers = [NSMutableSet new];
|
||||
_jsDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_jsThreadUpdate:)];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData
|
||||
{
|
||||
if (![moduleData.moduleClass conformsToProtocol:@protocol(RCTFrameUpdateObserver)] ||
|
||||
[_frameUpdateObservers containsObject:moduleData]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_frameUpdateObservers addObject:moduleData];
|
||||
|
||||
// Don't access the module instance via moduleData, as this will cause deadlock
|
||||
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)module;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
observer.pauseCallback = ^{
|
||||
typeof(self) strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
|
||||
CFRunLoopRef cfRunLoop = [strongSelf->_runLoop getCFRunLoop];
|
||||
if (!cfRunLoop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([NSRunLoop currentRunLoop] == strongSelf->_runLoop) {
|
||||
[weakSelf updateJSDisplayLinkState];
|
||||
} else {
|
||||
CFRunLoopPerformBlock(cfRunLoop, kCFRunLoopDefaultMode, ^{
|
||||
[weakSelf updateJSDisplayLinkState];
|
||||
});
|
||||
CFRunLoopWakeUp(cfRunLoop);
|
||||
}
|
||||
};
|
||||
|
||||
// Assuming we're paused right now, we only need to update the display link's state
|
||||
// when the new observer is not paused. If it not paused, the observer will immediately
|
||||
// start receiving updates anyway.
|
||||
if (![observer isPaused] && _runLoop) {
|
||||
CFRunLoopPerformBlock([_runLoop getCFRunLoop], kCFRunLoopDefaultMode, ^{
|
||||
[self updateJSDisplayLinkState];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addToRunLoop:(NSRunLoop *)runLoop
|
||||
{
|
||||
_runLoop = runLoop;
|
||||
[_jsDisplayLink addToRunLoop:runLoop forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[_jsDisplayLink invalidate];
|
||||
}
|
||||
|
||||
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue
|
||||
{
|
||||
if (queue == RCTJSThread) {
|
||||
block();
|
||||
} else if (queue) {
|
||||
dispatch_async(queue, block);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_jsThreadUpdate:(CADisplayLink *)displayLink
|
||||
{
|
||||
RCTAssertRunLoop();
|
||||
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTDisplayLink _jsThreadUpdate:]", nil);
|
||||
|
||||
RCTFrameUpdate *frameUpdate = [[RCTFrameUpdate alloc] initWithDisplayLink:displayLink];
|
||||
for (RCTModuleData *moduleData in _frameUpdateObservers) {
|
||||
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
||||
if (!observer.paused) {
|
||||
if (moduleData.methodQueue) {
|
||||
RCTProfileBeginFlowEvent();
|
||||
[self
|
||||
dispatchBlock:^{
|
||||
RCTProfileEndFlowEvent();
|
||||
[observer didUpdateFrame:frameUpdate];
|
||||
}
|
||||
queue:moduleData.methodQueue];
|
||||
} else {
|
||||
[observer didUpdateFrame:frameUpdate];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self updateJSDisplayLinkState];
|
||||
|
||||
RCTProfileImmediateEvent(RCTProfileTagAlways, @"JS Thread Tick", displayLink.timestamp, 'g');
|
||||
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"objc_call");
|
||||
}
|
||||
|
||||
- (void)updateJSDisplayLinkState
|
||||
{
|
||||
RCTAssertRunLoop();
|
||||
|
||||
BOOL pauseDisplayLink = YES;
|
||||
for (RCTModuleData *moduleData in _frameUpdateObservers) {
|
||||
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
||||
if (!observer.paused) {
|
||||
pauseDisplayLink = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_jsDisplayLink.paused = pauseDisplayLink;
|
||||
}
|
||||
|
||||
@end
|
23
node_modules/react-native/React/Base/RCTErrorCustomizer.h
generated
vendored
Normal file
23
node_modules/react-native/React/Base/RCTErrorCustomizer.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class RCTErrorInfo;
|
||||
|
||||
/**
|
||||
* Provides an interface to customize React Native error messages and stack
|
||||
* traces from exceptions.
|
||||
*/
|
||||
@protocol RCTErrorCustomizer <NSObject>
|
||||
|
||||
/**
|
||||
* Customizes the given error, returning the passed info argument if no
|
||||
* customization is required.
|
||||
*/
|
||||
- (nonnull RCTErrorInfo *)customizeErrorInfo:(nonnull RCTErrorInfo *)info;
|
||||
@end
|
21
node_modules/react-native/React/Base/RCTErrorInfo.h
generated
vendored
Normal file
21
node_modules/react-native/React/Base/RCTErrorInfo.h
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class RCTJSStackFrame;
|
||||
|
||||
/**
|
||||
* An ObjC wrapper for React Native errors.
|
||||
*/
|
||||
@interface RCTErrorInfo : NSObject
|
||||
@property (nonatomic, copy, readonly) NSString *errorMessage;
|
||||
@property (nonatomic, copy, readonly) NSArray<RCTJSStackFrame *> *stack;
|
||||
|
||||
- (instancetype)initWithErrorMessage:(NSString *)errorMessage stack:(NSArray<RCTJSStackFrame *> *)stack;
|
||||
|
||||
@end
|
24
node_modules/react-native/React/Base/RCTErrorInfo.m
generated
vendored
Normal file
24
node_modules/react-native/React/Base/RCTErrorInfo.m
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTErrorInfo.h"
|
||||
|
||||
#import "RCTJSStackFrame.h"
|
||||
|
||||
@implementation RCTErrorInfo
|
||||
|
||||
- (instancetype)initWithErrorMessage:(NSString *)errorMessage stack:(NSArray<RCTJSStackFrame *> *)stack
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_errorMessage = [errorMessage copy];
|
||||
_stack = [stack copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
121
node_modules/react-native/React/Base/RCTEventDispatcher.h
generated
vendored
Normal file
121
node_modules/react-native/React/Base/RCTEventDispatcher.h
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, RCTTextEventType) {
|
||||
RCTTextEventTypeFocus,
|
||||
RCTTextEventTypeBlur,
|
||||
RCTTextEventTypeChange,
|
||||
RCTTextEventTypeSubmit,
|
||||
RCTTextEventTypeEnd,
|
||||
RCTTextEventTypeKeyPress
|
||||
};
|
||||
|
||||
/**
|
||||
* The threshold at which text inputs will start warning that the JS thread
|
||||
* has fallen behind (resulting in poor input performance, missed keys, etc.)
|
||||
*/
|
||||
RCT_EXTERN const NSInteger RCTTextUpdateLagWarningThreshold;
|
||||
|
||||
/**
|
||||
* Takes an input event name and normalizes it to the form that is required
|
||||
* by the events system (currently that means starting with the "top" prefix,
|
||||
* but that's an implementation detail that may change in future).
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTNormalizeInputEventName(NSString *eventName);
|
||||
|
||||
@protocol RCTEvent <NSObject>
|
||||
@required
|
||||
|
||||
@property (nonatomic, strong, readonly) NSNumber *viewTag;
|
||||
@property (nonatomic, copy, readonly) NSString *eventName;
|
||||
|
||||
- (BOOL)canCoalesce;
|
||||
|
||||
/** used directly for doing a JS call */
|
||||
+ (NSString *)moduleDotMethod;
|
||||
|
||||
/** must contain only JSON compatible values */
|
||||
- (NSArray *)arguments;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Coalescing related methods must only be implemented if canCoalesce
|
||||
* returns YES.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) uint16_t coalescingKey;
|
||||
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* This protocol allows observing events dispatched by RCTEventDispatcher.
|
||||
*/
|
||||
@protocol RCTEventDispatcherObserver <NSObject>
|
||||
|
||||
/**
|
||||
* Called before dispatching an event, on the same thread the event was
|
||||
* dispatched from.
|
||||
*/
|
||||
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* This class wraps the -[RCTBridge enqueueJSCall:args:] method, and
|
||||
* provides some convenience methods for generating event calls.
|
||||
*/
|
||||
@interface RCTEventDispatcher : NSObject <RCTBridgeModule>
|
||||
|
||||
/**
|
||||
* Deprecated, do not use.
|
||||
*/
|
||||
- (void)sendAppEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
|
||||
|
||||
/**
|
||||
* Deprecated, do not use.
|
||||
*/
|
||||
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
|
||||
|
||||
/**
|
||||
* Send a text input/focus event. For internal use only.
|
||||
*/
|
||||
- (void)sendTextEventWithType:(RCTTextEventType)type
|
||||
reactTag:(NSNumber *)reactTag
|
||||
text:(NSString *)text
|
||||
key:(NSString *)key
|
||||
eventCount:(NSInteger)eventCount;
|
||||
|
||||
/**
|
||||
* Send a pre-prepared event object.
|
||||
*
|
||||
* Events are sent to JS as soon as the thread is free to process them.
|
||||
* If an event can be coalesced and there is another compatible event waiting, the coalescing will happen immediately.
|
||||
*/
|
||||
- (void)sendEvent:(id<RCTEvent>)event;
|
||||
|
||||
/**
|
||||
* Add an event dispatcher observer.
|
||||
*/
|
||||
- (void)addDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
|
||||
|
||||
/**
|
||||
* Remove an event dispatcher observer.
|
||||
*/
|
||||
- (void)removeDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTBridge (RCTEventDispatcher)
|
||||
|
||||
- (RCTEventDispatcher *)eventDispatcher;
|
||||
|
||||
@end
|
222
node_modules/react-native/React/Base/RCTEventDispatcher.m
generated
vendored
Normal file
222
node_modules/react-native/React/Base/RCTEventDispatcher.m
generated
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTEventDispatcher.h"
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTComponentEvent.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
const NSInteger RCTTextUpdateLagWarningThreshold = 3;
|
||||
|
||||
NSString *RCTNormalizeInputEventName(NSString *eventName)
|
||||
{
|
||||
if ([eventName hasPrefix:@"on"]) {
|
||||
eventName = [eventName stringByReplacingCharactersInRange:(NSRange){0, 2} withString:@"top"];
|
||||
} else if (![eventName hasPrefix:@"top"]) {
|
||||
eventName = [[@"top" stringByAppendingString:[eventName substringToIndex:1].uppercaseString]
|
||||
stringByAppendingString:[eventName substringFromIndex:1]];
|
||||
}
|
||||
return eventName;
|
||||
}
|
||||
|
||||
static NSNumber *RCTGetEventID(NSNumber *viewTag, NSString *eventName, uint16_t coalescingKey)
|
||||
{
|
||||
return @(viewTag.intValue | (((uint64_t)eventName.hash & 0xFFFF) << 32) | (((uint64_t)coalescingKey) << 48));
|
||||
}
|
||||
|
||||
static uint16_t RCTUniqueCoalescingKeyGenerator = 0;
|
||||
|
||||
@implementation RCTEventDispatcher {
|
||||
// We need this lock to protect access to _events, _eventQueue and _eventsDispatchScheduled. It's filled in on main
|
||||
// thread and consumed on js thread.
|
||||
NSLock *_eventQueueLock;
|
||||
// We have this id -> event mapping so we coalesce effectively.
|
||||
NSMutableDictionary<NSNumber *, id<RCTEvent>> *_events;
|
||||
// This array contains ids of events in order they come in, so we can emit them to JS in the exact same order.
|
||||
NSMutableArray<NSNumber *> *_eventQueue;
|
||||
BOOL _eventsDispatchScheduled;
|
||||
NSHashTable<id<RCTEventDispatcherObserver>> *_observers;
|
||||
NSLock *_observersLock;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)setBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_bridge = bridge;
|
||||
_events = [NSMutableDictionary new];
|
||||
_eventQueue = [NSMutableArray new];
|
||||
_eventQueueLock = [NSLock new];
|
||||
_eventsDispatchScheduled = NO;
|
||||
_observers = [NSHashTable weakObjectsHashTable];
|
||||
_observersLock = [NSLock new];
|
||||
}
|
||||
|
||||
- (void)sendAppEventWithName:(NSString *)name body:(id)body
|
||||
{
|
||||
[_bridge enqueueJSCall:@"RCTNativeAppEventEmitter"
|
||||
method:@"emit"
|
||||
args:body ? @[ name, body ] : @[ name ]
|
||||
completion:NULL];
|
||||
}
|
||||
|
||||
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body
|
||||
{
|
||||
[_bridge enqueueJSCall:@"RCTDeviceEventEmitter"
|
||||
method:@"emit"
|
||||
args:body ? @[ name, body ] : @[ name ]
|
||||
completion:NULL];
|
||||
}
|
||||
|
||||
- (void)sendTextEventWithType:(RCTTextEventType)type
|
||||
reactTag:(NSNumber *)reactTag
|
||||
text:(NSString *)text
|
||||
key:(NSString *)key
|
||||
eventCount:(NSInteger)eventCount
|
||||
{
|
||||
static NSString *events[] = {@"focus", @"blur", @"change", @"submitEditing", @"endEditing", @"keyPress"};
|
||||
|
||||
NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithDictionary:@{
|
||||
@"eventCount" : @(eventCount),
|
||||
}];
|
||||
|
||||
if (text) {
|
||||
body[@"text"] = text;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
if (key.length == 0) {
|
||||
key = @"Backspace"; // backspace
|
||||
} else {
|
||||
switch ([key characterAtIndex:0]) {
|
||||
case '\t':
|
||||
key = @"Tab";
|
||||
break;
|
||||
case '\n':
|
||||
key = @"Enter";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
body[@"key"] = key;
|
||||
}
|
||||
|
||||
RCTComponentEvent *event = [[RCTComponentEvent alloc] initWithName:events[type] viewTag:reactTag body:body];
|
||||
[self sendEvent:event];
|
||||
}
|
||||
|
||||
- (void)sendEvent:(id<RCTEvent>)event
|
||||
{
|
||||
[_observersLock lock];
|
||||
|
||||
for (id<RCTEventDispatcherObserver> observer in _observers) {
|
||||
[observer eventDispatcherWillDispatchEvent:event];
|
||||
}
|
||||
|
||||
[_observersLock unlock];
|
||||
|
||||
[_eventQueueLock lock];
|
||||
|
||||
NSNumber *eventID;
|
||||
if (event.canCoalesce) {
|
||||
eventID = RCTGetEventID(event.viewTag, event.eventName, event.coalescingKey);
|
||||
id<RCTEvent> previousEvent = _events[eventID];
|
||||
if (previousEvent) {
|
||||
event = [previousEvent coalesceWithEvent:event];
|
||||
} else {
|
||||
[_eventQueue addObject:eventID];
|
||||
}
|
||||
} else {
|
||||
id<RCTEvent> previousEvent = _events[eventID];
|
||||
eventID = RCTGetEventID(event.viewTag, event.eventName, RCTUniqueCoalescingKeyGenerator++);
|
||||
RCTAssert(
|
||||
previousEvent == nil,
|
||||
@"Got event %@ which cannot be coalesced, but has the same eventID %@ as the previous event %@",
|
||||
event,
|
||||
eventID,
|
||||
previousEvent);
|
||||
[_eventQueue addObject:eventID];
|
||||
}
|
||||
|
||||
_events[eventID] = event;
|
||||
|
||||
BOOL scheduleEventsDispatch = NO;
|
||||
if (!_eventsDispatchScheduled) {
|
||||
_eventsDispatchScheduled = YES;
|
||||
scheduleEventsDispatch = YES;
|
||||
}
|
||||
|
||||
// We have to release the lock before dispatching block with events,
|
||||
// since dispatchBlock: can be executed synchronously on the same queue.
|
||||
// (This is happening when chrome debugging is turned on.)
|
||||
[_eventQueueLock unlock];
|
||||
|
||||
if (scheduleEventsDispatch) {
|
||||
[_bridge
|
||||
dispatchBlock:^{
|
||||
[self flushEventsQueue];
|
||||
}
|
||||
queue:RCTJSThread];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addDispatchObserver:(id<RCTEventDispatcherObserver>)observer
|
||||
{
|
||||
[_observersLock lock];
|
||||
[_observers addObject:observer];
|
||||
[_observersLock unlock];
|
||||
}
|
||||
|
||||
- (void)removeDispatchObserver:(id<RCTEventDispatcherObserver>)observer
|
||||
{
|
||||
[_observersLock lock];
|
||||
[_observers removeObject:observer];
|
||||
[_observersLock unlock];
|
||||
}
|
||||
|
||||
- (void)dispatchEvent:(id<RCTEvent>)event
|
||||
{
|
||||
[_bridge enqueueJSCall:[[event class] moduleDotMethod] args:[event arguments]];
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return RCTJSThread;
|
||||
}
|
||||
|
||||
// js thread only (which surprisingly can be the main thread, depends on used JS executor)
|
||||
- (void)flushEventsQueue
|
||||
{
|
||||
[_eventQueueLock lock];
|
||||
NSDictionary *events = _events;
|
||||
_events = [NSMutableDictionary new];
|
||||
NSMutableArray *eventQueue = _eventQueue;
|
||||
_eventQueue = [NSMutableArray new];
|
||||
_eventsDispatchScheduled = NO;
|
||||
[_eventQueueLock unlock];
|
||||
|
||||
for (NSNumber *eventId in eventQueue) {
|
||||
[self dispatchEvent:events[eventId]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (RCTEventDispatcher)
|
||||
|
||||
- (RCTEventDispatcher *)eventDispatcher
|
||||
{
|
||||
return [self moduleForClass:[RCTEventDispatcher class]];
|
||||
}
|
||||
|
||||
@end
|
52
node_modules/react-native/React/Base/RCTFrameUpdate.h
generated
vendored
Normal file
52
node_modules/react-native/React/Base/RCTFrameUpdate.h
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class CADisplayLink;
|
||||
|
||||
/**
|
||||
* Interface containing the information about the last screen refresh.
|
||||
*/
|
||||
@interface RCTFrameUpdate : NSObject
|
||||
|
||||
/**
|
||||
* Timestamp for the actual screen refresh
|
||||
*/
|
||||
@property (nonatomic, readonly) NSTimeInterval timestamp;
|
||||
|
||||
/**
|
||||
* Time since the last frame update ( >= 16.6ms )
|
||||
*/
|
||||
@property (nonatomic, readonly) NSTimeInterval deltaTime;
|
||||
|
||||
- (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Protocol that must be implemented for subscribing to display refreshes (DisplayLink updates)
|
||||
*/
|
||||
@protocol RCTFrameUpdateObserver <NSObject>
|
||||
|
||||
/**
|
||||
* Method called on every screen refresh (if paused != YES)
|
||||
*/
|
||||
- (void)didUpdateFrame:(RCTFrameUpdate *)update;
|
||||
|
||||
/**
|
||||
* Synthesize and set to true to pause the calls to -[didUpdateFrame:]
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isPaused) BOOL paused;
|
||||
|
||||
/**
|
||||
* Callback for pause/resume observer.
|
||||
* Observer should call it when paused property is changed.
|
||||
*/
|
||||
@property (nonatomic, copy) dispatch_block_t pauseCallback;
|
||||
|
||||
@end
|
27
node_modules/react-native/React/Base/RCTFrameUpdate.m
generated
vendored
Normal file
27
node_modules/react-native/React/Base/RCTFrameUpdate.m
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/CADisplayLink.h>
|
||||
|
||||
#import "RCTFrameUpdate.h"
|
||||
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@implementation RCTFrameUpdate
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
- (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_timestamp = displayLink.timestamp;
|
||||
_deltaTime = displayLink.duration;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
40
node_modules/react-native/React/Base/RCTImageSource.h
generated
vendored
Normal file
40
node_modules/react-native/React/Base/RCTImageSource.h
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
/**
|
||||
* Object containing an image URL and associated metadata.
|
||||
*/
|
||||
@interface RCTImageSource : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSURLRequest *request;
|
||||
@property (nonatomic, assign, readonly) CGSize size;
|
||||
@property (nonatomic, assign, readonly) CGFloat scale;
|
||||
|
||||
/**
|
||||
* Create a new image source object.
|
||||
* Pass a size of CGSizeZero if you do not know or wish to specify the image
|
||||
* size. Pass a scale of zero if you do not know or wish to specify the scale.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request size:(CGSize)size scale:(CGFloat)scale;
|
||||
|
||||
/**
|
||||
* Create a copy of the image source with the specified size and scale.
|
||||
*/
|
||||
- (instancetype)imageSourceWithSize:(CGSize)size scale:(CGFloat)scale;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTConvert (ImageSource)
|
||||
|
||||
+ (RCTImageSource *)RCTImageSource:(id)json;
|
||||
+ (NSArray<RCTImageSource *> *)RCTImageSourceArray:(id)json;
|
||||
|
||||
@end
|
89
node_modules/react-native/React/Base/RCTImageSource.m
generated
vendored
Normal file
89
node_modules/react-native/React/Base/RCTImageSource.m
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTImageSource.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@interface RCTImageSource ()
|
||||
|
||||
@property (nonatomic, assign) BOOL packagerAsset;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTImageSource
|
||||
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request size:(CGSize)size scale:(CGFloat)scale
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_request = [request copy];
|
||||
_size = size;
|
||||
_scale = scale;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)imageSourceWithSize:(CGSize)size scale:(CGFloat)scale
|
||||
{
|
||||
RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:_request size:size scale:scale];
|
||||
imageSource.packagerAsset = _packagerAsset;
|
||||
return imageSource;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(RCTImageSource *)object
|
||||
{
|
||||
if (![object isKindOfClass:[RCTImageSource class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [_request isEqual:object.request] && _scale == object.scale &&
|
||||
(CGSizeEqualToSize(_size, object.size) || CGSizeEqualToSize(object.size, CGSizeZero));
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<RCTImageSource: %p URL=%@, size=%@, scale=%0.f>",
|
||||
self,
|
||||
_request.URL,
|
||||
NSStringFromCGSize(_size),
|
||||
_scale];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTConvert (ImageSource)
|
||||
|
||||
+ (RCTImageSource *)RCTImageSource:(id)json
|
||||
{
|
||||
if (!json) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSURLRequest *request;
|
||||
CGSize size = CGSizeZero;
|
||||
CGFloat scale = 1.0;
|
||||
BOOL packagerAsset = NO;
|
||||
if ([json isKindOfClass:[NSDictionary class]]) {
|
||||
if (!(request = [self NSURLRequest:json])) {
|
||||
return nil;
|
||||
}
|
||||
size = [self CGSize:json];
|
||||
scale = [self CGFloat:json[@"scale"]] ?: [self BOOL:json[@"deprecated"]] ? 0.0 : 1.0;
|
||||
packagerAsset = [self BOOL:json[@"__packager_asset"]];
|
||||
} else if ([json isKindOfClass:[NSString class]]) {
|
||||
request = [self NSURLRequest:json];
|
||||
} else {
|
||||
RCTLogConvertError(json, @"an image. Did you forget to call resolveAssetSource() on the JS side?");
|
||||
return nil;
|
||||
}
|
||||
|
||||
RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:request size:size scale:scale];
|
||||
imageSource.packagerAsset = packagerAsset;
|
||||
return imageSource;
|
||||
}
|
||||
|
||||
RCT_ARRAY_CONVERTER(RCTImageSource)
|
||||
|
||||
@end
|
14
node_modules/react-native/React/Base/RCTInvalidating.h
generated
vendored
Normal file
14
node_modules/react-native/React/Base/RCTInvalidating.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol RCTInvalidating <NSObject>
|
||||
|
||||
- (void)invalidate;
|
||||
|
||||
@end
|
16
node_modules/react-native/React/Base/RCTJSInvokerModule.h
generated
vendored
Normal file
16
node_modules/react-native/React/Base/RCTJSInvokerModule.h
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This protocol should be adopted when a turbo module needs to directly call into Javascript.
|
||||
* In bridge-less React Native, it is a replacement for [_bridge enqueueJSCall:].
|
||||
*/
|
||||
@protocol RCTJSInvokerModule
|
||||
|
||||
@property (nonatomic, copy, nonnull) void (^invokeJS)(NSString *module, NSString *method, NSArray *args);
|
||||
|
||||
@end
|
30
node_modules/react-native/React/Base/RCTJSStackFrame.h
generated
vendored
Normal file
30
node_modules/react-native/React/Base/RCTJSStackFrame.h
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RCTJSStackFrame : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *methodName;
|
||||
@property (nonatomic, copy, readonly) NSString *file;
|
||||
@property (nonatomic, readonly) NSInteger lineNumber;
|
||||
@property (nonatomic, readonly) NSInteger column;
|
||||
@property (nonatomic, readonly) NSInteger collapse;
|
||||
|
||||
- (instancetype)initWithMethodName:(NSString *)methodName
|
||||
file:(NSString *)file
|
||||
lineNumber:(NSInteger)lineNumber
|
||||
column:(NSInteger)column
|
||||
collapse:(NSInteger)collapse;
|
||||
- (NSDictionary *)toDictionary;
|
||||
|
||||
+ (instancetype)stackFrameWithLine:(NSString *)line;
|
||||
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict;
|
||||
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines;
|
||||
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithDictionaries:(NSArray<NSDictionary *> *)dicts;
|
||||
|
||||
@end
|
150
node_modules/react-native/React/Base/RCTJSStackFrame.m
generated
vendored
Normal file
150
node_modules/react-native/React/Base/RCTJSStackFrame.m
generated
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTJSStackFrame.h"
|
||||
|
||||
#import "RCTLog.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
/**
|
||||
* The RegEx used to parse Error.stack.
|
||||
*
|
||||
* JavaScriptCore has the following format:
|
||||
*
|
||||
* Exception: Error: argh
|
||||
* func1@/path/to/file.js:2:18
|
||||
* func2@/path/to/file.js:6:8
|
||||
* eval@[native code]
|
||||
* global code@/path/to/file.js:13:5
|
||||
*
|
||||
* Another supported format:
|
||||
*
|
||||
* Error: argh
|
||||
* at func1 (/path/to/file.js:2:18)
|
||||
* at func2 (/path/to/file.js:6:8)
|
||||
* at eval (native)
|
||||
* at global (/path/to/file.js:13:5)
|
||||
*/
|
||||
static NSRegularExpression *RCTJSStackFrameRegex()
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static NSRegularExpression *_regex;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *pattern =
|
||||
@"\\s*(?:at)?\\s*" // Skip leading "at" and whitespace, noncapturing
|
||||
@"(.+?)" // Capture the function name (group 1)
|
||||
@"\\s*[@(]" // Skip whitespace, then @ or (
|
||||
@"(.*):" // Capture the file name (group 2), then colon
|
||||
@"(\\d+):(\\d+)" // Line and column number (groups 3 and 4)
|
||||
@"\\)?$" // Optional closing paren and EOL
|
||||
;
|
||||
NSError *regexError;
|
||||
_regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:®exError];
|
||||
if (regexError) {
|
||||
RCTLogError(@"Failed to build regex: %@", [regexError localizedDescription]);
|
||||
}
|
||||
});
|
||||
return _regex;
|
||||
}
|
||||
|
||||
@implementation RCTJSStackFrame
|
||||
|
||||
- (instancetype)initWithMethodName:(NSString *)methodName
|
||||
file:(NSString *)file
|
||||
lineNumber:(NSInteger)lineNumber
|
||||
column:(NSInteger)column
|
||||
collapse:(NSInteger)collapse
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_methodName = methodName;
|
||||
_file = file;
|
||||
_lineNumber = lineNumber;
|
||||
_column = column;
|
||||
_collapse = collapse;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)toDictionary
|
||||
{
|
||||
return @{
|
||||
@"methodName" : RCTNullIfNil(self.methodName),
|
||||
@"file" : RCTNullIfNil(self.file),
|
||||
@"lineNumber" : @(self.lineNumber),
|
||||
@"column" : @(self.column),
|
||||
@"collapse" : @(self.collapse)
|
||||
};
|
||||
}
|
||||
|
||||
+ (instancetype)stackFrameWithLine:(NSString *)line
|
||||
{
|
||||
NSTextCheckingResult *match = [RCTJSStackFrameRegex() firstMatchInString:line
|
||||
options:0
|
||||
range:NSMakeRange(0, line.length)];
|
||||
if (!match) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// methodName may not be present for e.g. anonymous functions
|
||||
const NSRange methodNameRange = [match rangeAtIndex:1];
|
||||
NSString *methodName = methodNameRange.location == NSNotFound ? nil : [line substringWithRange:methodNameRange];
|
||||
NSString *file = [line substringWithRange:[match rangeAtIndex:2]];
|
||||
NSString *lineNumber = [line substringWithRange:[match rangeAtIndex:3]];
|
||||
NSString *column = [line substringWithRange:[match rangeAtIndex:4]];
|
||||
|
||||
return [[self alloc] initWithMethodName:methodName
|
||||
file:file
|
||||
lineNumber:[lineNumber integerValue]
|
||||
column:[column integerValue]
|
||||
collapse:@NO];
|
||||
}
|
||||
|
||||
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict
|
||||
{
|
||||
return [[self alloc] initWithMethodName:RCTNilIfNull(dict[@"methodName"])
|
||||
file:dict[@"file"]
|
||||
lineNumber:[RCTNilIfNull(dict[@"lineNumber"]) integerValue]
|
||||
column:[RCTNilIfNull(dict[@"column"]) integerValue]
|
||||
collapse:[RCTNilIfNull(dict[@"collapse"]) integerValue]];
|
||||
}
|
||||
|
||||
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines
|
||||
{
|
||||
NSMutableArray *stack = [NSMutableArray new];
|
||||
for (NSString *line in [lines componentsSeparatedByString:@"\n"]) {
|
||||
RCTJSStackFrame *frame = [self stackFrameWithLine:line];
|
||||
if (frame) {
|
||||
[stack addObject:frame];
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithDictionaries:(NSArray<NSDictionary *> *)dicts
|
||||
{
|
||||
NSMutableArray *stack = [NSMutableArray new];
|
||||
for (NSDictionary *dict in dicts) {
|
||||
RCTJSStackFrame *frame = [self stackFrameWithDictionary:dict];
|
||||
if (frame) {
|
||||
[stack addObject:frame];
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p method name: %@; file name: %@; line: %ld; column: %ld>",
|
||||
self.class,
|
||||
self,
|
||||
self.methodName,
|
||||
self.file,
|
||||
(long)self.lineNumber,
|
||||
(long)self.column];
|
||||
}
|
||||
|
||||
@end
|
80
node_modules/react-native/React/Base/RCTJavaScriptExecutor.h
generated
vendored
Normal file
80
node_modules/react-native/React/Base/RCTJavaScriptExecutor.h
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTInvalidating.h>
|
||||
|
||||
typedef void (^RCTJavaScriptCompleteBlock)(NSError *error);
|
||||
typedef void (^RCTJavaScriptCallback)(id result, NSError *error);
|
||||
|
||||
/**
|
||||
* Abstracts away a JavaScript execution context - we may be running code in a
|
||||
* web view (for debugging purposes), or may be running code in a `JSContext`.
|
||||
*/
|
||||
@protocol RCTJavaScriptExecutor <RCTInvalidating, RCTBridgeModule>
|
||||
|
||||
/**
|
||||
* Used to set up the executor after the bridge has been fully initialized.
|
||||
* Do any expensive setup in this method instead of `-init`.
|
||||
*/
|
||||
- (void)setUp;
|
||||
|
||||
/**
|
||||
* Whether the executor has been invalidated
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isValid) BOOL valid;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.flushedQueue on JS thread and calls the given callback
|
||||
* with JSValue, containing the next queue, and JSContext.
|
||||
*/
|
||||
- (void)flushedQueue:(RCTJavaScriptCallback)onComplete;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.callFunctionReturnFlushedQueue with the module name,
|
||||
* method name and optional additional arguments on the JS thread and calls the
|
||||
* given callback with JSValue, containing the next queue, and JSContext.
|
||||
*/
|
||||
- (void)callFunctionOnModule:(NSString *)module
|
||||
method:(NSString *)method
|
||||
arguments:(NSArray *)args
|
||||
callback:(RCTJavaScriptCallback)onComplete;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.invokeCallbackAndReturnFlushedQueue with the cbID,
|
||||
* and optional additional arguments on the JS thread and calls the
|
||||
* given callback with JSValue, containing the next queue, and JSContext.
|
||||
*/
|
||||
- (void)invokeCallbackID:(NSNumber *)cbID arguments:(NSArray *)args callback:(RCTJavaScriptCallback)onComplete;
|
||||
|
||||
/**
|
||||
* Runs an application script, and notifies of the script load being complete via `onComplete`.
|
||||
*/
|
||||
- (void)executeApplicationScript:(NSData *)script
|
||||
sourceURL:(NSURL *)sourceURL
|
||||
onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
||||
|
||||
- (void)injectJSONText:(NSString *)script
|
||||
asGlobalObjectNamed:(NSString *)objectName
|
||||
callback:(RCTJavaScriptCompleteBlock)onComplete;
|
||||
|
||||
/**
|
||||
* Enqueue a block to run in the executors JS thread. Fallback to `dispatch_async`
|
||||
* on the main queue if the executor doesn't own a thread.
|
||||
*/
|
||||
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block;
|
||||
|
||||
/**
|
||||
* Special case for Timers + ContextExecutor - instead of the default
|
||||
* if jsthread then call else dispatch call on jsthread
|
||||
* ensure the call is made async on the jsthread
|
||||
*/
|
||||
- (void)executeAsyncBlockOnJavaScriptQueue:(dispatch_block_t)block;
|
||||
|
||||
@end
|
94
node_modules/react-native/React/Base/RCTJavaScriptLoader.h
generated
vendored
Executable file
94
node_modules/react-native/React/Base/RCTJavaScriptLoader.h
generated
vendored
Executable file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
extern NSString *const RCTJavaScriptLoaderErrorDomain;
|
||||
|
||||
NS_ENUM(NSInteger){
|
||||
RCTJavaScriptLoaderErrorNoScriptURL = 1,
|
||||
RCTJavaScriptLoaderErrorFailedOpeningFile = 2,
|
||||
RCTJavaScriptLoaderErrorFailedReadingFile = 3,
|
||||
RCTJavaScriptLoaderErrorFailedStatingFile = 3,
|
||||
RCTJavaScriptLoaderErrorURLLoadFailed = 3,
|
||||
RCTJavaScriptLoaderErrorBCVersion = 4,
|
||||
RCTJavaScriptLoaderErrorBCNotSupported = 4,
|
||||
|
||||
RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000,
|
||||
};
|
||||
|
||||
NS_ENUM(NSInteger){
|
||||
RCTSourceFilesChangedCountNotBuiltByBundler = -2,
|
||||
RCTSourceFilesChangedCountRebuiltFromScratch = -1,
|
||||
};
|
||||
|
||||
@interface RCTLoadingProgress : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString *status;
|
||||
@property (strong, nonatomic) NSNumber *done;
|
||||
@property (strong, nonatomic) NSNumber *total;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTSource : NSObject
|
||||
|
||||
/**
|
||||
* URL of the source object.
|
||||
*/
|
||||
@property (strong, nonatomic, readonly) NSURL *url;
|
||||
|
||||
/**
|
||||
* JS source (or simply the binary header in the case of a RAM bundle).
|
||||
*/
|
||||
@property (strong, nonatomic, readonly) NSData *data;
|
||||
|
||||
/**
|
||||
* Length of the entire JS bundle. Note that self.length != self.data.length in the case of certain bundle formats. For
|
||||
* instance, when using RAM bundles:
|
||||
*
|
||||
* - self.data will point to the bundle header
|
||||
* - self.data.length is the length of the bundle header, i.e. sizeof(facebook::react::BundleHeader)
|
||||
* - self.length is the length of the entire bundle file (header + contents)
|
||||
*/
|
||||
@property (nonatomic, readonly) NSUInteger length;
|
||||
|
||||
/**
|
||||
* Returns number of files changed when building this bundle:
|
||||
*
|
||||
* - RCTSourceFilesChangedCountNotBuiltByBundler if the source wasn't built by the bundler (e.g. read from disk)
|
||||
* - RCTSourceFilesChangedCountRebuiltFromScratch if the source was rebuilt from scratch by the bundler
|
||||
* - Otherwise, the number of files changed when incrementally rebuilding the source
|
||||
*/
|
||||
@property (nonatomic, readonly) NSInteger filesChangedCount;
|
||||
|
||||
@end
|
||||
|
||||
typedef void (^RCTSourceLoadProgressBlock)(RCTLoadingProgress *progressData);
|
||||
typedef void (^RCTSourceLoadBlock)(NSError *error, RCTSource *source);
|
||||
|
||||
@interface RCTJavaScriptLoader : NSObject
|
||||
|
||||
+ (void)loadBundleAtURL:(NSURL *)scriptURL
|
||||
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||
onComplete:(RCTSourceLoadBlock)onComplete;
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
* Attempts to synchronously load the script at the given URL. The following two conditions must be met:
|
||||
* 1. It must be a file URL.
|
||||
* 2. It must not point to a text/javascript file.
|
||||
* If the URL does not meet those conditions, this method will return nil and supply an error with the domain
|
||||
* RCTJavaScriptLoaderErrorDomain and the code RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously.
|
||||
*/
|
||||
+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
|
||||
runtimeBCVersion:(int32_t)runtimeBCVersion
|
||||
sourceLength:(int64_t *)sourceLength
|
||||
error:(NSError **)error;
|
||||
|
||||
@end
|
378
node_modules/react-native/React/Base/RCTJavaScriptLoader.mm
generated
vendored
Executable file
378
node_modules/react-native/React/Base/RCTJavaScriptLoader.mm
generated
vendored
Executable file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTJavaScriptLoader.h"
|
||||
|
||||
#import <sys/stat.h>
|
||||
|
||||
#import <cxxreact/JSBundleType.h>
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTMultipartDataTask.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomain";
|
||||
|
||||
static const int32_t JSNoBytecodeFileFormatVersion = -1;
|
||||
|
||||
@interface RCTSource () {
|
||||
@public
|
||||
NSURL *_url;
|
||||
NSData *_data;
|
||||
NSUInteger _length;
|
||||
NSInteger _filesChangedCount;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTSource
|
||||
|
||||
static RCTSource *RCTSourceCreate(NSURL *url, NSData *data, int64_t length) NS_RETURNS_RETAINED
|
||||
{
|
||||
RCTSource *source = [RCTSource new];
|
||||
source->_url = url;
|
||||
source->_data = data;
|
||||
source->_length = length;
|
||||
source->_filesChangedCount = RCTSourceFilesChangedCountNotBuiltByBundler;
|
||||
return source;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTLoadingProgress
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSMutableString *desc = [NSMutableString new];
|
||||
[desc appendString:_status ?: @"Loading"];
|
||||
|
||||
if ([_total integerValue] > 0) {
|
||||
[desc appendFormat:@" %ld%% (%@/%@)", (long)(100 * [_done integerValue] / [_total integerValue]), _done, _total];
|
||||
}
|
||||
[desc appendString:@"\u2026"];
|
||||
return desc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTJavaScriptLoader
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
+ (void)loadBundleAtURL:(NSURL *)scriptURL
|
||||
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||
onComplete:(RCTSourceLoadBlock)onComplete
|
||||
{
|
||||
int64_t sourceLength;
|
||||
NSError *error;
|
||||
NSData *data = [self attemptSynchronousLoadOfBundleAtURL:scriptURL
|
||||
runtimeBCVersion:JSNoBytecodeFileFormatVersion
|
||||
sourceLength:&sourceLength
|
||||
error:&error];
|
||||
if (data) {
|
||||
onComplete(nil, RCTSourceCreate(scriptURL, data, sourceLength));
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL isCannotLoadSyncError = [error.domain isEqualToString:RCTJavaScriptLoaderErrorDomain] &&
|
||||
error.code == RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously;
|
||||
|
||||
if (isCannotLoadSyncError) {
|
||||
attemptAsynchronousLoadOfBundleAtURL(scriptURL, onProgress, onComplete);
|
||||
} else {
|
||||
onComplete(error, nil);
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
|
||||
runtimeBCVersion:(int32_t)runtimeBCVersion
|
||||
sourceLength:(int64_t *)sourceLength
|
||||
error:(NSError **)error
|
||||
{
|
||||
NSString *unsanitizedScriptURLString = scriptURL.absoluteString;
|
||||
// Sanitize the script URL
|
||||
scriptURL = sanitizeURL(scriptURL);
|
||||
|
||||
if (!scriptURL) {
|
||||
if (error) {
|
||||
*error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorNoScriptURL
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey : [NSString
|
||||
stringWithFormat:@"No script URL provided. Make sure the packager is "
|
||||
@"running or you have embedded a JS bundle in your application bundle.\n\n"
|
||||
@"unsanitizedScriptURLString = %@",
|
||||
unsanitizedScriptURLString]
|
||||
}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Load local script file
|
||||
if (!scriptURL.fileURL) {
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey :
|
||||
[NSString stringWithFormat:@"Cannot load %@ URLs synchronously", scriptURL.scheme]
|
||||
}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Load the first 4 bytes to check if the bundle is regular or RAM ("Random Access Modules" bundle).
|
||||
// The RAM bundle has a magic number in the 4 first bytes `(0xFB0BD1E5)`.
|
||||
// The benefit of RAM bundle over a regular bundle is that we can lazily inject
|
||||
// modules into JSC as they're required.
|
||||
FILE *bundle = fopen(scriptURL.path.UTF8String, "r");
|
||||
if (!bundle) {
|
||||
if (error) {
|
||||
*error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorFailedOpeningFile
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening bundle %@", scriptURL.path]
|
||||
}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
facebook::react::BundleHeader header;
|
||||
size_t readResult = fread(&header, sizeof(header), 1, bundle);
|
||||
fclose(bundle);
|
||||
if (readResult != 1) {
|
||||
if (error) {
|
||||
*error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorFailedReadingFile
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error reading bundle %@", scriptURL.path]
|
||||
}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
facebook::react::ScriptTag tag = facebook::react::parseTypeFromHeader(header);
|
||||
switch (tag) {
|
||||
case facebook::react::ScriptTag::RAMBundle:
|
||||
break;
|
||||
|
||||
case facebook::react::ScriptTag::String: {
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
NSData *source = [NSData dataWithContentsOfFile:scriptURL.path options:NSDataReadingMappedIfSafe error:error];
|
||||
if (sourceLength && source != nil) {
|
||||
*sourceLength = source.length;
|
||||
}
|
||||
return source;
|
||||
#else
|
||||
if (error) {
|
||||
*error =
|
||||
[NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously
|
||||
userInfo:@{NSLocalizedDescriptionKey : @"Cannot load text/javascript files synchronously"}];
|
||||
}
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
case facebook::react::ScriptTag::BCBundle:
|
||||
if (runtimeBCVersion == JSNoBytecodeFileFormatVersion || runtimeBCVersion < 0) {
|
||||
if (error) {
|
||||
*error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorBCNotSupported
|
||||
userInfo:@{NSLocalizedDescriptionKey : @"Bytecode bundles are not supported by this runtime."}];
|
||||
}
|
||||
return nil;
|
||||
} else if ((uint32_t)runtimeBCVersion != header.version) {
|
||||
if (error) {
|
||||
NSString *errDesc = [NSString
|
||||
stringWithFormat:@"BC Version Mismatch. Expect: %d, Actual: %u", runtimeBCVersion, header.version];
|
||||
|
||||
*error = [NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorBCVersion
|
||||
userInfo:@{NSLocalizedDescriptionKey : errDesc}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
struct stat statInfo;
|
||||
if (stat(scriptURL.path.UTF8String, &statInfo) != 0) {
|
||||
if (error) {
|
||||
*error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorFailedStatingFile
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error stating bundle %@", scriptURL.path]
|
||||
}];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
if (sourceLength) {
|
||||
*sourceLength = statInfo.st_size;
|
||||
}
|
||||
return [NSData dataWithBytes:&header length:sizeof(header)];
|
||||
}
|
||||
|
||||
static void parseHeaders(NSDictionary *headers, RCTSource *source)
|
||||
{
|
||||
source->_filesChangedCount = [headers[@"X-Metro-Files-Changed-Count"] integerValue];
|
||||
}
|
||||
|
||||
static void attemptAsynchronousLoadOfBundleAtURL(
|
||||
NSURL *scriptURL,
|
||||
RCTSourceLoadProgressBlock onProgress,
|
||||
RCTSourceLoadBlock onComplete)
|
||||
{
|
||||
scriptURL = sanitizeURL(scriptURL);
|
||||
|
||||
if (scriptURL.fileURL) {
|
||||
// Reading in a large bundle can be slow. Dispatch to the background queue to do it.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSError *error = nil;
|
||||
NSData *source = [NSData dataWithContentsOfFile:scriptURL.path options:NSDataReadingMappedIfSafe error:&error];
|
||||
onComplete(error, RCTSourceCreate(scriptURL, source, source.length));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
RCTMultipartDataTask *task = [[RCTMultipartDataTask alloc] initWithURL:scriptURL
|
||||
partHandler:^(NSInteger statusCode, NSDictionary *headers, NSData *data, NSError *error, BOOL done) {
|
||||
if (!done) {
|
||||
if (onProgress) {
|
||||
onProgress(progressEventFromData(data));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle general request errors
|
||||
if (error) {
|
||||
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
||||
error = [NSError
|
||||
errorWithDomain:RCTJavaScriptLoaderErrorDomain
|
||||
code:RCTJavaScriptLoaderErrorURLLoadFailed
|
||||
userInfo:@{
|
||||
NSLocalizedDescriptionKey :
|
||||
[@"Could not connect to development server.\n\n"
|
||||
"Ensure the following:\n"
|
||||
"- Node server is running and available on the same network - run 'npm start' from react-native root\n"
|
||||
"- Node server URL is correctly set in AppDelegate\n"
|
||||
"- WiFi is enabled and connected to the same network as the Node Server\n\n"
|
||||
"URL: " stringByAppendingString:scriptURL.absoluteString],
|
||||
NSLocalizedFailureReasonErrorKey : error.localizedDescription,
|
||||
NSUnderlyingErrorKey : error,
|
||||
}];
|
||||
}
|
||||
onComplete(error, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// For multipart responses packager sets X-Http-Status header in case HTTP status code
|
||||
// is different from 200 OK
|
||||
NSString *statusCodeHeader = headers[@"X-Http-Status"];
|
||||
if (statusCodeHeader) {
|
||||
statusCode = [statusCodeHeader integerValue];
|
||||
}
|
||||
|
||||
if (statusCode != 200) {
|
||||
error =
|
||||
[NSError errorWithDomain:@"JSServer"
|
||||
code:statusCode
|
||||
userInfo:userInfoForRawResponse([[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding])];
|
||||
onComplete(error, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate that the packager actually returned javascript.
|
||||
NSString *contentType = headers[@"Content-Type"];
|
||||
NSString *mimeType = [[contentType componentsSeparatedByString:@";"] firstObject];
|
||||
if (![mimeType isEqualToString:@"application/javascript"] && ![mimeType isEqualToString:@"text/javascript"]) {
|
||||
NSString *description = [NSString
|
||||
stringWithFormat:@"Expected MIME-Type to be 'application/javascript' or 'text/javascript', but got '%@'.",
|
||||
mimeType];
|
||||
error = [NSError
|
||||
errorWithDomain:@"JSServer"
|
||||
code:NSURLErrorCannotParseResponse
|
||||
userInfo:@{NSLocalizedDescriptionKey : description, @"headers" : headers, @"data" : data}];
|
||||
onComplete(error, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
RCTSource *source = RCTSourceCreate(scriptURL, data, data.length);
|
||||
parseHeaders(headers, source);
|
||||
onComplete(nil, source);
|
||||
}
|
||||
progressHandler:^(NSDictionary *headers, NSNumber *loaded, NSNumber *total) {
|
||||
// Only care about download progress events for the javascript bundle part.
|
||||
if ([headers[@"Content-Type"] isEqualToString:@"application/javascript"]) {
|
||||
onProgress(progressEventFromDownloadProgress(loaded, total));
|
||||
}
|
||||
}];
|
||||
|
||||
[task startTask];
|
||||
}
|
||||
|
||||
static NSURL *sanitizeURL(NSURL *url)
|
||||
{
|
||||
// Why we do this is lost to time. We probably shouldn't; passing a valid URL is the caller's responsibility not ours.
|
||||
return [RCTConvert NSURL:url.absoluteString];
|
||||
}
|
||||
|
||||
static RCTLoadingProgress *progressEventFromData(NSData *rawData)
|
||||
{
|
||||
NSString *text = [[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding];
|
||||
id info = RCTJSONParse(text, nil);
|
||||
if (!info || ![info isKindOfClass:[NSDictionary class]]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
RCTLoadingProgress *progress = [RCTLoadingProgress new];
|
||||
progress.status = info[@"status"];
|
||||
progress.done = info[@"done"];
|
||||
progress.total = info[@"total"];
|
||||
return progress;
|
||||
}
|
||||
|
||||
static RCTLoadingProgress *progressEventFromDownloadProgress(NSNumber *total, NSNumber *done)
|
||||
{
|
||||
RCTLoadingProgress *progress = [RCTLoadingProgress new];
|
||||
progress.status = @"Downloading JavaScript bundle";
|
||||
// Progress values are in bytes transform them to kilobytes for smaller numbers.
|
||||
progress.done = done != nil ? @([done integerValue] / 1024) : nil;
|
||||
progress.total = total != nil ? @([total integerValue] / 1024) : nil;
|
||||
return progress;
|
||||
}
|
||||
|
||||
static NSDictionary *userInfoForRawResponse(NSString *rawText)
|
||||
{
|
||||
NSDictionary *parsedResponse = RCTJSONParse(rawText, nil);
|
||||
if (![parsedResponse isKindOfClass:[NSDictionary class]]) {
|
||||
return @{NSLocalizedDescriptionKey : rawText};
|
||||
}
|
||||
NSArray *errors = parsedResponse[@"errors"];
|
||||
if (![errors isKindOfClass:[NSArray class]]) {
|
||||
return @{NSLocalizedDescriptionKey : rawText};
|
||||
}
|
||||
NSMutableArray<NSDictionary *> *fakeStack = [NSMutableArray new];
|
||||
for (NSDictionary *err in errors) {
|
||||
[fakeStack addObject:@{
|
||||
@"methodName" : err[@"description"] ?: @"",
|
||||
@"file" : err[@"filename"] ?: @"",
|
||||
@"lineNumber" : err[@"lineNumber"] ?: @0
|
||||
}];
|
||||
}
|
||||
return
|
||||
@{NSLocalizedDescriptionKey : parsedResponse[@"message"] ?: @"No message provided", @"stack" : [fakeStack copy]};
|
||||
}
|
||||
|
||||
@end
|
48
node_modules/react-native/React/Base/RCTKeyCommands.h
generated
vendored
Normal file
48
node_modules/react-native/React/Base/RCTKeyCommands.h
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface RCTKeyCommands : NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
/**
|
||||
* Register a single-press keyboard command.
|
||||
*/
|
||||
- (void)registerKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *command))block;
|
||||
|
||||
/**
|
||||
* Unregister a single-press keyboard command.
|
||||
*/
|
||||
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
||||
|
||||
/**
|
||||
* Check if a single-press command is registered.
|
||||
*/
|
||||
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
||||
|
||||
/**
|
||||
* Register a double-press keyboard command.
|
||||
*/
|
||||
- (void)registerDoublePressKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *command))block;
|
||||
|
||||
/**
|
||||
* Unregister a double-press keyboard command.
|
||||
*/
|
||||
- (void)unregisterDoublePressKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
||||
|
||||
/**
|
||||
* Check if a double-press command is registered.
|
||||
*/
|
||||
- (BOOL)isDoublePressKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
||||
|
||||
@end
|
329
node_modules/react-native/React/Base/RCTKeyCommands.m
generated
vendored
Normal file
329
node_modules/react-native/React/Base/RCTKeyCommands.m
generated
vendored
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTKeyCommands.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
#if RCT_DEV
|
||||
|
||||
@interface RCTKeyCommand : NSObject <NSCopying>
|
||||
|
||||
@property (nonatomic, strong) UIKeyCommand *keyCommand;
|
||||
@property (nonatomic, copy) void (^block)(UIKeyCommand *);
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTKeyCommand
|
||||
|
||||
- (instancetype)initWithKeyCommand:(UIKeyCommand *)keyCommand block:(void (^)(UIKeyCommand *))block
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_keyCommand = keyCommand;
|
||||
_block = block;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
- (id)copyWithZone:(__unused NSZone *)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return _keyCommand.input.hash ^ _keyCommand.modifierFlags;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(RCTKeyCommand *)object
|
||||
{
|
||||
if (![object isKindOfClass:[RCTKeyCommand class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self matchesInput:object.keyCommand.input flags:object.keyCommand.modifierFlags];
|
||||
}
|
||||
|
||||
- (BOOL)matchesInput:(NSString *)input flags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
return [_keyCommand.input isEqual:input] && _keyCommand.modifierFlags == flags;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@:%p input=\"%@\" flags=%lld hasBlock=%@>",
|
||||
[self class],
|
||||
self,
|
||||
_keyCommand.input,
|
||||
(long long)_keyCommand.modifierFlags,
|
||||
_block ? @"YES" : @"NO"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTKeyCommands ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableSet<RCTKeyCommand *> *commands;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIResponder (RCTKeyCommands)
|
||||
|
||||
+ (UIResponder *)RCT_getFirstResponder:(UIResponder *)view
|
||||
{
|
||||
UIResponder *firstResponder = nil;
|
||||
|
||||
if (view.isFirstResponder) {
|
||||
return view;
|
||||
} else if ([view isKindOfClass:[UIViewController class]]) {
|
||||
if ([(UIViewController *)view parentViewController]) {
|
||||
firstResponder = [UIResponder RCT_getFirstResponder:[(UIViewController *)view parentViewController]];
|
||||
}
|
||||
return firstResponder ? firstResponder : [UIResponder RCT_getFirstResponder:[(UIViewController *)view view]];
|
||||
} else if ([view isKindOfClass:[UIView class]]) {
|
||||
for (UIView *subview in [(UIView *)view subviews]) {
|
||||
firstResponder = [UIResponder RCT_getFirstResponder:subview];
|
||||
if (firstResponder) {
|
||||
return firstResponder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstResponder;
|
||||
}
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)RCT_keyCommands
|
||||
{
|
||||
NSSet<RCTKeyCommand *> *commands = [RCTKeyCommands sharedInstance].commands;
|
||||
return [[commands valueForKeyPath:@"keyCommand"] allObjects];
|
||||
}
|
||||
|
||||
/**
|
||||
* Single Press Key Command Response
|
||||
* Command + KeyEvent (Command + R/D, etc.)
|
||||
*/
|
||||
- (void)RCT_handleKeyCommand:(UIKeyCommand *)key
|
||||
{
|
||||
// NOTE: throttle the key handler because on iOS 9 the handleKeyCommand:
|
||||
// method gets called repeatedly if the command key is held down.
|
||||
static NSTimeInterval lastCommand = 0;
|
||||
if (CACurrentMediaTime() - lastCommand > 0.5) {
|
||||
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
|
||||
if ([command.keyCommand.input isEqualToString:key.input] &&
|
||||
command.keyCommand.modifierFlags == key.modifierFlags) {
|
||||
if (command.block) {
|
||||
command.block(key);
|
||||
lastCommand = CACurrentMediaTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Double Press Key Command Response
|
||||
* Double KeyEvent (Double R, etc.)
|
||||
*/
|
||||
- (void)RCT_handleDoublePressKeyCommand:(UIKeyCommand *)key
|
||||
{
|
||||
static BOOL firstPress = YES;
|
||||
static NSTimeInterval lastCommand = 0;
|
||||
static NSTimeInterval lastDoubleCommand = 0;
|
||||
static NSString *lastInput = nil;
|
||||
static UIKeyModifierFlags lastModifierFlags = 0;
|
||||
|
||||
if (firstPress) {
|
||||
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
|
||||
if ([command.keyCommand.input isEqualToString:key.input] &&
|
||||
command.keyCommand.modifierFlags == key.modifierFlags && command.block) {
|
||||
firstPress = NO;
|
||||
lastCommand = CACurrentMediaTime();
|
||||
lastInput = key.input;
|
||||
lastModifierFlags = key.modifierFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Second keyevent within 0.2 second,
|
||||
// with the same key as the first one.
|
||||
if (CACurrentMediaTime() - lastCommand < 0.2 && lastInput == key.input && lastModifierFlags == key.modifierFlags) {
|
||||
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
|
||||
if ([command.keyCommand.input isEqualToString:key.input] &&
|
||||
command.keyCommand.modifierFlags == key.modifierFlags && command.block) {
|
||||
// NOTE: throttle the key handler because on iOS 9 the handleKeyCommand:
|
||||
// method gets called repeatedly if the command key is held down.
|
||||
if (CACurrentMediaTime() - lastDoubleCommand > 0.5) {
|
||||
command.block(key);
|
||||
lastDoubleCommand = CACurrentMediaTime();
|
||||
}
|
||||
firstPress = YES;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastCommand = CACurrentMediaTime();
|
||||
lastInput = key.input;
|
||||
lastModifierFlags = key.modifierFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTKeyCommands
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
// swizzle UIResponder
|
||||
RCTSwapInstanceMethods([UIResponder class], @selector(keyCommands), @selector(RCT_keyCommands));
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static RCTKeyCommands *sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [self new];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_commands = [NSMutableSet new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *))block
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:input
|
||||
modifierFlags:flags
|
||||
action:@selector(RCT_handleKeyCommand:)];
|
||||
|
||||
RCTKeyCommand *keyCommand = [[RCTKeyCommand alloc] initWithKeyCommand:command block:block];
|
||||
[_commands removeObject:keyCommand];
|
||||
[_commands addObject:keyCommand];
|
||||
}
|
||||
|
||||
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
for (RCTKeyCommand *command in _commands.allObjects) {
|
||||
if ([command matchesInput:input flags:flags]) {
|
||||
[_commands removeObject:command];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
for (RCTKeyCommand *command in _commands) {
|
||||
if ([command matchesInput:input flags:flags]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)registerDoublePressKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *))block
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
UIKeyCommand *command = [UIKeyCommand keyCommandWithInput:input
|
||||
modifierFlags:flags
|
||||
action:@selector(RCT_handleDoublePressKeyCommand:)];
|
||||
|
||||
RCTKeyCommand *keyCommand = [[RCTKeyCommand alloc] initWithKeyCommand:command block:block];
|
||||
[_commands removeObject:keyCommand];
|
||||
[_commands addObject:keyCommand];
|
||||
}
|
||||
|
||||
- (void)unregisterDoublePressKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
for (RCTKeyCommand *command in _commands.allObjects) {
|
||||
if ([command matchesInput:input flags:flags]) {
|
||||
[_commands removeObject:command];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isDoublePressKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
for (RCTKeyCommand *command in _commands) {
|
||||
if ([command matchesInput:input flags:flags]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
@implementation RCTKeyCommands
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)registerKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *))block
|
||||
{
|
||||
}
|
||||
|
||||
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)registerDoublePressKeyCommandWithInput:(NSString *)input
|
||||
modifierFlags:(UIKeyModifierFlags)flags
|
||||
action:(void (^)(UIKeyCommand *))block
|
||||
{
|
||||
}
|
||||
|
||||
- (void)unregisterDoublePressKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL)isDoublePressKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
136
node_modules/react-native/React/Base/RCTLog.h
generated
vendored
Normal file
136
node_modules/react-native/React/Base/RCTLog.h
generated
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
#ifndef RCTLOG_ENABLED
|
||||
#define RCTLOG_ENABLED 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Thresholds for logs to display a redbox. You can override these values when debugging
|
||||
* in order to tweak the default logging behavior.
|
||||
*/
|
||||
#ifndef RCTLOG_REDBOX_LEVEL
|
||||
#define RCTLOG_REDBOX_LEVEL RCTLogLevelError
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Logging macros. Use these to log information, warnings and errors in your
|
||||
* own code.
|
||||
*/
|
||||
#define RCTLog(...) _RCTLog(RCTLogLevelInfo, __VA_ARGS__)
|
||||
#define RCTLogTrace(...) _RCTLog(RCTLogLevelTrace, __VA_ARGS__)
|
||||
#define RCTLogInfo(...) _RCTLog(RCTLogLevelInfo, __VA_ARGS__)
|
||||
#define RCTLogAdvice(string, ...) RCTLogWarn([@"(ADVICE) " stringByAppendingString:(NSString *)string], __VA_ARGS__)
|
||||
#define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__)
|
||||
#define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* An enum representing the severity of the log message.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, RCTLogLevel) {
|
||||
RCTLogLevelTrace = 0,
|
||||
RCTLogLevelInfo = 1,
|
||||
RCTLogLevelWarning = 2,
|
||||
RCTLogLevelError = 3,
|
||||
RCTLogLevelFatal = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* An enum representing the source of a log message.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, RCTLogSource) { RCTLogSourceNative = 1, RCTLogSourceJavaScript = 2 };
|
||||
|
||||
/**
|
||||
* A block signature to be used for custom logging functions. In most cases you
|
||||
* will want to pass these arguments to the RCTFormatLog function in order to
|
||||
* generate a string.
|
||||
*/
|
||||
typedef void (^RCTLogFunction)(
|
||||
RCTLogLevel level,
|
||||
RCTLogSource source,
|
||||
NSString *fileName,
|
||||
NSNumber *lineNumber,
|
||||
NSString *message);
|
||||
|
||||
/**
|
||||
* A method to generate a string from a collection of log data. To omit any
|
||||
* particular data from the log, just pass nil or zero for the argument.
|
||||
*/
|
||||
RCT_EXTERN NSString *
|
||||
RCTFormatLog(NSDate *timestamp, RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message);
|
||||
|
||||
/**
|
||||
* A method to generate a string RCTLogLevel
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTFormatLogLevel(RCTLogLevel);
|
||||
|
||||
/**
|
||||
* A method to generate a string from a RCTLogSource
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTFormatLogSource(RCTLogSource);
|
||||
|
||||
/**
|
||||
* The default logging function used by RCTLogXX.
|
||||
*/
|
||||
extern RCTLogFunction RCTDefaultLogFunction;
|
||||
|
||||
/**
|
||||
* These methods get and set the global logging threshold. This is the level
|
||||
* below which logs will be ignored. Default is RCTLogLevelInfo for debug and
|
||||
* RCTLogLevelError for production.
|
||||
*/
|
||||
RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold);
|
||||
RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void);
|
||||
|
||||
/**
|
||||
* These methods get and set the global logging function called by the RCTLogXX
|
||||
* macros. You can use these to replace the standard behavior with custom log
|
||||
* functionality.
|
||||
*/
|
||||
RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction);
|
||||
RCT_EXTERN RCTLogFunction RCTGetLogFunction(void);
|
||||
|
||||
/**
|
||||
* This appends additional code to the existing log function, without replacing
|
||||
* the existing functionality. Useful if you just want to forward logs to an
|
||||
* extra service without changing the default behavior.
|
||||
*/
|
||||
RCT_EXTERN void RCTAddLogFunction(RCTLogFunction logFunction);
|
||||
|
||||
/**
|
||||
* This method temporarily overrides the log function while performing the
|
||||
* specified block. This is useful for testing purposes (to detect if a given
|
||||
* function logs something) or to suppress or override logging temporarily.
|
||||
*/
|
||||
RCT_EXTERN void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction);
|
||||
|
||||
/**
|
||||
* This method adds a conditional prefix to any messages logged within the scope
|
||||
* of the passed block. This is useful for adding additional context to log
|
||||
* messages. The block will be performed synchronously on the current thread.
|
||||
*/
|
||||
RCT_EXTERN void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix);
|
||||
|
||||
/**
|
||||
* Private logging function - ignore this.
|
||||
*/
|
||||
#if RCTLOG_ENABLED
|
||||
#define _RCTLog(lvl, ...) _RCTLogNativeInternal(lvl, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define _RCTLog(lvl, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
RCT_EXTERN void _RCTLogNativeInternal(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4, 5);
|
||||
RCT_EXTERN void _RCTLogJavaScriptInternal(RCTLogLevel, NSString *);
|
308
node_modules/react-native/React/Base/RCTLog.mm
generated
vendored
Normal file
308
node_modules/react-native/React/Base/RCTLog.mm
generated
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
#include <cxxabi.h>
|
||||
|
||||
#import <objc/message.h>
|
||||
#import <os/log.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTRedBoxSetEnabled.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
static NSString *const RCTLogFunctionStack = @"RCTLogFunctionStack";
|
||||
|
||||
const char *RCTLogLevels[] = {
|
||||
"trace",
|
||||
"info",
|
||||
"warn",
|
||||
"error",
|
||||
"fatal",
|
||||
};
|
||||
|
||||
/* os log will discard debug and info messages if they are not needed */
|
||||
static const RCTLogLevel RCTDefaultLogThreshold = (RCTLogLevel)(RCTLogLevelInfo - 1);
|
||||
|
||||
static RCTLogFunction RCTCurrentLogFunction;
|
||||
static RCTLogLevel RCTCurrentLogThreshold = RCTDefaultLogThreshold;
|
||||
|
||||
RCTLogLevel RCTGetLogThreshold()
|
||||
{
|
||||
return RCTCurrentLogThreshold;
|
||||
}
|
||||
|
||||
void RCTSetLogThreshold(RCTLogLevel threshold)
|
||||
{
|
||||
RCTCurrentLogThreshold = threshold;
|
||||
}
|
||||
|
||||
static os_log_type_t RCTLogTypeForLogLevel(RCTLogLevel logLevel)
|
||||
{
|
||||
if (logLevel < RCTLogLevelInfo) {
|
||||
return OS_LOG_TYPE_DEBUG;
|
||||
} else if (logLevel <= RCTLogLevelWarning) {
|
||||
return OS_LOG_TYPE_INFO;
|
||||
} else {
|
||||
return OS_LOG_TYPE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static os_log_t RCTLogForLogSource(RCTLogSource source)
|
||||
{
|
||||
switch (source) {
|
||||
case RCTLogSourceNative: {
|
||||
static os_log_t nativeLog;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
nativeLog = os_log_create("com.facebook.react.log", "native");
|
||||
});
|
||||
return nativeLog;
|
||||
}
|
||||
case RCTLogSourceJavaScript: {
|
||||
static os_log_t javaScriptLog;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
javaScriptLog = os_log_create("com.facebook.react.log", "javascript");
|
||||
});
|
||||
return javaScriptLog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RCTLogFunction RCTDefaultLogFunction =
|
||||
^(RCTLogLevel level,
|
||||
RCTLogSource source,
|
||||
__unused NSString *fileName,
|
||||
__unused NSNumber *lineNumber,
|
||||
NSString *message) {
|
||||
os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String);
|
||||
};
|
||||
|
||||
void RCTSetLogFunction(RCTLogFunction logFunction)
|
||||
{
|
||||
RCTCurrentLogFunction = logFunction;
|
||||
}
|
||||
|
||||
RCTLogFunction RCTGetLogFunction()
|
||||
{
|
||||
if (!RCTCurrentLogFunction) {
|
||||
RCTCurrentLogFunction = RCTDefaultLogFunction;
|
||||
}
|
||||
return RCTCurrentLogFunction;
|
||||
}
|
||||
|
||||
void RCTAddLogFunction(RCTLogFunction logFunction)
|
||||
{
|
||||
RCTLogFunction existing = RCTGetLogFunction();
|
||||
if (existing) {
|
||||
RCTSetLogFunction(
|
||||
^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
existing(level, source, fileName, lineNumber, message);
|
||||
logFunction(level, source, fileName, lineNumber, message);
|
||||
});
|
||||
} else {
|
||||
RCTSetLogFunction(logFunction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the topmost stacked log function for the current thread, which
|
||||
* may not be the same as the current value of RCTCurrentLogFunction.
|
||||
*/
|
||||
static RCTLogFunction RCTGetLocalLogFunction()
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSArray<RCTLogFunction> *functionStack = threadDictionary[RCTLogFunctionStack];
|
||||
RCTLogFunction logFunction = functionStack.lastObject;
|
||||
if (logFunction) {
|
||||
return logFunction;
|
||||
}
|
||||
return RCTGetLogFunction();
|
||||
}
|
||||
|
||||
void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction)
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSMutableArray<RCTLogFunction> *functionStack = threadDictionary[RCTLogFunctionStack];
|
||||
if (!functionStack) {
|
||||
functionStack = [NSMutableArray new];
|
||||
threadDictionary[RCTLogFunctionStack] = functionStack;
|
||||
}
|
||||
[functionStack addObject:logFunction];
|
||||
block();
|
||||
[functionStack removeLastObject];
|
||||
}
|
||||
|
||||
void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix)
|
||||
{
|
||||
RCTLogFunction logFunction = RCTGetLocalLogFunction();
|
||||
if (logFunction) {
|
||||
RCTPerformBlockWithLogFunction(
|
||||
block, ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
logFunction(level, source, fileName, lineNumber, [prefix stringByAppendingString:message]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
NSString *
|
||||
RCTFormatLog(NSDate *timestamp, RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message)
|
||||
{
|
||||
NSMutableString *log = [NSMutableString new];
|
||||
if (timestamp) {
|
||||
static NSDateFormatter *formatter;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
formatter = [NSDateFormatter new];
|
||||
formatter.dateFormat = formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS ";
|
||||
});
|
||||
[log appendString:[formatter stringFromDate:timestamp]];
|
||||
}
|
||||
if (level) {
|
||||
[log appendFormat:@"[%s]", RCTLogLevels[level]];
|
||||
}
|
||||
|
||||
[log appendFormat:@"[tid:%@]", RCTCurrentThreadName()];
|
||||
|
||||
if (fileName) {
|
||||
fileName = fileName.lastPathComponent;
|
||||
if (lineNumber) {
|
||||
[log appendFormat:@"[%@:%@]", fileName, lineNumber];
|
||||
} else {
|
||||
[log appendFormat:@"[%@]", fileName];
|
||||
}
|
||||
}
|
||||
if (message) {
|
||||
[log appendString:@" "];
|
||||
[log appendString:message];
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
NSString *RCTFormatLogLevel(RCTLogLevel level)
|
||||
{
|
||||
NSDictionary *levelsToString = @{
|
||||
@(RCTLogLevelTrace) : @"trace",
|
||||
@(RCTLogLevelInfo) : @"info",
|
||||
@(RCTLogLevelWarning) : @"warning",
|
||||
@(RCTLogLevelFatal) : @"fatal",
|
||||
@(RCTLogLevelError) : @"error"
|
||||
};
|
||||
|
||||
return levelsToString[@(level)];
|
||||
}
|
||||
|
||||
NSString *RCTFormatLogSource(RCTLogSource source)
|
||||
{
|
||||
NSDictionary *sourcesToString = @{@(RCTLogSourceNative) : @"native", @(RCTLogSourceJavaScript) : @"js"};
|
||||
|
||||
return sourcesToString[@(source)];
|
||||
}
|
||||
|
||||
static NSRegularExpression *nativeStackFrameRegex()
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static NSRegularExpression *_regex;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSError *regexError;
|
||||
_regex = [NSRegularExpression regularExpressionWithPattern:@"0x[0-9a-f]+ (.*) \\+ (\\d+)$"
|
||||
options:0
|
||||
error:®exError];
|
||||
if (regexError) {
|
||||
RCTLogError(@"Failed to build regex: %@", [regexError localizedDescription]);
|
||||
}
|
||||
});
|
||||
return _regex;
|
||||
}
|
||||
|
||||
void _RCTLogNativeInternal(RCTLogLevel level, const char *fileName, int lineNumber, NSString *format, ...)
|
||||
{
|
||||
RCTLogFunction logFunction = RCTGetLocalLogFunction();
|
||||
BOOL log = RCT_DEBUG || (logFunction != nil);
|
||||
if (log && level >= RCTGetLogThreshold()) {
|
||||
// Get message
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
va_end(args);
|
||||
|
||||
// Call log function
|
||||
if (logFunction) {
|
||||
logFunction(
|
||||
level, RCTLogSourceNative, fileName ? @(fileName) : nil, lineNumber > 0 ? @(lineNumber) : nil, message);
|
||||
}
|
||||
|
||||
// Log to red box if one is configured.
|
||||
if (RCTSharedApplication() && RCTRedBoxGetEnabled() && level >= RCTLOG_REDBOX_LEVEL) {
|
||||
NSArray<NSString *> *stackSymbols = [NSThread callStackSymbols];
|
||||
NSMutableArray<NSDictionary *> *stack = [NSMutableArray arrayWithCapacity:(stackSymbols.count - 1)];
|
||||
[stackSymbols enumerateObjectsUsingBlock:^(NSString *frameSymbols, NSUInteger idx, __unused BOOL *stop) {
|
||||
if (idx == 0) {
|
||||
// don't include the current frame
|
||||
return;
|
||||
}
|
||||
|
||||
NSRange range = NSMakeRange(0, frameSymbols.length);
|
||||
NSTextCheckingResult *match = [nativeStackFrameRegex() firstMatchInString:frameSymbols options:0 range:range];
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *methodName = [frameSymbols substringWithRange:[match rangeAtIndex:1]];
|
||||
char *demangledName = abi::__cxa_demangle([methodName UTF8String], NULL, NULL, NULL);
|
||||
if (demangledName) {
|
||||
methodName = @(demangledName);
|
||||
free(demangledName);
|
||||
}
|
||||
|
||||
if (idx == 1 && fileName) {
|
||||
NSString *file = [@(fileName) componentsSeparatedByString:@"/"].lastObject;
|
||||
[stack addObject:@{@"methodName" : methodName, @"file" : file, @"lineNumber" : @(lineNumber)}];
|
||||
} else {
|
||||
[stack addObject:@{@"methodName" : methodName}];
|
||||
}
|
||||
}];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// red box is thread safe, but by deferring to main queue we avoid a startup
|
||||
// race condition that causes the module to be accessed before it has loaded
|
||||
id redbox = [[RCTBridge currentBridge] moduleForName:@"RedBox" lazilyLoadIfNecessary:YES];
|
||||
if (redbox) {
|
||||
void (*showErrorMessage)(id, SEL, NSString *, NSMutableArray<NSDictionary *> *) =
|
||||
(__typeof__(showErrorMessage))objc_msgSend;
|
||||
SEL showErrorMessageSEL = NSSelectorFromString(@"showErrorMessage:withStack:");
|
||||
|
||||
if ([redbox respondsToSelector:showErrorMessageSEL]) {
|
||||
showErrorMessage(redbox, showErrorMessageSEL, message, stack);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#if RCT_DEBUG
|
||||
if (!RCTRunningInTestEnvironment()) {
|
||||
// Log to JS executor
|
||||
[[RCTBridge currentBridge] logMessage:message level:level ? @(RCTLogLevels[level]) : @"info"];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void _RCTLogJavaScriptInternal(RCTLogLevel level, NSString *message)
|
||||
{
|
||||
RCTLogFunction logFunction = RCTGetLocalLogFunction();
|
||||
BOOL log = RCT_DEBUG || (logFunction != nil);
|
||||
if (log && level >= RCTGetLogThreshold()) {
|
||||
if (logFunction) {
|
||||
logFunction(level, RCTLogSourceJavaScript, nil, nil, message);
|
||||
}
|
||||
}
|
||||
}
|
40
node_modules/react-native/React/Base/RCTManagedPointer.h
generated
vendored
Normal file
40
node_modules/react-native/React/Base/RCTManagedPointer.h
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <memory>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Type erased wrapper over any cxx value that can be passed as an argument
|
||||
* to native method.
|
||||
*/
|
||||
|
||||
@interface RCTManagedPointer : NSObject
|
||||
|
||||
@property (nonatomic, readonly) void *voidPointer;
|
||||
|
||||
- (instancetype)initWithPointer:(std::shared_ptr<void>)pointer;
|
||||
|
||||
@end
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
template <typename T, typename P>
|
||||
RCTManagedPointer *managedPointer(P initializer)
|
||||
{
|
||||
auto ptr = std::shared_ptr<void>(new T(initializer));
|
||||
return [[RCTManagedPointer alloc] initWithPointer:std::move(ptr)];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
node_modules/react-native/React/Base/RCTManagedPointer.mm
generated
vendored
Normal file
27
node_modules/react-native/React/Base/RCTManagedPointer.mm
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTManagedPointer.h"
|
||||
|
||||
@implementation RCTManagedPointer {
|
||||
std::shared_ptr<void> _pointer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPointer:(std::shared_ptr<void>)pointer
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_pointer = std::move(pointer);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void *)voidPointer
|
||||
{
|
||||
return _pointer.get();
|
||||
}
|
||||
|
||||
@end
|
96
node_modules/react-native/React/Base/RCTModuleData.h
generated
vendored
Normal file
96
node_modules/react-native/React/Base/RCTModuleData.h
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTInvalidating.h>
|
||||
|
||||
@protocol RCTBridgeMethod;
|
||||
@protocol RCTBridgeModule;
|
||||
@class RCTBridge;
|
||||
|
||||
typedef id<RCTBridgeModule> (^RCTBridgeModuleProvider)(void);
|
||||
|
||||
@interface RCTModuleData : NSObject <RCTInvalidating>
|
||||
|
||||
- (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge;
|
||||
|
||||
- (instancetype)initWithModuleClass:(Class)moduleClass
|
||||
moduleProvider:(RCTBridgeModuleProvider)moduleProvider
|
||||
bridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance
|
||||
bridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Calls `constantsToExport` on the module and stores the result. Note that
|
||||
* this will init the module if it has not already been created. This method
|
||||
* can be called on any thread, but may block the main thread briefly if the
|
||||
* module implements `constantsToExport`.
|
||||
*/
|
||||
- (void)gatherConstants;
|
||||
|
||||
@property (nonatomic, strong, readonly) Class moduleClass;
|
||||
@property (nonatomic, copy, readonly) NSString *name;
|
||||
|
||||
/**
|
||||
* Returns the module methods. Note that this will gather the methods the first
|
||||
* time it is called and then memoize the results.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSArray<id<RCTBridgeMethod>> *methods;
|
||||
|
||||
/**
|
||||
* Returns a map of the module methods. Note that this will gather the methods the first
|
||||
* time it is called and then memoize the results.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id<RCTBridgeMethod>> *methodsByName;
|
||||
|
||||
/**
|
||||
* Returns the module's constants, if it exports any
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *exportedConstants;
|
||||
|
||||
/**
|
||||
* Returns YES if module instance has already been initialized; NO otherwise.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL hasInstance;
|
||||
|
||||
/**
|
||||
* Returns YES if module instance must be created on the main thread.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL requiresMainQueueSetup;
|
||||
|
||||
/**
|
||||
* Returns YES if module has constants to export.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL hasConstantsToExport;
|
||||
|
||||
/**
|
||||
* Returns the current module instance. Note that this will init the instance
|
||||
* if it has not already been created. To check if the module instance exists
|
||||
* without causing it to be created, use `hasInstance` instead.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) id<RCTBridgeModule> instance;
|
||||
|
||||
/**
|
||||
* Returns the module method dispatch queue. Note that this will init both the
|
||||
* queue and the module itself if they have not already been created.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue;
|
||||
|
||||
/**
|
||||
* Whether the receiver has a valid `instance` which implements -batchDidComplete.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL implementsBatchDidComplete;
|
||||
|
||||
/**
|
||||
* Whether the receiver has a valid `instance` which implements
|
||||
* -partialBatchDidFlush.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL implementsPartialBatchDidFlush;
|
||||
|
||||
@end
|
380
node_modules/react-native/React/Base/RCTModuleData.mm
generated
vendored
Normal file
380
node_modules/react-native/React/Base/RCTModuleData.mm
generated
vendored
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTModuleData.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#include <mutex>
|
||||
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTModuleMethod.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@implementation RCTModuleData {
|
||||
NSDictionary<NSString *, id> *_constantsToExport;
|
||||
NSString *_queueName;
|
||||
__weak RCTBridge *_bridge;
|
||||
RCTBridgeModuleProvider _moduleProvider;
|
||||
std::mutex _instanceLock;
|
||||
BOOL _setupComplete;
|
||||
}
|
||||
|
||||
@synthesize methods = _methods;
|
||||
@synthesize methodsByName = _methodsByName;
|
||||
@synthesize instance = _instance;
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
_implementsBatchDidComplete = [_moduleClass instancesRespondToSelector:@selector(batchDidComplete)];
|
||||
_implementsPartialBatchDidFlush = [_moduleClass instancesRespondToSelector:@selector(partialBatchDidFlush)];
|
||||
|
||||
// If a module overrides `constantsToExport` and doesn't implement `requiresMainQueueSetup`, then we must assume
|
||||
// that it must be called on the main thread, because it may need to access UIKit.
|
||||
_hasConstantsToExport = [_moduleClass instancesRespondToSelector:@selector(constantsToExport)];
|
||||
|
||||
const BOOL implementsRequireMainQueueSetup = [_moduleClass respondsToSelector:@selector(requiresMainQueueSetup)];
|
||||
if (implementsRequireMainQueueSetup) {
|
||||
_requiresMainQueueSetup = [_moduleClass requiresMainQueueSetup];
|
||||
} else {
|
||||
static IMP objectInitMethod;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
objectInitMethod = [NSObject instanceMethodForSelector:@selector(init)];
|
||||
});
|
||||
|
||||
// If a module overrides `init` then we must assume that it expects to be
|
||||
// initialized on the main thread, because it may need to access UIKit.
|
||||
const BOOL hasCustomInit =
|
||||
!_instance && [_moduleClass instanceMethodForSelector:@selector(init)] != objectInitMethod;
|
||||
|
||||
_requiresMainQueueSetup = _hasConstantsToExport || hasCustomInit;
|
||||
if (_requiresMainQueueSetup) {
|
||||
const char *methodName = "";
|
||||
if (_hasConstantsToExport) {
|
||||
methodName = "constantsToExport";
|
||||
} else if (hasCustomInit) {
|
||||
methodName = "init";
|
||||
}
|
||||
RCTLogWarn(
|
||||
@"Module %@ requires main queue setup since it overrides `%s` but doesn't implement "
|
||||
"`requiresMainQueueSetup`. In a future release React Native will default to initializing all native modules "
|
||||
"on a background thread unless explicitly opted-out of.",
|
||||
_moduleClass,
|
||||
methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge
|
||||
{
|
||||
return [self initWithModuleClass:moduleClass
|
||||
moduleProvider:^id<RCTBridgeModule> {
|
||||
return [moduleClass new];
|
||||
}
|
||||
bridge:bridge];
|
||||
}
|
||||
|
||||
- (instancetype)initWithModuleClass:(Class)moduleClass
|
||||
moduleProvider:(RCTBridgeModuleProvider)moduleProvider
|
||||
bridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
_moduleClass = moduleClass;
|
||||
_moduleProvider = [moduleProvider copy];
|
||||
[self setUp];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance bridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
_instance = instance;
|
||||
_moduleClass = [instance class];
|
||||
[self setUp];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init);
|
||||
|
||||
#pragma mark - private setup methods
|
||||
|
||||
- (void)setUpInstanceAndBridge
|
||||
{
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways,
|
||||
@"[RCTModuleData setUpInstanceAndBridge]",
|
||||
@{@"moduleClass" : NSStringFromClass(_moduleClass)});
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_instanceLock);
|
||||
|
||||
if (!_setupComplete && _bridge.valid) {
|
||||
if (!_instance) {
|
||||
if (RCT_DEBUG && _requiresMainQueueSetup) {
|
||||
RCTAssertMainQueue();
|
||||
}
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil);
|
||||
_instance = _moduleProvider ? _moduleProvider() : nil;
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
if (!_instance) {
|
||||
// Module init returned nil, probably because automatic instantiation
|
||||
// of the module is not supported, and it is supposed to be passed in to
|
||||
// the bridge constructor. Mark setup complete to avoid doing more work.
|
||||
_setupComplete = YES;
|
||||
RCTLogWarn(
|
||||
@"The module %@ is returning nil from its constructor. You "
|
||||
"may need to instantiate it yourself and pass it into the "
|
||||
"bridge.",
|
||||
_moduleClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (_instance && RCTProfileIsProfiling()) {
|
||||
RCTProfileHookInstance(_instance);
|
||||
}
|
||||
|
||||
// Bridge must be set before methodQueue is set up, as methodQueue
|
||||
// initialization requires it (View Managers get their queue by calling
|
||||
// self.bridge.uiManager.methodQueue)
|
||||
[self setBridgeForInstance];
|
||||
}
|
||||
|
||||
[self setUpMethodQueue];
|
||||
}
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
|
||||
// This is called outside of the lock in order to prevent deadlock issues
|
||||
// because the logic in `finishSetupForInstance` can cause
|
||||
// `moduleData.instance` to be accessed re-entrantly.
|
||||
if (_bridge.moduleSetupComplete) {
|
||||
[self finishSetupForInstance];
|
||||
} else {
|
||||
// If we're here, then the module is completely initialized,
|
||||
// except for what finishSetupForInstance does. When the instance
|
||||
// method is called after moduleSetupComplete,
|
||||
// finishSetupForInstance will run. If _requiresMainQueueSetup
|
||||
// is true, getting the instance will block waiting for the main
|
||||
// thread, which could take a while if the main thread is busy
|
||||
// (I've seen 50ms in testing). So we clear that flag, since
|
||||
// nothing in finishSetupForInstance needs to be run on the main
|
||||
// thread.
|
||||
_requiresMainQueueSetup = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBridgeForInstance
|
||||
{
|
||||
if ([_instance respondsToSelector:@selector(bridge)] && _instance.bridge != _bridge) {
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setBridgeForInstance]", nil);
|
||||
@try {
|
||||
[(id)_instance setValue:_bridge forKey:@"bridge"];
|
||||
} @catch (NSException *exception) {
|
||||
RCTLogError(
|
||||
@"%@ has no setter or ivar for its bridge, which is not "
|
||||
"permitted. You must either @synthesize the bridge property, "
|
||||
"or provide your own setter method.",
|
||||
self.name);
|
||||
}
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)finishSetupForInstance
|
||||
{
|
||||
if (!_setupComplete && _instance) {
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData finishSetupForInstance]", nil);
|
||||
_setupComplete = YES;
|
||||
[_bridge registerModuleForFrameUpdates:_instance withModuleData:self];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:RCTDidInitializeModuleNotification
|
||||
object:_bridge
|
||||
userInfo:@{@"module" : _instance, @"bridge" : RCTNullIfNil(_bridge.parentBridge)}];
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setUpMethodQueue
|
||||
{
|
||||
if (_instance && !_methodQueue && _bridge.valid) {
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpMethodQueue]", nil);
|
||||
BOOL implementsMethodQueue = [_instance respondsToSelector:@selector(methodQueue)];
|
||||
if (implementsMethodQueue && _bridge.valid) {
|
||||
_methodQueue = _instance.methodQueue;
|
||||
}
|
||||
if (!_methodQueue && _bridge.valid) {
|
||||
// Create new queue (store queueName, as it isn't retained by dispatch_queue)
|
||||
_queueName = [NSString stringWithFormat:@"com.facebook.react.%@Queue", self.name];
|
||||
_methodQueue = dispatch_queue_create(_queueName.UTF8String, DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
// assign it to the module
|
||||
if (implementsMethodQueue) {
|
||||
@try {
|
||||
[(id)_instance setValue:_methodQueue forKey:@"methodQueue"];
|
||||
} @catch (NSException *exception) {
|
||||
RCTLogError(
|
||||
@"%@ is returning nil for its methodQueue, which is not "
|
||||
"permitted. You must either return a pre-initialized "
|
||||
"queue, or @synthesize the methodQueue to let the bridge "
|
||||
"create a queue for you.",
|
||||
self.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)calculateMethods
|
||||
{
|
||||
if (_methods && _methodsByName) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableArray<id<RCTBridgeMethod>> *moduleMethods = [NSMutableArray new];
|
||||
NSMutableDictionary<NSString *, id<RCTBridgeMethod>> *moduleMethodsByName = [NSMutableDictionary new];
|
||||
|
||||
if ([_moduleClass instancesRespondToSelector:@selector(methodsToExport)]) {
|
||||
[moduleMethods addObjectsFromArray:[self.instance methodsToExport]];
|
||||
}
|
||||
|
||||
unsigned int methodCount;
|
||||
Class cls = _moduleClass;
|
||||
while (cls && cls != [NSObject class] && cls != [NSProxy class]) {
|
||||
Method *methods = class_copyMethodList(object_getClass(cls), &methodCount);
|
||||
|
||||
for (unsigned int i = 0; i < methodCount; i++) {
|
||||
Method method = methods[i];
|
||||
SEL selector = method_getName(method);
|
||||
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
|
||||
IMP imp = method_getImplementation(method);
|
||||
auto exportedMethod = ((const RCTMethodInfo *(*)(id, SEL))imp)(_moduleClass, selector);
|
||||
id<RCTBridgeMethod> moduleMethod = [[RCTModuleMethod alloc] initWithExportedMethod:exportedMethod
|
||||
moduleClass:_moduleClass];
|
||||
|
||||
NSString *str = [NSString stringWithUTF8String:moduleMethod.JSMethodName];
|
||||
[moduleMethodsByName setValue:moduleMethod forKey:str];
|
||||
[moduleMethods addObject:moduleMethod];
|
||||
}
|
||||
}
|
||||
|
||||
free(methods);
|
||||
cls = class_getSuperclass(cls);
|
||||
}
|
||||
|
||||
_methods = [moduleMethods copy];
|
||||
_methodsByName = [moduleMethodsByName copy];
|
||||
}
|
||||
|
||||
#pragma mark - public getters
|
||||
|
||||
- (BOOL)hasInstance
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_instanceLock);
|
||||
return _instance != nil;
|
||||
}
|
||||
|
||||
- (id<RCTBridgeModule>)instance
|
||||
{
|
||||
if (!_setupComplete) {
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass]), nil);
|
||||
if (_requiresMainQueueSetup) {
|
||||
// The chances of deadlock here are low, because module init very rarely
|
||||
// calls out to other threads, however we can't control when a module might
|
||||
// get accessed by client code during bridge setup, and a very low risk of
|
||||
// deadlock is better than a fairly high risk of an assertion being thrown.
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData instance] main thread setup", nil);
|
||||
|
||||
if (!RCTIsMainQueue()) {
|
||||
RCTLogWarn(@"RCTBridge required dispatch_sync to load %@. This may lead to deadlocks", _moduleClass);
|
||||
}
|
||||
|
||||
RCTUnsafeExecuteOnMainQueueSync(^{
|
||||
[self setUpInstanceAndBridge];
|
||||
});
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
} else {
|
||||
[self setUpInstanceAndBridge];
|
||||
}
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
return RCTBridgeModuleNameForClass(_moduleClass);
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeMethod>> *)methods
|
||||
{
|
||||
[self calculateMethods];
|
||||
return _methods;
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id<RCTBridgeMethod>> *)methodsByName
|
||||
{
|
||||
[self calculateMethods];
|
||||
return _methodsByName;
|
||||
}
|
||||
|
||||
- (void)gatherConstants
|
||||
{
|
||||
if (_hasConstantsToExport && !_constantsToExport) {
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData gatherConstants] %@", _moduleClass]), nil);
|
||||
(void)[self instance];
|
||||
if (_requiresMainQueueSetup) {
|
||||
if (!RCTIsMainQueue()) {
|
||||
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
|
||||
}
|
||||
|
||||
RCTUnsafeExecuteOnMainQueueSync(^{
|
||||
self->_constantsToExport = [self->_instance constantsToExport] ?: @{};
|
||||
});
|
||||
} else {
|
||||
_constantsToExport = [_instance constantsToExport] ?: @{};
|
||||
}
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id> *)exportedConstants
|
||||
{
|
||||
[self gatherConstants];
|
||||
NSDictionary<NSString *, id> *constants = _constantsToExport;
|
||||
_constantsToExport = nil; // Not needed anymore
|
||||
return constants;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
if (_bridge.valid) {
|
||||
id instance = self.instance;
|
||||
RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@)", self, instance);
|
||||
}
|
||||
return _methodQueue;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
_methodQueue = nil;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p; name=\"%@\">", [self class], self, self.name];
|
||||
}
|
||||
|
||||
@end
|
34
node_modules/react-native/React/Base/RCTModuleMethod.h
generated
vendored
Normal file
34
node_modules/react-native/React/Base/RCTModuleMethod.h
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTBridgeMethod.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTNullability.h>
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
@interface RCTMethodArgument : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *type;
|
||||
@property (nonatomic, readonly) RCTNullability nullability;
|
||||
@property (nonatomic, readonly) BOOL unused;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTModuleMethod : NSObject <RCTBridgeMethod>
|
||||
|
||||
@property (nonatomic, readonly) Class moduleClass;
|
||||
@property (nonatomic, readonly) SEL selector;
|
||||
|
||||
- (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportMethod
|
||||
moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
RCT_EXTERN NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments);
|
615
node_modules/react-native/React/Base/RCTModuleMethod.mm
generated
vendored
Normal file
615
node_modules/react-native/React/Base/RCTModuleMethod.mm
generated
vendored
Normal file
@ -0,0 +1,615 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTModuleMethod.h"
|
||||
|
||||
#import <objc/message.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTCxxConvert.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTManagedPointer.h"
|
||||
#import "RCTParserUtils.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
||||
|
||||
/**
|
||||
* Get the converter function for the specified type
|
||||
*/
|
||||
static SEL selectorForType(NSString *type)
|
||||
{
|
||||
const char *input = type.UTF8String;
|
||||
return NSSelectorFromString([RCTParseType(&input) stringByAppendingString:@":"]);
|
||||
}
|
||||
|
||||
@implementation RCTMethodArgument
|
||||
|
||||
- (instancetype)initWithType:(NSString *)type nullability:(RCTNullability)nullability unused:(BOOL)unused
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_type = [type copy];
|
||||
_nullability = nullability;
|
||||
_unused = unused;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTModuleMethod {
|
||||
Class _moduleClass;
|
||||
const RCTMethodInfo *_methodInfo;
|
||||
NSString *_JSMethodName;
|
||||
|
||||
SEL _selector;
|
||||
NSInvocation *_invocation;
|
||||
NSArray<RCTArgumentBlock> *_argumentBlocks;
|
||||
NSMutableArray *_retainedObjects;
|
||||
}
|
||||
|
||||
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index, id valueOrType, const char *issue)
|
||||
{
|
||||
RCTLogError(
|
||||
@"Argument %tu (%@) of %@.%s %s",
|
||||
index,
|
||||
valueOrType,
|
||||
RCTBridgeModuleNameForClass(method->_moduleClass),
|
||||
method.JSMethodName,
|
||||
issue);
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
RCT_EXTERN_C_BEGIN
|
||||
|
||||
// returns YES if the selector ends in a colon (indicating that there is at
|
||||
// least one argument, and maybe more selector parts) or NO if it doesn't.
|
||||
static BOOL RCTParseSelectorPart(const char **input, NSMutableString *selector)
|
||||
{
|
||||
NSString *selectorPart;
|
||||
if (RCTParseSelectorIdentifier(input, &selectorPart)) {
|
||||
[selector appendString:selectorPart];
|
||||
}
|
||||
RCTSkipWhitespace(input);
|
||||
if (RCTReadChar(input, ':')) {
|
||||
[selector appendString:@":"];
|
||||
RCTSkipWhitespace(input);
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
static BOOL RCTParseUnused(const char **input)
|
||||
{
|
||||
return RCTReadString(input, "__attribute__((unused))") || RCTReadString(input, "__attribute__((__unused__))") ||
|
||||
RCTReadString(input, "__unused");
|
||||
}
|
||||
|
||||
static RCTNullability RCTParseNullability(const char **input)
|
||||
{
|
||||
if (RCTReadString(input, "nullable")) {
|
||||
return RCTNullable;
|
||||
} else if (RCTReadString(input, "nonnull")) {
|
||||
return RCTNonnullable;
|
||||
}
|
||||
return RCTNullabilityUnspecified;
|
||||
}
|
||||
|
||||
static RCTNullability RCTParseNullabilityPostfix(const char **input)
|
||||
{
|
||||
if (RCTReadString(input, "_Nullable") || RCTReadString(input, "__nullable")) {
|
||||
return RCTNullable;
|
||||
} else if (RCTReadString(input, "_Nonnull") || RCTReadString(input, "__nonnull")) {
|
||||
return RCTNonnullable;
|
||||
}
|
||||
return RCTNullabilityUnspecified;
|
||||
}
|
||||
|
||||
// returns YES if execution is safe to proceed (enqueue callback invocation), NO if callback has already been invoked
|
||||
#if RCT_DEBUG
|
||||
static BOOL checkCallbackMultipleInvocations(BOOL *didInvoke)
|
||||
{
|
||||
if (*didInvoke) {
|
||||
RCTFatal(RCTErrorWithMessage(
|
||||
@"Illegal callback invocation from native module. This callback type only permits a single invocation from native code."));
|
||||
return NO;
|
||||
} else {
|
||||
*didInvoke = YES;
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments)
|
||||
{
|
||||
RCTSkipWhitespace(&input);
|
||||
|
||||
NSMutableArray *args;
|
||||
NSMutableString *selector = [NSMutableString new];
|
||||
while (RCTParseSelectorPart(&input, selector)) {
|
||||
if (!args) {
|
||||
args = [NSMutableArray new];
|
||||
}
|
||||
|
||||
// Parse type
|
||||
if (RCTReadChar(&input, '(')) {
|
||||
RCTSkipWhitespace(&input);
|
||||
|
||||
// 5 cases that both nullable and __unused exist
|
||||
// 1: foo:(nullable __unused id)foo 2: foo:(nullable id __unused)foo
|
||||
// 3: foo:(__unused id _Nullable)foo 4: foo:(id __unused _Nullable)foo
|
||||
// 5: foo:(id _Nullable __unused)foo
|
||||
RCTNullability nullability = RCTParseNullability(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
|
||||
BOOL unused = RCTParseUnused(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
|
||||
NSString *type = RCTParseType(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
|
||||
if (nullability == RCTNullabilityUnspecified) {
|
||||
nullability = RCTParseNullabilityPostfix(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
if (!unused) {
|
||||
unused = RCTParseUnused(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
if (unused && nullability == RCTNullabilityUnspecified) {
|
||||
nullability = RCTParseNullabilityPostfix(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
}
|
||||
}
|
||||
} else if (!unused) {
|
||||
unused = RCTParseUnused(&input);
|
||||
RCTSkipWhitespace(&input);
|
||||
}
|
||||
[args addObject:[[RCTMethodArgument alloc] initWithType:type nullability:nullability unused:unused]];
|
||||
RCTSkipWhitespace(&input);
|
||||
RCTReadChar(&input, ')');
|
||||
RCTSkipWhitespace(&input);
|
||||
} else {
|
||||
// Type defaults to id if unspecified
|
||||
[args addObject:[[RCTMethodArgument alloc] initWithType:@"id" nullability:RCTNullable unused:NO]];
|
||||
}
|
||||
|
||||
// Argument name
|
||||
RCTParseArgumentIdentifier(&input, NULL);
|
||||
RCTSkipWhitespace(&input);
|
||||
}
|
||||
|
||||
*arguments = [args copy];
|
||||
return selector;
|
||||
}
|
||||
|
||||
RCT_EXTERN_C_END
|
||||
|
||||
- (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportedMethod moduleClass:(Class)moduleClass
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_moduleClass = moduleClass;
|
||||
_methodInfo = exportedMethod;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)processMethodSignature
|
||||
{
|
||||
NSArray<RCTMethodArgument *> *arguments;
|
||||
_selector = NSSelectorFromString(RCTParseMethodSignature(_methodInfo->objcName, &arguments));
|
||||
RCTAssert(_selector, @"%s is not a valid selector", _methodInfo->objcName);
|
||||
|
||||
// Create method invocation
|
||||
NSMethodSignature *methodSignature = [_moduleClass instanceMethodSignatureForSelector:_selector];
|
||||
RCTAssert(methodSignature, @"%s is not a recognized Objective-C method.", sel_getName(_selector));
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
|
||||
invocation.selector = _selector;
|
||||
_invocation = invocation;
|
||||
NSMutableArray *retainedObjects = [NSMutableArray array];
|
||||
_retainedObjects = retainedObjects;
|
||||
|
||||
// Process arguments
|
||||
NSUInteger numberOfArguments = methodSignature.numberOfArguments;
|
||||
NSMutableArray<RCTArgumentBlock> *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
|
||||
|
||||
#if RCT_DEBUG
|
||||
__weak RCTModuleMethod *weakSelf = self;
|
||||
#endif
|
||||
|
||||
#define RCT_RETAINED_ARG_BLOCK(_logic) \
|
||||
[argumentBlocks addObject:^(__unused __weak RCTBridge * bridge, NSUInteger index, id json) { \
|
||||
_logic [invocation setArgument:&value atIndex:(index) + 2]; \
|
||||
if (value) { \
|
||||
[retainedObjects addObject:value]; \
|
||||
} \
|
||||
return YES; \
|
||||
}]
|
||||
|
||||
#define __PRIMITIVE_CASE(_type, _nullable) \
|
||||
{ \
|
||||
isNullableType = _nullable; \
|
||||
_type (*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend; \
|
||||
[argumentBlocks addObject:^(__unused RCTBridge * bridge, NSUInteger index, id json) { \
|
||||
_type value = convert([RCTConvert class], selector, json); \
|
||||
[invocation setArgument:&value atIndex:(index) + 2]; \
|
||||
return YES; \
|
||||
}]; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define PRIMITIVE_CASE(_type) __PRIMITIVE_CASE(_type, NO)
|
||||
#define NULLABLE_PRIMITIVE_CASE(_type) __PRIMITIVE_CASE(_type, YES)
|
||||
|
||||
// Explicitly copy the block
|
||||
#define __COPY_BLOCK(block...) \
|
||||
id value = [block copy]; \
|
||||
if (value) { \
|
||||
[retainedObjects addObject:value]; \
|
||||
}
|
||||
|
||||
#if RCT_DEBUG
|
||||
#define BLOCK_CASE(_block_args, _block) \
|
||||
RCT_RETAINED_ARG_BLOCK(if (json && ![json isKindOfClass:[NSNumber class]]) { \
|
||||
RCTLogArgumentError(weakSelf, index, json, "should be a function"); \
|
||||
return NO; \
|
||||
} __block BOOL didInvoke = NO; \
|
||||
__COPY_BLOCK(^_block_args { \
|
||||
if (checkCallbackMultipleInvocations(&didInvoke)) \
|
||||
_block \
|
||||
});)
|
||||
#else
|
||||
#define BLOCK_CASE(_block_args, _block) \
|
||||
RCT_RETAINED_ARG_BLOCK(__COPY_BLOCK(^_block_args{ \
|
||||
_block});)
|
||||
#endif
|
||||
|
||||
for (NSUInteger i = 2; i < numberOfArguments; i++) {
|
||||
const char *objcType = [methodSignature getArgumentTypeAtIndex:i];
|
||||
BOOL isNullableType = NO;
|
||||
RCTMethodArgument *argument = arguments[i - 2];
|
||||
NSString *typeName = argument.type;
|
||||
SEL selector = selectorForType(typeName);
|
||||
if ([RCTConvert respondsToSelector:selector]) {
|
||||
switch (objcType[0]) {
|
||||
// Primitives
|
||||
case _C_CHR:
|
||||
PRIMITIVE_CASE(char)
|
||||
case _C_UCHR:
|
||||
PRIMITIVE_CASE(unsigned char)
|
||||
case _C_SHT:
|
||||
PRIMITIVE_CASE(short)
|
||||
case _C_USHT:
|
||||
PRIMITIVE_CASE(unsigned short)
|
||||
case _C_INT:
|
||||
PRIMITIVE_CASE(int)
|
||||
case _C_UINT:
|
||||
PRIMITIVE_CASE(unsigned int)
|
||||
case _C_LNG:
|
||||
PRIMITIVE_CASE(long)
|
||||
case _C_ULNG:
|
||||
PRIMITIVE_CASE(unsigned long)
|
||||
case _C_LNG_LNG:
|
||||
PRIMITIVE_CASE(long long)
|
||||
case _C_ULNG_LNG:
|
||||
PRIMITIVE_CASE(unsigned long long)
|
||||
case _C_FLT:
|
||||
PRIMITIVE_CASE(float)
|
||||
case _C_DBL:
|
||||
PRIMITIVE_CASE(double)
|
||||
case _C_BOOL:
|
||||
PRIMITIVE_CASE(BOOL)
|
||||
case _C_SEL:
|
||||
NULLABLE_PRIMITIVE_CASE(SEL)
|
||||
case _C_CHARPTR:
|
||||
NULLABLE_PRIMITIVE_CASE(const char *)
|
||||
case _C_PTR:
|
||||
NULLABLE_PRIMITIVE_CASE(void *)
|
||||
|
||||
case _C_ID: {
|
||||
isNullableType = YES;
|
||||
id (*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
|
||||
RCT_RETAINED_ARG_BLOCK(id value = convert([RCTConvert class], selector, json););
|
||||
break;
|
||||
}
|
||||
|
||||
case _C_STRUCT_B: {
|
||||
NSMethodSignature *typeSignature = [RCTConvert methodSignatureForSelector:selector];
|
||||
NSInvocation *typeInvocation = [NSInvocation invocationWithMethodSignature:typeSignature];
|
||||
typeInvocation.selector = selector;
|
||||
typeInvocation.target = [RCTConvert class];
|
||||
|
||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) {
|
||||
void *returnValue = malloc(typeSignature.methodReturnLength);
|
||||
if (!returnValue) {
|
||||
// CWE - 391 : Unchecked error condition
|
||||
// https://www.cvedetails.com/cwe-details/391/Unchecked-Error-Condition.html
|
||||
// https://eli.thegreenplace.net/2009/10/30/handling-out-of-memory-conditions-in-c
|
||||
abort();
|
||||
}
|
||||
[typeInvocation setArgument:&json atIndex:2];
|
||||
[typeInvocation invoke];
|
||||
[typeInvocation getReturnValue:returnValue];
|
||||
[invocation setArgument:returnValue atIndex:index + 2];
|
||||
free(returnValue);
|
||||
return YES;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
static const char *blockType = @encode(__typeof__(^{
|
||||
}));
|
||||
if (!strcmp(objcType, blockType)) {
|
||||
BLOCK_CASE((NSArray * args), { [bridge enqueueCallback:json args:args]; });
|
||||
} else {
|
||||
RCTLogError(@"Unsupported argument type '%@' in method %@.", typeName, [self methodName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ([typeName isEqualToString:@"RCTResponseSenderBlock"]) {
|
||||
BLOCK_CASE((NSArray * args), { [bridge enqueueCallback:json args:args]; });
|
||||
} else if ([typeName isEqualToString:@"RCTResponseErrorBlock"]) {
|
||||
BLOCK_CASE((NSError * error), { [bridge enqueueCallback:json args:@[ RCTJSErrorFromNSError(error) ]]; });
|
||||
} else if ([typeName isEqualToString:@"RCTPromiseResolveBlock"]) {
|
||||
RCTAssert(
|
||||
i == numberOfArguments - 2,
|
||||
@"The RCTPromiseResolveBlock must be the second to last parameter in %@",
|
||||
[self methodName]);
|
||||
BLOCK_CASE((id result), { [bridge enqueueCallback:json args:result ? @[ result ] : @[]]; });
|
||||
} else if ([typeName isEqualToString:@"RCTPromiseRejectBlock"]) {
|
||||
RCTAssert(
|
||||
i == numberOfArguments - 1, @"The RCTPromiseRejectBlock must be the last parameter in %@", [self methodName]);
|
||||
BLOCK_CASE((NSString * code, NSString * message, NSError * error), {
|
||||
NSDictionary *errorJSON = RCTJSErrorFromCodeMessageAndNSError(code, message, error);
|
||||
[bridge enqueueCallback:json args:@[ errorJSON ]];
|
||||
});
|
||||
} else if ([typeName hasPrefix:@"JS::"]) {
|
||||
NSString *selectorNameForCxxType =
|
||||
[[typeName stringByReplacingOccurrencesOfString:@"::" withString:@"_"] stringByAppendingString:@":"];
|
||||
selector = NSSelectorFromString(selectorNameForCxxType);
|
||||
|
||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) {
|
||||
RCTManagedPointer *(*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
|
||||
RCTManagedPointer *box = convert([RCTCxxConvert class], selector, json);
|
||||
|
||||
void *pointer = box.voidPointer;
|
||||
[invocation setArgument:&pointer atIndex:index + 2];
|
||||
[retainedObjects addObject:box];
|
||||
|
||||
return YES;
|
||||
}];
|
||||
} else {
|
||||
// Unknown argument type
|
||||
RCTLogError(
|
||||
@"Unknown argument type '%@' in method %@. Extend RCTConvert to support this type.",
|
||||
typeName,
|
||||
[self methodName]);
|
||||
}
|
||||
|
||||
#if RCT_DEBUG
|
||||
RCTNullability nullability = argument.nullability;
|
||||
if (!isNullableType) {
|
||||
if (nullability == RCTNullable) {
|
||||
RCTLogArgumentError(
|
||||
weakSelf,
|
||||
i - 2,
|
||||
typeName,
|
||||
"is marked as "
|
||||
"nullable, but is not a nullable type.");
|
||||
}
|
||||
nullability = RCTNonnullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special case - Numbers are not nullable in Android, so we
|
||||
* don't support this for now. In future we may allow it.
|
||||
*/
|
||||
if ([typeName isEqualToString:@"NSNumber"]) {
|
||||
BOOL unspecified = (nullability == RCTNullabilityUnspecified);
|
||||
if (!argument.unused && (nullability == RCTNullable || unspecified)) {
|
||||
RCTLogArgumentError(
|
||||
weakSelf,
|
||||
i - 2,
|
||||
typeName,
|
||||
[unspecified ? @"has unspecified nullability" : @"is marked as nullable"
|
||||
stringByAppendingString:@" but React requires that all NSNumber "
|
||||
"arguments are explicitly marked as `nonnull` to ensure "
|
||||
"compatibility with Android."]
|
||||
.UTF8String);
|
||||
}
|
||||
nullability = RCTNonnullable;
|
||||
}
|
||||
|
||||
if (nullability == RCTNonnullable) {
|
||||
RCTArgumentBlock oldBlock = argumentBlocks[i - 2];
|
||||
argumentBlocks[i - 2] = ^(RCTBridge *bridge, NSUInteger index, id json) {
|
||||
if (json != nil) {
|
||||
if (!oldBlock(bridge, index, json)) {
|
||||
return NO;
|
||||
}
|
||||
if (isNullableType) {
|
||||
// Check converted value wasn't null either, as method probably
|
||||
// won't gracefully handle a nil value for a nonull argument
|
||||
void *value;
|
||||
[invocation getArgument:&value atIndex:index + 2];
|
||||
if (value == NULL) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
RCTLogArgumentError(weakSelf, index, typeName, "must not be null");
|
||||
return NO;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if RCT_DEBUG
|
||||
const char *objcType = _invocation.methodSignature.methodReturnType;
|
||||
if (_methodInfo->isSync && objcType[0] != _C_ID) {
|
||||
RCTLogError(
|
||||
@"Return type of %@.%s should be (id) as the method is \"sync\"",
|
||||
RCTBridgeModuleNameForClass(_moduleClass),
|
||||
self.JSMethodName);
|
||||
}
|
||||
#endif
|
||||
|
||||
_argumentBlocks = argumentBlocks;
|
||||
}
|
||||
|
||||
- (SEL)selector
|
||||
{
|
||||
if (_selector == NULL) {
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways,
|
||||
@"",
|
||||
(@{@"module" : NSStringFromClass(_moduleClass), @"method" : @(_methodInfo->objcName)}));
|
||||
[self processMethodSignature];
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
return _selector;
|
||||
}
|
||||
|
||||
- (const char *)JSMethodName
|
||||
{
|
||||
NSString *methodName = _JSMethodName;
|
||||
if (!methodName) {
|
||||
const char *jsName = _methodInfo->jsName;
|
||||
if (jsName && strlen(jsName) > 0) {
|
||||
methodName = @(jsName);
|
||||
} else {
|
||||
methodName = @(_methodInfo->objcName);
|
||||
NSRange colonRange = [methodName rangeOfString:@":"];
|
||||
if (colonRange.location != NSNotFound) {
|
||||
methodName = [methodName substringToIndex:colonRange.location];
|
||||
}
|
||||
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
RCTAssert(
|
||||
methodName.length,
|
||||
@"%s is not a valid JS function name, please"
|
||||
" supply an alternative using RCT_REMAP_METHOD()",
|
||||
_methodInfo->objcName);
|
||||
}
|
||||
_JSMethodName = methodName;
|
||||
}
|
||||
return methodName.UTF8String;
|
||||
}
|
||||
|
||||
- (RCTFunctionType)functionType
|
||||
{
|
||||
if (strstr(_methodInfo->objcName, "RCTPromise") != NULL) {
|
||||
RCTAssert(!_methodInfo->isSync, @"Promises cannot be used in sync functions");
|
||||
return RCTFunctionTypePromise;
|
||||
} else if (_methodInfo->isSync) {
|
||||
return RCTFunctionTypeSync;
|
||||
} else {
|
||||
return RCTFunctionTypeNormal;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments
|
||||
{
|
||||
if (_argumentBlocks == nil) {
|
||||
[self processMethodSignature];
|
||||
}
|
||||
|
||||
#if RCT_DEBUG
|
||||
// Sanity check
|
||||
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
|
||||
%@ on a module of class %@", [self methodName], [module class]);
|
||||
|
||||
// Safety check
|
||||
if (arguments.count != _argumentBlocks.count) {
|
||||
NSInteger actualCount = arguments.count;
|
||||
NSInteger expectedCount = _argumentBlocks.count;
|
||||
|
||||
// Subtract the implicit Promise resolver and rejecter functions for implementations of async functions
|
||||
if (self.functionType == RCTFunctionTypePromise) {
|
||||
actualCount -= 2;
|
||||
expectedCount -= 2;
|
||||
}
|
||||
|
||||
RCTLogError(
|
||||
@"%@.%s was called with %lld arguments but expects %lld arguments. "
|
||||
@"If you haven\'t changed this method yourself, this usually means that "
|
||||
@"your versions of the native code and JavaScript code are out of sync. "
|
||||
@"Updating both should make this error go away.",
|
||||
RCTBridgeModuleNameForClass(_moduleClass),
|
||||
self.JSMethodName,
|
||||
(long long)actualCount,
|
||||
(long long)expectedCount);
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set arguments
|
||||
NSUInteger index = 0;
|
||||
for (id json in arguments) {
|
||||
RCTArgumentBlock block = _argumentBlocks[index];
|
||||
if (!block(bridge, index, RCTNilIfNull(json))) {
|
||||
// Invalid argument, abort
|
||||
RCTLogArgumentError(self, index, json, "could not be processed. Aborting method call.");
|
||||
return nil;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
// Invoke method
|
||||
#ifdef RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD
|
||||
if (RCTIsMainQueue()) {
|
||||
CFTimeInterval start = CACurrentMediaTime();
|
||||
[_invocation invokeWithTarget:module];
|
||||
CFTimeInterval duration = CACurrentMediaTime() - start;
|
||||
if (duration > RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD) {
|
||||
RCTLogWarn(
|
||||
@"Main Thread Watchdog: Invocation of %@ blocked the main thread for %dms. "
|
||||
"Consider using background-threaded modules and asynchronous calls "
|
||||
"to spend less time on the main thread and keep the app's UI responsive.",
|
||||
[self methodName],
|
||||
(int)(duration * 1000));
|
||||
}
|
||||
} else {
|
||||
[_invocation invokeWithTarget:module];
|
||||
}
|
||||
#else
|
||||
[_invocation invokeWithTarget:module];
|
||||
#endif
|
||||
|
||||
[_retainedObjects removeAllObjects];
|
||||
|
||||
if (_methodInfo->isSync) {
|
||||
void *returnValue;
|
||||
[_invocation getReturnValue:&returnValue];
|
||||
return (__bridge id)returnValue;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)methodName
|
||||
{
|
||||
if (!_selector) {
|
||||
[self processMethodSignature];
|
||||
}
|
||||
return [NSString stringWithFormat:@"-[%@ %s]", _moduleClass, sel_getName(_selector)];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p; exports %@ as %s(); type: %s>",
|
||||
[self class],
|
||||
self,
|
||||
[self methodName],
|
||||
self.JSMethodName,
|
||||
RCTFunctionDescriptorFromType(self.functionType)];
|
||||
}
|
||||
|
||||
@end
|
27
node_modules/react-native/React/Base/RCTMultipartDataTask.h
generated
vendored
Normal file
27
node_modules/react-native/React/Base/RCTMultipartDataTask.h
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTMultipartStreamReader.h>
|
||||
|
||||
typedef void (^RCTMultipartDataTaskCallback)(
|
||||
NSInteger statusCode,
|
||||
NSDictionary *headers,
|
||||
NSData *content,
|
||||
NSError *error,
|
||||
BOOL done);
|
||||
|
||||
@interface RCTMultipartDataTask : NSObject
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
partHandler:(RCTMultipartDataTaskCallback)partHandler
|
||||
progressHandler:(RCTMultipartProgressCallback)progressHandler;
|
||||
|
||||
- (void)startTask;
|
||||
|
||||
@end
|
130
node_modules/react-native/React/Base/RCTMultipartDataTask.m
generated
vendored
Normal file
130
node_modules/react-native/React/Base/RCTMultipartDataTask.m
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTMultipartDataTask.h"
|
||||
|
||||
@interface RCTMultipartDataTask () <NSURLSessionDataDelegate, NSURLSessionDataDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTMultipartDataTask {
|
||||
NSURL *_url;
|
||||
RCTMultipartDataTaskCallback _partHandler;
|
||||
RCTMultipartProgressCallback _progressHandler;
|
||||
NSInteger _statusCode;
|
||||
NSDictionary *_headers;
|
||||
NSString *_boundary;
|
||||
NSMutableData *_data;
|
||||
}
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
partHandler:(RCTMultipartDataTaskCallback)partHandler
|
||||
progressHandler:(RCTMultipartProgressCallback)progressHandler
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_url = url;
|
||||
_partHandler = [partHandler copy];
|
||||
_progressHandler = [progressHandler copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startTask
|
||||
{
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
|
||||
delegate:self
|
||||
delegateQueue:nil];
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
|
||||
[request addValue:@"multipart/mixed" forHTTPHeaderField:@"Accept"];
|
||||
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
|
||||
[dataTask resume];
|
||||
[session finishTasksAndInvalidate];
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
dataTask:(__unused NSURLSessionDataTask *)dataTask
|
||||
didReceiveResponse:(NSURLResponse *)response
|
||||
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
|
||||
{
|
||||
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
_headers = [httpResponse allHeaderFields];
|
||||
_statusCode = [httpResponse statusCode];
|
||||
|
||||
NSString *contentType = @"";
|
||||
for (NSString *key in [_headers keyEnumerator]) {
|
||||
if ([[key lowercaseString] isEqualToString:@"content-type"]) {
|
||||
contentType = [_headers valueForKey:key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NSRegularExpression *regex =
|
||||
[NSRegularExpression regularExpressionWithPattern:@"multipart/mixed;.*boundary=\"([^\"]+)\""
|
||||
options:0
|
||||
error:nil];
|
||||
NSTextCheckingResult *match = [regex firstMatchInString:contentType
|
||||
options:0
|
||||
range:NSMakeRange(0, contentType.length)];
|
||||
if (match) {
|
||||
_boundary = [contentType substringWithRange:[match rangeAtIndex:1]];
|
||||
completionHandler(NSURLSessionResponseBecomeStream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// In case the server doesn't support multipart/mixed responses, fallback to normal download
|
||||
_data = [[NSMutableData alloc] initWithCapacity:1024 * 1024];
|
||||
completionHandler(NSURLSessionResponseAllow);
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
task:(__unused NSURLSessionTask *)task
|
||||
didCompleteWithError:(NSError *)error
|
||||
{
|
||||
if (_partHandler) {
|
||||
_partHandler(_statusCode, _headers, _data, error, YES);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
dataTask:(__unused NSURLSessionDataTask *)dataTask
|
||||
didReceiveData:(NSData *)data
|
||||
{
|
||||
[_data appendData:data];
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
dataTask:(__unused NSURLSessionDataTask *)dataTask
|
||||
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask
|
||||
{
|
||||
[streamTask captureStreams];
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
streamTask:(__unused NSURLSessionStreamTask *)streamTask
|
||||
didBecomeInputStream:(NSInputStream *)inputStream
|
||||
outputStream:(__unused NSOutputStream *)outputStream
|
||||
{
|
||||
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream
|
||||
boundary:_boundary];
|
||||
RCTMultipartDataTaskCallback partHandler = _partHandler;
|
||||
_partHandler = nil;
|
||||
NSInteger statusCode = _statusCode;
|
||||
|
||||
BOOL completed = [reader
|
||||
readAllPartsWithCompletionCallback:^(NSDictionary *headers, NSData *content, BOOL done) {
|
||||
partHandler(statusCode, headers, content, nil, done);
|
||||
}
|
||||
progressCallback:_progressHandler];
|
||||
if (!completed) {
|
||||
partHandler(
|
||||
statusCode, nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil], YES);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
21
node_modules/react-native/React/Base/RCTMultipartStreamReader.h
generated
vendored
Normal file
21
node_modules/react-native/React/Base/RCTMultipartStreamReader.h
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef void (^RCTMultipartCallback)(NSDictionary *headers, NSData *content, BOOL done);
|
||||
typedef void (^RCTMultipartProgressCallback)(NSDictionary *headers, NSNumber *loaded, NSNumber *total);
|
||||
|
||||
// RCTMultipartStreamReader can be used to parse responses with Content-Type: multipart/mixed
|
||||
// See https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
|
||||
@interface RCTMultipartStreamReader : NSObject
|
||||
|
||||
- (instancetype)initWithInputStream:(NSInputStream *)stream boundary:(NSString *)boundary;
|
||||
- (BOOL)readAllPartsWithCompletionCallback:(RCTMultipartCallback)callback
|
||||
progressCallback:(RCTMultipartProgressCallback)progressCallback;
|
||||
|
||||
@end
|
168
node_modules/react-native/React/Base/RCTMultipartStreamReader.m
generated
vendored
Normal file
168
node_modules/react-native/React/Base/RCTMultipartStreamReader.m
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTMultipartStreamReader.h"
|
||||
|
||||
#import <QuartzCore/CAAnimation.h>
|
||||
|
||||
#define CRLF @"\r\n"
|
||||
|
||||
@implementation RCTMultipartStreamReader {
|
||||
__strong NSInputStream *_stream;
|
||||
__strong NSString *_boundary;
|
||||
CFTimeInterval _lastDownloadProgress;
|
||||
}
|
||||
|
||||
- (instancetype)initWithInputStream:(NSInputStream *)stream boundary:(NSString *)boundary
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_stream = stream;
|
||||
_boundary = boundary;
|
||||
_lastDownloadProgress = CACurrentMediaTime();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)parseHeaders:(NSData *)data
|
||||
{
|
||||
NSMutableDictionary *headers = [NSMutableDictionary new];
|
||||
NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
NSArray<NSString *> *lines = [text componentsSeparatedByString:CRLF];
|
||||
for (NSString *line in lines) {
|
||||
NSUInteger location = [line rangeOfString:@":"].location;
|
||||
if (location == NSNotFound) {
|
||||
continue;
|
||||
}
|
||||
NSString *key = [line substringToIndex:location];
|
||||
NSString *value = [[line substringFromIndex:location + 1]
|
||||
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
[headers setValue:value forKey:key];
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
- (void)emitChunk:(NSData *)data headers:(NSDictionary *)headers callback:(RCTMultipartCallback)callback done:(BOOL)done
|
||||
{
|
||||
NSData *marker = [CRLF CRLF dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSRange range = [data rangeOfData:marker options:0 range:NSMakeRange(0, data.length)];
|
||||
if (range.location == NSNotFound) {
|
||||
callback(nil, data, done);
|
||||
} else if (headers != nil) {
|
||||
// If headers were parsed already just use that to avoid doing it twice.
|
||||
NSInteger bodyStart = range.location + marker.length;
|
||||
NSData *bodyData = [data subdataWithRange:NSMakeRange(bodyStart, data.length - bodyStart)];
|
||||
callback(headers, bodyData, done);
|
||||
} else {
|
||||
NSData *headersData = [data subdataWithRange:NSMakeRange(0, range.location)];
|
||||
NSInteger bodyStart = range.location + marker.length;
|
||||
NSData *bodyData = [data subdataWithRange:NSMakeRange(bodyStart, data.length - bodyStart)];
|
||||
callback([self parseHeaders:headersData], bodyData, done);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)emitProgress:(NSDictionary *)headers
|
||||
contentLength:(NSUInteger)contentLength
|
||||
final:(BOOL)final
|
||||
callback:(RCTMultipartProgressCallback)callback
|
||||
{
|
||||
if (headers == nil) {
|
||||
return;
|
||||
}
|
||||
// Throttle progress events so we don't send more that around 60 per second.
|
||||
CFTimeInterval currentTime = CACurrentMediaTime();
|
||||
|
||||
NSInteger headersContentLength = headers[@"Content-Length"] != nil ? [headers[@"Content-Length"] integerValue] : 0;
|
||||
if (callback && (currentTime - _lastDownloadProgress > 0.016 || final)) {
|
||||
_lastDownloadProgress = currentTime;
|
||||
callback(headers, @(headersContentLength), @(contentLength));
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)readAllPartsWithCompletionCallback:(RCTMultipartCallback)callback
|
||||
progressCallback:(RCTMultipartProgressCallback)progressCallback
|
||||
{
|
||||
NSInteger chunkStart = 0;
|
||||
NSInteger bytesSeen = 0;
|
||||
|
||||
NSData *delimiter =
|
||||
[[NSString stringWithFormat:@"%@--%@%@", CRLF, _boundary, CRLF] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *closeDelimiter =
|
||||
[[NSString stringWithFormat:@"%@--%@--%@", CRLF, _boundary, CRLF] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSMutableData *content = [[NSMutableData alloc] initWithCapacity:1];
|
||||
NSDictionary *currentHeaders = nil;
|
||||
NSUInteger currentHeadersLength = 0;
|
||||
|
||||
const NSUInteger bufferLen = 4 * 1024;
|
||||
uint8_t buffer[bufferLen];
|
||||
|
||||
[_stream open];
|
||||
while (true) {
|
||||
BOOL isCloseDelimiter = NO;
|
||||
// Search only a subset of chunk that we haven't seen before + few bytes
|
||||
// to allow for the edge case when the delimiter is cut by read call
|
||||
NSInteger searchStart = MAX(bytesSeen - (NSInteger)closeDelimiter.length, chunkStart);
|
||||
NSRange remainingBufferRange = NSMakeRange(searchStart, content.length - searchStart);
|
||||
|
||||
// Check for delimiters.
|
||||
NSRange range = [content rangeOfData:delimiter options:0 range:remainingBufferRange];
|
||||
if (range.location == NSNotFound) {
|
||||
isCloseDelimiter = YES;
|
||||
range = [content rangeOfData:closeDelimiter options:0 range:remainingBufferRange];
|
||||
}
|
||||
|
||||
if (range.location == NSNotFound) {
|
||||
if (currentHeaders == nil) {
|
||||
// Check for the headers delimiter.
|
||||
NSData *headersMarker = [CRLF CRLF dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSRange headersRange = [content rangeOfData:headersMarker options:0 range:remainingBufferRange];
|
||||
if (headersRange.location != NSNotFound) {
|
||||
NSData *headersData = [content subdataWithRange:NSMakeRange(chunkStart, headersRange.location - chunkStart)];
|
||||
currentHeadersLength = headersData.length;
|
||||
currentHeaders = [self parseHeaders:headersData];
|
||||
}
|
||||
} else {
|
||||
// When headers are loaded start sending progress callbacks.
|
||||
[self emitProgress:currentHeaders
|
||||
contentLength:content.length - currentHeadersLength
|
||||
final:NO
|
||||
callback:progressCallback];
|
||||
}
|
||||
|
||||
bytesSeen = content.length;
|
||||
NSInteger bytesRead = [_stream read:buffer maxLength:bufferLen];
|
||||
if (bytesRead <= 0 || _stream.streamError) {
|
||||
return NO;
|
||||
}
|
||||
[content appendBytes:buffer length:bytesRead];
|
||||
continue;
|
||||
}
|
||||
|
||||
NSInteger chunkEnd = range.location;
|
||||
NSInteger length = chunkEnd - chunkStart;
|
||||
bytesSeen = chunkEnd;
|
||||
|
||||
// Ignore preamble
|
||||
if (chunkStart > 0) {
|
||||
NSData *chunk = [content subdataWithRange:NSMakeRange(chunkStart, length)];
|
||||
[self emitProgress:currentHeaders
|
||||
contentLength:chunk.length - currentHeadersLength
|
||||
final:YES
|
||||
callback:progressCallback];
|
||||
[self emitChunk:chunk headers:currentHeaders callback:callback done:isCloseDelimiter];
|
||||
currentHeaders = nil;
|
||||
currentHeadersLength = 0;
|
||||
}
|
||||
|
||||
if (isCloseDelimiter) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
chunkStart = chunkEnd + delimiter.length;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
14
node_modules/react-native/React/Base/RCTNullability.h
generated
vendored
Normal file
14
node_modules/react-native/React/Base/RCTNullability.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, RCTNullability) {
|
||||
RCTNullabilityUnspecified,
|
||||
RCTNullable,
|
||||
RCTNonnullable,
|
||||
};
|
30
node_modules/react-native/React/Base/RCTParserUtils.h
generated
vendored
Normal file
30
node_modules/react-native/React/Base/RCTParserUtils.h
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
@interface RCTParserUtils : NSObject
|
||||
|
||||
/**
|
||||
* Generic utility functions for parsing Objective-C source code.
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTReadChar(const char **input, char c);
|
||||
RCT_EXTERN BOOL RCTReadString(const char **input, const char *string);
|
||||
RCT_EXTERN void RCTSkipWhitespace(const char **input);
|
||||
RCT_EXTERN BOOL RCTParseSelectorIdentifier(const char **input, NSString **string);
|
||||
RCT_EXTERN BOOL RCTParseArgumentIdentifier(const char **input, NSString **string);
|
||||
|
||||
/**
|
||||
* Parse an Objective-C type into a form that can be used by RCTConvert.
|
||||
* This doesn't really belong here, but it's used by both RCTConvert and
|
||||
* RCTModuleMethod, which makes it difficult to find a better home for it.
|
||||
*/
|
||||
RCT_EXTERN NSString *RCTParseType(const char **input);
|
||||
|
||||
@end
|
137
node_modules/react-native/React/Base/RCTParserUtils.m
generated
vendored
Normal file
137
node_modules/react-native/React/Base/RCTParserUtils.m
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTParserUtils.h"
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RCTParserUtils
|
||||
|
||||
BOOL RCTReadChar(const char **input, char c)
|
||||
{
|
||||
if (**input == c) {
|
||||
(*input)++;
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL RCTReadString(const char **input, const char *string)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; string[i] != 0; i++) {
|
||||
if (string[i] != (*input)[i]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
*input += i;
|
||||
return YES;
|
||||
}
|
||||
|
||||
void RCTSkipWhitespace(const char **input)
|
||||
{
|
||||
while (isspace(**input)) {
|
||||
(*input)++;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL RCTIsIdentifierHead(const char c)
|
||||
{
|
||||
return isalpha(c) || c == '_';
|
||||
}
|
||||
|
||||
static BOOL RCTIsIdentifierTail(const char c)
|
||||
{
|
||||
return isalnum(c) || c == '_';
|
||||
}
|
||||
|
||||
BOOL RCTParseArgumentIdentifier(const char **input, NSString **string)
|
||||
{
|
||||
const char *start = *input;
|
||||
|
||||
do {
|
||||
if (!RCTIsIdentifierHead(**input)) {
|
||||
return NO;
|
||||
}
|
||||
(*input)++;
|
||||
|
||||
while (RCTIsIdentifierTail(**input)) {
|
||||
(*input)++;
|
||||
}
|
||||
|
||||
// allow namespace resolution operator
|
||||
} while (RCTReadString(input, "::"));
|
||||
|
||||
if (string) {
|
||||
*string = [[NSString alloc] initWithBytes:start length:(NSInteger)(*input - start) encoding:NSASCIIStringEncoding];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL RCTParseSelectorIdentifier(const char **input, NSString **string)
|
||||
{
|
||||
const char *start = *input;
|
||||
if (!RCTIsIdentifierHead(**input)) {
|
||||
return NO;
|
||||
}
|
||||
(*input)++;
|
||||
while (RCTIsIdentifierTail(**input)) {
|
||||
(*input)++;
|
||||
}
|
||||
if (string) {
|
||||
*string = [[NSString alloc] initWithBytes:start length:(NSInteger)(*input - start) encoding:NSASCIIStringEncoding];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
static BOOL RCTIsCollectionType(NSString *type)
|
||||
{
|
||||
static NSSet *collectionTypes;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
collectionTypes = [[NSSet alloc] initWithObjects:@"NSArray", @"NSSet", @"NSDictionary", nil];
|
||||
});
|
||||
return [collectionTypes containsObject:type];
|
||||
}
|
||||
|
||||
NSString *RCTParseType(const char **input)
|
||||
{
|
||||
NSString *type;
|
||||
RCTParseArgumentIdentifier(input, &type);
|
||||
RCTSkipWhitespace(input);
|
||||
if (RCTReadChar(input, '<')) {
|
||||
RCTSkipWhitespace(input);
|
||||
NSString *subtype = RCTParseType(input);
|
||||
if (RCTIsCollectionType(type)) {
|
||||
if ([type isEqualToString:@"NSDictionary"]) {
|
||||
// Dictionaries have both a key *and* value type, but the key type has
|
||||
// to be a string for JSON, so we only care about the value type
|
||||
if (RCT_DEBUG && ![subtype isEqualToString:@"NSString"]) {
|
||||
RCTLogError(@"%@ is not a valid key type for a JSON dictionary", subtype);
|
||||
}
|
||||
RCTSkipWhitespace(input);
|
||||
RCTReadChar(input, ',');
|
||||
RCTSkipWhitespace(input);
|
||||
subtype = RCTParseType(input);
|
||||
}
|
||||
if (![subtype isEqualToString:@"id"]) {
|
||||
type = [type stringByReplacingCharactersInRange:(NSRange){0, 2 /* "NS" */} withString:subtype];
|
||||
}
|
||||
} else {
|
||||
// It's a protocol rather than a generic collection - ignore it
|
||||
}
|
||||
RCTSkipWhitespace(input);
|
||||
RCTReadChar(input, '>');
|
||||
}
|
||||
RCTSkipWhitespace(input);
|
||||
if (!RCTReadChar(input, '*')) {
|
||||
RCTReadChar(input, '&');
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@end
|
103
node_modules/react-native/React/Base/RCTPerformanceLogger.h
generated
vendored
Normal file
103
node_modules/react-native/React/Base/RCTPerformanceLogger.h
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Keep this in sync with _labelsForTags
|
||||
typedef NS_ENUM(NSUInteger, RCTPLTag) {
|
||||
RCTPLScriptDownload = 0,
|
||||
RCTPLScriptExecution,
|
||||
RCTPLRAMBundleLoad,
|
||||
RCTPLRAMStartupCodeSize,
|
||||
RCTPLRAMStartupNativeRequires,
|
||||
RCTPLRAMStartupNativeRequiresCount,
|
||||
RCTPLRAMNativeRequires,
|
||||
RCTPLRAMNativeRequiresCount,
|
||||
RCTPLNativeModuleInit,
|
||||
RCTPLNativeModuleMainThread,
|
||||
RCTPLNativeModulePrepareConfig,
|
||||
RCTPLNativeModuleMainThreadUsesCount,
|
||||
RCTPLNativeModuleSetup,
|
||||
RCTPLTurboModuleSetup,
|
||||
RCTPLJSCWrapperOpenLibrary,
|
||||
RCTPLBridgeStartup,
|
||||
RCTPLTTI,
|
||||
RCTPLBundleSize,
|
||||
RCTPLSize // This is used to count the size
|
||||
};
|
||||
|
||||
@interface RCTPerformanceLogger : NSObject
|
||||
|
||||
/**
|
||||
* Starts measuring a metric with the given tag.
|
||||
* Overrides previous value if the measurement has been already started.
|
||||
* If RCTProfile is enabled it also begins appropriate async event.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)markStartForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Stops measuring a metric with given tag.
|
||||
* Checks if RCTPerformanceLoggerStart() has been called before
|
||||
* and doesn't do anything and log a message if it hasn't.
|
||||
* If RCTProfile is enabled it also ends appropriate async event.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)markStopForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Sets given value for a metric with given tag.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)setValue:(int64_t)value forTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Adds given value to the current value for a metric with given tag.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)addValue:(int64_t)value forTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Starts an additional measurement for a metric with given tag.
|
||||
* It doesn't override previous measurement, instead it'll append a new value
|
||||
* to the old one.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)appendStartForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Stops measurement and appends the result to the metric with given tag.
|
||||
* Checks if RCTPerformanceLoggerAppendStart() has been called before
|
||||
* and doesn't do anything and log a message if it hasn't.
|
||||
* All work is scheduled on the background queue so this doesn't block current thread.
|
||||
*/
|
||||
- (void)appendStopForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Returns an array with values for all tags.
|
||||
* Use RCTPLTag to go over the array, there's a pair of values
|
||||
* for each tag: start and stop (with indexes 2 * tag and 2 * tag + 1).
|
||||
*/
|
||||
- (NSArray<NSNumber *> *)valuesForTags;
|
||||
|
||||
/**
|
||||
* Returns a duration in ms (stop_time - start_time) for given RCTPLTag.
|
||||
*/
|
||||
- (int64_t)durationForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Returns a value for given RCTPLTag.
|
||||
*/
|
||||
- (int64_t)valueForTag:(RCTPLTag)tag;
|
||||
|
||||
/**
|
||||
* Returns an array with values for all tags.
|
||||
* Use RCTPLTag to go over the array.
|
||||
*/
|
||||
- (NSArray<NSString *> *)labelsForTags;
|
||||
|
||||
@end
|
128
node_modules/react-native/React/Base/RCTPerformanceLogger.m
generated
vendored
Normal file
128
node_modules/react-native/React/Base/RCTPerformanceLogger.m
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import "RCTLog.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@interface RCTPerformanceLogger () {
|
||||
int64_t _data[RCTPLSize][2];
|
||||
NSUInteger _cookies[RCTPLSize];
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSArray<NSString *> *labelsForTags;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTPerformanceLogger
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
// Keep this in sync with RCTPLTag
|
||||
_labelsForTags = @[
|
||||
@"ScriptDownload",
|
||||
@"ScriptExecution",
|
||||
@"RAMBundleLoad",
|
||||
@"RAMStartupCodeSize",
|
||||
@"RAMStartupNativeRequires",
|
||||
@"RAMStartupNativeRequiresCount",
|
||||
@"RAMNativeRequires",
|
||||
@"RAMNativeRequiresCount",
|
||||
@"NativeModuleInit",
|
||||
@"NativeModuleMainThread",
|
||||
@"NativeModulePrepareConfig",
|
||||
@"NativeModuleMainThreadUsesCount",
|
||||
@"NativeModuleSetup",
|
||||
@"TurboModuleSetup",
|
||||
@"JSCWrapperOpenLibrary",
|
||||
@"BridgeStartup",
|
||||
@"RootViewTTI",
|
||||
@"BundleSize",
|
||||
];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)markStartForTag:(RCTPLTag)tag
|
||||
{
|
||||
#if RCT_PROFILE
|
||||
if (RCTProfileIsProfiling()) {
|
||||
NSString *label = _labelsForTags[tag];
|
||||
_cookies[tag] = RCTProfileBeginAsyncEvent(RCTProfileTagAlways, label, nil);
|
||||
}
|
||||
#endif
|
||||
_data[tag][0] = CACurrentMediaTime() * 1000;
|
||||
_data[tag][1] = 0;
|
||||
}
|
||||
|
||||
- (void)markStopForTag:(RCTPLTag)tag
|
||||
{
|
||||
#if RCT_PROFILE
|
||||
if (RCTProfileIsProfiling()) {
|
||||
NSString *label = _labelsForTags[tag];
|
||||
RCTProfileEndAsyncEvent(RCTProfileTagAlways, @"native", _cookies[tag], label, @"RCTPerformanceLogger");
|
||||
}
|
||||
#endif
|
||||
if (_data[tag][0] != 0 && _data[tag][1] == 0) {
|
||||
_data[tag][1] = CACurrentMediaTime() * 1000;
|
||||
} else {
|
||||
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setValue:(int64_t)value forTag:(RCTPLTag)tag
|
||||
{
|
||||
_data[tag][0] = 0;
|
||||
_data[tag][1] = value;
|
||||
}
|
||||
|
||||
- (void)addValue:(int64_t)value forTag:(RCTPLTag)tag
|
||||
{
|
||||
_data[tag][0] = 0;
|
||||
_data[tag][1] += value;
|
||||
}
|
||||
|
||||
- (void)appendStartForTag:(RCTPLTag)tag
|
||||
{
|
||||
_data[tag][0] = CACurrentMediaTime() * 1000;
|
||||
}
|
||||
|
||||
- (void)appendStopForTag:(RCTPLTag)tag
|
||||
{
|
||||
if (_data[tag][0] != 0) {
|
||||
_data[tag][1] += CACurrentMediaTime() * 1000 - _data[tag][0];
|
||||
_data[tag][0] = 0;
|
||||
} else {
|
||||
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)valuesForTags
|
||||
{
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
for (NSUInteger index = 0; index < RCTPLSize; index++) {
|
||||
[result addObject:@(_data[index][0])];
|
||||
[result addObject:@(_data[index][1])];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (int64_t)durationForTag:(RCTPLTag)tag
|
||||
{
|
||||
return _data[tag][1] - _data[tag][0];
|
||||
}
|
||||
|
||||
- (int64_t)valueForTag:(RCTPLTag)tag
|
||||
{
|
||||
return _data[tag][1];
|
||||
}
|
||||
|
||||
@end
|
14
node_modules/react-native/React/Base/RCTRedBoxSetEnabled.h
generated
vendored
Normal file
14
node_modules/react-native/React/Base/RCTRedBoxSetEnabled.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
// In debug builds, the red box is enabled by default but it is further
|
||||
// customizable using this method. However, this method only has an effect in
|
||||
// builds where RCTRedBox is actually compiled in.
|
||||
RCT_EXTERN void RCTRedBoxSetEnabled(BOOL enabled);
|
||||
RCT_EXTERN BOOL RCTRedBoxGetEnabled(void);
|
24
node_modules/react-native/React/Base/RCTRedBoxSetEnabled.m
generated
vendored
Normal file
24
node_modules/react-native/React/Base/RCTRedBoxSetEnabled.m
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTRedBoxSetEnabled.h"
|
||||
|
||||
#if RCT_DEV
|
||||
static BOOL redBoxEnabled = YES;
|
||||
#else
|
||||
static BOOL redBoxEnabled = NO;
|
||||
#endif
|
||||
|
||||
void RCTRedBoxSetEnabled(BOOL enabled)
|
||||
{
|
||||
redBoxEnabled = enabled;
|
||||
}
|
||||
|
||||
BOOL RCTRedBoxGetEnabled()
|
||||
{
|
||||
return redBoxEnabled;
|
||||
}
|
38
node_modules/react-native/React/Base/RCTReloadCommand.h
generated
vendored
Normal file
38
node_modules/react-native/React/Base/RCTReloadCommand.h
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
/**
|
||||
* A protocol which should be conformed to in order to be notified of RN reload events. These events can be
|
||||
* created by CMD+R or dev menu during development, or anywhere the trigger is exposed to JS.
|
||||
* The listener must also register itself using the method below.
|
||||
*/
|
||||
@protocol RCTReloadListener
|
||||
- (void)didReceiveReloadCommand;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Registers a weakly-held observer of RN reload events.
|
||||
*/
|
||||
RCT_EXTERN void RCTRegisterReloadCommandListener(id<RCTReloadListener> listener);
|
||||
|
||||
/**
|
||||
* Triggers a reload for all current listeners. Replaces [_bridge reload].
|
||||
*/
|
||||
RCT_EXTERN void RCTTriggerReloadCommandListeners(NSString *reason);
|
||||
|
||||
/**
|
||||
* This notification fires anytime RCTTriggerReloadCommandListeners() is called.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTTriggerReloadCommandNotification;
|
||||
RCT_EXTERN NSString *const RCTTriggerReloadCommandReasonKey;
|
||||
RCT_EXTERN NSString *const RCTTriggerReloadCommandBundleURLKey;
|
||||
|
||||
RCT_EXTERN void RCTReloadCommandSetBundleURL(NSURL *URL);
|
65
node_modules/react-native/React/Base/RCTReloadCommand.m
generated
vendored
Normal file
65
node_modules/react-native/React/Base/RCTReloadCommand.m
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTReloadCommand.h"
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTKeyCommands.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
static NSHashTable<id<RCTReloadListener>> *listeners;
|
||||
static NSLock *listenersLock;
|
||||
static NSURL *bundleURL;
|
||||
|
||||
NSString *const RCTTriggerReloadCommandNotification = @"RCTTriggerReloadCommandNotification";
|
||||
NSString *const RCTTriggerReloadCommandReasonKey = @"reason";
|
||||
NSString *const RCTTriggerReloadCommandBundleURLKey = @"bundleURL";
|
||||
|
||||
void RCTRegisterReloadCommandListener(id<RCTReloadListener> listener)
|
||||
{
|
||||
if (!listenersLock) {
|
||||
listenersLock = [NSLock new];
|
||||
}
|
||||
[listenersLock lock];
|
||||
if (!listeners) {
|
||||
listeners = [NSHashTable weakObjectsHashTable];
|
||||
}
|
||||
#if RCT_DEV
|
||||
RCTAssertMainQueue(); // because registerKeyCommandWithInput: must be called on the main thread
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r"
|
||||
modifierFlags:UIKeyModifierCommand
|
||||
action:^(__unused UIKeyCommand *command) {
|
||||
RCTTriggerReloadCommandListeners(@"Command + R");
|
||||
}];
|
||||
});
|
||||
#endif
|
||||
[listeners addObject:listener];
|
||||
[listenersLock unlock];
|
||||
}
|
||||
|
||||
void RCTTriggerReloadCommandListeners(NSString *reason)
|
||||
{
|
||||
[listenersLock lock];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTTriggerReloadCommandNotification
|
||||
object:nil
|
||||
userInfo:@{
|
||||
RCTTriggerReloadCommandReasonKey : RCTNullIfNil(reason),
|
||||
RCTTriggerReloadCommandBundleURLKey : RCTNullIfNil(bundleURL)
|
||||
}];
|
||||
|
||||
for (id<RCTReloadListener> l in [listeners allObjects]) {
|
||||
[l didReceiveReloadCommand];
|
||||
}
|
||||
[listenersLock unlock];
|
||||
}
|
||||
|
||||
void RCTReloadCommandSetBundleURL(NSURL *URL)
|
||||
{
|
||||
bundleURL = URL;
|
||||
}
|
32
node_modules/react-native/React/Base/RCTRootContentView.h
generated
vendored
Normal file
32
node_modules/react-native/React/Base/RCTRootContentView.h
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTInvalidating.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTView.h>
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTTouchHandler;
|
||||
|
||||
@interface RCTRootContentView : RCTView <RCTInvalidating>
|
||||
|
||||
@property (nonatomic, readonly, weak) RCTBridge *bridge;
|
||||
@property (nonatomic, readonly, assign) BOOL contentHasAppeared;
|
||||
@property (nonatomic, readonly, strong) RCTTouchHandler *touchHandler;
|
||||
@property (nonatomic, readonly, assign) CGSize availableSize;
|
||||
|
||||
@property (nonatomic, assign) BOOL passThroughTouches;
|
||||
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
bridge:(RCTBridge *)bridge
|
||||
reactTag:(NSNumber *)reactTag
|
||||
sizeFlexiblity:(RCTRootViewSizeFlexibility)sizeFlexibility NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
107
node_modules/react-native/React/Base/RCTRootContentView.m
generated
vendored
Normal file
107
node_modules/react-native/React/Base/RCTRootContentView.m
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTRootContentView.h"
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTRootView.h"
|
||||
#import "RCTRootViewInternal.h"
|
||||
#import "RCTTouchHandler.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
@implementation RCTRootContentView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
bridge:(RCTBridge *)bridge
|
||||
reactTag:(NSNumber *)reactTag
|
||||
sizeFlexiblity:(RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
_bridge = bridge;
|
||||
self.reactTag = reactTag;
|
||||
_sizeFlexibility = sizeFlexibility;
|
||||
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
|
||||
[_touchHandler attachToView:self];
|
||||
[_bridge.uiManager registerRootView:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (nonnull NSCoder *)aDecoder)
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
[self updateAvailableSize];
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self->_contentHasAppeared) {
|
||||
self->_contentHasAppeared = YES;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self.superview];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
if (_sizeFlexibility == sizeFlexibility) {
|
||||
return;
|
||||
}
|
||||
|
||||
_sizeFlexibility = sizeFlexibility;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (CGSize)availableSize
|
||||
{
|
||||
CGSize size = self.bounds.size;
|
||||
return CGSizeMake(
|
||||
_sizeFlexibility & RCTRootViewSizeFlexibilityWidth ? INFINITY : size.width,
|
||||
_sizeFlexibility & RCTRootViewSizeFlexibilityHeight ? INFINITY : size.height);
|
||||
}
|
||||
|
||||
- (void)updateAvailableSize
|
||||
{
|
||||
if (!self.reactTag || !_bridge.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_bridge.uiManager setAvailableSize:self.availableSize forRootView:self];
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
// The root content view itself should never receive touches
|
||||
UIView *hitView = [super hitTest:point withEvent:event];
|
||||
if (_passThroughTouches && hitView == self) {
|
||||
return nil;
|
||||
}
|
||||
return hitView;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
if (self.userInteractionEnabled) {
|
||||
self.userInteractionEnabled = NO;
|
||||
[(RCTRootView *)self.superview contentViewInvalidated];
|
||||
|
||||
[_bridge enqueueJSCall:@"AppRegistry"
|
||||
method:@"unmountApplicationComponentAtRootTag"
|
||||
args:@[ self.reactTag ]
|
||||
completion:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
165
node_modules/react-native/React/Base/RCTRootView.h
generated
vendored
Normal file
165
node_modules/react-native/React/Base/RCTRootView.h
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
@protocol RCTRootViewDelegate;
|
||||
|
||||
/**
|
||||
* This enum is used to define size flexibility type of the root view.
|
||||
* If a dimension is flexible, the view will recalculate that dimension
|
||||
* so the content fits. Recalculations are performed when the root's frame,
|
||||
* size flexibility mode or content size changes. After a recalculation,
|
||||
* rootViewDidChangeIntrinsicSize method of the RCTRootViewDelegate will be called.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
|
||||
RCTRootViewSizeFlexibilityNone = 0,
|
||||
RCTRootViewSizeFlexibilityWidth = 1 << 0,
|
||||
RCTRootViewSizeFlexibilityHeight = 1 << 1,
|
||||
RCTRootViewSizeFlexibilityWidthAndHeight = RCTRootViewSizeFlexibilityWidth | RCTRootViewSizeFlexibilityHeight,
|
||||
};
|
||||
|
||||
/**
|
||||
* This notification is sent when the first subviews are added to the root view
|
||||
* after the application has loaded. This is used to hide the `loadingView`, and
|
||||
* is a good indicator that the application is ready to use.
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#else
|
||||
extern
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const RCTContentDidAppearNotification;
|
||||
|
||||
/**
|
||||
* Native view used to host React-managed views within the app. Can be used just
|
||||
* like any ordinary UIView. You can have multiple RCTRootViews on screen at
|
||||
* once, all controlled by the same JavaScript application.
|
||||
*/
|
||||
@interface RCTRootView : UIView
|
||||
|
||||
/**
|
||||
* - Designated initializer -
|
||||
*/
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(nullable NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* - Convenience initializer -
|
||||
* A bridge will be created internally.
|
||||
* This initializer is intended to be used when the app has a single RCTRootView,
|
||||
* otherwise create an `RCTBridge` and pass it in via `initWithBridge:moduleName:`
|
||||
* to all the instances.
|
||||
*/
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(nullable NSDictionary *)initialProperties
|
||||
launchOptions:(nullable NSDictionary *)launchOptions;
|
||||
|
||||
/**
|
||||
* The name of the JavaScript module to execute within the
|
||||
* specified scriptURL (required). Setting this will not have
|
||||
* any immediate effect, but it must be done prior to loading
|
||||
* the script.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *moduleName;
|
||||
|
||||
/**
|
||||
* The bridge used by the root view. Bridges can be shared between multiple
|
||||
* root views, so you can use this property to initialize another RCTRootView.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) RCTBridge *bridge;
|
||||
|
||||
/**
|
||||
* The properties to apply to the view. Use this property to update
|
||||
* application properties and rerender the view. Initialized with
|
||||
* initialProperties argument of the initializer.
|
||||
*
|
||||
* Set this property only on the main thread.
|
||||
*/
|
||||
@property (nonatomic, copy, readwrite, nullable) NSDictionary *appProperties;
|
||||
|
||||
/**
|
||||
* The size flexibility mode of the root view.
|
||||
*/
|
||||
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
||||
|
||||
/*
|
||||
* The minimum size of the root view, defaults to CGSizeZero.
|
||||
*/
|
||||
@property (nonatomic, assign) CGSize minimumSize;
|
||||
|
||||
/**
|
||||
* The delegate that handles intrinsic size updates.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id<RCTRootViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
* The backing view controller of the root view.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) UIViewController *reactViewController;
|
||||
|
||||
/**
|
||||
* The React-managed contents view of the root view.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) UIView *contentView;
|
||||
|
||||
/**
|
||||
* A view to display while the JavaScript is loading, so users aren't presented
|
||||
* with a blank screen. By default this is nil, but you can override it with
|
||||
* (for example) a UIActivityIndicatorView or a placeholder image.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) UIView *loadingView;
|
||||
|
||||
/**
|
||||
* When set, any touches on the RCTRootView that are not matched up to any of the child
|
||||
* views will be passed to siblings of the RCTRootView. See -[UIView hitTest:withEvent:]
|
||||
* for details on iOS hit testing.
|
||||
*
|
||||
* Enable this to support a semi-transparent RN view that occupies the whole screen but
|
||||
* has visible content below it that the user can interact with.
|
||||
*
|
||||
* The default value is NO.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL passThroughTouches;
|
||||
|
||||
/**
|
||||
* Timings for hiding the loading view after the content has loaded. Both of
|
||||
* these values default to 0.25 seconds.
|
||||
*/
|
||||
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
|
||||
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTRootView (Deprecated)
|
||||
|
||||
/**
|
||||
* The intrinsic size of the root view's content. This is set right before the
|
||||
* `rootViewDidChangeIntrinsicSize` method of `RCTRootViewDelegate` is called.
|
||||
* This property is deprecated and will be removed in next releases.
|
||||
* Use UIKit `intrinsicContentSize` property instead.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign) CGSize intrinsicSize __deprecated_msg("Use `intrinsicContentSize` instead.");
|
||||
|
||||
/**
|
||||
* This methods is deprecated and will be removed soon.
|
||||
* To interrupt a React Native gesture recognizer, use the standard
|
||||
* `UIGestureRecognizer` negotiation process.
|
||||
* See `UIGestureRecognizerDelegate` for more details.
|
||||
*/
|
||||
- (void)cancelTouches;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
411
node_modules/react-native/React/Base/RCTRootView.m
generated
vendored
Normal file
411
node_modules/react-native/React/Base/RCTRootView.m
generated
vendored
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTRootView.h"
|
||||
#import "RCTRootViewDelegate.h"
|
||||
#import "RCTRootViewInternal.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTConstants.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTKeyCommands.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTRootContentView.h"
|
||||
#import "RCTRootShadowView.h"
|
||||
#import "RCTTouchHandler.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUIManagerUtils.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "RCTView.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
#if TARGET_OS_TV
|
||||
#import "RCTTVNavigationEventEmitter.h"
|
||||
#import "RCTTVRemoteHandler.h"
|
||||
#endif
|
||||
|
||||
NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification";
|
||||
|
||||
@interface RCTUIManager (RCTRootView)
|
||||
|
||||
- (NSNumber *)allocateRootTag;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTRootView {
|
||||
RCTBridge *_bridge;
|
||||
NSString *_moduleName;
|
||||
RCTRootContentView *_contentView;
|
||||
BOOL _passThroughTouches;
|
||||
CGSize _intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
|
||||
RCTAssert(moduleName, @"A moduleName is required to create an RCTRootView");
|
||||
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTRootView init]", nil);
|
||||
if (!bridge.isLoading) {
|
||||
[bridge.performanceLogger markStartForTag:RCTPLTTI];
|
||||
}
|
||||
|
||||
if (self = [super initWithFrame:CGRectZero]) {
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
_bridge = bridge;
|
||||
_moduleName = moduleName;
|
||||
_appProperties = [initialProperties copy];
|
||||
_loadingViewFadeDelay = 0.25;
|
||||
_loadingViewFadeDuration = 0.25;
|
||||
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
|
||||
_minimumSize = CGSizeZero;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(bridgeDidReload)
|
||||
name:RCTJavaScriptWillStartLoadingNotification
|
||||
object:_bridge];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(javaScriptDidLoad:)
|
||||
name:RCTJavaScriptDidLoadNotification
|
||||
object:_bridge];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(hideLoadingView)
|
||||
name:RCTContentDidAppearNotification
|
||||
object:self];
|
||||
|
||||
#if TARGET_OS_TV
|
||||
self.tvRemoteHandler = [RCTTVRemoteHandler new];
|
||||
for (NSString *key in [self.tvRemoteHandler.tvRemoteGestureRecognizers allKeys]) {
|
||||
[self addGestureRecognizer:self.tvRemoteHandler.tvRemoteGestureRecognizers[key]];
|
||||
}
|
||||
#endif
|
||||
|
||||
[self showLoadingView];
|
||||
|
||||
// Immediately schedule the application to be started.
|
||||
// (Sometimes actual `_bridge` is already batched bridge here.)
|
||||
[self bundleFinishedLoading:([_bridge batchedBridge] ?: _bridge)];
|
||||
}
|
||||
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
launchOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:bundleURL moduleProvider:nil launchOptions:launchOptions];
|
||||
|
||||
return [self initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
||||
|
||||
#if TARGET_OS_TV
|
||||
- (UIView *)preferredFocusedView
|
||||
{
|
||||
if (self.reactPreferredFocusedView) {
|
||||
return self.reactPreferredFocusedView;
|
||||
}
|
||||
return [super preferredFocusedView];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - passThroughTouches
|
||||
|
||||
- (BOOL)passThroughTouches
|
||||
{
|
||||
return _contentView.passThroughTouches;
|
||||
}
|
||||
|
||||
- (void)setPassThroughTouches:(BOOL)passThroughTouches
|
||||
{
|
||||
_passThroughTouches = passThroughTouches;
|
||||
_contentView.passThroughTouches = passThroughTouches;
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
CGSize fitSize = _intrinsicContentSize;
|
||||
CGSize currentSize = self.bounds.size;
|
||||
|
||||
// Following the current `size` and current `sizeFlexibility` policy.
|
||||
fitSize = CGSizeMake(
|
||||
_sizeFlexibility & RCTRootViewSizeFlexibilityWidth ? fitSize.width : currentSize.width,
|
||||
_sizeFlexibility & RCTRootViewSizeFlexibilityHeight ? fitSize.height : currentSize.height);
|
||||
|
||||
// Following the given size constraints.
|
||||
fitSize = CGSizeMake(MIN(size.width, fitSize.width), MIN(size.height, fitSize.height));
|
||||
|
||||
return fitSize;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
_contentView.frame = self.bounds;
|
||||
_loadingView.center = (CGPoint){CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)};
|
||||
}
|
||||
|
||||
- (void)setMinimumSize:(CGSize)minimumSize
|
||||
{
|
||||
if (CGSizeEqualToSize(_minimumSize, minimumSize)) {
|
||||
return;
|
||||
}
|
||||
_minimumSize = minimumSize;
|
||||
__block NSNumber *tag = self.reactTag;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
RCTExecuteOnUIManagerQueue(^{
|
||||
__strong typeof(self) strongSelf = weakSelf;
|
||||
if (strongSelf && strongSelf->_bridge.isValid) {
|
||||
RCTRootShadowView *shadowView = (RCTRootShadowView *)[strongSelf->_bridge.uiManager shadowViewForReactTag:tag];
|
||||
shadowView.minimumSize = minimumSize;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (UIViewController *)reactViewController
|
||||
{
|
||||
return _reactViewController ?: [super reactViewController];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setLoadingView:(UIView *)loadingView
|
||||
{
|
||||
_loadingView = loadingView;
|
||||
if (!_contentView.contentHasAppeared) {
|
||||
[self showLoadingView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showLoadingView
|
||||
{
|
||||
if (_loadingView && !_contentView.contentHasAppeared) {
|
||||
_loadingView.hidden = NO;
|
||||
[self addSubview:_loadingView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hideLoadingView
|
||||
{
|
||||
if (_loadingView.superview == self && _contentView.contentHasAppeared) {
|
||||
if (_loadingViewFadeDuration > 0) {
|
||||
dispatch_after(
|
||||
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_loadingViewFadeDelay * NSEC_PER_SEC)),
|
||||
dispatch_get_main_queue(),
|
||||
^{
|
||||
[UIView transitionWithView:self
|
||||
duration:self->_loadingViewFadeDuration
|
||||
options:UIViewAnimationOptionTransitionCrossDissolve
|
||||
animations:^{
|
||||
self->_loadingView.hidden = YES;
|
||||
}
|
||||
completion:^(__unused BOOL finished) {
|
||||
[self->_loadingView removeFromSuperview];
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
_loadingView.hidden = YES;
|
||||
[_loadingView removeFromSuperview];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)reactTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
if (!super.reactTag) {
|
||||
/**
|
||||
* Every root view that is created must have a unique react tag.
|
||||
* Numbering of these tags goes from 1, 11, 21, 31, etc
|
||||
*
|
||||
* NOTE: Since the bridge persists, the RootViews might be reused, so the
|
||||
* react tag must be re-assigned every time a new UIManager is created.
|
||||
*/
|
||||
self.reactTag = RCTAllocateRootViewTag();
|
||||
}
|
||||
return super.reactTag;
|
||||
}
|
||||
|
||||
- (void)bridgeDidReload
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
// Clear the reactTag so it can be re-assigned
|
||||
self.reactTag = nil;
|
||||
}
|
||||
|
||||
- (void)javaScriptDidLoad:(NSNotification *)notification
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
// Use the (batched) bridge that's sent in the notification payload, so the
|
||||
// RCTRootContentView is scoped to the right bridge
|
||||
RCTBridge *bridge = notification.userInfo[@"bridge"];
|
||||
if (bridge != _contentView.bridge) {
|
||||
[self bundleFinishedLoading:bridge];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)bundleFinishedLoading:(RCTBridge *)bridge
|
||||
{
|
||||
RCTAssert(bridge != nil, @"Bridge cannot be nil");
|
||||
if (!bridge.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_contentView removeFromSuperview];
|
||||
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds
|
||||
bridge:bridge
|
||||
reactTag:self.reactTag
|
||||
sizeFlexiblity:_sizeFlexibility];
|
||||
[self runApplication:bridge];
|
||||
|
||||
_contentView.passThroughTouches = _passThroughTouches;
|
||||
[self insertSubview:_contentView atIndex:0];
|
||||
|
||||
if (_sizeFlexibility == RCTRootViewSizeFlexibilityNone) {
|
||||
self.intrinsicContentSize = self.bounds.size;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)runApplication:(RCTBridge *)bridge
|
||||
{
|
||||
NSString *moduleName = _moduleName ?: @"";
|
||||
NSDictionary *appParameters = @{
|
||||
@"rootTag" : _contentView.reactTag,
|
||||
@"initialProps" : _appProperties ?: @{},
|
||||
};
|
||||
|
||||
RCTLogInfo(@"Running application %@ (%@)", moduleName, appParameters);
|
||||
[bridge enqueueJSCall:@"AppRegistry" method:@"runApplication" args:@[ moduleName, appParameters ] completion:NULL];
|
||||
}
|
||||
|
||||
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
if (_sizeFlexibility == sizeFlexibility) {
|
||||
return;
|
||||
}
|
||||
|
||||
_sizeFlexibility = sizeFlexibility;
|
||||
[self setNeedsLayout];
|
||||
_contentView.sizeFlexibility = _sizeFlexibility;
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
// The root view itself should never receive touches
|
||||
UIView *hitView = [super hitTest:point withEvent:event];
|
||||
if (self.passThroughTouches && hitView == self) {
|
||||
return nil;
|
||||
}
|
||||
return hitView;
|
||||
}
|
||||
|
||||
- (void)setAppProperties:(NSDictionary *)appProperties
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
if ([_appProperties isEqualToDictionary:appProperties]) {
|
||||
return;
|
||||
}
|
||||
|
||||
_appProperties = [appProperties copy];
|
||||
|
||||
if (_contentView && _bridge.valid && !_bridge.loading) {
|
||||
[self runApplication:_bridge];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIntrinsicContentSize:(CGSize)intrinsicContentSize
|
||||
{
|
||||
BOOL oldSizeHasAZeroDimension = _intrinsicContentSize.height == 0 || _intrinsicContentSize.width == 0;
|
||||
BOOL newSizeHasAZeroDimension = intrinsicContentSize.height == 0 || intrinsicContentSize.width == 0;
|
||||
BOOL bothSizesHaveAZeroDimension = oldSizeHasAZeroDimension && newSizeHasAZeroDimension;
|
||||
|
||||
BOOL sizesAreEqual = CGSizeEqualToSize(_intrinsicContentSize, intrinsicContentSize);
|
||||
|
||||
_intrinsicContentSize = intrinsicContentSize;
|
||||
|
||||
// Don't notify the delegate if the content remains invisible or its size has not changed
|
||||
if (bothSizesHaveAZeroDimension || sizesAreEqual) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidateIntrinsicContentSize];
|
||||
[self.superview setNeedsLayout];
|
||||
|
||||
[_delegate rootViewDidChangeIntrinsicSize:self];
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
return _intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (void)contentViewInvalidated
|
||||
{
|
||||
[_contentView removeFromSuperview];
|
||||
_contentView = nil;
|
||||
[self showLoadingView];
|
||||
}
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{
|
||||
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_contentView invalidate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTRootView (Deprecated)
|
||||
|
||||
- (CGSize)intrinsicSize
|
||||
{
|
||||
RCTLogWarn(@"Calling deprecated `[-RCTRootView intrinsicSize]`.");
|
||||
return self.intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (void)cancelTouches
|
||||
{
|
||||
RCTLogWarn(@"`-[RCTRootView cancelTouches]` is deprecated and will be deleted soon.");
|
||||
[[_contentView touchHandler] cancel];
|
||||
}
|
||||
|
||||
@end
|
30
node_modules/react-native/React/Base/RCTRootViewDelegate.h
generated
vendored
Normal file
30
node_modules/react-native/React/Base/RCTRootViewDelegate.h
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class RCTRootView;
|
||||
|
||||
@protocol RCTRootViewDelegate <NSObject>
|
||||
|
||||
/**
|
||||
* Called after the root view's intrinsic content size is changed.
|
||||
*
|
||||
* The method is not called when both old size and new size have
|
||||
* a dimension that equals to zero.
|
||||
*
|
||||
* The delegate can use this callback to appropriately resize
|
||||
* the root view's frame to fit the new intrinsic content view size,
|
||||
* but usually it is not necessary because the root view will also call
|
||||
* `setNeedsLayout` for its superview which in its turn will trigger relayout.
|
||||
*
|
||||
* The new intrinsic content size is available via the `intrinsicContentSize`
|
||||
* property of the root view. The view will not resize itself.
|
||||
*/
|
||||
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView;
|
||||
|
||||
@end
|
34
node_modules/react-native/React/Base/RCTRootViewInternal.h
generated
vendored
Normal file
34
node_modules/react-native/React/Base/RCTRootViewInternal.h
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@class RCTTVRemoteHandler;
|
||||
|
||||
/**
|
||||
* The interface provides a set of functions that allow other internal framework
|
||||
* classes to change the RCTRootViews's internal state.
|
||||
*/
|
||||
@interface RCTRootView ()
|
||||
|
||||
/**
|
||||
* This setter should be used only by RCTUIManager on react root view
|
||||
* intrinsic content size update.
|
||||
*/
|
||||
@property (readwrite, nonatomic, assign) CGSize intrinsicContentSize;
|
||||
|
||||
/**
|
||||
* TV remote gesture recognizers
|
||||
*/
|
||||
#if TARGET_OS_TV
|
||||
@property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler;
|
||||
@property (nonatomic, strong) UIView *reactPreferredFocusedView;
|
||||
#endif
|
||||
|
||||
- (void)contentViewInvalidated;
|
||||
|
||||
@end
|
31
node_modules/react-native/React/Base/RCTTVRemoteHandler.h
generated
vendored
Normal file
31
node_modules/react-native/React/Base/RCTTVRemoteHandler.h
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
extern NSString *const RCTTVRemoteEventMenu;
|
||||
extern NSString *const RCTTVRemoteEventPlayPause;
|
||||
extern NSString *const RCTTVRemoteEventSelect;
|
||||
|
||||
extern NSString *const RCTTVRemoteEventLongPlayPause;
|
||||
extern NSString *const RCTTVRemoteEventLongSelect;
|
||||
|
||||
extern NSString *const RCTTVRemoteEventLeft;
|
||||
extern NSString *const RCTTVRemoteEventRight;
|
||||
extern NSString *const RCTTVRemoteEventUp;
|
||||
extern NSString *const RCTTVRemoteEventDown;
|
||||
|
||||
extern NSString *const RCTTVRemoteEventSwipeLeft;
|
||||
extern NSString *const RCTTVRemoteEventSwipeRight;
|
||||
extern NSString *const RCTTVRemoteEventSwipeUp;
|
||||
extern NSString *const RCTTVRemoteEventSwipeDown;
|
||||
|
||||
@interface RCTTVRemoteHandler : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSDictionary *tvRemoteGestureRecognizers;
|
||||
|
||||
@end
|
233
node_modules/react-native/React/Base/RCTTVRemoteHandler.m
generated
vendored
Normal file
233
node_modules/react-native/React/Base/RCTTVRemoteHandler.m
generated
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTTVRemoteHandler.h"
|
||||
|
||||
#import <UIKit/UIGestureRecognizerSubclass.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTRootView.h"
|
||||
#import "RCTTVNavigationEventEmitter.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "RCTView.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
#if __has_include("RCTDevMenu.h")
|
||||
#import "RCTDevMenu.h"
|
||||
#endif
|
||||
|
||||
NSString *const RCTTVRemoteEventMenu = @"menu";
|
||||
NSString *const RCTTVRemoteEventPlayPause = @"playPause";
|
||||
NSString *const RCTTVRemoteEventSelect = @"select";
|
||||
|
||||
NSString *const RCTTVRemoteEventLongPlayPause = @"longPlayPause";
|
||||
NSString *const RCTTVRemoteEventLongSelect = @"longSelect";
|
||||
|
||||
NSString *const RCTTVRemoteEventLeft = @"left";
|
||||
NSString *const RCTTVRemoteEventRight = @"right";
|
||||
NSString *const RCTTVRemoteEventUp = @"up";
|
||||
NSString *const RCTTVRemoteEventDown = @"down";
|
||||
|
||||
NSString *const RCTTVRemoteEventSwipeLeft = @"swipeLeft";
|
||||
NSString *const RCTTVRemoteEventSwipeRight = @"swipeRight";
|
||||
NSString *const RCTTVRemoteEventSwipeUp = @"swipeUp";
|
||||
NSString *const RCTTVRemoteEventSwipeDown = @"swipeDown";
|
||||
|
||||
@implementation RCTTVRemoteHandler {
|
||||
NSMutableDictionary<NSString *, UIGestureRecognizer *> *_tvRemoteGestureRecognizers;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_tvRemoteGestureRecognizers = [NSMutableDictionary dictionary];
|
||||
|
||||
// Recognizers for Apple TV remote buttons
|
||||
|
||||
// Play/Pause
|
||||
[self addTapGestureRecognizerWithSelector:@selector(playPausePressed:)
|
||||
pressType:UIPressTypePlayPause
|
||||
name:RCTTVRemoteEventPlayPause];
|
||||
|
||||
// Menu
|
||||
[self addTapGestureRecognizerWithSelector:@selector(menuPressed:)
|
||||
pressType:UIPressTypeMenu
|
||||
name:RCTTVRemoteEventMenu];
|
||||
|
||||
// Select
|
||||
[self addTapGestureRecognizerWithSelector:@selector(selectPressed:)
|
||||
pressType:UIPressTypeSelect
|
||||
name:RCTTVRemoteEventSelect];
|
||||
|
||||
// Up
|
||||
[self addTapGestureRecognizerWithSelector:@selector(tappedUp:)
|
||||
pressType:UIPressTypeUpArrow
|
||||
name:RCTTVRemoteEventUp];
|
||||
|
||||
// Down
|
||||
[self addTapGestureRecognizerWithSelector:@selector(tappedDown:)
|
||||
pressType:UIPressTypeDownArrow
|
||||
name:RCTTVRemoteEventDown];
|
||||
|
||||
// Left
|
||||
[self addTapGestureRecognizerWithSelector:@selector(tappedLeft:)
|
||||
pressType:UIPressTypeLeftArrow
|
||||
name:RCTTVRemoteEventLeft];
|
||||
|
||||
// Right
|
||||
[self addTapGestureRecognizerWithSelector:@selector(tappedRight:)
|
||||
pressType:UIPressTypeRightArrow
|
||||
name:RCTTVRemoteEventRight];
|
||||
|
||||
// Recognizers for long button presses
|
||||
// We don't intercept long menu press -- that's used by the system to go to the home screen
|
||||
|
||||
[self addLongPressGestureRecognizerWithSelector:@selector(longPlayPausePressed:)
|
||||
pressType:UIPressTypePlayPause
|
||||
name:RCTTVRemoteEventLongPlayPause];
|
||||
|
||||
[self addLongPressGestureRecognizerWithSelector:@selector(longSelectPressed:)
|
||||
pressType:UIPressTypeSelect
|
||||
name:RCTTVRemoteEventLongSelect];
|
||||
|
||||
// Recognizers for Apple TV remote trackpad swipes
|
||||
|
||||
// Up
|
||||
[self addSwipeGestureRecognizerWithSelector:@selector(swipedUp:)
|
||||
direction:UISwipeGestureRecognizerDirectionUp
|
||||
name:RCTTVRemoteEventSwipeUp];
|
||||
|
||||
// Down
|
||||
[self addSwipeGestureRecognizerWithSelector:@selector(swipedDown:)
|
||||
direction:UISwipeGestureRecognizerDirectionDown
|
||||
name:RCTTVRemoteEventSwipeDown];
|
||||
|
||||
// Left
|
||||
[self addSwipeGestureRecognizerWithSelector:@selector(swipedLeft:)
|
||||
direction:UISwipeGestureRecognizerDirectionLeft
|
||||
name:RCTTVRemoteEventSwipeLeft];
|
||||
|
||||
// Right
|
||||
[self addSwipeGestureRecognizerWithSelector:@selector(swipedRight:)
|
||||
direction:UISwipeGestureRecognizerDirectionRight
|
||||
name:RCTTVRemoteEventSwipeRight];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)playPausePressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventPlayPause toView:r.view];
|
||||
}
|
||||
|
||||
- (void)menuPressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventMenu toView:r.view];
|
||||
}
|
||||
|
||||
- (void)selectPressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventSelect toView:r.view];
|
||||
}
|
||||
|
||||
- (void)longPlayPausePressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventLongPlayPause toView:r.view];
|
||||
|
||||
#if __has_include("RCTDevMenu.h") && RCT_DEV
|
||||
// If shake to show is enabled on device, use long play/pause event to show dev menu
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTShowDevMenuNotification object:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)longSelectPressed:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventLongSelect toView:r.view];
|
||||
}
|
||||
|
||||
- (void)swipedUp:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventSwipeUp toView:r.view];
|
||||
}
|
||||
|
||||
- (void)swipedDown:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventSwipeDown toView:r.view];
|
||||
}
|
||||
|
||||
- (void)swipedLeft:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventSwipeLeft toView:r.view];
|
||||
}
|
||||
|
||||
- (void)swipedRight:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventSwipeRight toView:r.view];
|
||||
}
|
||||
|
||||
- (void)tappedUp:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventUp toView:r.view];
|
||||
}
|
||||
|
||||
- (void)tappedDown:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventDown toView:r.view];
|
||||
}
|
||||
|
||||
- (void)tappedLeft:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventLeft toView:r.view];
|
||||
}
|
||||
|
||||
- (void)tappedRight:(UIGestureRecognizer *)r
|
||||
{
|
||||
[self sendAppleTVEvent:RCTTVRemoteEventRight toView:r.view];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector
|
||||
pressType:(UIPressType)pressType
|
||||
name:(NSString *)name
|
||||
{
|
||||
UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:selector];
|
||||
recognizer.allowedPressTypes = @[ @(pressType) ];
|
||||
|
||||
_tvRemoteGestureRecognizers[name] = recognizer;
|
||||
}
|
||||
|
||||
- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType name:(NSString *)name
|
||||
{
|
||||
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:selector];
|
||||
recognizer.allowedPressTypes = @[ @(pressType) ];
|
||||
|
||||
_tvRemoteGestureRecognizers[name] = recognizer;
|
||||
}
|
||||
|
||||
- (void)addSwipeGestureRecognizerWithSelector:(nonnull SEL)selector
|
||||
direction:(UISwipeGestureRecognizerDirection)direction
|
||||
name:(NSString *)name
|
||||
{
|
||||
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:selector];
|
||||
recognizer.direction = direction;
|
||||
|
||||
_tvRemoteGestureRecognizers[name] = recognizer;
|
||||
}
|
||||
|
||||
- (void)sendAppleTVEvent:(NSString *)eventType toView:(__unused UIView *)v
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTTVNavigationEventNotification
|
||||
object:@{@"eventType" : eventType}];
|
||||
}
|
||||
|
||||
@end
|
23
node_modules/react-native/React/Base/RCTTouchEvent.h
generated
vendored
Normal file
23
node_modules/react-native/React/Base/RCTTouchEvent.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
|
||||
/**
|
||||
* Represents a touch event, which may be composed of several touches (one for every finger).
|
||||
* For more information on contents of passed data structures see RCTTouchHandler.
|
||||
*/
|
||||
@interface RCTTouchEvent : NSObject <RCTEvent>
|
||||
|
||||
- (instancetype)initWithEventName:(NSString *)eventName
|
||||
reactTag:(NSNumber *)reactTag
|
||||
reactTouches:(NSArray<NSDictionary *> *)reactTouches
|
||||
changedIndexes:(NSArray<NSNumber *> *)changedIndexes
|
||||
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
|
||||
@end
|
107
node_modules/react-native/React/Base/RCTTouchEvent.m
generated
vendored
Normal file
107
node_modules/react-native/React/Base/RCTTouchEvent.m
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTTouchEvent.h"
|
||||
|
||||
#import "RCTAssert.h"
|
||||
|
||||
@implementation RCTTouchEvent {
|
||||
NSArray<NSDictionary *> *_reactTouches;
|
||||
NSArray<NSNumber *> *_changedIndexes;
|
||||
uint16_t _coalescingKey;
|
||||
}
|
||||
|
||||
@synthesize eventName = _eventName;
|
||||
@synthesize viewTag = _viewTag;
|
||||
|
||||
- (instancetype)initWithEventName:(NSString *)eventName
|
||||
reactTag:(NSNumber *)reactTag
|
||||
reactTouches:(NSArray<NSDictionary *> *)reactTouches
|
||||
changedIndexes:(NSArray<NSNumber *> *)changedIndexes
|
||||
coalescingKey:(uint16_t)coalescingKey
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_viewTag = reactTag;
|
||||
_eventName = eventName;
|
||||
_reactTouches = reactTouches;
|
||||
_changedIndexes = changedIndexes;
|
||||
_coalescingKey = coalescingKey;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
#pragma mark - RCTEvent
|
||||
|
||||
- (BOOL)canCoalesce
|
||||
{
|
||||
return [_eventName isEqual:@"touchMove"];
|
||||
}
|
||||
|
||||
// We coalesce only move events, while holding some assumptions that seem reasonable but there are no explicit
|
||||
// guarantees about them.
|
||||
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent
|
||||
{
|
||||
RCTAssert(
|
||||
[newEvent isKindOfClass:[RCTTouchEvent class]],
|
||||
@"Touch event cannot be coalesced with any other type of event, such as provided %@",
|
||||
newEvent);
|
||||
RCTTouchEvent *newTouchEvent = (RCTTouchEvent *)newEvent;
|
||||
RCTAssert(
|
||||
[_reactTouches count] == [newTouchEvent->_reactTouches count],
|
||||
@"Touch events have different number of touches. %@ %@",
|
||||
self,
|
||||
newEvent);
|
||||
|
||||
BOOL newEventIsMoreRecent = NO;
|
||||
BOOL oldEventIsMoreRecent = NO;
|
||||
NSInteger count = _reactTouches.count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
NSDictionary *touch = _reactTouches[i];
|
||||
NSDictionary *newTouch = newTouchEvent->_reactTouches[i];
|
||||
RCTAssert(
|
||||
[touch[@"identifier"] isEqual:newTouch[@"identifier"]],
|
||||
@"Touch events doesn't have touches in the same order. %@ %@",
|
||||
touch,
|
||||
newTouch);
|
||||
if ([touch[@"timestamp"] doubleValue] > [newTouch[@"timestamp"] doubleValue]) {
|
||||
oldEventIsMoreRecent = YES;
|
||||
} else {
|
||||
newEventIsMoreRecent = YES;
|
||||
}
|
||||
}
|
||||
RCTAssert(
|
||||
!(oldEventIsMoreRecent && newEventIsMoreRecent),
|
||||
@"Neither touch event is exclusively more recent than the other one. %@ %@",
|
||||
_reactTouches,
|
||||
newTouchEvent->_reactTouches);
|
||||
return newEventIsMoreRecent ? newEvent : self;
|
||||
}
|
||||
|
||||
+ (NSString *)moduleDotMethod
|
||||
{
|
||||
return @"RCTEventEmitter.receiveTouches";
|
||||
}
|
||||
|
||||
- (NSArray *)arguments
|
||||
{
|
||||
return @[ RCTNormalizeInputEventName(_eventName), _reactTouches, _changedIndexes ];
|
||||
}
|
||||
|
||||
- (uint16_t)coalescingKey
|
||||
{
|
||||
return _coalescingKey;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString
|
||||
stringWithFormat:@"<%@: %p; name = %@; coalescing key = %hu>", [self class], self, _eventName, _coalescingKey];
|
||||
}
|
||||
|
||||
@end
|
23
node_modules/react-native/React/Base/RCTTouchHandler.h
generated
vendored
Normal file
23
node_modules/react-native/React/Base/RCTTouchHandler.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTFrameUpdate.h>
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
@interface RCTTouchHandler : UIGestureRecognizer
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)attachToView:(UIView *)view;
|
||||
- (void)detachFromView:(UIView *)view;
|
||||
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
374
node_modules/react-native/React/Base/RCTTouchHandler.m
generated
vendored
Normal file
374
node_modules/react-native/React/Base/RCTTouchHandler.m
generated
vendored
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTTouchHandler.h"
|
||||
|
||||
#import <UIKit/UIGestureRecognizerSubclass.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTSurfaceView.h"
|
||||
#import "RCTTouchEvent.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
@interface RCTTouchHandler () <UIGestureRecognizerDelegate>
|
||||
@end
|
||||
|
||||
// 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 {
|
||||
__weak RCTEventDispatcher *_eventDispatcher;
|
||||
|
||||
/**
|
||||
* Arrays managed in parallel tracking native touch object along with the
|
||||
* native view that was touched, and the React touch data dictionary.
|
||||
* These must be kept track of because `UIKit` destroys the touch targets
|
||||
* if touches are canceled, and we have no other way to recover this info.
|
||||
*/
|
||||
NSMutableOrderedSet<UITouch *> *_nativeTouches;
|
||||
NSMutableArray<NSMutableDictionary *> *_reactTouches;
|
||||
NSMutableArray<UIView *> *_touchViews;
|
||||
|
||||
__weak UIView *_cachedRootView;
|
||||
|
||||
uint16_t _coalescingKey;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
{
|
||||
RCTAssertParam(bridge);
|
||||
|
||||
if ((self = [super initWithTarget:nil action:NULL])) {
|
||||
_eventDispatcher = [bridge moduleForClass:[RCTEventDispatcher class]];
|
||||
|
||||
_nativeTouches = [NSMutableOrderedSet new];
|
||||
_reactTouches = [NSMutableArray new];
|
||||
_touchViews = [NSMutableArray new];
|
||||
|
||||
// `cancelsTouchesInView` and `delaysTouches*` are needed in order to be used as a top level
|
||||
// event delegated recognizer. Otherwise, lower-level components not built
|
||||
// using RCT, will fail to recognize gestures.
|
||||
self.cancelsTouchesInView = NO;
|
||||
self.delaysTouchesBegan = NO; // This is default value.
|
||||
self.delaysTouchesEnded = NO;
|
||||
|
||||
self.delegate = self;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithTarget : (id)target action : (SEL)action)
|
||||
|
||||
- (void)attachToView:(UIView *)view
|
||||
{
|
||||
RCTAssert(self.view == nil, @"RCTTouchHandler already has attached view.");
|
||||
|
||||
[view addGestureRecognizer:self];
|
||||
}
|
||||
|
||||
- (void)detachFromView:(UIView *)view
|
||||
{
|
||||
RCTAssertParam(view);
|
||||
RCTAssert(self.view == view, @"RCTTouchHandler attached to another view.");
|
||||
|
||||
[view removeGestureRecognizer:self];
|
||||
}
|
||||
|
||||
#pragma mark - Bookkeeping for touch indices
|
||||
|
||||
- (void)_recordNewTouches:(NSSet<UITouch *> *)touches
|
||||
{
|
||||
for (UITouch *touch in touches) {
|
||||
RCTAssert(![_nativeTouches containsObject:touch], @"Touch is already recorded. This is a critical bug.");
|
||||
|
||||
// Find closest React-managed touchable view
|
||||
UIView *targetView = touch.view;
|
||||
while (targetView) {
|
||||
if (targetView.reactTag && targetView.userInteractionEnabled) {
|
||||
break;
|
||||
}
|
||||
targetView = targetView.superview;
|
||||
}
|
||||
|
||||
NSNumber *reactTag = [targetView reactTagAtPoint:[touch locationInView:targetView]];
|
||||
if (!reactTag || !targetView.userInteractionEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get new, unique touch identifier for the react touch
|
||||
const NSUInteger RCTMaxTouches = 11; // This is the maximum supported by iDevices
|
||||
NSInteger touchID = ([_reactTouches.lastObject[@"identifier"] integerValue] + 1) % RCTMaxTouches;
|
||||
for (NSDictionary *reactTouch in _reactTouches) {
|
||||
NSInteger usedID = [reactTouch[@"identifier"] integerValue];
|
||||
if (usedID == touchID) {
|
||||
// ID has already been used, try next value
|
||||
touchID++;
|
||||
} else if (usedID > touchID) {
|
||||
// If usedID > touchID, touchID must be unique, so we can stop looking
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create touch
|
||||
NSMutableDictionary *reactTouch = [[NSMutableDictionary alloc] initWithCapacity:RCTMaxTouches];
|
||||
reactTouch[@"target"] = reactTag;
|
||||
reactTouch[@"identifier"] = @(touchID);
|
||||
|
||||
// Add to arrays
|
||||
[_touchViews addObject:targetView];
|
||||
[_nativeTouches addObject:touch];
|
||||
[_reactTouches addObject:reactTouch];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_recordRemovedTouches:(NSSet<UITouch *> *)touches
|
||||
{
|
||||
for (UITouch *touch in touches) {
|
||||
NSUInteger index = [_nativeTouches indexOfObject:touch];
|
||||
if (index == NSNotFound) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[_touchViews removeObjectAtIndex:index];
|
||||
[_nativeTouches removeObjectAtIndex:index];
|
||||
[_reactTouches removeObjectAtIndex:index];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_updateReactTouchAtIndex:(NSInteger)touchIndex
|
||||
{
|
||||
UITouch *nativeTouch = _nativeTouches[touchIndex];
|
||||
CGPoint windowLocation = [nativeTouch locationInView:nativeTouch.window];
|
||||
RCTAssert(_cachedRootView, @"We were unable to find a root view for the touch");
|
||||
CGPoint rootViewLocation = [nativeTouch.window convertPoint:windowLocation toView:_cachedRootView];
|
||||
|
||||
UIView *touchView = _touchViews[touchIndex];
|
||||
CGPoint touchViewLocation = [nativeTouch.window convertPoint:windowLocation toView:touchView];
|
||||
|
||||
NSMutableDictionary *reactTouch = _reactTouches[touchIndex];
|
||||
reactTouch[@"pageX"] = @(RCTSanitizeNaNValue(rootViewLocation.x, @"touchEvent.pageX"));
|
||||
reactTouch[@"pageY"] = @(RCTSanitizeNaNValue(rootViewLocation.y, @"touchEvent.pageY"));
|
||||
reactTouch[@"locationX"] = @(RCTSanitizeNaNValue(touchViewLocation.x, @"touchEvent.locationX"));
|
||||
reactTouch[@"locationY"] = @(RCTSanitizeNaNValue(touchViewLocation.y, @"touchEvent.locationY"));
|
||||
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
|
||||
|
||||
// TODO: force for a 'normal' touch is usually 1.0;
|
||||
// should we expose a `normalTouchForce` constant somewhere (which would
|
||||
// have a value of `1.0 / nativeTouch.maximumPossibleForce`)?
|
||||
if (RCTForceTouchAvailable()) {
|
||||
reactTouch[@"force"] = @(RCTZeroIfNaN(nativeTouch.force / nativeTouch.maximumPossibleForce));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs information about touch events to send across the serialized
|
||||
* boundary. This data should be compliant with W3C `Touch` objects. This data
|
||||
* alone isn't sufficient to construct W3C `Event` objects. To construct that,
|
||||
* there must be a simple receiver on the other side of the bridge that
|
||||
* organizes the touch objects into `Event`s.
|
||||
*
|
||||
* We send the data as an array of `Touch`es, the type of action
|
||||
* (start/end/move/cancel) and the indices that represent "changed" `Touch`es
|
||||
* from that array.
|
||||
*/
|
||||
- (void)_updateAndDispatchTouches:(NSSet<UITouch *> *)touches eventName:(NSString *)eventName
|
||||
{
|
||||
// Update touches
|
||||
NSMutableArray<NSNumber *> *changedIndexes = [NSMutableArray new];
|
||||
for (UITouch *touch in touches) {
|
||||
NSInteger index = [_nativeTouches indexOfObject:touch];
|
||||
if (index == NSNotFound) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[self _updateReactTouchAtIndex:index];
|
||||
[changedIndexes addObject:@(index)];
|
||||
}
|
||||
|
||||
if (changedIndexes.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deep copy the touches because they will be accessed from another thread
|
||||
// TODO: would it be safer to do this in the bridge or executor, rather than trusting caller?
|
||||
NSMutableArray<NSDictionary *> *reactTouches = [[NSMutableArray alloc] initWithCapacity:_reactTouches.count];
|
||||
for (NSDictionary *touch in _reactTouches) {
|
||||
[reactTouches addObject:[touch copy]];
|
||||
}
|
||||
|
||||
BOOL canBeCoalesced = [eventName isEqualToString:@"touchMove"];
|
||||
|
||||
// We increment `_coalescingKey` twice here just for sure that
|
||||
// this `_coalescingKey` will not be reused by another (preceding or following) event
|
||||
// (yes, even if coalescing only happens (and makes sense) on events of the same type).
|
||||
|
||||
if (!canBeCoalesced) {
|
||||
_coalescingKey++;
|
||||
}
|
||||
|
||||
RCTTouchEvent *event = [[RCTTouchEvent alloc] initWithEventName:eventName
|
||||
reactTag:self.view.reactTag
|
||||
reactTouches:reactTouches
|
||||
changedIndexes:changedIndexes
|
||||
coalescingKey:_coalescingKey];
|
||||
|
||||
if (!canBeCoalesced) {
|
||||
_coalescingKey++;
|
||||
}
|
||||
|
||||
[_eventDispatcher sendEvent:event];
|
||||
}
|
||||
|
||||
/***
|
||||
* To ensure compatibility when using UIManager.measure and RCTTouchHandler, we have to adopt
|
||||
* UIManager.measure's behavior in finding a "root view".
|
||||
* Usually RCTTouchHandler is already attached to a root view but in some cases (e.g. Modal),
|
||||
* we are instead attached to some RCTView subtree. This is also the case when embedding some RN
|
||||
* views inside a separate ViewController not controlled by RN.
|
||||
* This logic will either find the nearest rootView, or go all the way to the UIWindow.
|
||||
* While this is not optimal, it is exactly what UIManager.measure does, and what Touchable.js
|
||||
* relies on.
|
||||
* We cache it here so that we don't have to repeat it for every touch in the gesture.
|
||||
*/
|
||||
- (void)_cacheRootView
|
||||
{
|
||||
UIView *rootView = self.view;
|
||||
while (rootView.superview && ![rootView isReactRootView] && ![rootView isKindOfClass:[RCTSurfaceView class]]) {
|
||||
rootView = rootView.superview;
|
||||
}
|
||||
_cachedRootView = rootView;
|
||||
}
|
||||
|
||||
#pragma mark - Gesture Recognizer Delegate Callbacks
|
||||
|
||||
static BOOL RCTAllTouchesAreCancelledOrEnded(NSSet<UITouch *> *touches)
|
||||
{
|
||||
for (UITouch *touch in touches) {
|
||||
if (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved || touch.phase == UITouchPhaseStationary) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
static BOOL RCTAnyTouchesChanged(NSSet<UITouch *> *touches)
|
||||
{
|
||||
for (UITouch *touch in touches) {
|
||||
if (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - `UIResponder`-ish touch-delivery methods
|
||||
|
||||
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
|
||||
[self _cacheRootView];
|
||||
|
||||
// "start" has to record new touches *before* extracting the event.
|
||||
// "end"/"cancel" needs to remove the touch *after* extracting the event.
|
||||
[self _recordNewTouches:touches];
|
||||
|
||||
[self _updateAndDispatchTouches:touches eventName:@"touchStart"];
|
||||
|
||||
if (self.state == UIGestureRecognizerStatePossible) {
|
||||
self.state = UIGestureRecognizerStateBegan;
|
||||
} else if (self.state == UIGestureRecognizerStateBegan) {
|
||||
self.state = UIGestureRecognizerStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesMoved:touches withEvent:event];
|
||||
|
||||
[self _updateAndDispatchTouches:touches eventName:@"touchMove"];
|
||||
self.state = UIGestureRecognizerStateChanged;
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
|
||||
[self _updateAndDispatchTouches:touches eventName:@"touchEnd"];
|
||||
|
||||
if (RCTAllTouchesAreCancelledOrEnded(event.allTouches)) {
|
||||
self.state = UIGestureRecognizerStateEnded;
|
||||
} else if (RCTAnyTouchesChanged(event.allTouches)) {
|
||||
self.state = UIGestureRecognizerStateChanged;
|
||||
}
|
||||
|
||||
[self _recordRemovedTouches:touches];
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[super touchesCancelled:touches withEvent:event];
|
||||
|
||||
[self _updateAndDispatchTouches:touches eventName:@"touchCancel"];
|
||||
|
||||
if (RCTAllTouchesAreCancelledOrEnded(event.allTouches)) {
|
||||
self.state = UIGestureRecognizerStateCancelled;
|
||||
} else if (RCTAnyTouchesChanged(event.allTouches)) {
|
||||
self.state = UIGestureRecognizerStateChanged;
|
||||
}
|
||||
|
||||
[self _recordRemovedTouches:touches];
|
||||
}
|
||||
|
||||
- (BOOL)canPreventGestureRecognizer:(__unused UIGestureRecognizer *)preventedGestureRecognizer
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
|
||||
{
|
||||
// We fail in favour of other external gesture recognizers.
|
||||
// iOS will ask `delegate`'s opinion about this gesture recognizer little bit later.
|
||||
return ![preventingGestureRecognizer.view isDescendantOfView:self.view];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
if (_nativeTouches.count != 0) {
|
||||
[self _updateAndDispatchTouches:_nativeTouches.set eventName:@"touchCancel"];
|
||||
|
||||
[_nativeTouches removeAllObjects];
|
||||
[_reactTouches removeAllObjects];
|
||||
[_touchViews removeAllObjects];
|
||||
|
||||
_cachedRootView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Other
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
self.enabled = NO;
|
||||
self.enabled = YES;
|
||||
}
|
||||
|
||||
#pragma mark - UIGestureRecognizerDelegate
|
||||
|
||||
- (BOOL)gestureRecognizer:(__unused UIGestureRecognizer *)gestureRecognizer
|
||||
shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
||||
{
|
||||
// Same condition for `failure of` as for `be prevented by`.
|
||||
return [self canBePreventedByGestureRecognizer:otherGestureRecognizer];
|
||||
}
|
||||
|
||||
@end
|
40
node_modules/react-native/React/Base/RCTURLRequestDelegate.h
generated
vendored
Normal file
40
node_modules/react-native/React/Base/RCTURLRequestDelegate.h
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* An abstract interface used by request handler modules to send
|
||||
* data back over the bridge back to JS.
|
||||
*/
|
||||
@protocol RCTURLRequestDelegate <NSObject>
|
||||
|
||||
/**
|
||||
* Call this when you send request data to the server. This is used to track
|
||||
* upload progress, so should be called multiple times for large request bodies.
|
||||
*/
|
||||
- (void)URLRequest:(id)requestToken didSendDataWithProgress:(int64_t)bytesSent;
|
||||
|
||||
/**
|
||||
* Call this when you first receives a response from the server. This should
|
||||
* include response headers, etc.
|
||||
*/
|
||||
- (void)URLRequest:(id)requestToken didReceiveResponse:(NSURLResponse *)response;
|
||||
|
||||
/**
|
||||
* Call this when you receive data from the server. This can be called multiple
|
||||
* times with partial data chunks, or just once with the full data packet.
|
||||
*/
|
||||
- (void)URLRequest:(id)requestToken didReceiveData:(NSData *)data;
|
||||
|
||||
/**
|
||||
* Call this when the request is complete and/or if an error is encountered.
|
||||
* For a successful request, the error parameter should be nil.
|
||||
*/
|
||||
- (void)URLRequest:(id)requestToken didCompleteWithError:(NSError *)error;
|
||||
|
||||
@end
|
52
node_modules/react-native/React/Base/RCTURLRequestHandler.h
generated
vendored
Normal file
52
node_modules/react-native/React/Base/RCTURLRequestHandler.h
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTURLRequestDelegate.h>
|
||||
|
||||
/**
|
||||
* Provides the interface needed to register a request handler. Request handlers
|
||||
* are also bridge modules, so should be registered using RCT_EXPORT_MODULE().
|
||||
*/
|
||||
@protocol RCTURLRequestHandler <RCTBridgeModule>
|
||||
|
||||
/**
|
||||
* Indicates whether this handler is capable of processing the specified
|
||||
* request. Typically the handler would examine the scheme/protocol of the
|
||||
* request URL (and possibly the HTTP method and/or headers) to determine this.
|
||||
*/
|
||||
- (BOOL)canHandleRequest:(NSURLRequest *)request;
|
||||
|
||||
/**
|
||||
* Send a network request and call the delegate with the response data. The
|
||||
* method should return a token, which can be anything, including the request
|
||||
* itself. This will be used later to refer to the request in callbacks. The
|
||||
* `sendRequest:withDelegate:` method *must* return before calling any of the
|
||||
* delegate methods, or the delegate won't recognize the token.
|
||||
* Following common Objective-C pattern, `delegate` will not be retained.
|
||||
*/
|
||||
- (id)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Not all request types can be cancelled, but this method can be implemented
|
||||
* for ones that can. It should be used to free up any resources on ongoing
|
||||
* processes associated with the request.
|
||||
*/
|
||||
- (void)cancelRequest:(id)requestToken;
|
||||
|
||||
/**
|
||||
* If more than one RCTURLRequestHandler responds YES to `canHandleRequest:`
|
||||
* then `handlerPriority` is used to determine which one to use. The handler
|
||||
* with the highest priority will be selected. Default priority is zero. If
|
||||
* two or more valid handlers have the same priority, the selection order is
|
||||
* undefined.
|
||||
*/
|
||||
- (float)handlerPriority;
|
||||
|
||||
@end
|
180
node_modules/react-native/React/Base/RCTUtils.h
generated
vendored
Normal file
180
node_modules/react-native/React/Base/RCTUtils.h
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <tgmath.h>
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// JSON serialization/deserialization
|
||||
RCT_EXTERN NSString *__nullable RCTJSONStringify(id __nullable jsonObject, NSError **error);
|
||||
RCT_EXTERN id __nullable RCTJSONParse(NSString *__nullable jsonString, NSError **error);
|
||||
RCT_EXTERN id __nullable RCTJSONParseMutable(NSString *__nullable jsonString, NSError **error);
|
||||
|
||||
// Sanitize a JSON object by stripping invalid types and/or NaN values
|
||||
RCT_EXTERN id RCTJSONClean(id object);
|
||||
|
||||
// Get MD5 hash of a string
|
||||
RCT_EXTERN NSString *RCTMD5Hash(NSString *string);
|
||||
|
||||
// Check if we are currently on the main queue (not to be confused with
|
||||
// the main thread, which is not necessarily the same thing)
|
||||
// https://twitter.com/olebegemann/status/738656134731599872
|
||||
RCT_EXTERN BOOL RCTIsMainQueue(void);
|
||||
|
||||
// Execute the specified block on the main queue. Unlike dispatch_async()
|
||||
// this will execute immediately if we're already on the main queue.
|
||||
RCT_EXTERN void RCTExecuteOnMainQueue(dispatch_block_t block);
|
||||
|
||||
// Legacy function to execute the specified block on the main queue synchronously.
|
||||
// Please do not use this unless you know what you're doing.
|
||||
RCT_EXTERN void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block);
|
||||
|
||||
// Get screen metrics in a thread-safe way
|
||||
RCT_EXTERN CGFloat RCTScreenScale(void);
|
||||
RCT_EXTERN CGSize RCTScreenSize(void);
|
||||
|
||||
// Round float coordinates to nearest whole screen pixel (not point)
|
||||
RCT_EXTERN CGFloat RCTRoundPixelValue(CGFloat value);
|
||||
RCT_EXTERN CGFloat RCTCeilPixelValue(CGFloat value);
|
||||
RCT_EXTERN CGFloat RCTFloorPixelValue(CGFloat value);
|
||||
|
||||
// Convert a size in points to pixels, rounded up to the nearest integral size
|
||||
RCT_EXTERN CGSize RCTSizeInPixels(CGSize pointSize, CGFloat scale);
|
||||
|
||||
// Method swizzling
|
||||
RCT_EXTERN void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
|
||||
RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
|
||||
|
||||
// Module subclass support
|
||||
RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
|
||||
RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
||||
|
||||
// Creates a standardized error object to return in callbacks
|
||||
RCT_EXTERN NSDictionary<NSString *, id>
|
||||
*RCTMakeError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
|
||||
RCT_EXTERN NSDictionary<NSString *, id> *
|
||||
RCTMakeAndLogError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
|
||||
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromNSError(NSError *error);
|
||||
RCT_EXTERN NSDictionary<NSString *, id>
|
||||
*RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *__nullable error);
|
||||
|
||||
// The default error code to use as the `code` property for callback error objects
|
||||
RCT_EXTERN NSString *const RCTErrorUnspecified;
|
||||
|
||||
// Returns YES if React is running in a test environment
|
||||
RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
|
||||
|
||||
// Returns YES if React is running in an iOS App Extension
|
||||
RCT_EXTERN BOOL RCTRunningInAppExtension(void);
|
||||
|
||||
// Returns the shared UIApplication instance, or nil if running in an App Extension
|
||||
RCT_EXTERN UIApplication *__nullable RCTSharedApplication(void);
|
||||
|
||||
// Returns the current main window, useful if you need to access the root view
|
||||
// or view controller
|
||||
RCT_EXTERN UIWindow *__nullable RCTKeyWindow(void);
|
||||
|
||||
// Returns the presented view controller, useful if you need
|
||||
// e.g. to present a modal view controller or alert over it
|
||||
RCT_EXTERN UIViewController *__nullable RCTPresentedViewController(void);
|
||||
|
||||
// Does this device support force touch (aka 3D Touch)?
|
||||
RCT_EXTERN BOOL RCTForceTouchAvailable(void);
|
||||
|
||||
// Create an NSError in the RCTErrorDomain
|
||||
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
|
||||
|
||||
// Convert nil values to NSNull, and vice-versa
|
||||
#define RCTNullIfNil(value) ((value) ?: (id)kCFNull)
|
||||
#define RCTNilIfNull(value) \
|
||||
({ \
|
||||
__typeof__(value) t = (value); \
|
||||
(id) t == (id)kCFNull ? (__typeof(value))nil : t; \
|
||||
})
|
||||
|
||||
// Convert NaN or infinite values to zero, as these aren't JSON-safe
|
||||
RCT_EXTERN double RCTZeroIfNaN(double value);
|
||||
|
||||
// Returns `0` and log special warning if value is NaN or INF.
|
||||
RCT_EXTERN double RCTSanitizeNaNValue(double value, NSString *property);
|
||||
|
||||
// Convert data to a Base64-encoded data URL
|
||||
RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
|
||||
|
||||
// Gzip functionality - compression level in range 0 - 1 (-1 for default)
|
||||
RCT_EXTERN NSData *__nullable RCTGzipData(NSData *__nullable data, float level);
|
||||
|
||||
// Returns the relative path within the main bundle for an absolute URL
|
||||
// (or nil, if the URL does not specify a path within the main bundle)
|
||||
RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL);
|
||||
|
||||
// Returns the Path of Library directory
|
||||
RCT_EXTERN NSString *__nullable RCTLibraryPath(void);
|
||||
|
||||
// Returns the relative path within the library for an absolute URL
|
||||
// (or nil, if the URL does not specify a path within the Library directory)
|
||||
RCT_EXTERN NSString *__nullable RCTLibraryPathForURL(NSURL *__nullable URL);
|
||||
|
||||
// Determines if a given image URL refers to a image in bundle
|
||||
RCT_EXTERN BOOL RCTIsBundleAssetURL(NSURL *__nullable imageURL);
|
||||
|
||||
// Determines if a given image URL refers to a image in library
|
||||
RCT_EXTERN BOOL RCTIsLibraryAssetURL(NSURL *__nullable imageURL);
|
||||
|
||||
// Determines if a given image URL refers to a local image
|
||||
RCT_EXTERN BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL);
|
||||
|
||||
// Returns an UIImage for a local image asset. Returns nil if the URL
|
||||
// does not correspond to a local asset.
|
||||
RCT_EXTERN UIImage *__nullable RCTImageFromLocalAssetURL(NSURL *imageURL);
|
||||
|
||||
// Only used in case when RCTImageFromLocalAssetURL fails to get an image
|
||||
// This method basically checks for the image in the bundle location, instead
|
||||
// of the CodePush location
|
||||
RCT_EXTERN UIImage *__nullable RCTImageFromLocalBundleAssetURL(NSURL *imageURL);
|
||||
|
||||
// Creates a new, unique temporary file path with the specified extension
|
||||
RCT_EXTERN NSString *__nullable RCTTempFilePath(NSString *__nullable extension, NSError **error);
|
||||
|
||||
// Get RGBA components of CGColor
|
||||
RCT_EXTERN void RCTGetRGBAColorComponents(CGColorRef color, CGFloat rgba[_Nonnull 4]);
|
||||
|
||||
// Converts a CGColor to a hex string
|
||||
RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
|
||||
|
||||
// Get standard localized string (if it exists)
|
||||
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string);
|
||||
|
||||
// Get a human readable type string from an NSObject. For example NSString becomes string
|
||||
RCT_EXTERN NSString *RCTHumanReadableType(NSObject *obj);
|
||||
|
||||
// URL manipulation
|
||||
RCT_EXTERN NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param);
|
||||
RCT_EXTERN NSURL *__nullable
|
||||
RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value);
|
||||
|
||||
// Given a string, drop common RN prefixes (RCT, RK, etc.)
|
||||
RCT_EXTERN NSString *RCTDropReactPrefixes(NSString *s);
|
||||
|
||||
RCT_EXTERN BOOL RCTUIManagerTypeForTagIsFabric(NSNumber *reactTag);
|
||||
|
||||
RCT_EXTERN BOOL RCTValidateTypeOfViewCommandArgument(
|
||||
NSObject *obj,
|
||||
id expectedClass,
|
||||
NSString const *expectedType,
|
||||
NSString const *componentName,
|
||||
NSString const *commandName,
|
||||
NSString const *argPos);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
1005
node_modules/react-native/React/Base/RCTUtils.m
generated
vendored
Normal file
1005
node_modules/react-native/React/Base/RCTUtils.m
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
node_modules/react-native/React/Base/RCTUtilsUIOverride.h
generated
vendored
Normal file
16
node_modules/react-native/React/Base/RCTUtilsUIOverride.h
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
@interface RCTUtilsUIOverride : NSObject
|
||||
/**
|
||||
Set the global presented view controller instance override.
|
||||
*/
|
||||
+ (void)setPresentedViewController:(UIViewController *)presentedViewController;
|
||||
+ (UIViewController *)presentedViewController;
|
||||
+ (BOOL)hasPresentedViewController;
|
||||
|
||||
@end
|
29
node_modules/react-native/React/Base/RCTUtilsUIOverride.m
generated
vendored
Normal file
29
node_modules/react-native/React/Base/RCTUtilsUIOverride.m
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTUtilsUIOverride.h"
|
||||
|
||||
@implementation RCTUtilsUIOverride
|
||||
|
||||
static UIViewController *_presentedViewController = nil;
|
||||
|
||||
+ (void)setPresentedViewController:(UIViewController *)presentedViewController
|
||||
{
|
||||
_presentedViewController = presentedViewController;
|
||||
}
|
||||
|
||||
+ (UIViewController *)presentedViewController
|
||||
{
|
||||
return _presentedViewController;
|
||||
}
|
||||
|
||||
+ (BOOL)hasPresentedViewController
|
||||
{
|
||||
return _presentedViewController != nil;
|
||||
}
|
||||
|
||||
@end
|
17
node_modules/react-native/React/Base/RCTVersion.h
generated
vendored
Normal file
17
node_modules/react-native/React/Base/RCTVersion.h
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
RCT_EXTERN NSString *const RCTVersionMajor;
|
||||
RCT_EXTERN NSString *const RCTVersionMinor;
|
||||
RCT_EXTERN NSString *const RCTVersionPatch;
|
||||
RCT_EXTERN NSString *const RCTVersionPrerelease;
|
||||
|
||||
RCT_EXTERN NSDictionary *RCTGetReactNativeVersion(void);
|
31
node_modules/react-native/React/Base/RCTVersion.m
generated
vendored
Normal file
31
node_modules/react-native/React/Base/RCTVersion.m
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @generated by scripts/bump-oss-version.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTVersion.h"
|
||||
|
||||
NSString* const RCTVersionMajor = @"major";
|
||||
NSString* const RCTVersionMinor = @"minor";
|
||||
NSString* const RCTVersionPatch = @"patch";
|
||||
NSString* const RCTVersionPrerelease = @"prerelease";
|
||||
|
||||
|
||||
NSDictionary* RCTGetReactNativeVersion(void)
|
||||
{
|
||||
static NSDictionary* __rnVersion;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^(void){
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(63),
|
||||
RCTVersionPatch: @(4),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
}
|
16
node_modules/react-native/React/Base/RCTWeakProxy.h
generated
vendored
Normal file
16
node_modules/react-native/React/Base/RCTWeakProxy.h
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RCTWeakProxy : NSObject
|
||||
|
||||
@property (nonatomic, weak, readonly) id target;
|
||||
|
||||
+ (instancetype)weakProxyWithTarget:(id)target;
|
||||
|
||||
@end
|
30
node_modules/react-native/React/Base/RCTWeakProxy.m
generated
vendored
Normal file
30
node_modules/react-native/React/Base/RCTWeakProxy.m
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTWeakProxy.h"
|
||||
|
||||
@implementation RCTWeakProxy
|
||||
|
||||
- (instancetype)initWithTarget:(id)target
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_target = target;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)weakProxyWithTarget:(id)target
|
||||
{
|
||||
return [[RCTWeakProxy alloc] initWithTarget:target];
|
||||
}
|
||||
|
||||
- (id)forwardingTargetForSelector:(SEL)aSelector
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
|
||||
@end
|
141
node_modules/react-native/React/Base/Surface/RCTSurface.h
generated
vendored
Normal file
141
node_modules/react-native/React/Base/Surface/RCTSurface.h
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTSurfaceStage.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTSurfaceView;
|
||||
@protocol RCTSurfaceDelegate;
|
||||
|
||||
/**
|
||||
* RCTSurface instance represents React Native-powered piece of a user interface
|
||||
* which can be a full-screen app, separate modal view controller,
|
||||
* or even small widget.
|
||||
* It is called "Surface".
|
||||
*
|
||||
* The RCTSurface instance is completely thread-safe by design;
|
||||
* it can be created on any thread, and any its method can be called from
|
||||
* any thread (if the opposite is not mentioned explicitly).
|
||||
*
|
||||
* The primary goals of the RCTSurface are:
|
||||
* * ability to measure and layout the surface in a thread-safe
|
||||
* and synchronous manner;
|
||||
* * ability to create a UIView instance on demand (later);
|
||||
* * ability to communicate the current stage of the surface granularly.
|
||||
*/
|
||||
@interface RCTSurface : NSObject
|
||||
|
||||
@property (atomic, readonly) RCTSurfaceStage stage;
|
||||
@property (atomic, readonly) NSString *moduleName;
|
||||
@property (atomic, readonly) NSNumber *rootViewTag;
|
||||
|
||||
@property (atomic, readwrite, weak, nullable) id<RCTSurfaceDelegate> delegate;
|
||||
|
||||
@property (atomic, copy, readwrite) NSDictionary *properties;
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties;
|
||||
|
||||
#pragma mark - Dealing with UIView representation, the Main thread only access
|
||||
|
||||
/**
|
||||
* Creates (if needed) and returns `UIView` instance which represents the Surface.
|
||||
* The Surface will cache and *retain* this object.
|
||||
* Returning the UIView instance does not mean that the Surface is ready
|
||||
* to execute and layout. It can be just a handler which Surface will use later
|
||||
* to mount the actual views.
|
||||
* RCTSurface does not control (or influence in any way) the size or origin
|
||||
* of this view. Some superview (or another owner) must use other methods
|
||||
* of this class to setup proper layout and interop interactions with UIKit
|
||||
* or another UI framework.
|
||||
* This method must be called only from the main queue.
|
||||
*/
|
||||
- (RCTSurfaceView *)view;
|
||||
|
||||
#pragma mark - Layout: Setting the size constrains
|
||||
|
||||
/**
|
||||
* Sets `minimumSize` and `maximumSize` layout constraints for the Surface.
|
||||
*/
|
||||
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
||||
|
||||
/**
|
||||
* Previously set `minimumSize` layout constraint.
|
||||
* Defaults to `{0, 0}`.
|
||||
*/
|
||||
@property (atomic, assign, readonly) CGSize minimumSize;
|
||||
|
||||
/**
|
||||
* Previously set `maximumSize` layout constraint.
|
||||
* Defaults to `{CGFLOAT_MAX, CGFLOAT_MAX}`.
|
||||
*/
|
||||
@property (atomic, assign, readonly) CGSize maximumSize;
|
||||
|
||||
/**
|
||||
* Simple shortcut to `-[RCTSurface setMinimumSize:size maximumSize:size]`.
|
||||
*/
|
||||
- (void)setSize:(CGSize)size;
|
||||
|
||||
#pragma mark - Layout: Measuring
|
||||
|
||||
/**
|
||||
* Measures the Surface with given constraints.
|
||||
* This method does not cause any side effects on the surface object.
|
||||
*/
|
||||
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
||||
|
||||
/**
|
||||
* Return the current size of the root view based on (but not clamp by) current
|
||||
* size constraints.
|
||||
*/
|
||||
@property (atomic, assign, readonly) CGSize intrinsicSize;
|
||||
|
||||
#pragma mark - Synchronous waiting
|
||||
|
||||
/**
|
||||
* Synchronously blocks the current thread up to given `timeout` until
|
||||
* the Surface reaches `stage`.
|
||||
* Limitations:
|
||||
* - Do nothing, if called on `UIManager` queue.
|
||||
* - Calling on the main queue with `RCTSurfaceStageSurfaceDidInitialMounting`
|
||||
* stage temporary is not supported; in this case the stage will be
|
||||
* downgraded to `RCTSurfaceStageSurfaceDidInitialLayout`.
|
||||
*/
|
||||
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout;
|
||||
|
||||
#pragma mark - Start & Stop
|
||||
|
||||
/**
|
||||
* Starts or stops the Surface.
|
||||
* Those methods are a no-op for regular RCTSurface (for now), but all call sites must call them appropriately.
|
||||
*/
|
||||
- (BOOL)start;
|
||||
- (BOOL)stop;
|
||||
|
||||
#pragma mark - Mounting/Unmounting of React components
|
||||
|
||||
/**
|
||||
* Mount the React component specified by the given moduleName. This is typically
|
||||
* calling runApplication.js from the native side.
|
||||
*/
|
||||
- (void)mountReactComponentWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
params:(NSDictionary *)params;
|
||||
|
||||
/**
|
||||
* Unmount the React component specified by the given rootViewTag, called from native.
|
||||
*/
|
||||
- (void)unmountReactComponentWithBridge:(RCTBridge *)bridge rootViewTag:(NSNumber *)rootViewTag;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
592
node_modules/react-native/React/Base/Surface/RCTSurface.mm
generated
vendored
Normal file
592
node_modules/react-native/React/Base/Surface/RCTSurface.mm
generated
vendored
Normal file
@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurface.h"
|
||||
#import "RCTSurfaceView+Internal.h"
|
||||
|
||||
#import <mutex>
|
||||
|
||||
#import <stdatomic.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTShadowView+Layout.h"
|
||||
#import "RCTSurfaceDelegate.h"
|
||||
#import "RCTSurfaceRootShadowView.h"
|
||||
#import "RCTSurfaceRootShadowViewDelegate.h"
|
||||
#import "RCTSurfaceRootView.h"
|
||||
#import "RCTSurfaceView.h"
|
||||
#import "RCTTouchHandler.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUIManagerObserverCoordinator.h"
|
||||
#import "RCTUIManagerUtils.h"
|
||||
|
||||
@interface RCTSurface () <RCTSurfaceRootShadowViewDelegate, RCTUIManagerObserver>
|
||||
@end
|
||||
|
||||
@implementation RCTSurface {
|
||||
// Immutable
|
||||
RCTBridge *_bridge;
|
||||
NSString *_moduleName;
|
||||
NSNumber *_rootViewTag;
|
||||
|
||||
// Protected by the `_mutex`
|
||||
std::mutex _mutex;
|
||||
RCTBridge *_batchedBridge;
|
||||
RCTSurfaceStage _stage;
|
||||
NSDictionary *_properties;
|
||||
CGSize _minimumSize;
|
||||
CGSize _maximumSize;
|
||||
CGSize _intrinsicSize;
|
||||
RCTUIManagerMountingBlock _mountingBlock;
|
||||
|
||||
// The Main thread only
|
||||
RCTSurfaceView *_Nullable _view;
|
||||
RCTTouchHandler *_Nullable _touchHandler;
|
||||
|
||||
// Semaphores
|
||||
dispatch_semaphore_t _rootShadowViewDidStartRenderingSemaphore;
|
||||
dispatch_semaphore_t _rootShadowViewDidStartLayingOutSemaphore;
|
||||
dispatch_semaphore_t _uiManagerDidPerformMountingSemaphore;
|
||||
|
||||
// Atomics
|
||||
atomic_bool _waitingForMountingStageOnMainQueue;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
{
|
||||
RCTAssert(bridge.valid, @"Valid bridge is required to instantiate `RCTSurface`.");
|
||||
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
_batchedBridge = [_bridge batchedBridge] ?: _bridge;
|
||||
_moduleName = moduleName;
|
||||
_properties = [initialProperties copy];
|
||||
_rootViewTag = RCTAllocateRootViewTag();
|
||||
|
||||
_rootShadowViewDidStartRenderingSemaphore = dispatch_semaphore_create(0);
|
||||
_rootShadowViewDidStartLayingOutSemaphore = dispatch_semaphore_create(0);
|
||||
_uiManagerDidPerformMountingSemaphore = dispatch_semaphore_create(0);
|
||||
|
||||
_minimumSize = CGSizeZero;
|
||||
_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleBridgeWillLoadJavaScriptNotification:)
|
||||
name:RCTJavaScriptWillStartLoadingNotification
|
||||
object:_bridge];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleBridgeDidLoadJavaScriptNotification:)
|
||||
name:RCTJavaScriptDidLoadNotification
|
||||
object:_bridge];
|
||||
|
||||
_stage = RCTSurfaceStageSurfaceDidInitialize;
|
||||
|
||||
if (!bridge.loading) {
|
||||
_stage = _stage | RCTSurfaceStageBridgeDidLoad;
|
||||
}
|
||||
|
||||
[_bridge.uiManager.observerCoordinator addObserver:self];
|
||||
|
||||
[self _registerRootView];
|
||||
[self _run];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self _stop];
|
||||
}
|
||||
|
||||
#pragma mark - Immutable Properties (no need to enforce synchronization)
|
||||
|
||||
- (RCTBridge *)bridge
|
||||
{
|
||||
return _bridge;
|
||||
}
|
||||
|
||||
- (NSString *)moduleName
|
||||
{
|
||||
return _moduleName;
|
||||
}
|
||||
|
||||
- (NSNumber *)rootViewTag
|
||||
{
|
||||
return _rootViewTag;
|
||||
}
|
||||
|
||||
#pragma mark - Convenience Internal Thread-Safe Properties
|
||||
|
||||
- (RCTBridge *)_batchedBridge
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _batchedBridge;
|
||||
}
|
||||
|
||||
- (RCTUIManager *)_uiManager
|
||||
{
|
||||
return self._batchedBridge.uiManager;
|
||||
}
|
||||
|
||||
#pragma mark - Main-Threaded Routines
|
||||
|
||||
- (RCTSurfaceView *)view
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
if (!_view) {
|
||||
_view = [[RCTSurfaceView alloc] initWithSurface:self];
|
||||
|
||||
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:self.bridge];
|
||||
[_touchHandler attachToView:_view];
|
||||
|
||||
[self _mountRootViewIfNeeded];
|
||||
}
|
||||
|
||||
return _view;
|
||||
}
|
||||
|
||||
- (void)_mountRootViewIfNeeded
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
RCTSurfaceView *view = self->_view;
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
|
||||
RCTSurfaceRootView *rootView = (RCTSurfaceRootView *)[self._uiManager viewForReactTag:self->_rootViewTag];
|
||||
if (!rootView) {
|
||||
return;
|
||||
}
|
||||
|
||||
RCTAssert(
|
||||
[rootView isKindOfClass:[RCTSurfaceRootView class]],
|
||||
@"Received root view is not an instance of `RCTSurfaceRootView`.");
|
||||
|
||||
if (rootView.superview != view) {
|
||||
view.rootView = rootView;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Bridge Events
|
||||
|
||||
- (void)handleBridgeWillLoadJavaScriptNotification:(__unused NSNotification *)notification
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
// Reset states because the bridge is reloading. This is similar to initialization phase.
|
||||
_stage = RCTSurfaceStageSurfaceDidInitialize;
|
||||
_view = nil;
|
||||
_touchHandler = nil;
|
||||
[self _setStage:RCTSurfaceStageBridgeDidLoad];
|
||||
}
|
||||
|
||||
- (void)handleBridgeDidLoadJavaScriptNotification:(NSNotification *)notification
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
[self _setStage:RCTSurfaceStageModuleDidLoad];
|
||||
|
||||
RCTBridge *bridge = notification.userInfo[@"bridge"];
|
||||
|
||||
BOOL isRerunNeeded = NO;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if (bridge != _batchedBridge) {
|
||||
_batchedBridge = bridge;
|
||||
isRerunNeeded = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRerunNeeded) {
|
||||
[self _registerRootView];
|
||||
[self _run];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Stage management
|
||||
|
||||
- (RCTSurfaceStage)stage
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _stage;
|
||||
}
|
||||
|
||||
- (void)_setStage:(RCTSurfaceStage)stage
|
||||
{
|
||||
RCTSurfaceStage updatedStage;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if (_stage & stage) {
|
||||
return;
|
||||
}
|
||||
|
||||
updatedStage = (RCTSurfaceStage)(_stage | stage);
|
||||
_stage = updatedStage;
|
||||
}
|
||||
|
||||
[self _propagateStageChange:updatedStage];
|
||||
}
|
||||
|
||||
- (void)_propagateStageChange:(RCTSurfaceStage)stage
|
||||
{
|
||||
// Updating the `view`
|
||||
RCTExecuteOnMainQueue(^{
|
||||
self->_view.stage = stage;
|
||||
});
|
||||
|
||||
// Notifying the `delegate`
|
||||
id<RCTSurfaceDelegate> delegate = self.delegate;
|
||||
if ([delegate respondsToSelector:@selector(surface:didChangeStage:)]) {
|
||||
[delegate surface:self didChangeStage:stage];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Properties Management
|
||||
|
||||
- (NSDictionary *)properties
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _properties;
|
||||
}
|
||||
|
||||
- (void)setProperties:(NSDictionary *)properties
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if ([properties isEqualToDictionary:_properties]) {
|
||||
return;
|
||||
}
|
||||
|
||||
_properties = [properties copy];
|
||||
}
|
||||
|
||||
[self _run];
|
||||
}
|
||||
|
||||
#pragma mark - Running
|
||||
|
||||
- (void)_run
|
||||
{
|
||||
RCTBridge *batchedBridge;
|
||||
NSDictionary *properties;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
batchedBridge = _batchedBridge;
|
||||
properties = _properties;
|
||||
}
|
||||
|
||||
if (!batchedBridge.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *applicationParameters = @{
|
||||
@"rootTag" : _rootViewTag,
|
||||
@"initialProps" : properties,
|
||||
};
|
||||
|
||||
RCTLogInfo(@"Running surface %@ (%@)", _moduleName, applicationParameters);
|
||||
|
||||
[self mountReactComponentWithBridge:batchedBridge moduleName:_moduleName params:applicationParameters];
|
||||
|
||||
[self _setStage:RCTSurfaceStageSurfaceDidRun];
|
||||
}
|
||||
|
||||
- (void)_stop
|
||||
{
|
||||
[self unmountReactComponentWithBridge:self._batchedBridge rootViewTag:self->_rootViewTag];
|
||||
}
|
||||
|
||||
- (void)_registerRootView
|
||||
{
|
||||
RCTBridge *batchedBridge;
|
||||
CGSize minimumSize;
|
||||
CGSize maximumSize;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
batchedBridge = _batchedBridge;
|
||||
minimumSize = _minimumSize;
|
||||
maximumSize = _maximumSize;
|
||||
}
|
||||
|
||||
RCTUIManager *uiManager = batchedBridge.uiManager;
|
||||
|
||||
// If we are on the main queue now, we have to proceed synchronously.
|
||||
// Otherwise, we cannot perform synchronous waiting for some stages later.
|
||||
(RCTIsMainQueue() ? RCTUnsafeExecuteOnUIManagerQueueSync : RCTExecuteOnUIManagerQueue)(^{
|
||||
[uiManager registerRootViewTag:self->_rootViewTag];
|
||||
|
||||
RCTSurfaceRootShadowView *rootShadowView =
|
||||
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
|
||||
RCTAssert(
|
||||
[rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
|
||||
@"Received shadow view is not an instance of `RCTSurfaceRootShadowView`.");
|
||||
|
||||
[rootShadowView setMinimumSize:minimumSize maximumSize:maximumSize];
|
||||
rootShadowView.delegate = self;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
|
||||
{
|
||||
RCTUIManager *uiManager = self._uiManager;
|
||||
__block CGSize fittingSize;
|
||||
|
||||
RCTUnsafeExecuteOnUIManagerQueueSync(^{
|
||||
RCTSurfaceRootShadowView *rootShadowView =
|
||||
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
|
||||
|
||||
RCTAssert(
|
||||
[rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
|
||||
@"Received shadow view is not an instance of `RCTSurfaceRootShadowView`.");
|
||||
|
||||
fittingSize = [rootShadowView sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize];
|
||||
});
|
||||
|
||||
return fittingSize;
|
||||
}
|
||||
|
||||
#pragma mark - Size Constraints
|
||||
|
||||
- (void)setSize:(CGSize)size
|
||||
{
|
||||
[self setMinimumSize:size maximumSize:size];
|
||||
}
|
||||
|
||||
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (CGSizeEqualToSize(minimumSize, _minimumSize) && CGSizeEqualToSize(maximumSize, _maximumSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_maximumSize = maximumSize;
|
||||
_minimumSize = minimumSize;
|
||||
}
|
||||
|
||||
RCTUIManager *uiManager = self._uiManager;
|
||||
|
||||
RCTUnsafeExecuteOnUIManagerQueueSync(^{
|
||||
RCTSurfaceRootShadowView *rootShadowView =
|
||||
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
|
||||
RCTAssert(
|
||||
[rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
|
||||
@"Received shadow view is not an instance of `RCTSurfaceRootShadowView`.");
|
||||
|
||||
[rootShadowView setMinimumSize:minimumSize maximumSize:maximumSize];
|
||||
[uiManager setNeedsLayout];
|
||||
});
|
||||
}
|
||||
|
||||
- (CGSize)minimumSize
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _minimumSize;
|
||||
}
|
||||
|
||||
- (CGSize)maximumSize
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _maximumSize;
|
||||
}
|
||||
|
||||
#pragma mark - intrinsicSize
|
||||
|
||||
- (void)setIntrinsicSize:(CGSize)intrinsicSize
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (CGSizeEqualToSize(intrinsicSize, _intrinsicSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_intrinsicSize = intrinsicSize;
|
||||
}
|
||||
|
||||
// Notifying `delegate`
|
||||
id<RCTSurfaceDelegate> delegate = self.delegate;
|
||||
if ([delegate respondsToSelector:@selector(surface:didChangeIntrinsicSize:)]) {
|
||||
[delegate surface:self didChangeIntrinsicSize:intrinsicSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicSize
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _intrinsicSize;
|
||||
}
|
||||
|
||||
#pragma mark - Synchronous Waiting
|
||||
|
||||
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout
|
||||
{
|
||||
if (RCTIsUIManagerQueue()) {
|
||||
RCTLogInfo(@"Synchronous waiting is not supported on UIManager queue.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (RCTIsMainQueue() && (stage & RCTSurfaceStageSurfaceDidInitialMounting)) {
|
||||
// All main-threaded execution (especially mounting process) has to be
|
||||
// intercepted, captured and performed synchronously at the end of this method
|
||||
// right after the semaphore signals.
|
||||
|
||||
// Atomic variant of `_waitingForMountingStageOnMainQueue = YES;`
|
||||
atomic_fetch_or(&_waitingForMountingStageOnMainQueue, 1);
|
||||
}
|
||||
|
||||
dispatch_semaphore_t semaphore;
|
||||
switch (stage) {
|
||||
case RCTSurfaceStageSurfaceDidInitialLayout:
|
||||
semaphore = _rootShadowViewDidStartLayingOutSemaphore;
|
||||
break;
|
||||
case RCTSurfaceStageSurfaceDidInitialRendering:
|
||||
semaphore = _rootShadowViewDidStartRenderingSemaphore;
|
||||
break;
|
||||
case RCTSurfaceStageSurfaceDidInitialMounting:
|
||||
semaphore = _uiManagerDidPerformMountingSemaphore;
|
||||
break;
|
||||
default:
|
||||
RCTAssert(
|
||||
NO,
|
||||
@"Only waiting for `RCTSurfaceStageSurfaceDidInitialRendering`, `RCTSurfaceStageSurfaceDidInitialLayout` and `RCTSurfaceStageSurfaceDidInitialMounting` stages are supported.");
|
||||
}
|
||||
|
||||
BOOL timeoutOccurred = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC));
|
||||
|
||||
// Atomic equivalent of `_waitingForMountingStageOnMainQueue = NO;`.
|
||||
atomic_fetch_and(&_waitingForMountingStageOnMainQueue, 0);
|
||||
|
||||
if (!timeoutOccurred) {
|
||||
// Balancing the semaphore.
|
||||
// Note: `dispatch_semaphore_wait` reverts the decrement in case when timeout occurred.
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}
|
||||
|
||||
if (RCTIsMainQueue() && (stage & RCTSurfaceStageSurfaceDidInitialMounting)) {
|
||||
// Time to apply captured mounting block.
|
||||
RCTUIManagerMountingBlock mountingBlock;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
mountingBlock = _mountingBlock;
|
||||
_mountingBlock = nil;
|
||||
}
|
||||
|
||||
if (mountingBlock) {
|
||||
mountingBlock();
|
||||
[self _mountRootViewIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
return !timeoutOccurred;
|
||||
}
|
||||
|
||||
#pragma mark - RCTSurfaceRootShadowViewDelegate
|
||||
|
||||
- (void)rootShadowView:(__unused RCTRootShadowView *)rootShadowView didChangeIntrinsicSize:(CGSize)intrinsicSize
|
||||
{
|
||||
self.intrinsicSize = intrinsicSize;
|
||||
}
|
||||
|
||||
- (void)rootShadowViewDidStartRendering:(__unused RCTSurfaceRootShadowView *)rootShadowView
|
||||
{
|
||||
[self _setStage:RCTSurfaceStageSurfaceDidInitialRendering];
|
||||
|
||||
dispatch_semaphore_signal(_rootShadowViewDidStartRenderingSemaphore);
|
||||
}
|
||||
|
||||
- (void)rootShadowViewDidStartLayingOut:(__unused RCTSurfaceRootShadowView *)rootShadowView
|
||||
{
|
||||
[self _setStage:RCTSurfaceStageSurfaceDidInitialLayout];
|
||||
|
||||
dispatch_semaphore_signal(_rootShadowViewDidStartLayingOutSemaphore);
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
// Rendering is happening, let's mount `rootView` into `view` if we already didn't do this.
|
||||
[self _mountRootViewIfNeeded];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - RCTUIManagerObserver
|
||||
|
||||
- (BOOL)uiManager:(__unused RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
|
||||
{
|
||||
if (atomic_load(&_waitingForMountingStageOnMainQueue) && (self.stage & RCTSurfaceStageSurfaceDidInitialLayout)) {
|
||||
// Atomic equivalent of `_waitingForMountingStageOnMainQueue = NO;`.
|
||||
atomic_fetch_and(&_waitingForMountingStageOnMainQueue, 0);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_mountingBlock = block;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)uiManagerDidPerformMounting:(__unused RCTUIManager *)manager
|
||||
{
|
||||
if (self.stage & RCTSurfaceStageSurfaceDidInitialLayout) {
|
||||
[self _setStage:RCTSurfaceStageSurfaceDidInitialMounting];
|
||||
dispatch_semaphore_signal(_uiManagerDidPerformMountingSemaphore);
|
||||
|
||||
// No need to listen to UIManager anymore.
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
|
||||
[self->_bridge.uiManager.observerCoordinator removeObserver:self];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)start
|
||||
{
|
||||
// Does nothing.
|
||||
// The Start&Stop feature is not implemented for regular Surface yet.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)stop
|
||||
{
|
||||
// Does nothing.
|
||||
// The Start&Stop feature is not implemented for regular Surface yet.
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Mounting/Unmounting of React components
|
||||
|
||||
- (void)mountReactComponentWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
params:(NSDictionary *)params
|
||||
{
|
||||
[bridge enqueueJSCall:@"AppRegistry" method:@"runApplication" args:@[ moduleName, params ] completion:NULL];
|
||||
}
|
||||
|
||||
- (void)unmountReactComponentWithBridge:(RCTBridge *)bridge rootViewTag:(NSNumber *)rootViewTag
|
||||
{
|
||||
[bridge enqueueJSCall:@"AppRegistry"
|
||||
method:@"unmountApplicationComponentAtRootTag"
|
||||
args:@[ rootViewTag ]
|
||||
completion:NULL];
|
||||
}
|
||||
|
||||
@end
|
34
node_modules/react-native/React/Base/Surface/RCTSurfaceDelegate.h
generated
vendored
Normal file
34
node_modules/react-native/React/Base/Surface/RCTSurfaceDelegate.h
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTSurfaceStage.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class RCTSurface;
|
||||
|
||||
@protocol RCTSurfaceDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Notifies a receiver that a surface transitioned to a new stage.
|
||||
* See `RCTSurfaceStage` for more details.
|
||||
*/
|
||||
- (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage;
|
||||
|
||||
/**
|
||||
* Notifies a receiver that root view got a new (intrinsic) size during the last
|
||||
* layout pass.
|
||||
*/
|
||||
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
32
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowView.h
generated
vendored
Normal file
32
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowView.h
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTShadowView.h>
|
||||
#import <React/RCTSurfaceRootShadowViewDelegate.h>
|
||||
#import <yoga/YGEnums.h>
|
||||
|
||||
@interface RCTSurfaceRootShadowView : RCTShadowView
|
||||
|
||||
@property (nonatomic, assign, readonly) CGSize minimumSize;
|
||||
@property (nonatomic, assign, readonly) CGSize maximumSize;
|
||||
|
||||
- (void)setMinimumSize:(CGSize)size maximumSize:(CGSize)maximumSize;
|
||||
|
||||
@property (nonatomic, assign, readonly) CGSize intrinsicSize;
|
||||
|
||||
@property (nonatomic, weak) id<RCTSurfaceRootShadowViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
* Layout direction (LTR or RTL) inherited from native environment and
|
||||
* is using as a base direction value in layout engine.
|
||||
* Defaults to value inferred from current locale.
|
||||
*/
|
||||
@property (nonatomic, assign) YGDirection baseDirection;
|
||||
|
||||
- (void)layoutWithAffectedShadowViews:(NSHashTable<RCTShadowView *> *)affectedShadowViews;
|
||||
|
||||
@end
|
92
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowView.m
generated
vendored
Normal file
92
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowView.m
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceRootShadowView.h"
|
||||
|
||||
#import "RCTI18nUtil.h"
|
||||
#import "RCTShadowView+Layout.h"
|
||||
#import "RCTUIManagerUtils.h"
|
||||
|
||||
@implementation RCTSurfaceRootShadowView {
|
||||
CGSize _intrinsicSize;
|
||||
BOOL _isRendered;
|
||||
BOOL _isLaidOut;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.viewName = @"RCTSurfaceRootView";
|
||||
_baseDirection = [[RCTI18nUtil sharedInstance] isRTL] ? YGDirectionRTL : YGDirectionLTR;
|
||||
_minimumSize = CGSizeZero;
|
||||
_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
|
||||
|
||||
self.alignSelf = YGAlignStretch;
|
||||
self.flex = 1;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
if (!_isRendered) {
|
||||
[_delegate rootShadowViewDidStartRendering:self];
|
||||
_isRendered = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutWithAffectedShadowViews:(NSHashTable<RCTShadowView *> *)affectedShadowViews
|
||||
{
|
||||
NSHashTable<NSString *> *other = [NSHashTable new];
|
||||
|
||||
RCTLayoutContext layoutContext = {};
|
||||
layoutContext.absolutePosition = CGPointZero;
|
||||
layoutContext.affectedShadowViews = affectedShadowViews;
|
||||
layoutContext.other = other;
|
||||
|
||||
[self layoutWithMinimumSize:_minimumSize
|
||||
maximumSize:_maximumSize
|
||||
layoutDirection:RCTUIKitLayoutDirectionFromYogaLayoutDirection(_baseDirection)
|
||||
layoutContext:layoutContext];
|
||||
|
||||
self.intrinsicSize = self.layoutMetrics.frame.size;
|
||||
|
||||
if (_isRendered && !_isLaidOut) {
|
||||
[_delegate rootShadowViewDidStartLayingOut:self];
|
||||
_isLaidOut = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
|
||||
{
|
||||
if (CGSizeEqualToSize(minimumSize, _minimumSize) && CGSizeEqualToSize(maximumSize, _maximumSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_maximumSize = maximumSize;
|
||||
_minimumSize = minimumSize;
|
||||
}
|
||||
|
||||
- (void)setIntrinsicSize:(CGSize)intrinsicSize
|
||||
{
|
||||
if (CGSizeEqualToSize(_intrinsicSize, intrinsicSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_intrinsicSize = intrinsicSize;
|
||||
|
||||
[_delegate rootShadowView:self didChangeIntrinsicSize:intrinsicSize];
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicSize
|
||||
{
|
||||
return _intrinsicSize;
|
||||
}
|
||||
|
||||
@end
|
22
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowViewDelegate.h
generated
vendored
Normal file
22
node_modules/react-native/React/Base/Surface/RCTSurfaceRootShadowViewDelegate.h
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class RCTSurfaceRootShadowView;
|
||||
|
||||
@protocol RCTSurfaceRootShadowViewDelegate <NSObject>
|
||||
|
||||
- (void)rootShadowView:(RCTSurfaceRootShadowView *)rootShadowView didChangeIntrinsicSize:(CGSize)instrinsicSize;
|
||||
- (void)rootShadowViewDidStartRendering:(RCTSurfaceRootShadowView *)rootShadowView;
|
||||
- (void)rootShadowViewDidStartLayingOut:(RCTSurfaceRootShadowView *)rootShadowView;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
21
node_modules/react-native/React/Base/Surface/RCTSurfaceRootView.h
generated
vendored
Normal file
21
node_modules/react-native/React/Base/Surface/RCTSurfaceRootView.h
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTView.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Internal class represents Surface's root view.
|
||||
*/
|
||||
@interface RCTSurfaceRootView : RCTView
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
16
node_modules/react-native/React/Base/Surface/RCTSurfaceRootView.mm
generated
vendored
Normal file
16
node_modules/react-native/React/Base/Surface/RCTSurfaceRootView.mm
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceRootView.h"
|
||||
|
||||
#import "RCTDefines.h"
|
||||
|
||||
@implementation RCTSurfaceRootView
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(nullable instancetype)initWithCoder : (NSCoder *)coder)
|
||||
|
||||
@end
|
47
node_modules/react-native/React/Base/Surface/RCTSurfaceStage.h
generated
vendored
Normal file
47
node_modules/react-native/React/Base/Surface/RCTSurfaceStage.h
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
/**
|
||||
* The stage of the Surface
|
||||
*/
|
||||
typedef NS_OPTIONS(NSInteger, RCTSurfaceStage) {
|
||||
RCTSurfaceStageSurfaceDidInitialize = 1 << 0, // Surface object was created
|
||||
RCTSurfaceStageBridgeDidLoad = 1 << 1, // Bridge was loaded
|
||||
RCTSurfaceStageModuleDidLoad = 1 << 2, // Module (JavaScript code) was loaded
|
||||
RCTSurfaceStageSurfaceDidRun = 1 << 3, // Module (JavaScript code) was run
|
||||
RCTSurfaceStageSurfaceDidInitialRendering = 1 << 4, // UIManager created the first shadow views
|
||||
RCTSurfaceStageSurfaceDidInitialLayout = 1 << 5, // UIManager completed the first layout pass
|
||||
RCTSurfaceStageSurfaceDidInitialMounting = 1 << 6, // UIManager completed the first mounting pass
|
||||
RCTSurfaceStageSurfaceDidStop = 1 << 7, // Surface stopped
|
||||
|
||||
// Most of the previously existed stages make no sense in the new architecture;
|
||||
// now Surface exposes only three simple stages:
|
||||
//
|
||||
// Surface object was constructed and still valid.
|
||||
RCTSurfaceStageInitialized = RCTSurfaceStageSurfaceDidInitialize,
|
||||
// Surface was started.
|
||||
RCTSurfaceStageStarted = 1 << 8,
|
||||
// All off-main-thread work is done; we are ready to mount the UI.
|
||||
RCTSurfaceStagePrepared = RCTSurfaceStageBridgeDidLoad | RCTSurfaceStageModuleDidLoad | RCTSurfaceStageSurfaceDidRun |
|
||||
RCTSurfaceStageSurfaceDidInitialRendering | RCTSurfaceStageSurfaceDidInitialLayout,
|
||||
// All main-thread work is done, the UI was mounted.
|
||||
RCTSurfaceStageMounted = RCTSurfaceStageSurfaceDidInitialMounting,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns `YES` if the stage is suitable for displaying normal React Native app.
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTSurfaceStageIsRunning(RCTSurfaceStage stage);
|
||||
|
||||
/**
|
||||
* Returns `YES` if the stage is suitable for displaying activity indicator.
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTSurfaceStageIsPreparing(RCTSurfaceStage stage);
|
18
node_modules/react-native/React/Base/Surface/RCTSurfaceStage.m
generated
vendored
Normal file
18
node_modules/react-native/React/Base/Surface/RCTSurfaceStage.m
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceStage.h"
|
||||
|
||||
BOOL RCTSurfaceStageIsRunning(RCTSurfaceStage stage)
|
||||
{
|
||||
return (stage & RCTSurfaceStageSurfaceDidInitialLayout) && !(stage & RCTSurfaceStageSurfaceDidStop);
|
||||
}
|
||||
|
||||
BOOL RCTSurfaceStageIsPreparing(RCTSurfaceStage stage)
|
||||
{
|
||||
return !(stage & RCTSurfaceStageSurfaceDidInitialLayout) && !(stage & RCTSurfaceStageSurfaceDidStop);
|
||||
}
|
24
node_modules/react-native/React/Base/Surface/RCTSurfaceView+Internal.h
generated
vendored
Normal file
24
node_modules/react-native/React/Base/Surface/RCTSurfaceView+Internal.h
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTSurfaceStage.h>
|
||||
#import <React/RCTSurfaceView.h>
|
||||
|
||||
@class RCTSurfaceRootView;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface RCTSurfaceView (Internal)
|
||||
|
||||
@property (nonatomic, strong) RCTSurfaceRootView *rootView;
|
||||
@property (nonatomic, assign) RCTSurfaceStage stage;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
25
node_modules/react-native/React/Base/Surface/RCTSurfaceView.h
generated
vendored
Normal file
25
node_modules/react-native/React/Base/Surface/RCTSurfaceView.h
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class RCTSurface;
|
||||
|
||||
/**
|
||||
* UIView instance which represents the Surface
|
||||
*/
|
||||
@interface RCTSurfaceView : UIView
|
||||
|
||||
- (instancetype)initWithSurface:(RCTSurface *)surface NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, weak, readonly, nullable) RCTSurface *surface;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
83
node_modules/react-native/React/Base/Surface/RCTSurfaceView.mm
generated
vendored
Normal file
83
node_modules/react-native/React/Base/Surface/RCTSurfaceView.mm
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceView.h"
|
||||
#import "RCTSurfaceView+Internal.h"
|
||||
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTSurface.h"
|
||||
#import "RCTSurfaceRootView.h"
|
||||
|
||||
@implementation RCTSurfaceView {
|
||||
RCTSurfaceRootView *_Nullable _rootView;
|
||||
RCTSurfaceStage _stage;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(-(nullable instancetype)initWithCoder : (NSCoder *)coder)
|
||||
|
||||
- (instancetype)initWithSurface:(RCTSurface *)surface
|
||||
{
|
||||
if (self = [super initWithFrame:CGRectZero]) {
|
||||
_stage = surface.stage;
|
||||
_surface = surface;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Internal Interface
|
||||
|
||||
- (void)setRootView:(RCTSurfaceRootView *)rootView
|
||||
{
|
||||
if (_rootView == rootView) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_rootView removeFromSuperview];
|
||||
_rootView = rootView;
|
||||
[self _updateStage];
|
||||
}
|
||||
|
||||
- (RCTSurfaceRootView *)rootView
|
||||
{
|
||||
return _rootView;
|
||||
}
|
||||
|
||||
#pragma mark - stage
|
||||
|
||||
- (void)setStage:(RCTSurfaceStage)stage
|
||||
{
|
||||
if (stage == _stage) {
|
||||
return;
|
||||
}
|
||||
|
||||
_stage = stage;
|
||||
|
||||
[self _updateStage];
|
||||
}
|
||||
|
||||
- (RCTSurfaceStage)stage
|
||||
{
|
||||
return _stage;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)_updateStage
|
||||
{
|
||||
if (RCTSurfaceStageIsRunning(_stage)) {
|
||||
if (_rootView.superview != self) {
|
||||
[self addSubview:_rootView];
|
||||
}
|
||||
} else {
|
||||
[_rootView removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
55
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h
generated
vendored
Normal file
55
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#import "RCTSurfaceHostingView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This is a RCTRootView-compatible implementation of RCTSurfaceHostingView.
|
||||
* Use this class to replace all usages of RCTRootView in the app for easier migration
|
||||
* to RCTSurfaceHostingView.
|
||||
*
|
||||
* WARNING: In the future, RCTRootView will be deprecated in favor of RCTSurfaceHostingView.
|
||||
*/
|
||||
@interface RCTSurfaceHostingProxyRootView : RCTSurfaceHostingView
|
||||
|
||||
#pragma mark RCTRootView compatibility - keep these sync'ed with RCTRootView.h
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *moduleName;
|
||||
@property (nonatomic, strong, readonly) RCTBridge *bridge;
|
||||
@property (nonatomic, copy, readwrite) NSDictionary *appProperties;
|
||||
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
||||
@property (nonatomic, weak) id<RCTRootViewDelegate> delegate;
|
||||
@property (nonatomic, weak) UIViewController *reactViewController;
|
||||
@property (nonatomic, strong, readonly) UIView *contentView;
|
||||
@property (nonatomic, strong) UIView *loadingView;
|
||||
@property (nonatomic, assign) BOOL passThroughTouches;
|
||||
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
|
||||
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
launchOptions:(NSDictionary *)launchOptions;
|
||||
|
||||
- (instancetype)initWithSurface:(RCTSurface *)surface
|
||||
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode NS_UNAVAILABLE;
|
||||
|
||||
- (void)cancelTouches;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
182
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm
generated
vendored
Normal file
182
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm
generated
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceHostingProxyRootView.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTProfile.h"
|
||||
#import "RCTRootContentView.h"
|
||||
#import "RCTRootViewDelegate.h"
|
||||
#import "RCTSurface.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
static RCTSurfaceSizeMeasureMode convertToSurfaceSizeMeasureMode(RCTRootViewSizeFlexibility sizeFlexibility)
|
||||
{
|
||||
switch (sizeFlexibility) {
|
||||
case RCTRootViewSizeFlexibilityWidthAndHeight:
|
||||
return RCTSurfaceSizeMeasureModeWidthUndefined | RCTSurfaceSizeMeasureModeHeightUndefined;
|
||||
case RCTRootViewSizeFlexibilityWidth:
|
||||
return RCTSurfaceSizeMeasureModeWidthUndefined | RCTSurfaceSizeMeasureModeHeightExact;
|
||||
case RCTRootViewSizeFlexibilityHeight:
|
||||
return RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightUndefined;
|
||||
case RCTRootViewSizeFlexibilityNone:
|
||||
return RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact;
|
||||
}
|
||||
}
|
||||
|
||||
static RCTRootViewSizeFlexibility convertToRootViewSizeFlexibility(RCTSurfaceSizeMeasureMode sizeMeasureMode)
|
||||
{
|
||||
switch (sizeMeasureMode) {
|
||||
case RCTSurfaceSizeMeasureModeWidthUndefined | RCTSurfaceSizeMeasureModeHeightUndefined:
|
||||
return RCTRootViewSizeFlexibilityWidthAndHeight;
|
||||
case RCTSurfaceSizeMeasureModeWidthUndefined | RCTSurfaceSizeMeasureModeHeightExact:
|
||||
return RCTRootViewSizeFlexibilityWidth;
|
||||
case RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightUndefined:
|
||||
return RCTRootViewSizeFlexibilityHeight;
|
||||
case RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact:
|
||||
default:
|
||||
return RCTRootViewSizeFlexibilityNone;
|
||||
}
|
||||
}
|
||||
|
||||
@implementation RCTSurfaceHostingProxyRootView
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
RCTAssert(bridge, @"A bridge instance is required to create an RCTSurfaceHostingProxyRootView");
|
||||
RCTAssert(moduleName, @"A moduleName is required to create an RCTSurfaceHostingProxyRootView");
|
||||
|
||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTSurfaceHostingProxyRootView init]", nil);
|
||||
|
||||
_bridge = bridge;
|
||||
|
||||
if (!bridge.isLoading) {
|
||||
[bridge.performanceLogger markStartForTag:RCTPLTTI];
|
||||
}
|
||||
|
||||
// `RCTRootViewSizeFlexibilityNone` is the RCTRootView's default.
|
||||
RCTSurfaceSizeMeasureMode sizeMeasureMode = convertToSurfaceSizeMeasureMode(RCTRootViewSizeFlexibilityNone);
|
||||
|
||||
RCTSurface *surface = [[self class] createSurfaceWithBridge:bridge
|
||||
moduleName:moduleName
|
||||
initialProperties:initialProperties];
|
||||
[surface start];
|
||||
if (self = [super initWithSurface:surface sizeMeasureMode:sizeMeasureMode]) {
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
launchOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:bundleURL moduleProvider:nil launchOptions:launchOptions];
|
||||
|
||||
return [self initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
||||
|
||||
#pragma mark proxy methods to RCTSurfaceHostingView
|
||||
|
||||
- (NSString *)moduleName
|
||||
{
|
||||
return super.surface.moduleName;
|
||||
}
|
||||
|
||||
- (UIView *)contentView
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSNumber *)reactTag
|
||||
{
|
||||
return super.surface.rootViewTag;
|
||||
}
|
||||
|
||||
- (RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
return convertToRootViewSizeFlexibility(super.sizeMeasureMode);
|
||||
}
|
||||
|
||||
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
super.sizeMeasureMode = convertToSurfaceSizeMeasureMode(sizeFlexibility);
|
||||
}
|
||||
|
||||
- (NSDictionary *)appProperties
|
||||
{
|
||||
return super.surface.properties;
|
||||
}
|
||||
|
||||
- (void)setAppProperties:(NSDictionary *)appProperties
|
||||
{
|
||||
[super.surface setProperties:appProperties];
|
||||
}
|
||||
|
||||
- (UIView *)loadingView
|
||||
{
|
||||
return super.activityIndicatorViewFactory ? super.activityIndicatorViewFactory() : nil;
|
||||
}
|
||||
|
||||
- (void)setLoadingView:(UIView *)loadingView
|
||||
{
|
||||
super.activityIndicatorViewFactory = ^UIView *(void)
|
||||
{
|
||||
return loadingView;
|
||||
};
|
||||
}
|
||||
|
||||
#pragma mark RCTSurfaceDelegate proxying
|
||||
|
||||
- (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
|
||||
{
|
||||
[super surface:surface didChangeStage:stage];
|
||||
if (RCTSurfaceStageIsRunning(stage)) {
|
||||
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize
|
||||
{
|
||||
[super surface:surface didChangeIntrinsicSize:intrinsicSize];
|
||||
|
||||
[_delegate rootViewDidChangeIntrinsicSize:(RCTRootView *)self];
|
||||
}
|
||||
|
||||
#pragma mark legacy
|
||||
|
||||
- (UIViewController *)reactViewController
|
||||
{
|
||||
return _reactViewController ?: [super reactViewController];
|
||||
}
|
||||
|
||||
#pragma mark unsupported
|
||||
|
||||
- (void)cancelTouches
|
||||
{
|
||||
// Not supported.
|
||||
}
|
||||
|
||||
@end
|
77
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h
generated
vendored
Normal file
77
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTSurfaceDelegate.h>
|
||||
#import <React/RCTSurfaceSizeMeasureMode.h>
|
||||
#import <React/RCTSurfaceStage.h>
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTSurface;
|
||||
|
||||
typedef UIView *_Nullable (^RCTSurfaceHostingViewActivityIndicatorViewFactory)(void);
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* UIView subclass which providers interoperability between UIKit and
|
||||
* Surface regarding layout and life-cycle.
|
||||
* This class can be used as easy-to-use general purpose integration point
|
||||
* of ReactNative-powered experiences in UIKit based apps.
|
||||
*/
|
||||
@interface RCTSurfaceHostingView : UIView <RCTSurfaceDelegate>
|
||||
|
||||
/**
|
||||
* Create an instance of RCTSurface to be hosted.
|
||||
*/
|
||||
+ (RCTSurface *)createSurfaceWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties;
|
||||
|
||||
/**
|
||||
* Designated initializer.
|
||||
* Instanciates a view with given Surface object.
|
||||
* Note: The view retains the surface object.
|
||||
*/
|
||||
- (instancetype)initWithSurface:(RCTSurface *)surface
|
||||
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Convenience initializer.
|
||||
* Instanciates a Surface object with given `bridge`, `moduleName`, and
|
||||
* `initialProperties`, and then use it to instanciate a view.
|
||||
*/
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode;
|
||||
|
||||
/**
|
||||
* Surface object which is currently using to power the view.
|
||||
* Read-only.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) RCTSurface *surface;
|
||||
|
||||
/**
|
||||
* Size measure mode which are defining relationship between UIKit and ReactNative
|
||||
* layout approaches.
|
||||
* Defaults to `RCTSurfaceSizeMeasureModeWidthAtMost | RCTSurfaceSizeMeasureModeHeightAtMost`.
|
||||
*/
|
||||
@property (nonatomic, assign) RCTSurfaceSizeMeasureMode sizeMeasureMode;
|
||||
|
||||
/**
|
||||
* Activity indicator factory.
|
||||
* A hosting view may use this block to instantiate and display custom activity
|
||||
* (loading) indicator (aka "spinner") when it needed.
|
||||
* Defaults to `nil` (no activity indicator).
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) RCTSurfaceHostingViewActivityIndicatorViewFactory activityIndicatorViewFactory;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
247
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm
generated
vendored
Normal file
247
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTSurfaceHostingView.h"
|
||||
|
||||
#import "RCTConstants.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTSurface.h"
|
||||
#import "RCTSurfaceDelegate.h"
|
||||
#import "RCTSurfaceView.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@interface RCTSurfaceHostingView ()
|
||||
|
||||
@property (nonatomic, assign) BOOL isActivityIndicatorViewVisible;
|
||||
@property (nonatomic, assign) BOOL isSurfaceViewVisible;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTSurfaceHostingView {
|
||||
UIView *_Nullable _activityIndicatorView;
|
||||
UIView *_Nullable _surfaceView;
|
||||
RCTSurfaceStage _stage;
|
||||
}
|
||||
|
||||
+ (RCTSurface *)createSurfaceWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
{
|
||||
return [[RCTSurface alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(-(nullable instancetype)initWithCoder : (NSCoder *)coder)
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
initialProperties:(NSDictionary *)initialProperties
|
||||
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
|
||||
{
|
||||
RCTSurface *surface = [[self class] createSurfaceWithBridge:bridge
|
||||
moduleName:moduleName
|
||||
initialProperties:initialProperties];
|
||||
[surface start];
|
||||
return [self initWithSurface:surface sizeMeasureMode:sizeMeasureMode];
|
||||
}
|
||||
|
||||
- (instancetype)initWithSurface:(RCTSurface *)surface sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
|
||||
{
|
||||
if (self = [super initWithFrame:CGRectZero]) {
|
||||
_surface = surface;
|
||||
_sizeMeasureMode = sizeMeasureMode;
|
||||
|
||||
_surface.delegate = self;
|
||||
_stage = surface.stage;
|
||||
[self _updateViews];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_surface stop];
|
||||
}
|
||||
|
||||
- (void)setFrame:(CGRect)frame
|
||||
{
|
||||
[super setFrame:frame];
|
||||
|
||||
CGSize minimumSize;
|
||||
CGSize maximumSize;
|
||||
|
||||
RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
|
||||
self.bounds.size, _sizeMeasureMode, &minimumSize, &maximumSize);
|
||||
|
||||
[_surface setMinimumSize:minimumSize maximumSize:maximumSize];
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
if (RCTSurfaceStageIsPreparing(_stage)) {
|
||||
if (_activityIndicatorView) {
|
||||
return _activityIndicatorView.intrinsicContentSize;
|
||||
}
|
||||
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
return _surface.intrinsicSize;
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
if (RCTSurfaceStageIsPreparing(_stage)) {
|
||||
if (_activityIndicatorView) {
|
||||
return [_activityIndicatorView sizeThatFits:size];
|
||||
}
|
||||
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
CGSize minimumSize;
|
||||
CGSize maximumSize;
|
||||
|
||||
RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(size, _sizeMeasureMode, &minimumSize, &maximumSize);
|
||||
|
||||
return [_surface sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize];
|
||||
}
|
||||
|
||||
- (void)setStage:(RCTSurfaceStage)stage
|
||||
{
|
||||
if (stage == _stage) {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL shouldInvalidateLayout = RCTSurfaceStageIsRunning(stage) != RCTSurfaceStageIsRunning(_stage) ||
|
||||
RCTSurfaceStageIsPreparing(stage) != RCTSurfaceStageIsPreparing(_stage);
|
||||
|
||||
_stage = stage;
|
||||
|
||||
if (shouldInvalidateLayout) {
|
||||
[self _invalidateLayout];
|
||||
[self _updateViews];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
|
||||
{
|
||||
if (sizeMeasureMode == _sizeMeasureMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
_sizeMeasureMode = sizeMeasureMode;
|
||||
[self _invalidateLayout];
|
||||
}
|
||||
|
||||
#pragma mark - isActivityIndicatorViewVisible
|
||||
|
||||
- (void)setIsActivityIndicatorViewVisible:(BOOL)visible
|
||||
{
|
||||
if (_isActivityIndicatorViewVisible == visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
_isActivityIndicatorViewVisible = visible;
|
||||
|
||||
if (visible) {
|
||||
if (_activityIndicatorViewFactory) {
|
||||
_activityIndicatorView = _activityIndicatorViewFactory();
|
||||
_activityIndicatorView.frame = self.bounds;
|
||||
_activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[self addSubview:_activityIndicatorView];
|
||||
}
|
||||
} else {
|
||||
[_activityIndicatorView removeFromSuperview];
|
||||
_activityIndicatorView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - isSurfaceViewVisible
|
||||
|
||||
- (void)setIsSurfaceViewVisible:(BOOL)visible
|
||||
{
|
||||
if (_isSurfaceViewVisible == visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
_isSurfaceViewVisible = visible;
|
||||
|
||||
if (visible) {
|
||||
_surfaceView = _surface.view;
|
||||
_surfaceView.frame = self.bounds;
|
||||
_surfaceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[self addSubview:_surfaceView];
|
||||
} else {
|
||||
[_surfaceView removeFromSuperview];
|
||||
_surfaceView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - activityIndicatorViewFactory
|
||||
|
||||
- (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorViewFactory)activityIndicatorViewFactory
|
||||
{
|
||||
_activityIndicatorViewFactory = activityIndicatorViewFactory;
|
||||
if (_isActivityIndicatorViewVisible) {
|
||||
self.isActivityIndicatorViewVisible = NO;
|
||||
self.isActivityIndicatorViewVisible = YES;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITraitCollection updates
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{
|
||||
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Private stuff
|
||||
|
||||
- (void)_invalidateLayout
|
||||
{
|
||||
[self invalidateIntrinsicContentSize];
|
||||
[self.superview setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)_updateViews
|
||||
{
|
||||
self.isSurfaceViewVisible = RCTSurfaceStageIsRunning(_stage);
|
||||
self.isActivityIndicatorViewVisible = RCTSurfaceStageIsPreparing(_stage);
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
[super didMoveToWindow];
|
||||
[self _updateViews];
|
||||
}
|
||||
|
||||
#pragma mark - RCTSurfaceDelegate
|
||||
|
||||
- (void)surface:(__unused RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
|
||||
{
|
||||
RCTExecuteOnMainQueue(^{
|
||||
[self setStage:stage];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)surface:(__unused RCTSurface *)surface didChangeIntrinsicSize:(__unused CGSize)intrinsicSize
|
||||
{
|
||||
RCTExecuteOnMainQueue(^{
|
||||
[self _invalidateLayout];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
32
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h
generated
vendored
Normal file
32
node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
/**
|
||||
* Bitmask defines how size constrains from `-[UIView sizeThatFits:]`
|
||||
* are translated to `-[RCTSurface sizeThatFitsMinimumSize:maximumSize:]`.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSInteger, RCTSurfaceSizeMeasureMode) {
|
||||
RCTSurfaceSizeMeasureModeWidthUndefined = 0 << 0,
|
||||
RCTSurfaceSizeMeasureModeWidthExact = 1 << 0,
|
||||
RCTSurfaceSizeMeasureModeWidthAtMost = 2 << 0,
|
||||
RCTSurfaceSizeMeasureModeHeightUndefined = 0 << 2,
|
||||
RCTSurfaceSizeMeasureModeHeightExact = 1 << 2,
|
||||
RCTSurfaceSizeMeasureModeHeightAtMost = 2 << 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns size constraints based on `size` and `sizeMeasureMode`.
|
||||
*/
|
||||
RCT_EXTERN void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
|
||||
CGSize size,
|
||||
RCTSurfaceSizeMeasureMode sizeMeasureMode,
|
||||
CGSize *minimumSize,
|
||||
CGSize *maximumSize);
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user