Updates from Thu 9 Apr
- [React Native] Fix RCTText crashes | Alex Akers - Ensure that NSLocationWhenInUseUsageDescription is set, throw error if not | Alex Kotliarskyi - [ReactNative] fix exception handler method name | Spencer Ahrens - [ReactNative] Re-configure horizontal swipe animations | Eric Vicenti - [ReactNative] <Text>: apply the fontWeight correctly if fontFamily style is also present | Kevin Gozali - [MAdMan] Dimensions.get('window') considered harmful | Philipp von Weitershausen - Navigator: Changed transitioner background color to 'transparent' | Eric Vicenti - [react-native] Listen on all IPv6 interfaces | Ben Alpert - [react-packager] Don't depend on error.stack being available | Amjad Masad - [ReactNative] fixup AnimationExperimental a bit | Spencer Ahrens - [react-packager] Implement new style asset packaging (with dimensions) | Amjad Masad - [React Native] RCT_EXPORT lvl.2 | Alex Akers - [react_native] Implement TextInput end editing | Andrei Coman - [react_native] Make TextInput focus, blur, dismiss and show keyboard work | Andrei Coman - Added non-class-scanning-based approach fror registering js methods | Nick Lockwood - [ReactNative] Update package.json | Christopher Chedeau - [ReactNative] Do flow check when running packager | Spencer Ahrens - [ReactNative] Fix typo/bug in Navigator._completeTransition | Eric Vicenti - [ReactNative] Fix Navigator exception when touching during transition | Eric Vicenti - [ReactNative] Remove bridge retaining cycles | Tadeu Zagallo - [ReactNative] Fix and re-add WebView executor | Tadeu Zagallo
This commit is contained in:
parent
83fbef5dd1
commit
0686b0147c
|
@ -73,19 +73,29 @@ class Tile extends React.Component {
|
||||||
if (tile.isNew()) {
|
if (tile.isNew()) {
|
||||||
offset.opacity = 0;
|
offset.opacity = 0;
|
||||||
} else {
|
} else {
|
||||||
var point = [
|
var point = {
|
||||||
animationPosition(tile.toColumn()),
|
x: animationPosition(tile.toColumn()),
|
||||||
animationPosition(tile.toRow()),
|
y: animationPosition(tile.toRow()),
|
||||||
];
|
};
|
||||||
AnimationExperimental.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {position: point});
|
AnimationExperimental.startAnimation({
|
||||||
|
node: this.refs['this'],
|
||||||
|
duration: 100,
|
||||||
|
easing: 'easeInOutQuad',
|
||||||
|
property: 'position',
|
||||||
|
toValue: point,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
AnimationExperimental.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {opacity: 1});
|
AnimationExperimental.startAnimation({
|
||||||
|
node: this.refs['this'],
|
||||||
|
duration: 100,
|
||||||
|
easing: 'easeInOutQuad',
|
||||||
|
property: 'opacity',
|
||||||
|
toValue: 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
00481BE81AC0C86700671115 /* libRCTWebSocketDebugger.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00481BE61AC0C7FA00671115 /* libRCTWebSocketDebugger.a */; };
|
00481BE81AC0C86700671115 /* libRCTWebSocketDebugger.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00481BE61AC0C7FA00671115 /* libRCTWebSocketDebugger.a */; };
|
||||||
00481BEA1AC0C89D00671115 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 00481BE91AC0C89D00671115 /* libicucore.dylib */; };
|
|
||||||
008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; };
|
008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; };
|
||||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
||||||
00C302E61ABCBA2D00DB3ED1 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302B41ABCB8E700DB3ED1 /* libRCTAdSupport.a */; };
|
00C302E61ABCBA2D00DB3ED1 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302B41ABCB8E700DB3ED1 /* libRCTAdSupport.a */; };
|
||||||
|
@ -116,7 +115,6 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
00481BEA1AC0C89D00671115 /* libicucore.dylib in Frameworks */,
|
|
||||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||||
00481BE81AC0C86700671115 /* libRCTWebSocketDebugger.a in Frameworks */,
|
00481BE81AC0C86700671115 /* libRCTWebSocketDebugger.a in Frameworks */,
|
||||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||||
|
|
|
@ -36,5 +36,7 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
004D28A31AAF61C70097A701 /* UIExplorerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 004D28A21AAF61C70097A701 /* UIExplorerTests.m */; };
|
004D28A31AAF61C70097A701 /* UIExplorerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 004D28A21AAF61C70097A701 /* UIExplorerTests.m */; };
|
||||||
00D2771A1AB8C3E100DC1E48 /* libRCTWebSocketDebugger.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D277131AB8C2C700DC1E48 /* libRCTWebSocketDebugger.a */; };
|
00D2771A1AB8C3E100DC1E48 /* libRCTWebSocketDebugger.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D277131AB8C2C700DC1E48 /* libRCTWebSocketDebugger.a */; };
|
||||||
00D2771C1AB8C55500DC1E48 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D2771B1AB8C55500DC1E48 /* libicucore.dylib */; };
|
|
||||||
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
|
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
|
||||||
134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
|
134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
|
||||||
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; };
|
||||||
|
@ -118,7 +117,6 @@
|
||||||
004D28A11AAF61C70097A701 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
004D28A11AAF61C70097A701 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
004D28A21AAF61C70097A701 /* UIExplorerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIExplorerTests.m; sourceTree = "<group>"; };
|
004D28A21AAF61C70097A701 /* UIExplorerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIExplorerTests.m; sourceTree = "<group>"; };
|
||||||
00D2770E1AB8C2C700DC1E48 /* RCTWebSocketDebugger.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocketDebugger.xcodeproj; path = ../../Libraries/RCTWebSocketDebugger/RCTWebSocketDebugger.xcodeproj; sourceTree = "<group>"; };
|
00D2770E1AB8C2C700DC1E48 /* RCTWebSocketDebugger.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocketDebugger.xcodeproj; path = ../../Libraries/RCTWebSocketDebugger/RCTWebSocketDebugger.xcodeproj; sourceTree = "<group>"; };
|
||||||
00D2771B1AB8C55500DC1E48 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
|
|
||||||
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
@ -150,7 +148,6 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
00D2771C1AB8C55500DC1E48 /* libicucore.dylib in Frameworks */,
|
|
||||||
14AADF051AC3DBB1002390C9 /* libReact.a in Frameworks */,
|
14AADF051AC3DBB1002390C9 /* libReact.a in Frameworks */,
|
||||||
00D2771A1AB8C3E100DC1E48 /* libRCTWebSocketDebugger.a in Frameworks */,
|
00D2771A1AB8C3E100DC1E48 /* libRCTWebSocketDebugger.a in Frameworks */,
|
||||||
58005BF21ABA80A60062E044 /* libRCTTest.a in Frameworks */,
|
58005BF21ABA80A60062E044 /* libRCTTest.a in Frameworks */,
|
||||||
|
@ -207,7 +204,6 @@
|
||||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
|
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
|
||||||
00D2770E1AB8C2C700DC1E48 /* RCTWebSocketDebugger.xcodeproj */,
|
00D2770E1AB8C2C700DC1E48 /* RCTWebSocketDebugger.xcodeproj */,
|
||||||
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */,
|
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */,
|
||||||
00D2771B1AB8C55500DC1E48 /* libicucore.dylib */,
|
|
||||||
);
|
);
|
||||||
name = Libraries;
|
name = Libraries;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
|
@ -72,7 +72,8 @@
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable>
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||||
|
@ -90,7 +91,8 @@
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
debugDocumentVersioning = "YES">
|
debugDocumentVersioning = "YES">
|
||||||
<BuildableProductRunnable>
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||||
|
|
|
@ -11,14 +11,17 @@
|
||||||
|
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
|
|
||||||
@interface RCTActionSheetManager() <UIActionSheetDelegate>
|
@interface RCTActionSheetManager () <UIActionSheetDelegate>
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTActionSheetManager {
|
@implementation RCTActionSheetManager
|
||||||
|
{
|
||||||
NSMutableDictionary *_callbacks;
|
NSMutableDictionary *_callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -27,12 +30,10 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showActionSheetWithOptions:(NSDictionary *)options
|
RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
|
||||||
failureCallback:(RCTResponseSenderBlock)failureCallback
|
failureCallback:(RCTResponseSenderBlock)failureCallback
|
||||||
successCallback:(RCTResponseSenderBlock)successCallback
|
successCallback:(RCTResponseSenderBlock)successCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
|
UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
|
||||||
|
|
||||||
|
@ -62,12 +63,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showShareActionSheetWithOptions:(NSDictionary *)options
|
RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
|
||||||
failureCallback:(RCTResponseSenderBlock)failureCallback
|
failureCallback:(RCTResponseSenderBlock)failureCallback
|
||||||
successCallback:(RCTResponseSenderBlock)successCallback
|
successCallback:(RCTResponseSenderBlock)successCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
NSMutableArray *items = [NSMutableArray array];
|
NSMutableArray *items = [NSMutableArray array];
|
||||||
id message = options[@"message"];
|
id message = options[@"message"];
|
||||||
|
@ -134,7 +133,7 @@
|
||||||
|
|
||||||
#pragma mark Private
|
#pragma mark Private
|
||||||
|
|
||||||
static NSString *keyForInstance(id instance)
|
NS_INLINE NSString *keyForInstance(id instance)
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"%p", instance];
|
return [NSString stringWithFormat:@"%p", instance];
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,11 @@
|
||||||
|
|
||||||
@implementation RCTAdSupport
|
@implementation RCTAdSupport
|
||||||
|
|
||||||
- (void)getAdvertisingId:(RCTResponseSenderBlock)callback withErrorCallback:(RCTResponseSenderBlock)errorCallback
|
RCT_EXPORT_MODULE()
|
||||||
{
|
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(getAdvertisingId:(RCTResponseSenderBlock)callback
|
||||||
|
withErrorCallback:(RCTResponseSenderBlock)errorCallback)
|
||||||
|
{
|
||||||
if ([ASIdentifierManager class]) {
|
if ([ASIdentifierManager class]) {
|
||||||
callback(@[[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]]);
|
callback(@[[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,12 +23,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getAdvertisingTrackingEnabled:(RCTResponseSenderBlock)callback withErrorCallback:(RCTResponseSenderBlock)errorCallback
|
RCT_EXPORT_METHOD(getAdvertisingTrackingEnabled:(RCTResponseSenderBlock)callback
|
||||||
|
withErrorCallback:(RCTResponseSenderBlock)errorCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if ([ASIdentifierManager class]) {
|
if ([ASIdentifierManager class]) {
|
||||||
bool hasTracking = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
|
BOOL hasTracking = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
|
||||||
callback(@[@(hasTracking)]);
|
callback(@[@(hasTracking)]);
|
||||||
} else {
|
} else {
|
||||||
return errorCallback(@[@"as_identifier_unavailable"]);
|
return errorCallback(@[@"as_identifier_unavailable"]);
|
||||||
|
|
|
@ -16,6 +16,17 @@ var AnimationUtils = require('AnimationUtils');
|
||||||
|
|
||||||
type EasingFunction = (t: number) => number;
|
type EasingFunction = (t: number) => number;
|
||||||
|
|
||||||
|
var Properties = {
|
||||||
|
opacity: true,
|
||||||
|
position: true,
|
||||||
|
positionX: true,
|
||||||
|
positionY: true,
|
||||||
|
rotation: true,
|
||||||
|
scaleXY: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ValueType = number | Array<number> | {[key: string]: number};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an experimental module that is under development, incomplete,
|
* This is an experimental module that is under development, incomplete,
|
||||||
* potentially buggy, not used in any production apps, and will probably change
|
* potentially buggy, not used in any production apps, and will probably change
|
||||||
|
@ -24,24 +35,34 @@ type EasingFunction = (t: number) => number;
|
||||||
* Use at your own risk.
|
* Use at your own risk.
|
||||||
*/
|
*/
|
||||||
var AnimationExperimental = {
|
var AnimationExperimental = {
|
||||||
Mixin: require('AnimationExperimentalMixin'),
|
|
||||||
|
|
||||||
startAnimation: function(
|
startAnimation: function(
|
||||||
node: any,
|
anim: {
|
||||||
duration: number,
|
node: any;
|
||||||
delay: number,
|
duration: number;
|
||||||
easing: (string | EasingFunction),
|
easing: ($Enum<typeof AnimationUtils.Defaults> | EasingFunction);
|
||||||
properties: {[key: string]: any}
|
property: $Enum<typeof Properties>;
|
||||||
|
toValue: ValueType;
|
||||||
|
fromValue?: ValueType;
|
||||||
|
delay?: number;
|
||||||
|
},
|
||||||
|
callback?: ?(finished: bool) => void
|
||||||
): number {
|
): number {
|
||||||
var nodeHandle = +node.getNodeHandle();
|
var nodeHandle = anim.node.getNodeHandle();
|
||||||
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
var easingSample = AnimationUtils.evaluateEasingFunction(
|
||||||
var tag: number = RCTAnimationManager.startAnimation(
|
anim.duration,
|
||||||
|
anim.easing
|
||||||
|
);
|
||||||
|
var tag: number = AnimationUtils.allocateTag();
|
||||||
|
var props = {};
|
||||||
|
props[anim.property] = {to: anim.toValue};
|
||||||
|
RCTAnimationManager.startAnimation(
|
||||||
nodeHandle,
|
nodeHandle,
|
||||||
AnimationUtils.allocateTag(),
|
tag,
|
||||||
duration,
|
anim.duration,
|
||||||
delay,
|
anim.delay,
|
||||||
easingSample,
|
easingSample,
|
||||||
properties
|
props,
|
||||||
|
callback
|
||||||
);
|
);
|
||||||
return tag;
|
return tag;
|
||||||
},
|
},
|
||||||
|
@ -51,4 +72,18 @@ var AnimationExperimental = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (__DEV__) {
|
||||||
|
if (RCTAnimationManager && RCTAnimationManager.Properties) {
|
||||||
|
var a = Object.keys(Properties);
|
||||||
|
var b = RCTAnimationManager.Properties;
|
||||||
|
var diff = a.filter((i) => b.indexOf(i) < 0).concat(
|
||||||
|
b.filter((i) => a.indexOf(i) < 0)
|
||||||
|
);
|
||||||
|
if (diff.length > 0) {
|
||||||
|
throw new Error('JS animation properties don\'t match native properties.' +
|
||||||
|
JSON.stringify(diff, null, ' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = AnimationExperimental;
|
module.exports = AnimationExperimental;
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2015-present, Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*
|
|
||||||
* @providesModule AnimationExperimentalMixin
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var AnimationUtils = require('AnimationUtils');
|
|
||||||
var RCTAnimationManager = require('NativeModules').AnimationExperimentalManager;
|
|
||||||
|
|
||||||
var invariant = require('invariant');
|
|
||||||
|
|
||||||
type EasingFunction = (t: number) => number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an experimental module that is under development, incomplete,
|
|
||||||
* potentially buggy, not used in any production apps, and will probably change
|
|
||||||
* in non-backward compatible ways.
|
|
||||||
*
|
|
||||||
* Use at your own risk.
|
|
||||||
*/
|
|
||||||
var AnimationExperimentalMixin = {
|
|
||||||
getInitialState: function(): Object {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
|
|
||||||
startAnimation: function(
|
|
||||||
refKey: string,
|
|
||||||
duration: number,
|
|
||||||
delay: number,
|
|
||||||
easing: (string | EasingFunction),
|
|
||||||
properties: {[key: string]: any}
|
|
||||||
): number {
|
|
||||||
var ref = this.refs[refKey];
|
|
||||||
invariant(
|
|
||||||
ref,
|
|
||||||
'Invalid refKey ' + refKey + '; ' +
|
|
||||||
'valid refs: ' + JSON.stringify(Object.keys(this.refs))
|
|
||||||
);
|
|
||||||
|
|
||||||
var nodeHandle = +ref.getNodeHandle();
|
|
||||||
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
|
||||||
var tag: number = RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
|
||||||
return tag;
|
|
||||||
},
|
|
||||||
|
|
||||||
stopAnimation: function(tag: number) {
|
|
||||||
RCTAnimationManager.stopAnimation(tag);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AnimationExperimentalMixin;
|
|
|
@ -20,27 +20,27 @@
|
||||||
type EasingFunction = (t: number) => number;
|
type EasingFunction = (t: number) => number;
|
||||||
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
easeInQuad: function(t) {
|
easeInQuad: function(t: number): number {
|
||||||
return t * t;
|
return t * t;
|
||||||
},
|
},
|
||||||
easeOutQuad: function(t) {
|
easeOutQuad: function(t: number): number {
|
||||||
return -t * (t - 2);
|
return -t * (t - 2);
|
||||||
},
|
},
|
||||||
easeInOutQuad: function(t) {
|
easeInOutQuad: function(t: number): number {
|
||||||
t = t * 2;
|
t = t * 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
return 0.5 * t * t;
|
return 0.5 * t * t;
|
||||||
}
|
}
|
||||||
return -((t - 1) * (t - 3) - 1) / 2;
|
return -((t - 1) * (t - 3) - 1) / 2;
|
||||||
},
|
},
|
||||||
easeInCubic: function(t) {
|
easeInCubic: function(t: number): number {
|
||||||
return t * t * t;
|
return t * t * t;
|
||||||
},
|
},
|
||||||
easeOutCubic: function(t) {
|
easeOutCubic: function(t: number): number {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return t * t * t + 1;
|
return t * t * t + 1;
|
||||||
},
|
},
|
||||||
easeInOutCubic: function(t) {
|
easeInOutCubic: function(t: number): number {
|
||||||
t *= 2;
|
t *= 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
return 0.5 * t * t * t;
|
return 0.5 * t * t * t;
|
||||||
|
@ -48,14 +48,14 @@ var defaults = {
|
||||||
t -= 2;
|
t -= 2;
|
||||||
return (t * t * t + 2) / 2;
|
return (t * t * t + 2) / 2;
|
||||||
},
|
},
|
||||||
easeInQuart: function(t) {
|
easeInQuart: function(t: number): number {
|
||||||
return t * t * t * t;
|
return t * t * t * t;
|
||||||
},
|
},
|
||||||
easeOutQuart: function(t) {
|
easeOutQuart: function(t: number): number {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return -(t * t * t * t - 1);
|
return -(t * t * t * t - 1);
|
||||||
},
|
},
|
||||||
easeInOutQuart: function(t) {
|
easeInOutQuart: function(t: number): number {
|
||||||
t *= 2;
|
t *= 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
return 0.5 * t * t * t * t;
|
return 0.5 * t * t * t * t;
|
||||||
|
@ -63,14 +63,14 @@ var defaults = {
|
||||||
t -= 2;
|
t -= 2;
|
||||||
return -(t * t * t * t - 2) / 2;
|
return -(t * t * t * t - 2) / 2;
|
||||||
},
|
},
|
||||||
easeInQuint: function(t) {
|
easeInQuint: function(t: number): number {
|
||||||
return t * t * t * t * t;
|
return t * t * t * t * t;
|
||||||
},
|
},
|
||||||
easeOutQuint: function(t) {
|
easeOutQuint: function(t: number): number {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return t * t * t * t * t + 1;
|
return t * t * t * t * t + 1;
|
||||||
},
|
},
|
||||||
easeInOutQuint: function(t) {
|
easeInOutQuint: function(t: number): number {
|
||||||
t *= 2;
|
t *= 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
return (t * t * t * t * t) / 2;
|
return (t * t * t * t * t) / 2;
|
||||||
|
@ -78,22 +78,22 @@ var defaults = {
|
||||||
t -= 2;
|
t -= 2;
|
||||||
return (t * t * t * t * t + 2) / 2;
|
return (t * t * t * t * t + 2) / 2;
|
||||||
},
|
},
|
||||||
easeInSine: function(t) {
|
easeInSine: function(t: number): number {
|
||||||
return -Math.cos(t * (Math.PI / 2)) + 1;
|
return -Math.cos(t * (Math.PI / 2)) + 1;
|
||||||
},
|
},
|
||||||
easeOutSine: function(t) {
|
easeOutSine: function(t: number): number {
|
||||||
return Math.sin(t * (Math.PI / 2));
|
return Math.sin(t * (Math.PI / 2));
|
||||||
},
|
},
|
||||||
easeInOutSine: function(t) {
|
easeInOutSine: function(t: number): number {
|
||||||
return -(Math.cos(Math.PI * t) - 1) / 2;
|
return -(Math.cos(Math.PI * t) - 1) / 2;
|
||||||
},
|
},
|
||||||
easeInExpo: function(t) {
|
easeInExpo: function(t: number): number {
|
||||||
return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
|
return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
|
||||||
},
|
},
|
||||||
easeOutExpo: function(t) {
|
easeOutExpo: function(t: number): number {
|
||||||
return (t === 1) ? 1 : (-Math.pow(2, -10 * t) + 1);
|
return (t === 1) ? 1 : (-Math.pow(2, -10 * t) + 1);
|
||||||
},
|
},
|
||||||
easeInOutExpo: function(t) {
|
easeInOutExpo: function(t: number): number {
|
||||||
if (t === 0) {
|
if (t === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -106,14 +106,14 @@ var defaults = {
|
||||||
}
|
}
|
||||||
return (-Math.pow(2, -10 * (t - 1)) + 2) / 2;
|
return (-Math.pow(2, -10 * (t - 1)) + 2) / 2;
|
||||||
},
|
},
|
||||||
easeInCirc: function(t) {
|
easeInCirc: function(t: number): number {
|
||||||
return -(Math.sqrt(1 - t * t) - 1);
|
return -(Math.sqrt(1 - t * t) - 1);
|
||||||
},
|
},
|
||||||
easeOutCirc: function(t) {
|
easeOutCirc: function(t: number): number {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return Math.sqrt(1 - t * t);
|
return Math.sqrt(1 - t * t);
|
||||||
},
|
},
|
||||||
easeInOutCirc: function(t) {
|
easeInOutCirc: function(t: number): number {
|
||||||
t *= 2;
|
t *= 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
return -(Math.sqrt(1 - t * t) - 1) / 2;
|
return -(Math.sqrt(1 - t * t) - 1) / 2;
|
||||||
|
@ -121,7 +121,7 @@ var defaults = {
|
||||||
t -= 2;
|
t -= 2;
|
||||||
return (Math.sqrt(1 - t * t) + 1) / 2;
|
return (Math.sqrt(1 - t * t) + 1) / 2;
|
||||||
},
|
},
|
||||||
easeInElastic: function(t) {
|
easeInElastic: function(t: number): number {
|
||||||
var s = 1.70158;
|
var s = 1.70158;
|
||||||
var p = 0.3;
|
var p = 0.3;
|
||||||
if (t === 0) {
|
if (t === 0) {
|
||||||
|
@ -134,7 +134,7 @@ var defaults = {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
||||||
},
|
},
|
||||||
easeOutElastic: function(t) {
|
easeOutElastic: function(t: number): number {
|
||||||
var s = 1.70158;
|
var s = 1.70158;
|
||||||
var p = 0.3;
|
var p = 0.3;
|
||||||
if (t === 0) {
|
if (t === 0) {
|
||||||
|
@ -146,7 +146,7 @@ var defaults = {
|
||||||
var s = p / (2 * Math.PI) * Math.asin(1);
|
var s = p / (2 * Math.PI) * Math.asin(1);
|
||||||
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
||||||
},
|
},
|
||||||
easeInOutElastic: function(t) {
|
easeInOutElastic: function(t: number): number {
|
||||||
var s = 1.70158;
|
var s = 1.70158;
|
||||||
var p = 0.3 * 1.5;
|
var p = 0.3 * 1.5;
|
||||||
if (t === 0) {
|
if (t === 0) {
|
||||||
|
@ -164,16 +164,16 @@ var defaults = {
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) / 2 + 1;
|
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) / 2 + 1;
|
||||||
},
|
},
|
||||||
easeInBack: function(t) {
|
easeInBack: function(t: number): number {
|
||||||
var s = 1.70158;
|
var s = 1.70158;
|
||||||
return t * t * ((s + 1) * t - s);
|
return t * t * ((s + 1) * t - s);
|
||||||
},
|
},
|
||||||
easeOutBack: function(t) {
|
easeOutBack: function(t: number): number {
|
||||||
var s = 1.70158;
|
var s = 1.70158;
|
||||||
t -= 1;
|
t -= 1;
|
||||||
return (t * t * ((s + 1) * t + s) + 1);
|
return (t * t * ((s + 1) * t + s) + 1);
|
||||||
},
|
},
|
||||||
easeInOutBack: function(t) {
|
easeInOutBack: function(t: number): number {
|
||||||
var s = 1.70158 * 1.525;
|
var s = 1.70158 * 1.525;
|
||||||
t *= 2;
|
t *= 2;
|
||||||
if (t < 1) {
|
if (t < 1) {
|
||||||
|
@ -182,10 +182,10 @@ var defaults = {
|
||||||
t -= 2;
|
t -= 2;
|
||||||
return (t * t * ((s + 1) * t + s) + 2) / 2;
|
return (t * t * ((s + 1) * t + s) + 2) / 2;
|
||||||
},
|
},
|
||||||
easeInBounce: function(t) {
|
easeInBounce: function(t: number): number {
|
||||||
return 1 - this.easeOutBounce(1 - t);
|
return 1 - this.easeOutBounce(1 - t);
|
||||||
},
|
},
|
||||||
easeOutBounce: function(t) {
|
easeOutBounce: function(t: number): number {
|
||||||
if (t < (1 / 2.75)) {
|
if (t < (1 / 2.75)) {
|
||||||
return 7.5625 * t * t;
|
return 7.5625 * t * t;
|
||||||
} else if (t < (2 / 2.75)) {
|
} else if (t < (2 / 2.75)) {
|
||||||
|
@ -199,7 +199,7 @@ var defaults = {
|
||||||
return 7.5625 * t * t + 0.984375;
|
return 7.5625 * t * t + 0.984375;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
easeInOutBounce: function(t) {
|
easeInOutBounce: function(t: number): number {
|
||||||
if (t < 0.5) {
|
if (t < 0.5) {
|
||||||
return this.easeInBounce(t * 2) / 2;
|
return this.easeInBounce(t * 2) / 2;
|
||||||
}
|
}
|
||||||
|
@ -234,4 +234,6 @@ module.exports = {
|
||||||
|
|
||||||
return samples;
|
return samples;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Defaults: defaults,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,18 +17,20 @@ var RCTUIManager = require('NativeModules').UIManager;
|
||||||
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
|
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
|
||||||
var keyMirror = require('keyMirror');
|
var keyMirror = require('keyMirror');
|
||||||
|
|
||||||
var Types = keyMirror({
|
var TypesEnum = {
|
||||||
spring: true,
|
spring: true,
|
||||||
linear: true,
|
linear: true,
|
||||||
easeInEaseOut: true,
|
easeInEaseOut: true,
|
||||||
easeIn: true,
|
easeIn: true,
|
||||||
easeOut: true,
|
easeOut: true,
|
||||||
});
|
};
|
||||||
|
var Types = keyMirror(TypesEnum);
|
||||||
|
|
||||||
var Properties = keyMirror({
|
var PropertiesEnum = {
|
||||||
opacity: true,
|
opacity: true,
|
||||||
scaleXY: true,
|
scaleXY: true,
|
||||||
});
|
};
|
||||||
|
var Properties = keyMirror(PropertiesEnum);
|
||||||
|
|
||||||
var animChecker = createStrictShapeTypeChecker({
|
var animChecker = createStrictShapeTypeChecker({
|
||||||
duration: PropTypes.number,
|
duration: PropTypes.number,
|
||||||
|
@ -48,8 +50,8 @@ type Anim = {
|
||||||
delay?: number;
|
delay?: number;
|
||||||
springDamping?: number;
|
springDamping?: number;
|
||||||
initialVelocity?: number;
|
initialVelocity?: number;
|
||||||
type?: $Enum<typeof Types>;
|
type?: $Enum<typeof TypesEnum>;
|
||||||
property?: $Enum<typeof Properties>;
|
property?: $Enum<typeof PropertiesEnum>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var configChecker = createStrictShapeTypeChecker({
|
var configChecker = createStrictShapeTypeChecker({
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#import "RCTSparseArray.h"
|
#import "RCTSparseArray.h"
|
||||||
#import "RCTUIManager.h"
|
#import "RCTUIManager.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
#if CGFLOAT_IS_DOUBLE
|
#if CGFLOAT_IS_DOUBLE
|
||||||
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_D
|
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_D
|
||||||
|
@ -23,14 +24,45 @@
|
||||||
@implementation RCTAnimationExperimentalManager
|
@implementation RCTAnimationExperimentalManager
|
||||||
{
|
{
|
||||||
RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag
|
RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag
|
||||||
|
RCTSparseArray *_callbackRegistry; // Main thread only; animation tag -> callback
|
||||||
|
NSDictionary *_keypathMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
_animationRegistry = [[RCTSparseArray alloc] init];
|
_animationRegistry = [[RCTSparseArray alloc] init];
|
||||||
|
_callbackRegistry = [[RCTSparseArray alloc] init];
|
||||||
|
_keypathMapping = @{
|
||||||
|
@"opacity": @{
|
||||||
|
@"keypath": @"opacity",
|
||||||
|
@"type": @"NSNumber",
|
||||||
|
},
|
||||||
|
@"position": @{
|
||||||
|
@"keypath": @"position",
|
||||||
|
@"type": @"CGPoint",
|
||||||
|
},
|
||||||
|
@"positionX": @{
|
||||||
|
@"keypath": @"position.x",
|
||||||
|
@"type": @"NSNumber",
|
||||||
|
},
|
||||||
|
@"positionY": @{
|
||||||
|
@"keypath": @"position.y",
|
||||||
|
@"type": @"NSNumber",
|
||||||
|
},
|
||||||
|
@"rotation": @{
|
||||||
|
@"keypath": @"transform.rotation.z",
|
||||||
|
@"type": @"NSNumber",
|
||||||
|
},
|
||||||
|
@"scaleXY": @{
|
||||||
|
@"keypath": @"transform.scale",
|
||||||
|
@"type": @"CGPoint",
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -61,10 +93,26 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startAnimationForTag:(NSNumber *)reactTag animationTag:(NSNumber *)animationTag duration:(double)duration delay:(double)delay easingSample:(NSArray *)easingSample properties:(NSDictionary *)properties
|
static void RCTInvalidAnimationProp(RCTSparseArray *callbacks, NSNumber *tag, NSString *key, id value)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(startAnimation);
|
RCTResponseSenderBlock callback = callbacks[tag];
|
||||||
|
RCTLogError(@"Invalid animation property `%@ = %@`", key, value);
|
||||||
|
if (callback) {
|
||||||
|
callback(@[@NO]);
|
||||||
|
callbacks[tag] = nil;
|
||||||
|
}
|
||||||
|
[CATransaction commit];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(startAnimation:(NSNumber *)reactTag
|
||||||
|
animationTag:(NSNumber *)animationTag
|
||||||
|
duration:(NSTimeInterval)duration
|
||||||
|
delay:(NSTimeInterval)delay
|
||||||
|
easingSample:(NSArray *)easingSample
|
||||||
|
properties:(NSDictionary *)properties
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
|
{
|
||||||
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
||||||
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
||||||
|
@ -74,12 +122,21 @@
|
||||||
RCTLogWarn(@"React tag #%@ is not registered with the view registry", reactTag);
|
RCTLogWarn(@"React tag #%@ is not registered with the view registry", reactTag);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
__block BOOL completionBlockSet = NO;
|
||||||
[properties enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
|
[CATransaction begin];
|
||||||
|
for (NSString *prop in properties) {
|
||||||
|
NSString *keypath = _keypathMapping[prop][@"keypath"];
|
||||||
|
id obj = properties[prop][@"to"];
|
||||||
|
if (!keypath) {
|
||||||
|
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||||
|
}
|
||||||
NSValue *toValue = nil;
|
NSValue *toValue = nil;
|
||||||
if ([key isEqualToString:@"scaleXY"]) {
|
if ([keypath isEqualToString:@"transform.scale"]) {
|
||||||
key = @"transform.scale";
|
CGPoint point = [RCTConvert CGPoint:obj];
|
||||||
toValue = obj[0];
|
if (point.x != point.y) {
|
||||||
|
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||||
|
}
|
||||||
|
toValue = @(point.x);
|
||||||
} else if ([obj respondsToSelector:@selector(count)]) {
|
} else if ([obj respondsToSelector:@selector(count)]) {
|
||||||
switch ([obj count]) {
|
switch ([obj count]) {
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -95,11 +152,15 @@
|
||||||
case 16:
|
case 16:
|
||||||
toValue = [NSValue valueWithCGAffineTransform:[RCTConvert CGAffineTransform:obj]];
|
toValue = [NSValue valueWithCGAffineTransform:[RCTConvert CGAffineTransform:obj]];
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||||
}
|
}
|
||||||
|
} else if (![obj respondsToSelector:@selector(objCType)]) {
|
||||||
|
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||||
|
}
|
||||||
|
if (!toValue) {
|
||||||
|
toValue = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toValue) toValue = obj;
|
|
||||||
|
|
||||||
const char *typeName = toValue.objCType;
|
const char *typeName = toValue.objCType;
|
||||||
|
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -150,7 +211,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSValue *fromValue = [view.layer.presentationLayer valueForKeyPath:key];
|
NSValue *fromValue = [view.layer.presentationLayer valueForKeyPath:keypath];
|
||||||
CGFloat fromFields[count];
|
CGFloat fromFields[count];
|
||||||
[fromValue getValue:fromFields];
|
[fromValue getValue:fromFields];
|
||||||
|
|
||||||
|
@ -161,27 +222,38 @@
|
||||||
CGFloat t = sample.CG_APPEND(, floatValue, doubleValue);
|
CGFloat t = sample.CG_APPEND(, floatValue, doubleValue);
|
||||||
[sampledValues addObject:interpolationBlock(t)];
|
[sampledValues addObject:interpolationBlock(t)];
|
||||||
}
|
}
|
||||||
|
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keypath];
|
||||||
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:key];
|
animation.beginTime = CACurrentMediaTime() + delay;
|
||||||
animation.beginTime = CACurrentMediaTime() + delay / 1000.0;
|
animation.duration = duration;
|
||||||
animation.duration = duration / 1000.0;
|
|
||||||
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
||||||
animation.values = sampledValues;
|
animation.values = sampledValues;
|
||||||
|
@try {
|
||||||
[view.layer setValue:toValue forKey:key];
|
[view.layer setValue:toValue forKey:keypath];
|
||||||
|
NSString *animationKey = [@"RCT" stringByAppendingString:RCTJSONStringify(@{@"tag": animationTag, @"key": keypath}, nil)];
|
||||||
NSString *animationKey = [NSString stringWithFormat:@"RCT.%@.%@", animationTag, key];
|
[view.layer addAnimation:animation forKey:animationKey];
|
||||||
[view.layer addAnimation:animation forKey:animationKey];
|
if (!completionBlockSet) {
|
||||||
}];
|
strongSelf->_callbackRegistry[animationTag] = callback;
|
||||||
|
[CATransaction setCompletionBlock:^{
|
||||||
|
RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag];
|
||||||
|
if (cb) {
|
||||||
|
cb(@[@YES]);
|
||||||
|
strongSelf->_callbackRegistry[animationTag] = nil;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
completionBlockSet = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@catch (NSException *exception) {
|
||||||
|
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, toValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[CATransaction commit];
|
||||||
strongSelf->_animationRegistry[animationTag] = reactTag;
|
strongSelf->_animationRegistry[animationTag] = reactTag;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopAnimation:(NSNumber *)animationTag
|
RCT_EXPORT_METHOD(stopAnimation:(NSNumber *)animationTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(stopAnimation);
|
|
||||||
|
|
||||||
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
||||||
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
||||||
|
@ -191,19 +263,25 @@
|
||||||
|
|
||||||
UIView *view = viewRegistry[reactTag];
|
UIView *view = viewRegistry[reactTag];
|
||||||
for (NSString *animationKey in view.layer.animationKeys) {
|
for (NSString *animationKey in view.layer.animationKeys) {
|
||||||
if ([animationKey hasPrefix:@"RCT"]) {
|
if ([animationKey hasPrefix:@"RCT{"]) {
|
||||||
NSRange periodLocation = [animationKey rangeOfString:@"." options:0 range:(NSRange){3, animationKey.length - 3}];
|
NSDictionary *data = RCTJSONParse([animationKey substringFromIndex:3], nil);
|
||||||
if (periodLocation.location != NSNotFound) {
|
if (animationTag.integerValue == [data[@"tag"] integerValue]) {
|
||||||
NSInteger integerTag = [[animationKey substringWithRange:(NSRange){3, periodLocation.location}] integerValue];
|
[view.layer removeAnimationForKey:animationKey];
|
||||||
if (animationTag.integerValue == integerTag) {
|
|
||||||
[view.layer removeAnimationForKey:animationKey];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag];
|
||||||
|
if (cb) {
|
||||||
|
cb(@[@NO]);
|
||||||
|
strongSelf->_callbackRegistry[animationTag] = nil;
|
||||||
|
}
|
||||||
strongSelf->_animationRegistry[animationTag] = nil;
|
strongSelf->_animationRegistry[animationTag] = nil;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)constantsToExport
|
||||||
|
{
|
||||||
|
return @{@"Properties": [_keypathMapping allKeys] };
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -492,7 +492,7 @@ var TextInput = React.createClass({
|
||||||
|
|
||||||
_renderAndroid: function() {
|
_renderAndroid: function() {
|
||||||
var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize];
|
var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize];
|
||||||
return (
|
var textContainer =
|
||||||
<AndroidTextInput
|
<AndroidTextInput
|
||||||
ref="input"
|
ref="input"
|
||||||
style={[this.props.style]}
|
style={[this.props.style]}
|
||||||
|
@ -503,11 +503,19 @@ var TextInput = React.createClass({
|
||||||
onFocus={this._onFocus}
|
onFocus={this._onFocus}
|
||||||
onBlur={this._onBlur}
|
onBlur={this._onBlur}
|
||||||
onChange={this._onChange}
|
onChange={this._onChange}
|
||||||
|
onEndEditing={this.props.onEndEditing}
|
||||||
|
onSubmitEditing={this.props.onSubmitEditing}
|
||||||
password={this.props.password}
|
password={this.props.password}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
value={this.props.value}
|
value={this.state.bufferedValue}
|
||||||
testID={this.props.testID}
|
/>;
|
||||||
/>
|
|
||||||
|
return (
|
||||||
|
<TouchableWithoutFeedback
|
||||||
|
onPress={this._onPress}
|
||||||
|
testID={this.props.testID}>
|
||||||
|
{textContainer}
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ var copyProperties = require('copyProperties');
|
||||||
var onlyChild = require('onlyChild');
|
var onlyChild = require('onlyChild');
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
animationID: ?number;
|
animationID: ?number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ var TouchableBounce = React.createClass({
|
||||||
value: number,
|
value: number,
|
||||||
velocity: number,
|
velocity: number,
|
||||||
bounciness: number,
|
bounciness: number,
|
||||||
fromValue?: ?Function | number,
|
fromValue?: ?number,
|
||||||
callback?: ?Function
|
callback?: ?Function
|
||||||
) {
|
) {
|
||||||
if (POPAnimation) {
|
if (POPAnimation) {
|
||||||
|
@ -71,21 +71,21 @@ var TouchableBounce = React.createClass({
|
||||||
toValue: [value, value],
|
toValue: [value, value],
|
||||||
velocity: [velocity, velocity],
|
velocity: [velocity, velocity],
|
||||||
springBounciness: bounciness,
|
springBounciness: bounciness,
|
||||||
fromValue: (undefined: ?any),
|
fromValue: fromValue ? [fromValue, fromValue] : undefined,
|
||||||
};
|
};
|
||||||
if (fromValue) {
|
|
||||||
anim.fromValue = [fromValue, fromValue];
|
|
||||||
}
|
|
||||||
this.state.animationID = POPAnimation.createSpringAnimation(anim);
|
this.state.animationID = POPAnimation.createSpringAnimation(anim);
|
||||||
this.addAnimation(this.state.animationID, callback);
|
this.addAnimation(this.state.animationID, callback);
|
||||||
} else {
|
} else {
|
||||||
AnimationExperimental.startAnimation(this, 300, 0, 'easeOutBack', {scaleXY: [value, value]});
|
AnimationExperimental.startAnimation(
|
||||||
if (fromValue && typeof fromValue === 'function') {
|
{
|
||||||
callback = fromValue;
|
node: this,
|
||||||
}
|
duration: 300,
|
||||||
if (callback) {
|
easing: 'easeOutBack',
|
||||||
setTimeout(callback, 300);
|
property: 'scaleXY',
|
||||||
}
|
toValue: { x: value, y: value},
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
|
var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule;
|
||||||
var BackAndroid = require('BackAndroid');
|
var BackAndroid = require('BackAndroid');
|
||||||
var Dimensions = require('Dimensions');
|
|
||||||
var InteractionMixin = require('InteractionMixin');
|
var InteractionMixin = require('InteractionMixin');
|
||||||
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
var NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
||||||
var NavigatorInterceptor = require('NavigatorInterceptor');
|
var NavigatorInterceptor = require('NavigatorInterceptor');
|
||||||
|
@ -52,9 +51,6 @@ var rebound = require('rebound');
|
||||||
|
|
||||||
var PropTypes = React.PropTypes;
|
var PropTypes = React.PropTypes;
|
||||||
|
|
||||||
var SCREEN_WIDTH = Dimensions.get('window').width;
|
|
||||||
var SCREEN_HEIGHT = Dimensions.get('window').height;
|
|
||||||
|
|
||||||
var OFF_SCREEN = {style: {opacity: 0}};
|
var OFF_SCREEN = {style: {opacity: 0}};
|
||||||
|
|
||||||
var __uid = 0;
|
var __uid = 0;
|
||||||
|
@ -69,8 +65,11 @@ var styles = StyleSheet.create({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
defaultSceneStyle: {
|
defaultSceneStyle: {
|
||||||
width: SCREEN_WIDTH,
|
position: 'absolute',
|
||||||
height: SCREEN_HEIGHT,
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
},
|
},
|
||||||
presentNavItem: {
|
presentNavItem: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
@ -88,7 +87,7 @@ var styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
transitioner: {
|
transitioner: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: '#555555',
|
backgroundColor: 'transparent',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -510,7 +509,7 @@ var Navigator = React.createClass({
|
||||||
this.state.fromIndex = this.state.presentedIndex;
|
this.state.fromIndex = this.state.presentedIndex;
|
||||||
this.state.toIndex = this.state.presentedIndex;
|
this.state.toIndex = this.state.presentedIndex;
|
||||||
}
|
}
|
||||||
this._hideOtherScenes(presentedIndex);
|
this._hideOtherScenes(this.state.presentedIndex);
|
||||||
},
|
},
|
||||||
|
|
||||||
_transitionToToIndexWithVelocity: function(v) {
|
_transitionToToIndexWithVelocity: function(v) {
|
||||||
|
@ -596,7 +595,7 @@ var Navigator = React.createClass({
|
||||||
|
|
||||||
_handlePanResponderGrant: function(e, gestureState) {
|
_handlePanResponderGrant: function(e, gestureState) {
|
||||||
invariant(
|
invariant(
|
||||||
this._expectingGestureGrant,
|
this._expectingGestureGrant || this.state.isAnimating,
|
||||||
'Responder granted unexpectedly.'
|
'Responder granted unexpectedly.'
|
||||||
);
|
);
|
||||||
this._activeGestureAction = this._expectingGestureGrant;
|
this._activeGestureAction = this._expectingGestureGrant;
|
||||||
|
|
|
@ -34,7 +34,7 @@ var buildStyleInterpolator = require('buildStyleInterpolator');
|
||||||
var SCREEN_WIDTH = Dimensions.get('window').width;
|
var SCREEN_WIDTH = Dimensions.get('window').width;
|
||||||
var SCREEN_HEIGHT = Dimensions.get('window').height;
|
var SCREEN_HEIGHT = Dimensions.get('window').height;
|
||||||
|
|
||||||
var ToTheLeft = {
|
var FadeToTheLeft = {
|
||||||
// Rotate *requires* you to break out each individual component of
|
// Rotate *requires* you to break out each individual component of
|
||||||
// rotation (x, y, z, w)
|
// rotation (x, y, z, w)
|
||||||
transformTranslate: {
|
transformTranslate: {
|
||||||
|
@ -101,6 +101,23 @@ var ToTheLeft = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var ToTheLeft = {
|
||||||
|
transformTranslate: {
|
||||||
|
from: {x: 0, y: 0, z: 0},
|
||||||
|
to: {x: -Dimensions.get('window').width, y: 0, z: 0},
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
type: 'linear',
|
||||||
|
extrapolate: true,
|
||||||
|
round: PixelRatio.get(),
|
||||||
|
},
|
||||||
|
opacity: {
|
||||||
|
value: 1.0,
|
||||||
|
type: 'constant',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var FromTheRight = {
|
var FromTheRight = {
|
||||||
opacity: {
|
opacity: {
|
||||||
value: 1.0,
|
value: 1.0,
|
||||||
|
@ -271,7 +288,7 @@ var BaseConfig = {
|
||||||
// Animation interpolators for horizontal transitioning:
|
// Animation interpolators for horizontal transitioning:
|
||||||
animationInterpolators: {
|
animationInterpolators: {
|
||||||
into: buildStyleInterpolator(FromTheRight),
|
into: buildStyleInterpolator(FromTheRight),
|
||||||
out: buildStyleInterpolator(ToTheLeft),
|
out: buildStyleInterpolator(FadeToTheLeft),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -312,8 +329,12 @@ var NavigatorSceneConfigs = {
|
||||||
overswipe: BaseOverswipeConfig,
|
overswipe: BaseOverswipeConfig,
|
||||||
edgeHitWidth: null,
|
edgeHitWidth: null,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
animationInterpolators: {
|
||||||
|
into: buildStyleInterpolator(FromTheRight),
|
||||||
|
out: buildStyleInterpolator(ToTheLeft),
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = NavigatorSceneConfigs;
|
module.exports = NavigatorSceneConfigs;
|
||||||
|
|
|
@ -23,11 +23,9 @@ var subscriptions = [];
|
||||||
var updatesEnabled = false;
|
var updatesEnabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /!\ ATTENTION /!\
|
* You need to include the `NSLocationWhenInUseUsageDescription` key
|
||||||
* You need to add NSLocationWhenInUseUsageDescription key
|
* in Info.plist to enable geolocation. Geolocation is enabled by default
|
||||||
* in Info.plist to enable geolocation, otherwise it's going
|
* when you create a project with `react-native init`.
|
||||||
* to *fail silently*!
|
|
||||||
* \!/ \!/
|
|
||||||
*
|
*
|
||||||
* Geolocation follows the MDN specification:
|
* Geolocation follows the MDN specification:
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
|
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
|
||||||
|
|
|
@ -99,6 +99,8 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
|
||||||
RCTLocationOptions _observerOptions;
|
RCTLocationOptions _observerOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
|
@ -151,9 +153,9 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
|
||||||
|
|
||||||
#pragma mark - Public API
|
#pragma mark - Public API
|
||||||
|
|
||||||
- (void)startObserving:(NSDictionary *)optionsJSON
|
RCT_EXPORT_METHOD(startObserving:(NSDictionary *)optionsJSON)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
[self checkLocationConfig];
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
|
@ -170,10 +172,8 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopObserving
|
RCT_EXPORT_METHOD(stopObserving)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
// Stop observing
|
// Stop observing
|
||||||
|
@ -187,11 +187,11 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getCurrentPosition:(NSDictionary *)optionsJSON
|
RCT_EXPORT_METHOD(getCurrentPosition:(NSDictionary *)optionsJSON
|
||||||
withSuccessCallback:(RCTResponseSenderBlock)successBlock
|
withSuccessCallback:(RCTResponseSenderBlock)successBlock
|
||||||
errorCallback:(RCTResponseSenderBlock)errorBlock
|
errorCallback:(RCTResponseSenderBlock)errorBlock)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
[self checkLocationConfig];
|
||||||
|
|
||||||
if (!successBlock) {
|
if (!successBlock) {
|
||||||
RCTLogError(@"%@.getCurrentPosition called with nil success parameter.", [self class]);
|
RCTLogError(@"%@.getCurrentPosition called with nil success parameter.", [self class]);
|
||||||
|
@ -323,4 +323,11 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
|
||||||
_locationManager.desiredAccuracy = RCT_DEFAULT_LOCATION_ACCURACY;
|
_locationManager.desiredAccuracy = RCT_DEFAULT_LOCATION_ACCURACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)checkLocationConfig
|
||||||
|
{
|
||||||
|
if (![[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
|
||||||
|
RCTLogError(@"NSLocationWhenInUseUsageDescription key must be present in Info.plist to use geolocation.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -14,15 +14,17 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import "RCTImageLoader.h"
|
#import "RCTImageLoader.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
|
|
||||||
@implementation RCTCameraRollManager
|
@implementation RCTCameraRollManager
|
||||||
|
|
||||||
- (void)saveImageWithTag:(NSString *)imageTag successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseSenderBlock)errorCallback
|
RCT_EXPORT_MODULE()
|
||||||
{
|
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
|
||||||
|
successCallback:(RCTResponseSenderBlock)successCallback
|
||||||
|
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
||||||
|
{
|
||||||
[RCTImageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) {
|
[RCTImageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) {
|
||||||
if (loadError) {
|
if (loadError) {
|
||||||
errorCallback(@[[loadError localizedDescription]]);
|
errorCallback(@[[loadError localizedDescription]]);
|
||||||
|
@ -59,10 +61,10 @@
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getPhotos:(NSDictionary *)params callback:(RCTResponseSenderBlock)callback errorCallback:(RCTResponseSenderBlock)errorCallback
|
RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
||||||
|
callback:(RCTResponseSenderBlock)callback
|
||||||
|
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
NSUInteger first = [params[@"first"] integerValue];
|
NSUInteger first = [params[@"first"] integerValue];
|
||||||
NSString *afterCursor = params[@"after"];
|
NSString *afterCursor = params[@"after"];
|
||||||
NSString *groupTypesStr = params[@"groupTypes"];
|
NSString *groupTypesStr = params[@"groupTypes"];
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
@implementation RCTNetworkImageViewManager
|
@implementation RCTNetworkImageViewManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
RCTNetworkImageView *view = [[RCTNetworkImageView alloc] initWithFrame:CGRectZero imageDownloader:[RCTImageDownloader sharedInstance]];
|
RCTNetworkImageView *view = [[RCTNetworkImageView alloc] initWithFrame:CGRectZero imageDownloader:[RCTImageDownloader sharedInstance]];
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
@implementation RCTStaticImageManager
|
@implementation RCTStaticImageManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTStaticImage alloc] init];
|
return [[RCTStaticImage alloc] init];
|
||||||
|
|
|
@ -18,6 +18,8 @@ NSString *const RCTOpenURLNotification = @"RCTOpenURLNotification";
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -52,19 +54,15 @@ NSString *const RCTOpenURLNotification = @"RCTOpenURLNotification";
|
||||||
body:[notification userInfo]];
|
body:[notification userInfo]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)openURL:(NSString *)url
|
RCT_EXPORT_METHOD(openURL:(NSURL *)url)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
[[UIApplication sharedApplication] openURL:url];
|
||||||
|
|
||||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)canOpenURL:(NSString *)url
|
RCT_EXPORT_METHOD(canOpenURL:(NSURL *)url
|
||||||
callback:(RCTResponseSenderBlock)callback
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
BOOL supported = [[UIApplication sharedApplication] canOpenURL:url];
|
||||||
|
|
||||||
BOOL supported = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]];
|
|
||||||
callback(@[@(supported)]);
|
callback(@[@(supported)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,17 @@
|
||||||
|
|
||||||
@implementation RCTDataManager
|
@implementation RCTDataManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a network request.
|
* Executes a network request.
|
||||||
* The responseSender block won't be called on same thread as called.
|
* The responseSender block won't be called on same thread as called.
|
||||||
*/
|
*/
|
||||||
- (void)executeQuery:(NSString *)queryType
|
RCT_EXPORT_METHOD(queryData:(NSString *)queryType
|
||||||
query:(id)query
|
withQuery:(id)query
|
||||||
queryHash:(__unused NSString *)queryHash
|
queryHash:(__unused NSString *)queryHash
|
||||||
responseSender:(RCTResponseSenderBlock)responseSender
|
responseSender:(RCTResponseSenderBlock)responseSender)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(queryData);
|
|
||||||
|
|
||||||
if ([queryType isEqualToString:@"http"]) {
|
if ([queryType isEqualToString:@"http"]) {
|
||||||
|
|
||||||
// Parse query
|
// Parse query
|
||||||
|
|
|
@ -53,6 +53,8 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
|
|
||||||
- (instancetype)initWithHost:(NSString *)host
|
- (instancetype)initWithHost:(NSString *)host
|
||||||
|
@ -81,11 +83,9 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
|
||||||
#pragma mark - Public API
|
#pragma mark - Public API
|
||||||
|
|
||||||
// TODO: remove error callback - not needed except by Subscribable interface
|
// TODO: remove error callback - not needed except by Subscribable interface
|
||||||
- (void)getCurrentReachability:(RCTResponseSenderBlock)getSuccess
|
RCT_EXPORT_METHOD(getCurrentReachability:(RCTResponseSenderBlock)getSuccess
|
||||||
withErrorCallback:(__unused RCTResponseSenderBlock)getError
|
withErrorCallback:(__unused RCTResponseSenderBlock)getError)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
getSuccess(@[@{@"network_reachability": _status}]);
|
getSuccess(@[@{@"network_reachability": _status}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived";
|
||||||
NSDictionary *_initialNotification;
|
NSDictionary *_initialNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
|
@ -66,29 +68,23 @@ NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived";
|
||||||
/**
|
/**
|
||||||
* Update the application icon badge number on the home screen
|
* Update the application icon badge number on the home screen
|
||||||
*/
|
*/
|
||||||
+ (void)setApplicationIconBadgeNumber:(NSInteger)number
|
RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(NSInteger)number)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[UIApplication sharedApplication].applicationIconBadgeNumber = number;
|
[UIApplication sharedApplication].applicationIconBadgeNumber = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current application icon badge number on the home screen
|
* Get the current application icon badge number on the home screen
|
||||||
*/
|
*/
|
||||||
+ (void)getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
callback(@[
|
callback(@[
|
||||||
@([UIApplication sharedApplication].applicationIconBadgeNumber)
|
@([UIApplication sharedApplication].applicationIconBadgeNumber)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)requestPermissions
|
RCT_EXPORT_METHOD(requestPermissions)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
|
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
|
||||||
|
|
||||||
// if we are targeting iOS 7, *and* the new UIUserNotificationSettings
|
// if we are targeting iOS 7, *and* the new UIUserNotificationSettings
|
||||||
|
@ -104,13 +100,10 @@ NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived";
|
||||||
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
|
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
|
||||||
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
|
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
|
||||||
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
|
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)checkPermissions:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
|
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
|
||||||
|
|
|
@ -13,12 +13,15 @@
|
||||||
#import "RCTAssert.h"
|
#import "RCTAssert.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
|
|
||||||
@implementation RCTTestModule {
|
@implementation RCTTestModule
|
||||||
|
{
|
||||||
__weak FBSnapshotTestController *_snapshotController;
|
__weak FBSnapshotTestController *_snapshotController;
|
||||||
__weak UIView *_view;
|
__weak UIView *_view;
|
||||||
NSMutableDictionary *_snapshotCounter;
|
NSMutableDictionary *_snapshotCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)initWithSnapshotController:(FBSnapshotTestController *)controller view:(UIView *)view
|
- (instancetype)initWithSnapshotController:(FBSnapshotTestController *)controller view:(UIView *)view
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -29,10 +32,8 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)verifySnapshot:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (!_snapshotController) {
|
if (!_snapshotController) {
|
||||||
RCTLogWarn(@"No snapshot controller configured.");
|
RCTLogWarn(@"No snapshot controller configured.");
|
||||||
callback(@[]);
|
callback(@[]);
|
||||||
|
@ -52,10 +53,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)markTestCompleted
|
RCT_EXPORT_METHOD(markTestCompleted)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
_done = YES;
|
_done = YES;
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,7 +47,7 @@ typedef void (^WSMessageCallback)(NSError *error, NSDictionary *reply);
|
||||||
[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:startDevToolsURL] delegate:nil];
|
[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:startDevToolsURL] delegate:nil];
|
||||||
|
|
||||||
if (![self connectToProxy]) {
|
if (![self connectToProxy]) {
|
||||||
RCTLogError(@"Connection to %@ timed out. Are you running node proxy?", url);
|
RCTLogError(@"Connection to %@ timed out. Are you running node proxy? If you are running on the device check if you have the right IP address on `RCTWebSocketExecutor.m` file.", url);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,12 @@
|
||||||
|
|
||||||
#import <Availability.h>
|
#import <Availability.h>
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
//NOTE: libicucore ins't actually needed for the socket to function
|
||||||
#define HAS_ICU
|
//and by commenting this out, we avoid the need to import it into every app.
|
||||||
#endif
|
|
||||||
|
//#if TARGET_OS_IPHONE
|
||||||
|
//#define HAS_ICU
|
||||||
|
//#endif
|
||||||
|
|
||||||
#ifdef HAS_ICU
|
#ifdef HAS_ICU
|
||||||
#import <unicode/utf8.h>
|
#import <unicode/utf8.h>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
@implementation RCTRawTextManager
|
@implementation RCTRawTextManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
@ -38,34 +38,53 @@
|
||||||
|
|
||||||
- (void)setAttributedText:(NSAttributedString *)attributedText
|
- (void)setAttributedText:(NSAttributedString *)attributedText
|
||||||
{
|
{
|
||||||
[_textStorage setAttributedString:attributedText];
|
for (NSLayoutManager *existingLayoutManager in _textStorage.layoutManagers) {
|
||||||
|
[_textStorage removeLayoutManager:existingLayoutManager];
|
||||||
|
}
|
||||||
|
|
||||||
|
_textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedText];
|
||||||
|
|
||||||
|
if (_layoutManager) {
|
||||||
|
[_textStorage addLayoutManager:_layoutManager];
|
||||||
|
}
|
||||||
|
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTextContainer:(NSTextContainer *)textContainer
|
- (void)setTextContainer:(NSTextContainer *)textContainer
|
||||||
{
|
{
|
||||||
if ([_textContainer isEqual:textContainer]) return;
|
if ([_textContainer isEqual:textContainer]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_textContainer = textContainer;
|
_textContainer = textContainer;
|
||||||
|
|
||||||
for (NSInteger i = _layoutManager.textContainers.count - 1; i >= 0; i--) {
|
for (NSInteger i = _layoutManager.textContainers.count - 1; i >= 0; i--) {
|
||||||
[_layoutManager removeTextContainerAtIndex:i];
|
[_layoutManager removeTextContainerAtIndex:i];
|
||||||
}
|
}
|
||||||
[_layoutManager addTextContainer:_textContainer];
|
|
||||||
|
if (_textContainer) {
|
||||||
|
[_layoutManager addTextContainer:_textContainer];
|
||||||
|
}
|
||||||
|
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setLayoutManager:(NSLayoutManager *)layoutManager
|
- (void)setLayoutManager:(NSLayoutManager *)layoutManager
|
||||||
{
|
{
|
||||||
if ([_layoutManager isEqual:layoutManager]) return;
|
if ([_layoutManager isEqual:layoutManager]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_layoutManager = layoutManager;
|
_layoutManager = layoutManager;
|
||||||
|
|
||||||
for (NSLayoutManager *existingLayoutManager in _textStorage.layoutManagers) {
|
for (NSLayoutManager *existingLayoutManager in _textStorage.layoutManagers) {
|
||||||
[_textStorage removeLayoutManager:existingLayoutManager];
|
[_textStorage removeLayoutManager:existingLayoutManager];
|
||||||
}
|
}
|
||||||
[_textStorage addLayoutManager:_layoutManager];
|
|
||||||
|
if (_layoutManager) {
|
||||||
|
[_textStorage addLayoutManager:_layoutManager];
|
||||||
|
}
|
||||||
|
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
@implementation RCTTextManager
|
@implementation RCTTextManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTText alloc] init];
|
return [[RCTText alloc] init];
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
|
|
||||||
@implementation RCTVibration
|
@implementation RCTVibration
|
||||||
|
|
||||||
- (void)vibrate
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(vibrate)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
*/
|
*/
|
||||||
typedef NSArray *(^RCTBridgeModuleProviderBlock)(void);
|
typedef NSArray *(^RCTBridgeModuleProviderBlock)(void);
|
||||||
|
|
||||||
extern NSString *const RCTReloadBridge;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the module name for a given class.
|
* This function returns the module name for a given class.
|
||||||
*/
|
*/
|
||||||
|
@ -38,8 +36,6 @@ extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
|
||||||
*/
|
*/
|
||||||
@interface RCTBridge : NSObject <RCTInvalidating>
|
@interface RCTBridge : NSObject <RCTInvalidating>
|
||||||
|
|
||||||
@property (nonatomic, assign, readonly, getter=isLoaded) BOOL loaded;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The designated initializer. This creates a new bridge on top of the specified
|
* The designated initializer. This creates a new bridge on top of the specified
|
||||||
* executor. The bridge should then be used for all subsequent communication
|
* executor. The bridge should then be used for all subsequent communication
|
||||||
|
@ -55,16 +51,31 @@ extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
|
||||||
/**
|
/**
|
||||||
* This method is used to call functions in the JavaScript application context.
|
* 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
|
* It is primarily intended for use by modules that require two-way communication
|
||||||
* with the JavaScript code.
|
* with the JavaScript code. Method should be regsitered using the
|
||||||
|
* RCT_IMPORT_METHOD macro below. Attempting to call a method that has not been
|
||||||
|
* registered will result in an error.
|
||||||
*/
|
*/
|
||||||
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
|
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This macro is used to register a JS method to be called via the enqueueJSCall
|
||||||
|
* bridge method. You should place this macro inside any file that uses the
|
||||||
|
* imported method. If a method has already been registered by another class, it
|
||||||
|
* is not necessary to register it again, but it is good practice. Registering
|
||||||
|
* the same method more than once will not result in an error.
|
||||||
|
*/
|
||||||
|
#define RCT_IMPORT_METHOD(module, method) \
|
||||||
|
__attribute__((used, section("__DATA,RCTImport"))) \
|
||||||
|
static const char *__rct_import_##module##_##method##__ = #module"."#method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to execute a new application script. It is called
|
* This method is used to execute a new application script. It is called
|
||||||
* internally whenever a JS application bundle is loaded/reloaded, but should
|
* internally whenever a JS application bundle is loaded/reloaded, but should
|
||||||
* probably not be used at any other time.
|
* probably not be used at any other time.
|
||||||
*/
|
*/
|
||||||
- (void)enqueueApplicationScript:(NSString *)script url:(NSURL *)url onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
- (void)enqueueApplicationScript:(NSString *)script
|
||||||
|
url:(NSURL *)url
|
||||||
|
onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
||||||
|
|
||||||
@property (nonatomic, strong) Class executorClass;
|
@property (nonatomic, strong) Class executorClass;
|
||||||
|
|
||||||
|
@ -86,14 +97,19 @@ extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, readonly) dispatch_queue_t shadowQueue;
|
@property (nonatomic, readonly) dispatch_queue_t shadowQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The launch options that were used to initialize the bridge.
|
||||||
|
*/
|
||||||
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
|
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this to check if the bridge is currently loading.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, readonly, getter=isLoaded) BOOL loaded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to check that a valid executor exists with which to log
|
* Reload the bundle and reset executor and modules.
|
||||||
*/
|
*/
|
||||||
+ (BOOL)hasValidJSExecutor;
|
|
||||||
|
|
||||||
- (void)reload;
|
- (void)reload;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#import "RCTRootView.h"
|
#import "RCTRootView.h"
|
||||||
#import "RCTSparseArray.h"
|
#import "RCTSparseArray.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "RCTWebViewExecutor.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be kept in sync with `MessageQueue.js`.
|
* Must be kept in sync with `MessageQueue.js`.
|
||||||
|
@ -40,11 +39,32 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) {
|
||||||
RCTBridgeFieldFlushDateMillis
|
RCTBridgeFieldFlushDateMillis
|
||||||
};
|
};
|
||||||
|
|
||||||
NSString *const RCTReloadBridge = @"RCTReloadBridge";
|
#ifdef __LP64__
|
||||||
|
typedef uint64_t RCTHeaderValue;
|
||||||
|
typedef struct section_64 RCTHeaderSection;
|
||||||
|
#define RCTGetSectByNameFromHeader getsectbynamefromheader_64
|
||||||
|
#else
|
||||||
|
typedef uint32_t RCTHeaderValue;
|
||||||
|
typedef struct section RCTHeaderSection;
|
||||||
|
#define RCTGetSectByNameFromHeader getsectbynamefromheader
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the module name for a given class.
|
||||||
|
*/
|
||||||
NSString *RCTBridgeModuleNameForClass(Class cls)
|
NSString *RCTBridgeModuleNameForClass(Class cls)
|
||||||
{
|
{
|
||||||
return [cls respondsToSelector:@selector(moduleName)] ? [cls moduleName] : NSStringFromClass(cls);
|
NSString *name = nil;
|
||||||
|
if ([cls respondsToSelector:@selector(moduleName)]) {
|
||||||
|
name = [cls valueForKey:@"moduleName"];
|
||||||
|
}
|
||||||
|
if ([name length] == 0) {
|
||||||
|
name = NSStringFromClass(cls);
|
||||||
|
}
|
||||||
|
if ([name hasPrefix:@"RK"]) {
|
||||||
|
name = [name stringByReplacingCharactersInRange:(NSRange){0,@"RK".length} withString:@"RCT"];
|
||||||
|
}
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,11 +78,22 @@ static NSArray *RCTJSMethods(void)
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
NSMutableSet *uniqueMethods = [NSMutableSet set];
|
NSMutableSet *uniqueMethods = [NSMutableSet set];
|
||||||
|
|
||||||
RCTEnumerateClasses(^(__unsafe_unretained Class cls) {
|
Dl_info info;
|
||||||
if (RCTClassOverridesClassMethod(cls, @selector(JSMethods))) {
|
dladdr(&RCTJSMethods, &info);
|
||||||
[uniqueMethods addObjectsFromArray:[cls JSMethods]];
|
|
||||||
|
const RCTHeaderValue mach_header = (RCTHeaderValue)info.dli_fbase;
|
||||||
|
const RCTHeaderSection *section = RCTGetSectByNameFromHeader((void *)mach_header, "__DATA", "RCTImport");
|
||||||
|
|
||||||
|
if (section) {
|
||||||
|
for (RCTHeaderValue addr = section->offset;
|
||||||
|
addr < section->offset + section->size;
|
||||||
|
addr += sizeof(const char **)) {
|
||||||
|
|
||||||
|
// Get data entry
|
||||||
|
NSString *entry = @(*(const char **)(mach_header + addr));
|
||||||
|
[uniqueMethods addObject:entry];
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
JSMethods = [uniqueMethods allObjects];
|
JSMethods = [uniqueMethods allObjects];
|
||||||
});
|
});
|
||||||
|
@ -71,35 +102,85 @@ static NSArray *RCTJSMethods(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function scans all classes available at runtime and returns an array
|
* This function scans all exported modules available at runtime and returns an
|
||||||
* of all classes that implement the RTCBridgeModule protocol.
|
* array. As a backup, it also scans all classes that implement the
|
||||||
|
* RTCBridgeModule protocol to ensure they've been exported. This scanning
|
||||||
|
* functionality is disabled in release mode to improve startup performance.
|
||||||
*/
|
*/
|
||||||
static NSArray *RCTModuleNamesByID;
|
static NSArray *RCTModuleNamesByID;
|
||||||
|
static NSArray *RCTModuleClassesByID;
|
||||||
static NSArray *RCTBridgeModuleClassesByModuleID(void)
|
static NSArray *RCTBridgeModuleClassesByModuleID(void)
|
||||||
{
|
{
|
||||||
static NSArray *modules;
|
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
modules = [NSMutableArray array];
|
|
||||||
RCTModuleNamesByID = [NSMutableArray array];
|
RCTModuleNamesByID = [NSMutableArray array];
|
||||||
|
RCTModuleClassesByID = [NSMutableArray array];
|
||||||
|
|
||||||
RCTEnumerateClasses(^(__unsafe_unretained Class cls) {
|
Dl_info info;
|
||||||
if ([cls conformsToProtocol:@protocol(RCTBridgeModule)]) {
|
dladdr(&RCTBridgeModuleClassesByModuleID, &info);
|
||||||
|
|
||||||
// Add module
|
const RCTHeaderValue mach_header = (RCTHeaderValue)info.dli_fbase;
|
||||||
[(NSMutableArray *)modules addObject:cls];
|
const RCTHeaderSection *section = RCTGetSectByNameFromHeader((void *)mach_header, "__DATA", "RCTExportModule");
|
||||||
|
|
||||||
// Add module name
|
if (section) {
|
||||||
NSString *moduleName = RCTBridgeModuleNameForClass(cls);
|
for (RCTHeaderValue addr = section->offset;
|
||||||
[(NSMutableArray *)RCTModuleNamesByID addObject:moduleName];
|
addr < section->offset + section->size;
|
||||||
|
addr += sizeof(const char **)) {
|
||||||
|
|
||||||
|
// Get data entry
|
||||||
|
NSString *entry = @(*(const char **)(mach_header + addr));
|
||||||
|
NSArray *parts = [[entry substringWithRange:(NSRange){2, entry.length - 3}] componentsSeparatedByString:@" "];
|
||||||
|
|
||||||
|
// Parse class name
|
||||||
|
NSString *moduleClassName = parts[0];
|
||||||
|
NSRange categoryRange = [moduleClassName rangeOfString:@"("];
|
||||||
|
if (categoryRange.length) {
|
||||||
|
moduleClassName = [moduleClassName substringToIndex:categoryRange.location];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get class
|
||||||
|
Class cls = NSClassFromString(moduleClassName);
|
||||||
|
RCTCAssert([cls conformsToProtocol:@protocol(RCTBridgeModule)],
|
||||||
|
@"%@ does not conform to the RCTBridgeModule protocol",
|
||||||
|
NSStringFromClass(cls));
|
||||||
|
|
||||||
|
// Register module
|
||||||
|
[(NSMutableArray *)RCTModuleNamesByID addObject:RCTBridgeModuleNameForClass(cls)];
|
||||||
|
[(NSMutableArray *)RCTModuleClassesByID addObject:cls];
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
// We may be able to get rid of this check in future, once people
|
||||||
|
// get used to the new registration system. That would potentially
|
||||||
|
// allow you to create modules that are not automatically registered
|
||||||
|
|
||||||
|
static unsigned int classCount;
|
||||||
|
Class *classes = objc_copyClassList(&classCount);
|
||||||
|
for (unsigned int i = 0; i < classCount; i++)
|
||||||
|
{
|
||||||
|
Class cls = classes[i];
|
||||||
|
Class superclass = cls;
|
||||||
|
while (superclass)
|
||||||
|
{
|
||||||
|
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
|
||||||
|
{
|
||||||
|
if (![RCTModuleClassesByID containsObject:cls]) {
|
||||||
|
RCTLogError(@"Class %@ was not exported. Did you forget to use RCT_EXPORT_MODULE()?", NSStringFromClass(cls));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
superclass = class_getSuperclass(superclass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
modules = [modules copy];
|
|
||||||
RCTModuleNamesByID = [RCTModuleNamesByID copy];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return modules;
|
return RCTModuleClassesByID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface RCTBridge ()
|
@interface RCTBridge ()
|
||||||
|
@ -132,30 +213,61 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void)
|
||||||
|
|
||||||
static Class _globalExecutorClass;
|
static Class _globalExecutorClass;
|
||||||
|
|
||||||
|
NS_INLINE NSString *RCTStringUpToFirstArgument(NSString *methodName) {
|
||||||
|
NSRange colonRange = [methodName rangeOfString:@":"];
|
||||||
|
if (colonRange.length) {
|
||||||
|
methodName = [methodName substringToIndex:colonRange.location];
|
||||||
|
}
|
||||||
|
return methodName;
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithMethodName:(NSString *)methodName
|
- (instancetype)initWithMethodName:(NSString *)methodName
|
||||||
JSMethodName:(NSString *)JSMethodName
|
JSMethodName:(NSString *)JSMethodName
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
|
||||||
_methodName = methodName;
|
_methodName = methodName;
|
||||||
NSArray *parts = [[methodName substringWithRange:NSMakeRange(2, methodName.length - 3)] componentsSeparatedByString:@" "];
|
NSArray *parts = [[methodName substringWithRange:(NSRange){2, methodName.length - 3}] componentsSeparatedByString:@" "];
|
||||||
|
|
||||||
// Parse class and method
|
// Parse class and method
|
||||||
_moduleClassName = parts[0];
|
_moduleClassName = parts[0];
|
||||||
NSRange categoryRange = [_moduleClassName rangeOfString:@"("];
|
NSRange categoryRange = [_moduleClassName rangeOfString:@"("];
|
||||||
if (categoryRange.length)
|
if (categoryRange.length) {
|
||||||
{
|
|
||||||
_moduleClassName = [_moduleClassName substringToIndex:categoryRange.location];
|
_moduleClassName = [_moduleClassName substringToIndex:categoryRange.location];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSArray *argumentNames = nil;
|
||||||
|
if ([parts[1] hasPrefix:@"__rct_export__"]) {
|
||||||
|
// New format
|
||||||
|
NSString *selectorString = [parts[1] substringFromIndex:14];
|
||||||
|
_selector = NSSelectorFromString(selectorString);
|
||||||
|
_JSMethodName = RCTStringUpToFirstArgument(selectorString);
|
||||||
|
|
||||||
|
static NSRegularExpression *regExp;
|
||||||
|
if (!regExp) {
|
||||||
|
NSString *unusedPattern = @"(?:(?:__unused|__attribute__\\(\\(unused\\)\\)))";
|
||||||
|
NSString *constPattern = @"(?:const)";
|
||||||
|
NSString *constUnusedPattern = [NSString stringWithFormat:@"(?:(?:%@|%@)\\s*)", unusedPattern, constPattern];
|
||||||
|
NSString *pattern = [NSString stringWithFormat:@"\\(%1$@?(\\w+?)(?:\\s*\\*)?%1$@?\\)", constUnusedPattern];
|
||||||
|
regExp = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:NULL];
|
||||||
|
}
|
||||||
|
|
||||||
|
argumentNames = [NSMutableArray array];
|
||||||
|
[regExp enumerateMatchesInString:JSMethodName options:0 range:NSMakeRange(0, JSMethodName.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
||||||
|
NSString *argumentName = [JSMethodName substringWithRange:[result rangeAtIndex:1]];
|
||||||
|
[(NSMutableArray *)argumentNames addObject:argumentName];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
// Old format
|
||||||
|
NSString *selectorString = parts[1];
|
||||||
|
_selector = NSSelectorFromString(selectorString);
|
||||||
|
_JSMethodName = JSMethodName ?: RCTStringUpToFirstArgument(selectorString);
|
||||||
|
}
|
||||||
|
|
||||||
// Extract class and method details
|
// Extract class and method details
|
||||||
_isClassMethod = [methodName characterAtIndex:0] == '+';
|
_isClassMethod = [methodName characterAtIndex:0] == '+';
|
||||||
_moduleClass = NSClassFromString(_moduleClassName);
|
_moduleClass = NSClassFromString(_moduleClassName);
|
||||||
_selector = NSSelectorFromString(parts[1]);
|
|
||||||
_JSMethodName = JSMethodName ?: [NSStringFromSelector(_selector) componentsSeparatedByString:@":"][0];
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
|
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
|
||||||
@"You are attempting to export the method %@, but %@ does not \
|
@"You are attempting to export the method %@, but %@ does not \
|
||||||
|
@ -170,15 +282,87 @@ static Class _globalExecutorClass;
|
||||||
// Process arguments
|
// Process arguments
|
||||||
NSUInteger numberOfArguments = _methodSignature.numberOfArguments;
|
NSUInteger numberOfArguments = _methodSignature.numberOfArguments;
|
||||||
NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
|
NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
|
||||||
for (NSUInteger i = 2; i < numberOfArguments; i++) {
|
|
||||||
const char *argumentType = [_methodSignature getArgumentTypeAtIndex:i];
|
|
||||||
switch (argumentType[0]) {
|
|
||||||
|
|
||||||
#define RCT_ARG_BLOCK(_logic) \
|
#define RCT_ARG_BLOCK(_logic) \
|
||||||
[argumentBlocks addObject:^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
|
[argumentBlocks addObject:^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
|
||||||
_logic \
|
_logic \
|
||||||
[invocation setArgument:&value atIndex:index]; \
|
[invocation setArgument:&value atIndex:index]; \
|
||||||
}]; \
|
}]; \
|
||||||
|
|
||||||
|
void (^addBlockArgument)(void) = ^{
|
||||||
|
RCT_ARG_BLOCK(
|
||||||
|
if (json && ![json isKindOfClass:[NSNumber class]]) {
|
||||||
|
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
|
||||||
|
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
||||||
|
__autoreleasing id value = (json ? ^(NSArray *args) {
|
||||||
|
[bridge _invokeAndProcessModule:@"BatchedBridge"
|
||||||
|
method:@"invokeCallbackAndReturnFlushedQueue"
|
||||||
|
arguments:@[json, args]];
|
||||||
|
} : ^(NSArray *unused) {});
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
void (^defaultCase)(const char *) = ^(const char *argumentType) {
|
||||||
|
static const char *blockType = @encode(typeof(^{}));
|
||||||
|
if (!strcmp(argumentType, blockType)) {
|
||||||
|
addBlockArgument();
|
||||||
|
} else {
|
||||||
|
RCT_ARG_BLOCK( id value = json; )
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (NSUInteger i = 2; i < numberOfArguments; i++) {
|
||||||
|
const char *argumentType = [_methodSignature getArgumentTypeAtIndex:i];
|
||||||
|
|
||||||
|
BOOL useFallback = YES;
|
||||||
|
if (argumentNames) {
|
||||||
|
NSString *argumentName = argumentNames[i - 2];
|
||||||
|
SEL selector = NSSelectorFromString([argumentName stringByAppendingString:@":"]);
|
||||||
|
if ([RCTConvert respondsToSelector:selector]) {
|
||||||
|
useFallback = NO;
|
||||||
|
switch (argumentType[0]) {
|
||||||
|
|
||||||
|
#define RCT_CONVERT_CASE(_value, _type) \
|
||||||
|
case _value: { \
|
||||||
|
_type (*convert)(id, SEL, id) = (typeof(convert))[RCTConvert methodForSelector:selector]; \
|
||||||
|
RCT_ARG_BLOCK( _type value = convert([RCTConvert class], selector, json); ) \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_CONVERT_CASE(':', SEL)
|
||||||
|
RCT_CONVERT_CASE('*', const char *)
|
||||||
|
RCT_CONVERT_CASE('c', char)
|
||||||
|
RCT_CONVERT_CASE('C', unsigned char)
|
||||||
|
RCT_CONVERT_CASE('s', short)
|
||||||
|
RCT_CONVERT_CASE('S', unsigned short)
|
||||||
|
RCT_CONVERT_CASE('i', int)
|
||||||
|
RCT_CONVERT_CASE('I', unsigned int)
|
||||||
|
RCT_CONVERT_CASE('l', long)
|
||||||
|
RCT_CONVERT_CASE('L', unsigned long)
|
||||||
|
RCT_CONVERT_CASE('q', long long)
|
||||||
|
RCT_CONVERT_CASE('Q', unsigned long long)
|
||||||
|
RCT_CONVERT_CASE('f', float)
|
||||||
|
RCT_CONVERT_CASE('d', double)
|
||||||
|
RCT_CONVERT_CASE('B', BOOL)
|
||||||
|
RCT_CONVERT_CASE('@', id)
|
||||||
|
RCT_CONVERT_CASE('^', void *)
|
||||||
|
|
||||||
|
default:
|
||||||
|
defaultCase(argumentType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if ([argumentName isEqualToString:@"RCTResponseSenderBlock"]) {
|
||||||
|
addBlockArgument();
|
||||||
|
useFallback = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useFallback) {
|
||||||
|
switch (argumentType[0]) {
|
||||||
|
|
||||||
#define RCT_CASE(_value, _class, _logic) \
|
#define RCT_CASE(_value, _class, _logic) \
|
||||||
case _value: { \
|
case _value: { \
|
||||||
|
@ -193,61 +377,46 @@ static Class _globalExecutorClass;
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_CASE(':', NSString, SEL value = NSSelectorFromString(json); );
|
RCT_CASE(':', NSString, SEL value = NSSelectorFromString(json); )
|
||||||
RCT_CASE('*', NSString, const char *value = [json UTF8String]; );
|
RCT_CASE('*', NSString, const char *value = [json UTF8String]; )
|
||||||
|
|
||||||
#define RCT_SIMPLE_CASE(_value, _type, _selector) \
|
#define RCT_SIMPLE_CASE(_value, _type, _selector) \
|
||||||
case _value: { \
|
case _value: { \
|
||||||
RCT_ARG_BLOCK( \
|
RCT_ARG_BLOCK( \
|
||||||
if (json && ![json respondsToSelector:@selector(_selector)]) { \
|
if (json && ![json respondsToSelector:@selector(_selector)]) { \
|
||||||
RCTLogError(@"Argument %tu (%@) of %@.%@ does not respond to selector: %@", \
|
RCTLogError(@"Argument %tu (%@) of %@.%@ does not respond to selector: %@", \
|
||||||
index, json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, @#_selector); \
|
index, json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, @#_selector); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
_type value = [json _selector]; \
|
_type value = [json _selector]; \
|
||||||
) \
|
) \
|
||||||
break; \
|
break; \
|
||||||
}
|
|
||||||
|
|
||||||
RCT_SIMPLE_CASE('c', char, charValue)
|
|
||||||
RCT_SIMPLE_CASE('C', unsigned char, unsignedCharValue)
|
|
||||||
RCT_SIMPLE_CASE('s', short, shortValue)
|
|
||||||
RCT_SIMPLE_CASE('S', unsigned short, unsignedShortValue)
|
|
||||||
RCT_SIMPLE_CASE('i', int, intValue)
|
|
||||||
RCT_SIMPLE_CASE('I', unsigned int, unsignedIntValue)
|
|
||||||
RCT_SIMPLE_CASE('l', long, longValue)
|
|
||||||
RCT_SIMPLE_CASE('L', unsigned long, unsignedLongValue)
|
|
||||||
RCT_SIMPLE_CASE('q', long long, longLongValue)
|
|
||||||
RCT_SIMPLE_CASE('Q', unsigned long long, unsignedLongLongValue)
|
|
||||||
RCT_SIMPLE_CASE('f', float, floatValue)
|
|
||||||
RCT_SIMPLE_CASE('d', double, doubleValue)
|
|
||||||
RCT_SIMPLE_CASE('B', BOOL, boolValue)
|
|
||||||
|
|
||||||
default: {
|
|
||||||
static const char *blockType = @encode(typeof(^{}));
|
|
||||||
if (!strcmp(argumentType, blockType)) {
|
|
||||||
RCT_ARG_BLOCK(
|
|
||||||
if (json && ![json isKindOfClass:[NSNumber class]]) {
|
|
||||||
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
|
|
||||||
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
|
||||||
__autoreleasing id value = (json ? ^(NSArray *args) {
|
|
||||||
[bridge _invokeAndProcessModule:@"BatchedBridge"
|
|
||||||
method:@"invokeCallbackAndReturnFlushedQueue"
|
|
||||||
arguments:@[json, args]];
|
|
||||||
} : ^(NSArray *unused) {});
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
RCT_ARG_BLOCK( id value = json; )
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
RCT_SIMPLE_CASE('c', char, charValue)
|
||||||
|
RCT_SIMPLE_CASE('C', unsigned char, unsignedCharValue)
|
||||||
|
RCT_SIMPLE_CASE('s', short, shortValue)
|
||||||
|
RCT_SIMPLE_CASE('S', unsigned short, unsignedShortValue)
|
||||||
|
RCT_SIMPLE_CASE('i', int, intValue)
|
||||||
|
RCT_SIMPLE_CASE('I', unsigned int, unsignedIntValue)
|
||||||
|
RCT_SIMPLE_CASE('l', long, longValue)
|
||||||
|
RCT_SIMPLE_CASE('L', unsigned long, unsignedLongValue)
|
||||||
|
RCT_SIMPLE_CASE('q', long long, longLongValue)
|
||||||
|
RCT_SIMPLE_CASE('Q', unsigned long long, unsignedLongLongValue)
|
||||||
|
RCT_SIMPLE_CASE('f', float, floatValue)
|
||||||
|
RCT_SIMPLE_CASE('d', double, doubleValue)
|
||||||
|
RCT_SIMPLE_CASE('B', BOOL, boolValue)
|
||||||
|
|
||||||
|
default:
|
||||||
|
defaultCase(argumentType);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_argumentBlocks = [argumentBlocks copy];
|
_argumentBlocks = [argumentBlocks copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +426,6 @@ static Class _globalExecutorClass;
|
||||||
{
|
{
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
|
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
|
||||||
%@ on a module of class %@", _methodName, [module class]);
|
%@ on a module of class %@", _methodName, [module class]);
|
||||||
|
@ -274,6 +442,7 @@ static Class _globalExecutorClass;
|
||||||
// Create invocation (we can't re-use this as it wouldn't be thread-safe)
|
// Create invocation (we can't re-use this as it wouldn't be thread-safe)
|
||||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature];
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature];
|
||||||
[invocation setArgument:&_selector atIndex:1];
|
[invocation setArgument:&_selector atIndex:1];
|
||||||
|
[invocation retainArguments];
|
||||||
|
|
||||||
// Set arguments
|
// Set arguments
|
||||||
NSUInteger index = 0;
|
NSUInteger index = 0;
|
||||||
|
@ -281,7 +450,7 @@ static Class _globalExecutorClass;
|
||||||
id arg = (json == [NSNull null]) ? nil : json;
|
id arg = (json == [NSNull null]) ? nil : json;
|
||||||
void (^block)(RCTBridge *, NSInvocation *, NSUInteger, id) = _argumentBlocks[index];
|
void (^block)(RCTBridge *, NSInvocation *, NSUInteger, id) = _argumentBlocks[index];
|
||||||
block(bridge, invocation, index + 2, arg);
|
block(bridge, invocation, index + 2, arg);
|
||||||
index ++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke method
|
// Invoke method
|
||||||
|
@ -309,18 +478,8 @@ static RCTSparseArray *RCTExportedMethodsByModuleID(void)
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
dladdr(&RCTExportedMethodsByModuleID, &info);
|
dladdr(&RCTExportedMethodsByModuleID, &info);
|
||||||
|
|
||||||
#ifdef __LP64__
|
const RCTHeaderValue mach_header = (RCTHeaderValue)info.dli_fbase;
|
||||||
typedef uint64_t RCTExportValue;
|
const RCTHeaderSection *section = RCTGetSectByNameFromHeader((void *)mach_header, "__DATA", "RCTExport");
|
||||||
typedef struct section_64 RCTExportSection;
|
|
||||||
#define RCTGetSectByNameFromHeader getsectbynamefromheader_64
|
|
||||||
#else
|
|
||||||
typedef uint32_t RCTExportValue;
|
|
||||||
typedef struct section RCTExportSection;
|
|
||||||
#define RCTGetSectByNameFromHeader getsectbynamefromheader
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const RCTExportValue mach_header = (RCTExportValue)info.dli_fbase;
|
|
||||||
const RCTExportSection *section = RCTGetSectByNameFromHeader((void *)mach_header, "__DATA", "RCTExport");
|
|
||||||
|
|
||||||
if (section == NULL) {
|
if (section == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -329,7 +488,7 @@ static RCTSparseArray *RCTExportedMethodsByModuleID(void)
|
||||||
NSArray *classes = RCTBridgeModuleClassesByModuleID();
|
NSArray *classes = RCTBridgeModuleClassesByModuleID();
|
||||||
NSMutableDictionary *methodsByModuleClassName = [NSMutableDictionary dictionaryWithCapacity:[classes count]];
|
NSMutableDictionary *methodsByModuleClassName = [NSMutableDictionary dictionaryWithCapacity:[classes count]];
|
||||||
|
|
||||||
for (RCTExportValue addr = section->offset;
|
for (RCTHeaderValue addr = section->offset;
|
||||||
addr < section->offset + section->size;
|
addr < section->offset + section->size;
|
||||||
addr += sizeof(const char **) * 2) {
|
addr += sizeof(const char **) * 2) {
|
||||||
|
|
||||||
|
@ -530,11 +689,7 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
- (void)setUp
|
- (void)setUp
|
||||||
{
|
{
|
||||||
Class executorClass = _executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class];
|
Class executorClass = _executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class];
|
||||||
if ([NSStringFromClass(executorClass) isEqualToString:@"RCTWebViewExecutor"]) {
|
_javaScriptExecutor = [[executorClass alloc] init];
|
||||||
_javaScriptExecutor = [[RCTWebViewExecutor alloc] initWithWebView:[[UIWebView alloc] init]];
|
|
||||||
} else {
|
|
||||||
_javaScriptExecutor = [[executorClass alloc] init];
|
|
||||||
}
|
|
||||||
_latestJSExecutor = _javaScriptExecutor;
|
_latestJSExecutor = _javaScriptExecutor;
|
||||||
_eventDispatcher = [[RCTEventDispatcher alloc] initWithBridge:self];
|
_eventDispatcher = [[RCTEventDispatcher alloc] initWithBridge:self];
|
||||||
_shadowQueue = dispatch_queue_create("com.facebook.ReactKit.ShadowQueue", DISPATCH_QUEUE_SERIAL);
|
_shadowQueue = dispatch_queue_create("com.facebook.ReactKit.ShadowQueue", DISPATCH_QUEUE_SERIAL);
|
||||||
|
@ -598,32 +753,34 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
_loaded = YES;
|
_loaded = YES;
|
||||||
} else if (_bundlePath != nil) { // Allow testing without a script
|
} else if (_bundlePath != nil) { // Allow testing without a script
|
||||||
RCTJavaScriptLoader *loader = [[RCTJavaScriptLoader alloc] initWithBridge:self];
|
RCTJavaScriptLoader *loader = [[RCTJavaScriptLoader alloc] initWithBridge:self];
|
||||||
[loader loadBundleAtURL:[NSURL URLWithString:_bundlePath]
|
[loader loadBundleAtURL:[NSURL URLWithString:_bundlePath] onComplete:^(NSError *error) {
|
||||||
onComplete:^(NSError *error) {
|
_loaded = YES;
|
||||||
_loaded = YES;
|
if (error != nil) {
|
||||||
if (error != nil) {
|
NSArray *stack = [[error userInfo] objectForKey:@"stack"];
|
||||||
NSArray *stack = [[error userInfo] objectForKey:@"stack"];
|
if (stack) {
|
||||||
if (stack) {
|
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription]
|
||||||
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription] withStack:stack];
|
withStack:stack];
|
||||||
} else {
|
} else {
|
||||||
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription] withDetails:[error localizedFailureReason]];
|
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription]
|
||||||
}
|
withDetails:[error localizedFailureReason]];
|
||||||
} else {
|
}
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
|
} else {
|
||||||
object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
object:self];
|
||||||
selector:@selector(reload)
|
}
|
||||||
name:RCTReloadNotification
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
object:nil];
|
selector:@selector(reload)
|
||||||
;
|
name:RCTReloadNotification
|
||||||
}
|
object:nil];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)bindKeys
|
- (void)bindKeys
|
||||||
{
|
{
|
||||||
#if TARGET_IPHONE_SIMULATOR
|
#if TARGET_IPHONE_SIMULATOR
|
||||||
|
__weak RCTBridge *weakSelf = self;
|
||||||
|
|
||||||
// Workaround around the first cmd+r not working: http://openradar.appspot.com/19613391
|
// Workaround around the first cmd+r not working: http://openradar.appspot.com/19613391
|
||||||
// You can register just the cmd key and do nothing. This will trigger the bug and cmd+r
|
// You can register just the cmd key and do nothing. This will trigger the bug and cmd+r
|
||||||
// will work like a charm!
|
// will work like a charm!
|
||||||
|
@ -632,31 +789,38 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
action:^(UIKeyCommand *command) {
|
action:^(UIKeyCommand *command) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r"
|
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r"
|
||||||
modifierFlags:UIKeyModifierCommand
|
modifierFlags:UIKeyModifierCommand
|
||||||
action:^(UIKeyCommand *command) {
|
action:^(UIKeyCommand *command) {
|
||||||
[self reload];
|
[weakSelf reload];
|
||||||
}];
|
}];
|
||||||
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"n"
|
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"n"
|
||||||
modifierFlags:UIKeyModifierCommand
|
modifierFlags:UIKeyModifierCommand
|
||||||
action:^(UIKeyCommand *command) {
|
action:^(UIKeyCommand *command) {
|
||||||
_executorClass = Nil;
|
RCTBridge *strongSelf = weakSelf;
|
||||||
[self reload];
|
if (!strongSelf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strongSelf->_executorClass = Nil;
|
||||||
|
[strongSelf reload];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"d"
|
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"d"
|
||||||
modifierFlags:UIKeyModifierCommand
|
modifierFlags:UIKeyModifierCommand
|
||||||
action:^(UIKeyCommand *command) {
|
action:^(UIKeyCommand *command) {
|
||||||
_executorClass = NSClassFromString(@"RCTWebSocketExecutor");
|
RCTBridge *strongSelf = weakSelf;
|
||||||
if (!_executorClass) {
|
if (!strongSelf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strongSelf->_executorClass = NSClassFromString(@"RCTWebSocketExecutor");
|
||||||
|
if (!strongSelf->_executorClass) {
|
||||||
RCTLogError(@"WebSocket debugger is not available. Did you forget to include RCTWebSocketExecutor?");
|
RCTLogError(@"WebSocket debugger is not available. Did you forget to include RCTWebSocketExecutor?");
|
||||||
}
|
}
|
||||||
[self reload];
|
[strongSelf reload];
|
||||||
}];
|
}];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSDictionary *)modules
|
- (NSDictionary *)modules
|
||||||
{
|
{
|
||||||
RCTAssert(_modulesByName != nil, @"Bridge modules have not yet been initialized. \
|
RCTAssert(_modulesByName != nil, @"Bridge modules have not yet been initialized. \
|
||||||
|
@ -693,6 +857,11 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
[_javaScriptExecutor invalidate];
|
[_javaScriptExecutor invalidate];
|
||||||
_javaScriptExecutor = nil;
|
_javaScriptExecutor = nil;
|
||||||
|
|
||||||
|
// Wait for queued methods to finish
|
||||||
|
dispatch_sync(self.shadowQueue, ^{
|
||||||
|
// Make sure all dispatchers have been executed before continuing
|
||||||
|
});
|
||||||
|
|
||||||
// Invalidate modules
|
// Invalidate modules
|
||||||
for (id target in _modulesByID.allObjects) {
|
for (id target in _modulesByID.allObjects) {
|
||||||
if ([target respondsToSelector:@selector(invalidate)]) {
|
if ([target respondsToSelector:@selector(invalidate)]) {
|
||||||
|
@ -888,15 +1057,9 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)hasValidJSExecutor
|
|
||||||
{
|
|
||||||
return (_latestJSExecutor != nil && [_latestJSExecutor isValid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)logMessage:(NSString *)message level:(NSString *)level
|
+ (void)logMessage:(NSString *)message level:(NSString *)level
|
||||||
{
|
{
|
||||||
if (!_latestJSExecutor || ![_latestJSExecutor isValid]) {
|
if (!_latestJSExecutor || ![_latestJSExecutor isValid]) {
|
||||||
RCTLogError(@"ERROR: No valid JS executor to log '%@'.", message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import "RCTJSMethodRegistrar.h"
|
|
||||||
|
|
||||||
@class RCTBridge;
|
@class RCTBridge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +20,7 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
||||||
/**
|
/**
|
||||||
* Provides the interface needed to register a bridge module.
|
* Provides the interface needed to register a bridge module.
|
||||||
*/
|
*/
|
||||||
@protocol RCTBridgeModule <RCTJSMethodRegistrar>
|
@protocol RCTBridgeModule <NSObject>
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,10 +32,14 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
||||||
@property (nonatomic, strong) RCTBridge *bridge;
|
@property (nonatomic, strong) RCTBridge *bridge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The module name exposed to JS. If omitted, this will be inferred
|
* Place this macro in your class implementation, to automatically register
|
||||||
* automatically by using the native module's class name.
|
* 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.
|
||||||
*/
|
*/
|
||||||
+ (NSString *)moduleName;
|
#define RCT_EXPORT_MODULE(js_name) \
|
||||||
|
+ (NSString *)moduleName { __attribute__((used, section("__DATA,RCTExportModule" \
|
||||||
|
))) static const char *__rct_export_entry__ = { __func__ }; return @#js_name; } \
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place this macro inside the method body of any method you want to expose
|
* Place this macro inside the method body of any method you want to expose
|
||||||
|
@ -46,8 +48,37 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
||||||
* If omitted, the JS method name will match the first part of the Objective-C
|
* If omitted, the JS method name will match the first part of the Objective-C
|
||||||
* method selector name (up to the first colon).
|
* method selector name (up to the first colon).
|
||||||
*/
|
*/
|
||||||
#define RCT_EXPORT(js_name) __attribute__((used, section("__DATA,RCTExport" \
|
#define RCT_EXPORT(js_name) \
|
||||||
))) static const char *__rct_export_entry__[] = { __func__, #js_name }
|
_Pragma("message(\"RCT_EXPORT is deprecated. Use RCT_EXPORT_METHOD instead.\")") \
|
||||||
|
__attribute__((used, section("__DATA,RCTExport"))) \
|
||||||
|
static const char *__rct_export_entry__[] = { __func__, #js_name }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap the parameter line of your method implementation with this macro to
|
||||||
|
* expose it to JS. Unlike the deprecated RCT_EXPORT, this macro does not take
|
||||||
|
* a js_name argument and the exposed method will match the first part of the
|
||||||
|
* Objective-C method selector name (up to the first colon).
|
||||||
|
*
|
||||||
|
* For example, in MyClass.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`.
|
||||||
|
*/
|
||||||
|
#define RCT_EXPORT_METHOD(method) \
|
||||||
|
- (void)__rct_export__##method { \
|
||||||
|
__attribute__((used, section("__DATA,RCTExport"))) \
|
||||||
|
static const char *__rct_export_entry__[] = { __func__, #method }; \
|
||||||
|
} \
|
||||||
|
- (void)method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects constants into JS. These constants are made accessible via
|
* Injects constants into JS. These constants are made accessible via
|
||||||
|
@ -65,3 +96,11 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
||||||
- (void)batchDidComplete;
|
- (void)batchDidComplete;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void RCTBridgeModuleRegisterClass(Class cls, NSString *moduleName);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -82,14 +82,26 @@
|
||||||
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family
|
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family
|
||||||
size:(id)size weight:(id)weight style:(id)style;
|
size:(id)size weight:(id)weight style:(id)style;
|
||||||
|
|
||||||
+ (NSArray *)NSStringArray:(id)json;
|
typedef NSArray NSStringArray;
|
||||||
+ (NSArray *)NSDictionaryArray:(id)json;
|
+ (NSStringArray *)NSStringArray:(id)json;
|
||||||
+ (NSArray *)NSURLArray:(id)json;
|
|
||||||
+ (NSArray *)NSNumberArray:(id)json;
|
|
||||||
+ (NSArray *)UIColorArray:(id)json;
|
|
||||||
+ (NSArray *)CGColorArray:(id)json;
|
|
||||||
|
|
||||||
+ (BOOL)css_overflow:(id)json;
|
typedef NSArray NSDictionaryArray;
|
||||||
|
+ (NSDictionaryArray *)NSDictionaryArray:(id)json;
|
||||||
|
|
||||||
|
typedef NSArray NSURLArray;
|
||||||
|
+ (NSURLArray *)NSURLArray:(id)json;
|
||||||
|
|
||||||
|
typedef NSArray NSNumberArray;
|
||||||
|
+ (NSNumberArray *)NSNumberArray:(id)json;
|
||||||
|
|
||||||
|
typedef NSArray UIColorArray;
|
||||||
|
+ (UIColorArray *)UIColorArray:(id)json;
|
||||||
|
|
||||||
|
typedef NSArray CGColorArray;
|
||||||
|
+ (CGColorArray *)CGColorArray:(id)json;
|
||||||
|
|
||||||
|
typedef BOOL css_overflow;
|
||||||
|
+ (css_overflow)css_overflow:(id)json;
|
||||||
+ (css_flex_direction_t)css_flex_direction_t:(id)json;
|
+ (css_flex_direction_t)css_flex_direction_t:(id)json;
|
||||||
+ (css_justify_t)css_justify_t:(id)json;
|
+ (css_justify_t)css_justify_t:(id)json;
|
||||||
+ (css_align_t)css_align_t:(id)json;
|
+ (css_align_t)css_align_t:(id)json;
|
||||||
|
@ -195,7 +207,7 @@ RCT_CUSTOM_CONVERTER(type, type, [[self NSNumber:json] getter])
|
||||||
* This macro is used for creating converter functions for typed arrays.
|
* This macro is used for creating converter functions for typed arrays.
|
||||||
*/
|
*/
|
||||||
#define RCT_ARRAY_CONVERTER(type) \
|
#define RCT_ARRAY_CONVERTER(type) \
|
||||||
+ (NSArray *)type##Array:(id)json \
|
+ (type##Array *)type##Array:(id)json \
|
||||||
{ \
|
{ \
|
||||||
NSMutableArray *values = [[NSMutableArray alloc] init]; \
|
NSMutableArray *values = [[NSMutableArray alloc] init]; \
|
||||||
for (id jsonValue in [self NSArray:json]) { \
|
for (id jsonValue in [self NSArray:json]) { \
|
||||||
|
|
|
@ -670,11 +670,6 @@ static BOOL RCTFontIsCondensed(UIFont *font)
|
||||||
isCondensed = RCTFontIsCondensed(font);
|
isCondensed = RCTFontIsCondensed(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get font weight
|
|
||||||
if (weight) {
|
|
||||||
fontWeight = [self RCTFontWeight:weight];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get font style
|
// Get font style
|
||||||
if (style) {
|
if (style) {
|
||||||
isItalic = [self RCTFontStyle:style];
|
isItalic = [self RCTFontStyle:style];
|
||||||
|
@ -700,6 +695,11 @@ static BOOL RCTFontIsCondensed(UIFont *font)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get font weight
|
||||||
|
if (weight) {
|
||||||
|
fontWeight = [self RCTFontWeight:weight];
|
||||||
|
}
|
||||||
|
|
||||||
// Get closest match
|
// Get closest match
|
||||||
UIFont *bestMatch = font;
|
UIFont *bestMatch = font;
|
||||||
CGFloat closestWeight = font ? RCTWeightOfFont(font) : INFINITY;
|
CGFloat closestWeight = font ? RCTWeightOfFont(font) : INFINITY;
|
||||||
|
@ -742,8 +742,6 @@ RCT_ARRAY_CONVERTER(UIColor)
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BOOL css_overflow;
|
|
||||||
|
|
||||||
RCT_ENUM_CONVERTER(css_overflow, (@{
|
RCT_ENUM_CONVERTER(css_overflow, (@{
|
||||||
@"hidden": @NO,
|
@"hidden": @NO,
|
||||||
@"visible": @YES
|
@"visible": @YES
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#import "RCTRedBox.h"
|
#import "RCTRedBox.h"
|
||||||
#import "RCTRootView.h"
|
#import "RCTRootView.h"
|
||||||
#import "RCTSourceCode.h"
|
#import "RCTSourceCode.h"
|
||||||
|
#import "RCTWebViewExecutor.h"
|
||||||
|
|
||||||
@interface RCTDevMenu () <UIActionSheetDelegate> {
|
@interface RCTDevMenu () <UIActionSheetDelegate> {
|
||||||
BOOL _liveReload;
|
BOOL _liveReload;
|
||||||
|
@ -33,13 +34,14 @@
|
||||||
|
|
||||||
- (void)show
|
- (void)show
|
||||||
{
|
{
|
||||||
NSString *debugTitle = self.bridge.executorClass == Nil ? @"Enable Debugging" : @"Disable Debugging";
|
NSString *debugTitleChrome = self.bridge.executorClass != Nil && self.bridge.executorClass == NSClassFromString(@"RCTWebSocketExecutor") ? @"Disable Chrome Debugging" : @"Enable Chrome Debugging";
|
||||||
|
NSString *debugTitleSafari = self.bridge.executorClass == [RCTWebViewExecutor class] ? @"Disable Safari Debugging" : @"Enable Safari Debugging";
|
||||||
NSString *liveReloadTitle = _liveReload ? @"Disable Live Reload" : @"Enable Live Reload";
|
NSString *liveReloadTitle = _liveReload ? @"Disable Live Reload" : @"Enable Live Reload";
|
||||||
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"React Native: Development"
|
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"React Native: Development"
|
||||||
delegate:self
|
delegate:self
|
||||||
cancelButtonTitle:@"Cancel"
|
cancelButtonTitle:@"Cancel"
|
||||||
destructiveButtonTitle:nil
|
destructiveButtonTitle:nil
|
||||||
otherButtonTitles:@"Reload", debugTitle, liveReloadTitle, nil];
|
otherButtonTitles:@"Reload", debugTitleChrome, debugTitleSafari, liveReloadTitle, nil];
|
||||||
actionSheet.actionSheetStyle = UIBarStyleBlack;
|
actionSheet.actionSheetStyle = UIBarStyleBlack;
|
||||||
[actionSheet showInView:[[[[UIApplication sharedApplication] keyWindow] rootViewController] view]];
|
[actionSheet showInView:[[[[UIApplication sharedApplication] keyWindow] rootViewController] view]];
|
||||||
}
|
}
|
||||||
|
@ -49,9 +51,14 @@
|
||||||
if (buttonIndex == 0) {
|
if (buttonIndex == 0) {
|
||||||
[self.bridge reload];
|
[self.bridge reload];
|
||||||
} else if (buttonIndex == 1) {
|
} else if (buttonIndex == 1) {
|
||||||
self.bridge.executorClass = self.bridge.executorClass == Nil ? NSClassFromString(@"RCTWebSocketExecutor") : nil;
|
Class cls = NSClassFromString(@"RCTWebSocketExecutor");
|
||||||
|
self.bridge.executorClass = (self.bridge.executorClass != cls) ? cls : nil;
|
||||||
[self.bridge reload];
|
[self.bridge reload];
|
||||||
} else if (buttonIndex == 2) {
|
} else if (buttonIndex == 2) {
|
||||||
|
Class cls = [RCTWebViewExecutor class];
|
||||||
|
self.bridge.executorClass = (self.bridge.executorClass != cls) ? cls : Nil;
|
||||||
|
[self.bridge reload];
|
||||||
|
} else if (buttonIndex == 3) {
|
||||||
_liveReload = !_liveReload;
|
_liveReload = !_liveReload;
|
||||||
[self _pollAndReload];
|
[self _pollAndReload];
|
||||||
}
|
}
|
||||||
|
@ -60,7 +67,7 @@
|
||||||
- (void)_pollAndReload
|
- (void)_pollAndReload
|
||||||
{
|
{
|
||||||
if (_liveReload) {
|
if (_liveReload) {
|
||||||
RCTSourceCode *sourceCodeModule = self.bridge.modules[NSStringFromClass([RCTSourceCode class])];
|
RCTSourceCode *sourceCodeModule = self.bridge.modules[RCTBridgeModuleNameForClass([RCTSourceCode class])];
|
||||||
NSURL *url = sourceCodeModule.scriptURL;
|
NSURL *url = sourceCodeModule.scriptURL;
|
||||||
NSURL *longPollURL = [[NSURL alloc] initWithString:@"/onchange" relativeToURL:url];
|
NSURL *longPollURL = [[NSURL alloc] initWithString:@"/onchange" relativeToURL:url];
|
||||||
[self performSelectorInBackground:@selector(_checkForUpdates:) withObject:longPollURL];
|
[self performSelectorInBackground:@selector(_checkForUpdates:) withObject:longPollURL];
|
||||||
|
|
|
@ -25,14 +25,9 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)JSMethods
|
RCT_IMPORT_METHOD(RCTNativeAppEventEmitter, emit);
|
||||||
{
|
RCT_IMPORT_METHOD(RCTDeviceEventEmitter, emit);
|
||||||
return @[
|
RCT_IMPORT_METHOD(RCTEventEmitter, receiveEvent);
|
||||||
@"RCTNativeAppEventEmitter.emit",
|
|
||||||
@"RCTDeviceEventEmitter.emit",
|
|
||||||
@"RCTEventEmitter.receiveEvent",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendAppEventWithName:(NSString *)name body:(id)body
|
- (void)sendAppEventWithName:(NSString *)name body:(id)body
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,15 +104,20 @@
|
||||||
if ([response isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)response statusCode] != 200) {
|
if ([response isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)response statusCode] != 200) {
|
||||||
NSDictionary *userInfo;
|
NSDictionary *userInfo;
|
||||||
NSDictionary *errorDetails = RCTJSONParse(rawText, nil);
|
NSDictionary *errorDetails = RCTJSONParse(rawText, nil);
|
||||||
if ([errorDetails isKindOfClass:[NSDictionary class]]) {
|
if ([errorDetails isKindOfClass:[NSDictionary class]] &&
|
||||||
|
[errorDetails[@"errors"] isKindOfClass:[NSArray class]]) {
|
||||||
|
NSMutableArray *fakeStack = [[NSMutableArray alloc] init];
|
||||||
|
for (NSDictionary *err in errorDetails[@"errors"]) {
|
||||||
|
[fakeStack addObject: @{
|
||||||
|
@"methodName": err[@"description"] ?: @"",
|
||||||
|
@"file": err[@"filename"] ?: @"",
|
||||||
|
@"lineNumber": err[@"lineNumber"] ?: @0
|
||||||
|
}];
|
||||||
|
}
|
||||||
userInfo = @{
|
userInfo = @{
|
||||||
NSLocalizedDescriptionKey: errorDetails[@"message"] ?: @"No message provided",
|
NSLocalizedDescriptionKey: errorDetails[@"message"] ?: @"No message provided",
|
||||||
@"stack": @[@{
|
@"stack": fakeStack,
|
||||||
@"methodName": errorDetails[@"description"] ?: @"",
|
};
|
||||||
@"file": errorDetails[@"filename"] ?: @"",
|
|
||||||
@"lineNumber": errorDetails[@"lineNumber"] ?: @0
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
userInfo = @{NSLocalizedDescriptionKey: rawText};
|
userInfo = @{NSLocalizedDescriptionKey: rawText};
|
||||||
}
|
}
|
||||||
|
@ -123,7 +128,7 @@
|
||||||
onComplete(error);
|
onComplete(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RCTSourceCode *sourceCodeModule = _bridge.modules[NSStringFromClass([RCTSourceCode class])];
|
RCTSourceCode *sourceCodeModule = _bridge.modules[RCTBridgeModuleNameForClass([RCTSourceCode class])];
|
||||||
sourceCodeModule.scriptURL = scriptURL;
|
sourceCodeModule.scriptURL = scriptURL;
|
||||||
sourceCodeModule.scriptText = rawText;
|
sourceCodeModule.scriptText = rawText;
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,7 @@ typedef NS_ENUM(NSInteger, RCTLogLevel) {
|
||||||
/**
|
/**
|
||||||
* A block signature to be used for custom logging functions. In most cases you
|
* 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
|
* will want to pass these arguments to the RCTFormatLog function in order to
|
||||||
* generate a string, or use the RCTSimpleLogFunction() constructor to register
|
* generate a string.
|
||||||
* a simple function that does not use all of the arguments.
|
|
||||||
*/
|
*/
|
||||||
typedef void (^RCTLogFunction)(
|
typedef void (^RCTLogFunction)(
|
||||||
RCTLogLevel level,
|
RCTLogLevel level,
|
||||||
|
@ -65,13 +64,6 @@ NSString *RCTFormatLog(
|
||||||
NSString *message
|
NSString *message
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* A method to generate a log function from a block with a much simpler
|
|
||||||
* template. The message passed to the simpler block is equivalent to the
|
|
||||||
* output of the RCTFormatLog() function.
|
|
||||||
*/
|
|
||||||
RCTLogFunction RCTSimpleLogFunction(void (^logFunction)(RCTLogLevel level, NSString *message));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default logging function used by RCTLogXX.
|
* The default logging function used by RCTLogXX.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -116,12 +116,11 @@ NSString *RCTFormatLog(
|
||||||
});
|
});
|
||||||
[log appendString:[formatter stringFromDate:timestamp]];
|
[log appendString:[formatter stringFromDate:timestamp]];
|
||||||
}
|
}
|
||||||
[log appendString:@"[react]"];
|
|
||||||
if (level) {
|
if (level) {
|
||||||
[log appendFormat:@"[%s]", RCTLogLevels[level - 1]];
|
[log appendFormat:@"[%s]", RCTLogLevels[level - 1]];
|
||||||
}
|
}
|
||||||
if (thread) {
|
if (thread) {
|
||||||
NSString *threadName = thread.name;
|
NSString *threadName = [thread isMainThread] ? @"main" : thread.name;
|
||||||
if (threadName.length == 0) {
|
if (threadName.length == 0) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
@ -149,19 +148,6 @@ NSString *RCTFormatLog(
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTLogFunction RCTSimpleLogFunction(void (^logFunction)(RCTLogLevel level, NSString *message))
|
|
||||||
{
|
|
||||||
return ^(RCTLogLevel level,
|
|
||||||
NSString *fileName,
|
|
||||||
NSNumber *lineNumber,
|
|
||||||
NSString *message) {
|
|
||||||
|
|
||||||
logFunction(level, RCTFormatLog(
|
|
||||||
[NSDate date], [NSThread currentThread], level, fileName, lineNumber, message
|
|
||||||
));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void _RCTLogFormat(RCTLogLevel level, const char *fileName, int lineNumber, NSString *format, ...)
|
void _RCTLogFormat(RCTLogLevel level, const char *fileName, int lineNumber, NSString *format, ...)
|
||||||
{
|
{
|
||||||
if (RCTCurrentLogFunction && level >= RCTCurrentLogThreshold) {
|
if (RCTCurrentLogFunction && level >= RCTCurrentLogThreshold) {
|
||||||
|
@ -193,9 +179,7 @@ void _RCTLogFormat(RCTLogLevel level, const char *fileName, int lineNumber, NSSt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log to JS executor
|
// Log to JS executor
|
||||||
if ([RCTBridge hasValidJSExecutor]) {
|
[RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"];
|
||||||
[RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@
|
||||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
|
||||||
cell.textLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
|
cell.textLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
|
||||||
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
|
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
|
||||||
|
cell.textLabel.numberOfLines = 2;
|
||||||
cell.detailTextLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
|
cell.detailTextLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
|
||||||
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
|
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
|
||||||
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
||||||
|
@ -196,7 +197,7 @@
|
||||||
CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
|
CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
|
||||||
return ceil(boundingRect.size.height) + 40;
|
return ceil(boundingRect.size.height) + 40;
|
||||||
} else {
|
} else {
|
||||||
return 44;
|
return 50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,8 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)JSMethods
|
RCT_IMPORT_METHOD(AppRegistry, runApplication)
|
||||||
{
|
RCT_IMPORT_METHOD(ReactIOS, unmountComponentAtNodeAndRemoveContainer)
|
||||||
return @[
|
|
||||||
@"AppRegistry.runApplication",
|
|
||||||
@"ReactIOS.unmountComponentAtNodeAndRemoveContainer"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)bundleFinishedLoading
|
- (void)bundleFinishedLoading
|
||||||
{
|
{
|
||||||
|
@ -176,9 +171,9 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification";
|
||||||
_registered = YES;
|
_registered = YES;
|
||||||
NSString *moduleName = _moduleName ?: @"";
|
NSString *moduleName = _moduleName ?: @"";
|
||||||
NSDictionary *appParameters = @{
|
NSDictionary *appParameters = @{
|
||||||
@"rootTag": _contentView.reactTag,
|
@"rootTag": _contentView.reactTag,
|
||||||
@"initialProps": self.initialProperties ?: @{},
|
@"initialProps": self.initialProperties ?: @{},
|
||||||
};
|
};
|
||||||
[_bridge.uiManager registerRootView:_contentView];
|
[_bridge.uiManager registerRootView:_contentView];
|
||||||
[_bridge enqueueJSCall:@"AppRegistry.runApplication"
|
[_bridge enqueueJSCall:@"AppRegistry.runApplication"
|
||||||
args:@[moduleName, appParameters]];
|
args:@[moduleName, appParameters]];
|
||||||
|
|
|
@ -200,10 +200,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
|
||||||
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
|
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)JSMethods
|
RCT_IMPORT_METHOD(RCTEventEmitter, receiveTouches);
|
||||||
{
|
|
||||||
return @[@"RCTEventEmitter.receiveTouches"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs information about touch events to send across the serialized
|
* Constructs information about touch events to send across the serialized
|
||||||
|
|
|
@ -45,9 +45,6 @@ void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
|
||||||
BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
|
BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
|
||||||
BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
||||||
|
|
||||||
// Enumerate all classes that conform to NSObject protocol
|
|
||||||
void RCTEnumerateClasses(void (^block)(Class cls));
|
|
||||||
|
|
||||||
// Creates a standardized error object
|
// Creates a standardized error object
|
||||||
// TODO(#6472857): create NSErrors and automatically convert them over the bridge.
|
// TODO(#6472857): create NSErrors and automatically convert them over the bridge.
|
||||||
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData);
|
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData);
|
||||||
|
|
|
@ -183,31 +183,6 @@ BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector)
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTEnumerateClasses(void (^block)(Class cls))
|
|
||||||
{
|
|
||||||
static Class *classes;
|
|
||||||
static unsigned int classCount;
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
classes = objc_copyClassList(&classCount);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < classCount; i++)
|
|
||||||
{
|
|
||||||
Class cls = classes[i];
|
|
||||||
Class superclass = cls;
|
|
||||||
while (superclass)
|
|
||||||
{
|
|
||||||
if (class_conformsToProtocol(superclass, @protocol(NSObject)))
|
|
||||||
{
|
|
||||||
block(cls);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
superclass = class_getSuperclass(superclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData)
|
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData)
|
||||||
{
|
{
|
||||||
if (toStringify) {
|
if (toStringify) {
|
||||||
|
|
|
@ -125,6 +125,8 @@ static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...)
|
||||||
RCTAssert(onComplete != nil, @"");
|
RCTAssert(onComplete != nil, @"");
|
||||||
_onApplicationScriptLoaded = onComplete;
|
_onApplicationScriptLoaded = onComplete;
|
||||||
|
|
||||||
|
script = [script stringByReplacingOccurrencesOfString:@"<script>" withString:@""];
|
||||||
|
script = [script stringByReplacingOccurrencesOfString:@"</script>" withString:@""];
|
||||||
if (_objectsToInject.count > 0) {
|
if (_objectsToInject.count > 0) {
|
||||||
NSMutableString *scriptWithInjections = [[NSMutableString alloc] initWithString:@"/* BEGIN NATIVELY INJECTED OBJECTS */\n"];
|
NSMutableString *scriptWithInjections = [[NSMutableString alloc] initWithString:@"/* BEGIN NATIVELY INJECTED OBJECTS */\n"];
|
||||||
[_objectsToInject enumerateKeysAndObjectsUsingBlock:^(NSString *objectName, NSString *blockScript, BOOL *stop) {
|
[_objectsToInject enumerateKeysAndObjectsUsingBlock:^(NSString *objectName, NSString *blockScript, BOOL *stop) {
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
NSMutableArray *_alertButtonKeys;
|
NSMutableArray *_alertButtonKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -47,10 +49,9 @@
|
||||||
* Buttons are displayed in the order they are specified. If "cancel" is used as
|
* Buttons are displayed in the order they are specified. If "cancel" is used as
|
||||||
* the button key, it will be differently highlighted, according to iOS UI conventions.
|
* the button key, it will be differently highlighted, according to iOS UI conventions.
|
||||||
*/
|
*/
|
||||||
- (void)alertWithArgs:(NSDictionary *)args callback:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
NSString *title = args[@"title"];
|
NSString *title = args[@"title"];
|
||||||
NSString *message = args[@"message"];
|
NSString *message = args[@"message"];
|
||||||
NSArray *buttons = args[@"buttons"];
|
NSArray *buttons = args[@"buttons"];
|
||||||
|
|
|
@ -35,6 +35,8 @@ static NSString *RCTCurrentAppBackgroundState()
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
|
@ -79,11 +81,9 @@ static NSString *RCTCurrentAppBackgroundState()
|
||||||
/**
|
/**
|
||||||
* Get the current background/foreground state of the app
|
* Get the current background/foreground state of the app
|
||||||
*/
|
*/
|
||||||
- (void)getCurrentAppState:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(getCurrentAppState:(RCTResponseSenderBlock)callback
|
||||||
error:(__unused RCTResponseSenderBlock)error
|
error:(__unused RCTResponseSenderBlock)error)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
callback(@[@{@"app_state": _lastKnownState}]);
|
callback(@[@{@"app_state": _lastKnownState}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,8 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
NSString *_storageDirectory;
|
NSString *_storageDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (NSString *)_filePathForKey:(NSString *)key
|
- (NSString *)_filePathForKey:(NSString *)key
|
||||||
{
|
{
|
||||||
NSString *safeFileName = RCTMD5Hash(key);
|
NSString *safeFileName = RCTMD5Hash(key);
|
||||||
|
@ -186,10 +188,9 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
|
|
||||||
#pragma mark - Exported JS Functions
|
#pragma mark - Exported JS Functions
|
||||||
|
|
||||||
- (void)multiGet:(NSArray *)keys callback:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(multiGet:(NSArray *)keys
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
RCTLogError(@"Called getItem without a callback.");
|
RCTLogError(@"Called getItem without a callback.");
|
||||||
return;
|
return;
|
||||||
|
@ -212,10 +213,9 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)multiSet:(NSArray *)kvPairs callback:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(multiSet:(NSArray *)kvPairs
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(RCTFileQueue(), ^{
|
dispatch_async(RCTFileQueue(), ^{
|
||||||
id errorOut = [self _ensureSetup];
|
id errorOut = [self _ensureSetup];
|
||||||
if (errorOut) {
|
if (errorOut) {
|
||||||
|
@ -234,10 +234,9 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)multiRemove:(NSArray *)keys callback:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(RCTFileQueue(), ^{
|
dispatch_async(RCTFileQueue(), ^{
|
||||||
id errorOut = [self _ensureSetup];
|
id errorOut = [self _ensureSetup];
|
||||||
if (errorOut) {
|
if (errorOut) {
|
||||||
|
@ -261,10 +260,8 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clear:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(clear:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(RCTFileQueue(), ^{
|
dispatch_async(RCTFileQueue(), ^{
|
||||||
id errorOut = [self _ensureSetup];
|
id errorOut = [self _ensureSetup];
|
||||||
if (!errorOut) {
|
if (!errorOut) {
|
||||||
|
@ -282,10 +279,8 @@ static dispatch_queue_t RCTFileQueue(void)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getAllKeys:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(RCTFileQueue(), ^{
|
dispatch_async(RCTFileQueue(), ^{
|
||||||
id errorOut = [self _ensureSetup];
|
id errorOut = [self _ensureSetup];
|
||||||
if (errorOut) {
|
if (errorOut) {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
__weak id<RCTExceptionsManagerDelegate> _delegate;
|
__weak id<RCTExceptionsManagerDelegate> _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate
|
- (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
@ -29,10 +31,9 @@
|
||||||
return [self initWithDelegate:nil];
|
return [self initWithDelegate:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reportUnhandledExceptionWithMessage:(NSString *)message stack:(NSArray *)stack
|
RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
|
||||||
|
stack:(NSArray *)stack)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(reportUnhandledException);
|
|
||||||
|
|
||||||
if (_delegate) {
|
if (_delegate) {
|
||||||
[_delegate unhandledJSExceptionWithMessage:message stack:stack];
|
[_delegate unhandledJSExceptionWithMessage:message stack:stack];
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,10 +41,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateExceptionMessage:(NSString *)message stack:(NSArray *)stack
|
RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
|
||||||
|
stack:(NSArray *)stack)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(updateExceptionMessage);
|
|
||||||
|
|
||||||
[[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack];
|
[[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
|
|
||||||
@implementation RCTSourceCode
|
@implementation RCTSourceCode
|
||||||
|
|
||||||
- (void)getScriptText:(RCTResponseSenderBlock)successCallback failureCallback:(RCTResponseSenderBlock)failureCallback
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(getScriptText:(RCTResponseSenderBlock)successCallback
|
||||||
|
failureCallback:(RCTResponseSenderBlock)failureCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
if (self.scriptText && self.scriptURL) {
|
if (self.scriptText && self.scriptURL) {
|
||||||
successCallback(@[@{@"text": self.scriptText, @"url":[self.scriptURL absoluteString]}]);
|
successCallback(@[@{@"text": self.scriptText, @"url":[self.scriptURL absoluteString]}]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,10 +24,11 @@ static BOOL RCTViewControllerBasedStatusBarAppearance()
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated
|
RCT_EXPORT_MODULE()
|
||||||
{
|
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(setStyle:(UIStatusBarStyle)statusBarStyle
|
||||||
|
animated:(BOOL)animated)
|
||||||
|
{
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
if (RCTViewControllerBasedStatusBarAppearance()) {
|
if (RCTViewControllerBasedStatusBarAppearance()) {
|
||||||
|
@ -40,10 +41,9 @@ static BOOL RCTViewControllerBasedStatusBarAppearance()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation
|
RCT_EXPORT_METHOD(setHidden:(BOOL)hidden
|
||||||
|
withAnimation:(UIStatusBarAnimation)animation)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
if (RCTViewControllerBasedStatusBarAppearance()) {
|
if (RCTViewControllerBasedStatusBarAppearance()) {
|
||||||
|
|
|
@ -63,10 +63,9 @@
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
+ (NSArray *)JSMethods
|
RCT_EXPORT_MODULE()
|
||||||
{
|
|
||||||
return @[@"RCTJSTimers.callTimers"];
|
RCT_IMPORT_METHOD(RCTJSTimers, callTimers)
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
|
@ -166,34 +165,29 @@
|
||||||
* calculating the timer's target time. We calculate this by passing in
|
* calculating the timer's target time. We calculate this by passing in
|
||||||
* Date.now() from JS and then subtracting that from the current time here.
|
* Date.now() from JS and then subtracting that from the current time here.
|
||||||
*/
|
*/
|
||||||
- (void)createTimer:(NSNumber *)callbackID
|
RCT_EXPORT_METHOD(createTimer:(NSNumber *)callbackID
|
||||||
duration:(double)jsDuration
|
duration:(NSTimeInterval)jsDuration
|
||||||
jsSchedulingTime:(double)jsSchedulingTime
|
jsSchedulingTime:(NSDate *)jsSchedulingTime
|
||||||
repeats:(BOOL)repeats
|
repeats:(BOOL)repeats)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (jsDuration == 0 && repeats == NO) {
|
if (jsDuration == 0 && repeats == NO) {
|
||||||
// For super fast, one-off timers, just enqueue them immediately rather than waiting a frame.
|
// For super fast, one-off timers, just enqueue them immediately rather than waiting a frame.
|
||||||
[_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[@[callbackID]]];
|
[_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[@[callbackID]]];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSTimeInterval interval = jsDuration / 1000;
|
NSTimeInterval jsSchedulingOverhead = -jsSchedulingTime.timeIntervalSinceNow;
|
||||||
NSTimeInterval jsCreationTimeSinceUnixEpoch = jsSchedulingTime / 1000;
|
|
||||||
NSTimeInterval currentTimeSinceUnixEpoch = [[NSDate date] timeIntervalSince1970];
|
|
||||||
NSTimeInterval jsSchedulingOverhead = currentTimeSinceUnixEpoch - jsCreationTimeSinceUnixEpoch;
|
|
||||||
if (jsSchedulingOverhead < 0) {
|
if (jsSchedulingOverhead < 0) {
|
||||||
RCTLogWarn(@"jsSchedulingOverhead (%ims) should be positive", (int)(jsSchedulingOverhead * 1000));
|
RCTLogWarn(@"jsSchedulingOverhead (%ims) should be positive", (int)(jsSchedulingOverhead * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
NSTimeInterval targetTime = interval - jsSchedulingOverhead;
|
NSTimeInterval targetTime = jsDuration - jsSchedulingOverhead;
|
||||||
if (interval < 0.018) { // Make sure short intervals run each frame
|
if (jsDuration < 0.018) { // Make sure short intervals run each frame
|
||||||
interval = 0;
|
jsDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTTimer *timer = [[RCTTimer alloc] initWithCallbackID:callbackID
|
RCTTimer *timer = [[RCTTimer alloc] initWithCallbackID:callbackID
|
||||||
interval:interval
|
interval:jsDuration
|
||||||
targetTime:targetTime
|
targetTime:targetTime
|
||||||
repeats:repeats];
|
repeats:repeats];
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
@ -202,10 +196,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)deleteTimer:(NSNumber *)timerID
|
RCT_EXPORT_METHOD(deleteTimer:(NSNumber *)timerID)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (timerID) {
|
if (timerID) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
_timers[timerID] = nil;
|
_timers[timerID] = nil;
|
||||||
|
|
|
@ -197,6 +197,8 @@ static UIViewAnimationCurve UIViewAnimationCurveFromRCTAnimationType(RCTAnimatio
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declared in RCTBridge.
|
* Declared in RCTBridge.
|
||||||
*/
|
*/
|
||||||
|
@ -209,6 +211,7 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls);
|
||||||
static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
{
|
{
|
||||||
NSString *name = moduleName;
|
NSString *name = moduleName;
|
||||||
|
RCTCAssert(name.length, @"Invalid moduleName '%@'", moduleName);
|
||||||
if ([name hasSuffix:@"Manager"]) {
|
if ([name hasSuffix:@"Manager"]) {
|
||||||
name = [name substringToIndex:name.length - @"Manager".length];
|
name = [name substringToIndex:name.length - @"Manager".length];
|
||||||
}
|
}
|
||||||
|
@ -511,10 +514,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
* A method to be called from JS, which takes a container ID and then releases
|
* A method to be called from JS, which takes a container ID and then releases
|
||||||
* all subviews for that container upon receipt.
|
* all subviews for that container upon receipt.
|
||||||
*/
|
*/
|
||||||
- (void)removeSubviewsFromContainerWithID:(NSNumber *)containerID
|
RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(NSNumber *)containerID)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
id<RCTViewNodeProtocol> container = _shadowViewRegistry[containerID];
|
id<RCTViewNodeProtocol> container = _shadowViewRegistry[containerID];
|
||||||
RCTAssert(container != nil, @"container view (for ID %@) not found", containerID);
|
RCTAssert(container != nil, @"container view (for ID %@) not found", containerID);
|
||||||
|
|
||||||
|
@ -568,10 +569,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeRootView:(NSNumber *)rootReactTag
|
RCT_EXPORT_METHOD(removeRootView:(NSNumber *)rootReactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTShadowView *rootShadowView = _shadowViewRegistry[rootReactTag];
|
RCTShadowView *rootShadowView = _shadowViewRegistry[rootReactTag];
|
||||||
RCTAssert(rootShadowView.superview == nil, @"root view cannot have superview (ID %@)", rootReactTag);
|
RCTAssert(rootShadowView.superview == nil, @"root view cannot have superview (ID %@)", rootReactTag);
|
||||||
[self _purgeChildren:rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry];
|
[self _purgeChildren:rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry];
|
||||||
|
@ -586,10 +585,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)replaceExistingNonRootView:(NSNumber *)reactTag withView:(NSNumber *)newReactTag
|
RCT_EXPORT_METHOD(replaceExistingNonRootView:(NSNumber *)reactTag withView:(NSNumber *)newReactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||||
RCTAssert(shadowView != nil, @"shadowView (for ID %@) not found", reactTag);
|
RCTAssert(shadowView != nil, @"shadowView (for ID %@) not found", reactTag);
|
||||||
|
|
||||||
|
@ -608,15 +605,13 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
removeAtIndices:removeAtIndices];
|
removeAtIndices:removeAtIndices];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)manageChildren:(NSNumber *)containerReactTag
|
RCT_EXPORT_METHOD(manageChildren:(NSNumber *)containerReactTag
|
||||||
moveFromIndices:(NSArray *)moveFromIndices
|
moveFromIndices:(NSArray *)moveFromIndices
|
||||||
moveToIndices:(NSArray *)moveToIndices
|
moveToIndices:(NSArray *)moveToIndices
|
||||||
addChildReactTags:(NSArray *)addChildReactTags
|
addChildReactTags:(NSArray *)addChildReactTags
|
||||||
addAtIndices:(NSArray *)addAtIndices
|
addAtIndices:(NSArray *)addAtIndices
|
||||||
removeAtIndices:(NSArray *)removeAtIndices
|
removeAtIndices:(NSArray *)removeAtIndices)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self _manageChildren:containerReactTag
|
[self _manageChildren:containerReactTag
|
||||||
moveFromIndices:moveFromIndices
|
moveFromIndices:moveFromIndices
|
||||||
moveToIndices:moveToIndices
|
moveToIndices:moveToIndices
|
||||||
|
@ -626,7 +621,6 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
|
||||||
registry:_shadowViewRegistry];
|
registry:_shadowViewRegistry];
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
|
|
||||||
[uiManager _manageChildren:containerReactTag
|
[uiManager _manageChildren:containerReactTag
|
||||||
moveFromIndices:moveFromIndices
|
moveFromIndices:moveFromIndices
|
||||||
moveToIndices:moveToIndices
|
moveToIndices:moveToIndices
|
||||||
|
@ -735,12 +729,10 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
[shadowView updateLayout];
|
[shadowView updateLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)createAndRegisterViewWithReactTag:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(createView:(NSNumber *)reactTag
|
||||||
viewName:(NSString *)viewName
|
viewName:(NSString *)viewName
|
||||||
props:(NSDictionary *)props
|
props:(NSDictionary *)props)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(createView);
|
|
||||||
|
|
||||||
RCTViewManager *manager = _viewManagers[viewName];
|
RCTViewManager *manager = _viewManagers[viewName];
|
||||||
if (manager == nil) {
|
if (manager == nil) {
|
||||||
RCTLogWarn(@"No manager class found for view with module name \"%@\"", viewName);
|
RCTLogWarn(@"No manager class found for view with module name \"%@\"", viewName);
|
||||||
|
@ -792,12 +784,12 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
// TODO: remove viewName param as it isn't needed
|
// TODO: remove viewName param as it isn't needed
|
||||||
- (void)updateView:(NSNumber *)reactTag viewName:(__unused NSString *)_ props:(NSDictionary *)props
|
RCT_EXPORT_METHOD(updateView:(NSNumber *)reactTag
|
||||||
|
viewName:(__unused NSString *)_
|
||||||
|
props:(NSDictionary *)props)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTViewManager *viewManager = _viewManagerRegistry[reactTag];
|
RCTViewManager *viewManager = _viewManagerRegistry[reactTag];
|
||||||
NSString *viewName = RCTViewNameForModuleName([[viewManager class] moduleName]);
|
NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([viewManager class]));
|
||||||
|
|
||||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||||
RCTSetShadowViewProps(props, shadowView, _defaultShadowViews[viewName], viewManager);
|
RCTSetShadowViewProps(props, shadowView, _defaultShadowViews[viewName], viewManager);
|
||||||
|
@ -808,10 +800,8 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)becomeResponder:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(focus:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(focus);
|
|
||||||
|
|
||||||
if (!reactTag) return;
|
if (!reactTag) return;
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
UIView *newResponder = viewRegistry[reactTag];
|
UIView *newResponder = viewRegistry[reactTag];
|
||||||
|
@ -821,10 +811,8 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resignResponder:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(blur:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(blur);
|
|
||||||
|
|
||||||
if (!reactTag) return;
|
if (!reactTag) return;
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
UIView *currentResponder = viewRegistry[reactTag];
|
UIView *currentResponder = viewRegistry[reactTag];
|
||||||
|
@ -889,10 +877,9 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)measure:(NSNumber *)reactTag callback:(RCTResponseSenderBlock)callback
|
RCT_EXPORT_METHOD(measure:(NSNumber *)reactTag
|
||||||
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
RCTLogError(@"Called measure with no callback");
|
RCTLogError(@"Called measure with no callback");
|
||||||
return;
|
return;
|
||||||
|
@ -965,13 +952,11 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
* anything on the main UI thread. Invokes supplied callback with (x, y, width,
|
* anything on the main UI thread. Invokes supplied callback with (x, y, width,
|
||||||
* height).
|
* height).
|
||||||
*/
|
*/
|
||||||
- (void)measureLayout:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(measureLayout:(NSNumber *)reactTag
|
||||||
relativeTo:(NSNumber *)ancestorReactTag
|
relativeTo:(NSNumber *)ancestorReactTag
|
||||||
errorCallback:(RCTResponseSenderBlock)errorCallback
|
errorCallback:(RCTResponseSenderBlock)errorCallback
|
||||||
callback:(RCTResponseSenderBlock)callback
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||||
RCTShadowView *ancestorShadowView = _shadowViewRegistry[ancestorReactTag];
|
RCTShadowView *ancestorShadowView = _shadowViewRegistry[ancestorReactTag];
|
||||||
RCTMeasureLayout(shadowView, ancestorShadowView, callback);
|
RCTMeasureLayout(shadowView, ancestorShadowView, callback);
|
||||||
|
@ -984,12 +969,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
* anything on the main UI thread. Invokes supplied callback with (x, y, width,
|
* anything on the main UI thread. Invokes supplied callback with (x, y, width,
|
||||||
* height).
|
* height).
|
||||||
*/
|
*/
|
||||||
- (void)measureLayoutRelativeToParent:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(measureLayoutRelativeToParent:(NSNumber *)reactTag
|
||||||
errorCallback:(RCTResponseSenderBlock)errorCallback
|
errorCallback:(RCTResponseSenderBlock)errorCallback
|
||||||
callback:(RCTResponseSenderBlock)callback
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||||
RCTMeasureLayout(shadowView, shadowView.reactSuperview, callback);
|
RCTMeasureLayout(shadowView, shadowView.reactSuperview, callback);
|
||||||
}
|
}
|
||||||
|
@ -1001,13 +984,11 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
* Only layouts for views that are within the rect passed in are returned. Invokes the error callback if the
|
* Only layouts for views that are within the rect passed in are returned. Invokes the error callback if the
|
||||||
* passed in parent view does not exist. Invokes the supplied callback with the array of computed layouts.
|
* passed in parent view does not exist. Invokes the supplied callback with the array of computed layouts.
|
||||||
*/
|
*/
|
||||||
- (void)measureViewsInRect:(NSDictionary *)rect
|
RCT_EXPORT_METHOD(measureViewsInRect:(NSDictionary *)rect
|
||||||
parentView:(NSNumber *)reactTag
|
parentView:(NSNumber *)reactTag
|
||||||
errorCallback:(RCTResponseSenderBlock)errorCallback
|
errorCallback:(RCTResponseSenderBlock)errorCallback
|
||||||
callback:(RCTResponseSenderBlock)callback
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
|
||||||
if (!shadowView) {
|
if (!shadowView) {
|
||||||
RCTLogError(@"Attempting to measure view that does not exist (tag #%@)", reactTag);
|
RCTLogError(@"Attempting to measure view that does not exist (tag #%@)", reactTag);
|
||||||
|
@ -1047,10 +1028,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
callback(@[results]);
|
callback(@[results]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setMainScrollViewTag:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(setMainScrollViewTag:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
// - There should be at most one designated "main scroll view"
|
// - There should be at most one designated "main scroll view"
|
||||||
// - There should be at most one designated "`nativeMainScrollDelegate`"
|
// - There should be at most one designated "`nativeMainScrollDelegate`"
|
||||||
|
@ -1073,10 +1052,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollToOffsetWithView:(NSNumber *)reactTag scrollToOffsetX:(NSNumber *)offsetX offsetY:(NSNumber *)offsetY
|
RCT_EXPORT_METHOD(scrollTo:(NSNumber *)reactTag
|
||||||
|
withOffsetX:(NSNumber *)offsetX
|
||||||
|
offsetY:(NSNumber *)offsetY)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(scrollTo);
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
UIView *view = viewRegistry[reactTag];
|
UIView *view = viewRegistry[reactTag];
|
||||||
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
||||||
|
@ -1087,10 +1066,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollWithoutAnimationToOffsetWithView:(NSNumber *)reactTag scrollToOffsetX:(NSNumber *)offsetX offsetY:(NSNumber *)offsetY
|
RCT_EXPORT_METHOD(scrollWithoutAnimationTo:(NSNumber *)reactTag
|
||||||
|
offsetX:(NSNumber *)offsetX
|
||||||
|
offsetY:(NSNumber *)offsetY)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(scrollWithoutAnimationTo);
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
UIView *view = viewRegistry[reactTag];
|
UIView *view = viewRegistry[reactTag];
|
||||||
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
||||||
|
@ -1101,10 +1080,9 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)zoomToRectWithView:(NSNumber *)reactTag rect:(NSDictionary *)rectDict
|
RCT_EXPORT_METHOD(zoomToRect:(NSNumber *)reactTag
|
||||||
|
withRect:(NSDictionary *)rectDict)
|
||||||
{
|
{
|
||||||
RCT_EXPORT(zoomToRect);
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
UIView *view = viewRegistry[reactTag];
|
UIView *view = viewRegistry[reactTag];
|
||||||
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
|
||||||
|
@ -1119,10 +1097,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
* JS sets what *it* considers to be the responder. Later, scroll views can use
|
* JS sets what *it* considers to be the responder. Later, scroll views can use
|
||||||
* this in order to determine if scrolling is appropriate.
|
* this in order to determine if scrolling is appropriate.
|
||||||
*/
|
*/
|
||||||
- (void)setJSResponder:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(setJSResponder:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
_jsResponder = viewRegistry[reactTag];
|
_jsResponder = viewRegistry[reactTag];
|
||||||
if (!_jsResponder) {
|
if (!_jsResponder) {
|
||||||
|
@ -1131,10 +1107,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearJSResponder
|
RCT_EXPORT_METHOD(clearJSResponder)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
_jsResponder = nil;
|
_jsResponder = nil;
|
||||||
}];
|
}];
|
||||||
|
@ -1404,12 +1378,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
return allJSConstants;
|
return allJSConstants;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)configureNextLayoutAnimation:(NSDictionary *)config
|
RCT_EXPORT_METHOD(configureNextLayoutAnimation:(NSDictionary *)config
|
||||||
withCallback:(RCTResponseSenderBlock)callback
|
withCallback:(RCTResponseSenderBlock)callback
|
||||||
errorCallback:(RCTResponseSenderBlock)errorCallback
|
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
if (_nextLayoutAnimation) {
|
if (_nextLayoutAnimation) {
|
||||||
RCTLogWarn(@"Warning: Overriding previous layout animation with new one before the first began:\n%@ -> %@.",
|
RCTLogWarn(@"Warning: Overriding previous layout animation with new one before the first began:\n%@ -> %@.",
|
||||||
_nextLayoutAnimation, config);
|
_nextLayoutAnimation, config);
|
||||||
|
@ -1417,13 +1389,12 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
if (config[@"delete"] != nil) {
|
if (config[@"delete"] != nil) {
|
||||||
RCTLogError(@"LayoutAnimation only supports create and update right now. Config: %@", config);
|
RCTLogError(@"LayoutAnimation only supports create and update right now. Config: %@", config);
|
||||||
}
|
}
|
||||||
_nextLayoutAnimation = [[RCTLayoutAnimation alloc] initWithDictionary:config callback:callback];
|
_nextLayoutAnimation = [[RCTLayoutAnimation alloc] initWithDictionary:config
|
||||||
|
callback:callback];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startOrResetInteractionTiming
|
RCT_EXPORT_METHOD(startOrResetInteractionTiming)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
NSSet *rootViewTags = [_rootViewTags copy];
|
NSSet *rootViewTags = [_rootViewTags copy];
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
for (NSNumber *reactTag in rootViewTags) {
|
for (NSNumber *reactTag in rootViewTags) {
|
||||||
|
@ -1435,11 +1406,9 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)endAndResetInteractionTiming:(RCTResponseSenderBlock)onSuccess
|
RCT_EXPORT_METHOD(endAndResetInteractionTiming:(RCTResponseSenderBlock)onSuccess
|
||||||
onError:(RCTResponseSenderBlock)onError
|
onError:(RCTResponseSenderBlock)onError)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
NSSet *rootViewTags = [_rootViewTags copy];
|
NSSet *rootViewTags = [_rootViewTags copy];
|
||||||
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
NSMutableDictionary *timingData = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *timingData = [[NSMutableDictionary alloc] init];
|
||||||
|
@ -1449,7 +1418,7 @@ static void RCTMeasureLayout(RCTShadowView *view,
|
||||||
timingData[reactTag.stringValue] = [rootView endAndResetInteractionTiming];
|
timingData[reactTag.stringValue] = [rootView endAndResetInteractionTiming];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onSuccess(@[ timingData ]);
|
onSuccess(@[timingData]);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,7 +1435,7 @@ static UIView *_jsResponder;
|
||||||
|
|
||||||
- (RCTUIManager *)uiManager
|
- (RCTUIManager *)uiManager
|
||||||
{
|
{
|
||||||
return self.modules[NSStringFromClass([RCTUIManager class])];
|
return self.modules[RCTBridgeModuleNameForClass([RCTUIManager class])];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -146,7 +146,6 @@
|
||||||
13E067501A70F44B002CDEE1 /* RCTView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTView.m; sourceTree = "<group>"; };
|
13E067501A70F44B002CDEE1 /* RCTView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTView.m; sourceTree = "<group>"; };
|
||||||
13E067531A70F44B002CDEE1 /* UIView+React.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+React.h"; sourceTree = "<group>"; };
|
13E067531A70F44B002CDEE1 /* UIView+React.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+React.h"; sourceTree = "<group>"; };
|
||||||
13E067541A70F44B002CDEE1 /* UIView+React.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+React.m"; sourceTree = "<group>"; };
|
13E067541A70F44B002CDEE1 /* UIView+React.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+React.m"; sourceTree = "<group>"; };
|
||||||
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSMethodRegistrar.h; sourceTree = "<group>"; };
|
|
||||||
14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptLoader.h; sourceTree = "<group>"; };
|
14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJavaScriptLoader.h; sourceTree = "<group>"; };
|
||||||
14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJavaScriptLoader.m; sourceTree = "<group>"; };
|
14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJavaScriptLoader.m; sourceTree = "<group>"; };
|
||||||
14435CE11AAC4AE100FC20F4 /* RCTMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMap.h; sourceTree = "<group>"; };
|
14435CE11AAC4AE100FC20F4 /* RCTMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMap.h; sourceTree = "<group>"; };
|
||||||
|
@ -366,7 +365,6 @@
|
||||||
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */,
|
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */,
|
||||||
83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */,
|
83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */,
|
||||||
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */,
|
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */,
|
||||||
13EFFCCF1A98E6FE002607DC /* RCTJSMethodRegistrar.h */,
|
|
||||||
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */,
|
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */,
|
||||||
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */,
|
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */,
|
||||||
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,
|
83CBBA4D1A601E3B00E9B192 /* RCTLog.h */,
|
||||||
|
@ -452,7 +450,7 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "if nc -w 5 -z localhost 8081 ; then\n if ! curl -4 -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\nelse\n open $SRCROOT/../packager/launchPackager.command || echo \"Can't start packager automatically\"\nfi";
|
shellScript = "if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\nelse\n open $SRCROOT/../packager/launchPackager.command || echo \"Can't start packager automatically\"\nfi";
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ RCT_ENUM_CONVERTER(UIDatePickerMode, (@{
|
||||||
|
|
||||||
@implementation RCTDatePickerManager
|
@implementation RCTDatePickerManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
UIDatePicker *picker = [[UIDatePicker alloc] init];
|
UIDatePicker *picker = [[UIDatePicker alloc] init];
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
@implementation RCTMapManager
|
@implementation RCTMapManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
RCTMap *map = [[RCTMap alloc] init];
|
RCTMap *map = [[RCTMap alloc] init];
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
@implementation RCTNavItemManager
|
@implementation RCTNavItemManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTNavItem alloc] init];
|
return [[RCTNavItem alloc] init];
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
@implementation RCTNavigatorManager
|
@implementation RCTNavigatorManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTNavigator alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
return [[RCTNavigator alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
@ -34,12 +36,10 @@ RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack, NSInteger)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove error callbacks
|
// TODO: remove error callbacks
|
||||||
- (void)requestSchedulingJavaScriptNavigation:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(requestSchedulingJavaScriptNavigation:(NSNumber *)reactTag
|
||||||
errorCallback:(RCTResponseSenderBlock)errorCallback
|
errorCallback:(RCTResponseSenderBlock)errorCallback
|
||||||
callback:(__unused RCTResponseSenderBlock)callback
|
callback:(__unused RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
|
||||||
RCTNavigator *navigator = viewRegistry[reactTag];
|
RCTNavigator *navigator = viewRegistry[reactTag];
|
||||||
if ([navigator isKindOfClass:[RCTNavigator class]]) {
|
if ([navigator isKindOfClass:[RCTNavigator class]]) {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
@implementation RCTPickerManager
|
@implementation RCTPickerManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTPicker alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
return [[RCTPicker alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
@implementation RCTScrollViewManager
|
@implementation RCTScrollViewManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTScrollView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
return [[RCTScrollView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
@ -63,11 +65,9 @@ RCT_DEPRECATED_VIEW_PROPERTY(throttleScrollCallbackMS, scrollEventThrottle)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getContentSize:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(getContentSize:(NSNumber *)reactTag
|
||||||
callback:(RCTResponseSenderBlock)callback
|
callback:(RCTResponseSenderBlock)callback)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
|
||||||
UIView *view = viewRegistry[reactTag];
|
UIView *view = viewRegistry[reactTag];
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
@implementation RCTSliderManager
|
@implementation RCTSliderManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
UISlider *slider = [[UISlider alloc] init];
|
UISlider *slider = [[UISlider alloc] init];
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
@implementation RCTSwitchManager
|
@implementation RCTSwitchManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
RCTSwitch *switcher = [[RCTSwitch alloc] init];
|
RCTSwitch *switcher = [[RCTSwitch alloc] init];
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
@implementation RCTTabBarItemManager
|
@implementation RCTTabBarItemManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTTabBarItem alloc] init];
|
return [[RCTTabBarItem alloc] init];
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTTabBar alloc] initWithEventDispatcher:_bridge.eventDispatcher];
|
return [[RCTTabBar alloc] initWithEventDispatcher:_bridge.eventDispatcher];
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
@implementation RCTTextFieldManager
|
@implementation RCTTextFieldManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTTextField alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
return [[RCTTextField alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
|
|
@ -24,6 +24,8 @@ RCT_ENUM_CONVERTER(UIActivityIndicatorViewStyle, (@{
|
||||||
|
|
||||||
@implementation RCTUIActivityIndicatorViewManager
|
@implementation RCTUIActivityIndicatorViewManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE(UIActivityIndicatorViewManager)
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[UIActivityIndicatorView alloc] init];
|
return [[UIActivityIndicatorView alloc] init];
|
||||||
|
|
|
@ -30,14 +30,6 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, strong) RCTBridge *bridge;
|
@property (nonatomic, strong) RCTBridge *bridge;
|
||||||
|
|
||||||
/**
|
|
||||||
* The module name exposed to React JS. If omitted, this will be inferred
|
|
||||||
* automatically by using the view module's class name. It is better to not
|
|
||||||
* override this, and just follow standard naming conventions for your view
|
|
||||||
* module subclasses.
|
|
||||||
*/
|
|
||||||
+ (NSString *)moduleName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instantiates a native view to be managed by the module. Override
|
* This method instantiates a native view to be managed by the module. Override
|
||||||
* this to return a custom view instance, which may be preconfigured with default
|
* this to return a custom view instance, which may be preconfigured with default
|
||||||
|
|
|
@ -21,18 +21,7 @@
|
||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
+ (NSString *)moduleName
|
RCT_EXPORT_MODULE()
|
||||||
{
|
|
||||||
// Default implementation, works in most cases
|
|
||||||
NSString *name = NSStringFromClass(self);
|
|
||||||
if ([name hasPrefix:@"RK"]) {
|
|
||||||
name = [name stringByReplacingCharactersInRange:(NSRange){0,@"RK".length} withString:@"RCT"];
|
|
||||||
}
|
|
||||||
if ([name hasPrefix:@"RCTUI"]) {
|
|
||||||
name = [name substringFromIndex:@"RCT".length];
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
@implementation RCTWebViewManager
|
@implementation RCTWebViewManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
return [[RCTWebView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
return [[RCTWebView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
@ -41,10 +43,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)goBack:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(goBack:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
RCTWebView *view = viewRegistry[reactTag];
|
RCTWebView *view = viewRegistry[reactTag];
|
||||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
@ -54,10 +54,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)goForward:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(goForward:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
id view = viewRegistry[reactTag];
|
id view = viewRegistry[reactTag];
|
||||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
@ -68,10 +66,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)reload:(NSNumber *)reactTag
|
RCT_EXPORT_METHOD(reload:(NSNumber *)reactTag)
|
||||||
{
|
{
|
||||||
RCT_EXPORT();
|
|
||||||
|
|
||||||
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
RCTWebView *view = viewRegistry[reactTag];
|
RCTWebView *view = viewRegistry[reactTag];
|
||||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
"start": "./packager/packager.sh"
|
"start": "./packager/packager.sh"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"react-native": "local-cli/wrong-react-native.js",
|
|
||||||
"react-native-start": "packager/packager.sh"
|
"react-native-start": "packager/packager.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -62,7 +61,9 @@
|
||||||
"underscore": "1.7.0",
|
"underscore": "1.7.0",
|
||||||
"worker-farm": "1.1.0",
|
"worker-farm": "1.1.0",
|
||||||
"ws": "0.4.31",
|
"ws": "0.4.31",
|
||||||
"yargs": "1.3.2"
|
"yargs": "1.3.2",
|
||||||
|
"bluebird": "^2.9.21",
|
||||||
|
"image-size": "0.3.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jest-cli": "0.2.1",
|
"jest-cli": "0.2.1",
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
|
||||||
|
function getFlowTypeCheckMiddleware(options) {
|
||||||
|
return function(req, res, next) {
|
||||||
|
if (options.skipflow) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
if (options.flowroot || options.projectRoots.length === 1) {
|
||||||
|
var flowroot = options.flowroot || options.projectRoots[0];
|
||||||
|
} else {
|
||||||
|
console.warn('flow: No suitable root');
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
exec('command -v flow >/dev/null 2>&1', function(error, stdout) {
|
||||||
|
if (error) {
|
||||||
|
console.warn('flow: Skipping because not installed. Install with ' +
|
||||||
|
'`brew install flow`.');
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
return doFlowTypecheck(res, flowroot, next);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function doFlowTypecheck(res, flowroot, next) {
|
||||||
|
var flowCmd = 'cd "' + flowroot + '" && flow --json --timeout 20';
|
||||||
|
var start = Date.now();
|
||||||
|
console.log('flow: Running static typechecks.');
|
||||||
|
exec(flowCmd, function(flowError, stdout) {
|
||||||
|
if (!flowError) {
|
||||||
|
console.log('flow: Typechecks passed (' + (Date.now() - start) + 'ms).');
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var flowResponse = JSON.parse(stdout);
|
||||||
|
var errors = [];
|
||||||
|
var errorNum = 1;
|
||||||
|
flowResponse.errors.forEach(function(err) {
|
||||||
|
// flow errors are paired across callsites, so we indent and prefix to
|
||||||
|
// group them
|
||||||
|
var indent = '';
|
||||||
|
err.message.forEach(function(msg) {
|
||||||
|
errors.push({
|
||||||
|
description: indent + 'E' + errorNum + ': ' + msg.descr,
|
||||||
|
filename: msg.path,
|
||||||
|
lineNumber: msg.line,
|
||||||
|
column: msg.start,
|
||||||
|
});
|
||||||
|
indent = ' ';
|
||||||
|
});
|
||||||
|
errorNum++;
|
||||||
|
});
|
||||||
|
var message = 'Flow found type errors. If you think these are wrong, ' +
|
||||||
|
'make sure flow is up to date, or disable with --skipflow.';
|
||||||
|
} catch (e) {
|
||||||
|
var message =
|
||||||
|
'Flow failed to provide parseable output:\n\n`' + stdout + '`';
|
||||||
|
console.error(message, '\nException: `', e, '`\n\n');
|
||||||
|
}
|
||||||
|
var error = {
|
||||||
|
status: 500,
|
||||||
|
message: message,
|
||||||
|
type: 'FlowError',
|
||||||
|
errors: errors,
|
||||||
|
};
|
||||||
|
console.error('flow: Error running command `' + flowCmd + '`:\n', error);
|
||||||
|
res.writeHead(error.status, {
|
||||||
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getFlowTypeCheckMiddleware;
|
|
@ -13,6 +13,8 @@ var path = require('path');
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
|
|
||||||
|
var getFlowTypeCheckMiddleware = require('./getFlowTypeCheckMiddleware');
|
||||||
|
|
||||||
if (!fs.existsSync(path.resolve(__dirname, '..', 'node_modules'))) {
|
if (!fs.existsSync(path.resolve(__dirname, '..', 'node_modules'))) {
|
||||||
console.log(
|
console.log(
|
||||||
'\n' +
|
'\n' +
|
||||||
|
@ -40,6 +42,9 @@ var options = parseCommandLine([{
|
||||||
}, {
|
}, {
|
||||||
command: 'assetRoots',
|
command: 'assetRoots',
|
||||||
description: 'specify the root directories of app assets'
|
description: 'specify the root directories of app assets'
|
||||||
|
}, {
|
||||||
|
command: 'skipflow',
|
||||||
|
description: 'Disable flow checks'
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
if (options.projectRoots) {
|
if (options.projectRoots) {
|
||||||
|
@ -203,6 +208,7 @@ function runServer(
|
||||||
.use(openStackFrameInEditor)
|
.use(openStackFrameInEditor)
|
||||||
.use(getDevToolsLauncher(options))
|
.use(getDevToolsLauncher(options))
|
||||||
.use(statusPageMiddleware)
|
.use(statusPageMiddleware)
|
||||||
|
.use(getFlowTypeCheckMiddleware(options))
|
||||||
.use(getAppMiddleware(options));
|
.use(getAppMiddleware(options));
|
||||||
|
|
||||||
options.projectRoots.forEach(function(root) {
|
options.projectRoots.forEach(function(root) {
|
||||||
|
@ -213,5 +219,5 @@ function runServer(
|
||||||
.use(connect.compress())
|
.use(connect.compress())
|
||||||
.use(connect.errorHandler());
|
.use(connect.errorHandler());
|
||||||
|
|
||||||
return http.createServer(app).listen(options.port, readyCallback);
|
return http.createServer(app).listen(options.port, '::', readyCallback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,13 @@ function ModuleDescriptor(fields) {
|
||||||
|
|
||||||
this.isPolyfill = fields.isPolyfill || false;
|
this.isPolyfill = fields.isPolyfill || false;
|
||||||
|
|
||||||
|
this.isAsset_DEPRECATED = fields.isAsset_DEPRECATED || false;
|
||||||
this.isAsset = fields.isAsset || false;
|
this.isAsset = fields.isAsset || false;
|
||||||
|
|
||||||
|
if (this.isAsset_DEPRECATED && this.isAsset) {
|
||||||
|
throw new Error('Cannot be an asset and a deprecated asset');
|
||||||
|
}
|
||||||
|
|
||||||
this.altId = fields.altId;
|
this.altId = fields.altId;
|
||||||
|
|
||||||
this._fields = fields;
|
this._fields = fields;
|
||||||
|
|
|
@ -92,7 +92,7 @@ describe('DependencyGraph', function() {
|
||||||
{ id: 'image!a',
|
{ id: 'image!a',
|
||||||
path: '/root/imgs/a.png',
|
path: '/root/imgs/a.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true
|
isAsset_DEPRECATED: true
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -183,7 +183,7 @@ describe('DependencyGraph', function() {
|
||||||
id: 'image!a',
|
id: 'image!a',
|
||||||
path: '/root/imgs/a.png',
|
path: '/root/imgs/a.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true
|
isAsset_DEPRECATED: true
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -954,7 +954,7 @@ describe('DependencyGraph', function() {
|
||||||
{ id: 'image!foo',
|
{ id: 'image!foo',
|
||||||
path: '/root/foo.png',
|
path: '/root/foo.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -596,7 +596,7 @@ DependecyGraph.prototype._processAsset_DEPRECATED = function(file) {
|
||||||
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
|
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
|
||||||
id: 'image!' + name,
|
id: 'image!' + name,
|
||||||
path: path.resolve(file),
|
path: path.resolve(file),
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ function formatError(err, filename, source) {
|
||||||
function formatGenericError(err, filename) {
|
function formatGenericError(err, filename) {
|
||||||
var msg = 'TransformError: ' + filename + ': ' + err.message;
|
var msg = 'TransformError: ' + filename + ': ' + err.message;
|
||||||
var error = new TransformError();
|
var error = new TransformError();
|
||||||
var stack = err.stack.split('\n').slice(0, -1);
|
var stack = (err.stack || '').split('\n').slice(0, -1);
|
||||||
stack.push(msg);
|
stack.push(msg);
|
||||||
error.stack = stack.join('\n');
|
error.stack = stack.join('\n');
|
||||||
error.message = msg;
|
error.message = msg;
|
||||||
|
|
|
@ -43,14 +43,21 @@ describe('Packager', function() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var packager = new Packager({projectRoots: []});
|
var packager = new Packager({projectRoots: ['/root']});
|
||||||
var modules = [
|
var modules = [
|
||||||
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
||||||
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
||||||
{ id: 'image!img',
|
{
|
||||||
|
id: 'image!img',
|
||||||
path: '/root/img/img.png',
|
path: '/root/img/img.png',
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_image.png',
|
||||||
|
path: '/root/img/new_image.png',
|
||||||
|
isAsset: true,
|
||||||
|
dependencies: []
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -74,6 +81,10 @@ describe('Packager', function() {
|
||||||
return 'lol ' + code + ' lol';
|
return 'lol ' + code + ' lol';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
require('image-size').mockImpl(function(path, cb) {
|
||||||
|
cb(null, { width: 50, height: 100 });
|
||||||
|
});
|
||||||
|
|
||||||
return packager.package('/root/foo.js', true, 'source_map_url')
|
return packager.package('/root/foo.js', true, 'source_map_url')
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
expect(p.addModule.mock.calls[0]).toEqual([
|
expect(p.addModule.mock.calls[0]).toEqual([
|
||||||
|
@ -96,6 +107,24 @@ describe('Packager', function() {
|
||||||
'/root/img/img.png'
|
'/root/img/img.png'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
var imgModule = {
|
||||||
|
isStatic: true,
|
||||||
|
path: '/root/img/new_image.png',
|
||||||
|
uri: 'img/new_image.png',
|
||||||
|
width: 50,
|
||||||
|
height: 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(p.addModule.mock.calls[3]).toEqual([
|
||||||
|
'lol module.exports = ' +
|
||||||
|
JSON.stringify(imgModule) +
|
||||||
|
'; lol',
|
||||||
|
'module.exports = ' +
|
||||||
|
JSON.stringify(imgModule) +
|
||||||
|
';',
|
||||||
|
'/root/img/new_image.png'
|
||||||
|
]);
|
||||||
|
|
||||||
expect(p.finalize.mock.calls[0]).toEqual([
|
expect(p.finalize.mock.calls[0]).toEqual([
|
||||||
{runMainModule: true}
|
{runMainModule: true}
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -18,6 +18,7 @@ var _ = require('underscore');
|
||||||
var Package = require('./Package');
|
var Package = require('./Package');
|
||||||
var Activity = require('../Activity');
|
var Activity = require('../Activity');
|
||||||
var declareOpts = require('../lib/declareOpts');
|
var declareOpts = require('../lib/declareOpts');
|
||||||
|
var imageSize = require('image-size');
|
||||||
|
|
||||||
var validateOpts = declareOpts({
|
var validateOpts = declareOpts({
|
||||||
projectRoots: {
|
projectRoots: {
|
||||||
|
@ -88,6 +89,8 @@ function Packager(options) {
|
||||||
transformModulePath: opts.transformModulePath,
|
transformModulePath: opts.transformModulePath,
|
||||||
nonPersistent: opts.nonPersistent,
|
nonPersistent: opts.nonPersistent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._projectRoots = opts.projectRoots;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packager.prototype.kill = function() {
|
Packager.prototype.kill = function() {
|
||||||
|
@ -138,8 +141,13 @@ Packager.prototype.getDependencies = function(main, isDev) {
|
||||||
Packager.prototype._transformModule = function(module) {
|
Packager.prototype._transformModule = function(module) {
|
||||||
var transform;
|
var transform;
|
||||||
|
|
||||||
if (module.isAsset) {
|
if (module.isAsset_DEPRECATED) {
|
||||||
transform = Promise.resolve(generateAssetModule(module));
|
transform = Promise.resolve(generateAssetModule_DEPRECATED(module));
|
||||||
|
} else if (module.isAsset) {
|
||||||
|
transform = generateAssetModule(
|
||||||
|
module,
|
||||||
|
getPathRelativeToRoot(this._projectRoots, module.path)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
transform = this._transformer.loadFileAndTransform(
|
transform = this._transformer.loadFileAndTransform(
|
||||||
path.resolve(module.path)
|
path.resolve(module.path)
|
||||||
|
@ -166,7 +174,7 @@ Packager.prototype.getGraphDebugInfo = function() {
|
||||||
return this._resolver.getDebugInfo();
|
return this._resolver.getDebugInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateAssetModule(module) {
|
function generateAssetModule_DEPRECATED(module) {
|
||||||
var code = 'module.exports = ' + JSON.stringify({
|
var code = 'module.exports = ' + JSON.stringify({
|
||||||
uri: module.id.replace(/^[^!]+!/, ''),
|
uri: module.id.replace(/^[^!]+!/, ''),
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
|
@ -179,4 +187,39 @@ function generateAssetModule(module) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sizeOf = Promise.promisify(imageSize);
|
||||||
|
|
||||||
|
function generateAssetModule(module, relPath) {
|
||||||
|
return sizeOf(module.path).then(function(dimensions) {
|
||||||
|
var img = {
|
||||||
|
isStatic: true,
|
||||||
|
path: module.path, //TODO(amasad): this should be path inside tar file.
|
||||||
|
uri: relPath,
|
||||||
|
width: dimensions.width,
|
||||||
|
height: dimensions.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
var code = 'module.exports = ' + JSON.stringify(img) + ';';
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: code,
|
||||||
|
sourceCode: code,
|
||||||
|
sourcePath: module.path,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPathRelativeToRoot(roots, absPath) {
|
||||||
|
for (var i = 0; i < roots.length; i++) {
|
||||||
|
var relPath = path.relative(roots[i], absPath);
|
||||||
|
if (relPath[0] !== '.') {
|
||||||
|
return relPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
'Expected root module to be relative to one of the project roots'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Packager;
|
module.exports = Packager;
|
||||||
|
|
|
@ -320,6 +320,12 @@ function handleError(res, error) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error.type === 'TransformError' || error.type === 'NotFoundError') {
|
if (error.type === 'TransformError' || error.type === 'NotFoundError') {
|
||||||
|
error.errors = [{
|
||||||
|
description: error.description,
|
||||||
|
filename: error.filename,
|
||||||
|
lineNumber: error.lineNumber,
|
||||||
|
}];
|
||||||
|
console.error(error);
|
||||||
res.end(JSON.stringify(error));
|
res.end(JSON.stringify(error));
|
||||||
} else {
|
} else {
|
||||||
console.error(error.stack || error);
|
console.error(error.stack || error);
|
||||||
|
|
Loading…
Reference in New Issue