diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m index 90a3fed9c..0829e5e0c 100644 --- a/React/Base/RCTRootView.m +++ b/React/Base/RCTRootView.m @@ -24,7 +24,6 @@ #import "RCTUIManager.h" #import "RCTUtils.h" #import "RCTView.h" -#import "RCTWebViewExecutor.h" #import "UIView+React.h" NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification"; diff --git a/React/Executors/RCTWebViewExecutor.h b/React/Executors/RCTWebViewExecutor.h deleted file mode 100644 index db8710c7d..000000000 --- a/React/Executors/RCTWebViewExecutor.h +++ /dev/null @@ -1,48 +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. - */ - -#import "RCTDefines.h" - -#if RCT_DEV // Debug executors are only supported in dev mode - -#import - -#import "RCTJavaScriptExecutor.h" - -/** - * Uses an embedded web view merely for the purpose of being able to reuse the - * existing webkit debugging tools. Fulfills the role of a very constrained - * `JSContext`, which we call `RCTJavaScriptExecutor`. - * - * TODO: To ensure production-identical execution, scrub the window - * environment. And ensure main thread operations are actually added to a queue - * instead of being executed immediately if already on the main thread. - */ -@interface RCTWebViewExecutor : NSObject - -// Only one callback stored - will only be invoked for the latest issued -// application script request. -@property (nonatomic, copy) RCTJavaScriptCompleteBlock onApplicationScriptLoaded; - -/** - * Instantiate with a specific webview instance - */ -- (instancetype)initWithWebView:(UIWebView *)webView NS_DESIGNATED_INITIALIZER; - -/** - * Invoke this to reclaim the web view for reuse. This is necessary in order to - * allow debuggers to remain open, when creating a new `RCTWebViewExecutor`. - * This guards against the web view being invalidated, and makes sure the - * `delegate` is cleared first. - */ -- (UIWebView *)invalidateAndReclaimWebView; - -@end - -#endif diff --git a/React/Executors/RCTWebViewExecutor.m b/React/Executors/RCTWebViewExecutor.m deleted file mode 100644 index b3136db04..000000000 --- a/React/Executors/RCTWebViewExecutor.m +++ /dev/null @@ -1,229 +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. - */ - -#import "RCTDefines.h" - -#if RCT_DEV // Debug executors are only supported in dev mode - -#import "RCTWebViewExecutor.h" - -#import - -#import "RCTLog.h" -#import "RCTUtils.h" - -static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...) -{ - va_list args; - va_start(args, fmt); - - NSString *description = [[NSString alloc] initWithFormat:fmt arguments:args]; - RCTLogError(@"%@", description); - - NSError *error = [NSError errorWithDomain:NSStringFromClass([RCTWebViewExecutor class]) - code:3 - userInfo:@{NSLocalizedDescriptionKey:description}]; - callback(nil, error); - - va_end(args); -} - -@interface RCTWebViewExecutor () - -@end - -@implementation RCTWebViewExecutor -{ - UIWebView *_webView; - NSMutableDictionary *_objectsToInject; - NSRegularExpression *_commentsRegex; - NSRegularExpression *_scriptTagsRegex; -} - -RCT_EXPORT_MODULE() - -@synthesize valid = _valid; - -- (instancetype)initWithWebView:(UIWebView *)webView -{ - if ((self = [super init])) { - _webView = webView; - } - return self; -} - -- (instancetype)init -{ - return [self initWithWebView:nil]; -} - -- (void)setUp -{ - if (!_webView) { - [self executeBlockOnJavaScriptQueue:^{ - _webView = [UIWebView new]; - _webView.delegate = self; - }]; - } - - _objectsToInject = [NSMutableDictionary new]; - _commentsRegex = [NSRegularExpression regularExpressionWithPattern:@"(^ *?\\/\\/.*?$|\\/\\*\\*[\\s\\S]*?\\*\\/)" options:NSRegularExpressionAnchorsMatchLines error:NULL]; - _scriptTagsRegex = [NSRegularExpression regularExpressionWithPattern:@"<(\\/?script[^>]*?)>" options:0 error:NULL]; -} - -- (void)invalidate -{ - _valid = NO; - _webView.delegate = nil; - _webView = nil; -} - -- (UIWebView *)invalidateAndReclaimWebView -{ - UIWebView *webView = _webView; - [self invalidate]; - return webView; -} - -- (void)executeJSCall:(NSString *)name - method:(NSString *)method - arguments:(NSArray *)arguments - callback:(RCTJavaScriptCallback)onComplete -{ - RCTAssert(onComplete != nil, @""); - [self executeBlockOnJavaScriptQueue:^{ - if (!self.isValid) { - return; - } - - NSError *error; - NSString *argsString = RCTJSONStringify(arguments, &error); - if (!argsString) { - RCTReportError(onComplete, @"Cannot convert argument to string: %@", error); - return; - } - NSString *execString = [NSString stringWithFormat:@"JSON.stringify(require('%@').%@.apply(null, %@));", name, method, argsString]; - - NSString *ret = [_webView stringByEvaluatingJavaScriptFromString:execString]; - if (ret.length == 0) { - RCTReportError(onComplete, @"Empty return string: JavaScript error running script: %@", execString); - return; - } - - id objcValue = RCTJSONParse(ret, &error); - if (!objcValue) { - RCTReportError(onComplete, @"Cannot parse json response: %@", error); - return; - } - onComplete(objcValue, nil); - }]; -} - -/** - * We cannot use the standard eval JS method. Source will not show up in the - * debugger. So we have to use this (essentially) async API - and register - * ourselves as the webview delegate to be notified when load is complete. - */ -- (void)executeApplicationScript:(NSData *)script - sourceURL:(NSURL *)url - onComplete:(RCTJavaScriptCompleteBlock)onComplete -{ - if (![NSThread isMainThread]) { - dispatch_sync(dispatch_get_main_queue(), ^{ - [self executeApplicationScript:script sourceURL:url onComplete:onComplete]; - }); - return; - } - - RCTAssert(onComplete != nil, @""); - NSString *scriptString = [[NSString alloc] initWithData:script encoding:NSUTF8StringEncoding]; - __weak RCTWebViewExecutor *weakSelf = self; - _onApplicationScriptLoaded = ^(NSError *error){ - RCTWebViewExecutor *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - strongSelf->_valid = error == nil; - onComplete(error); - }; - - if (_objectsToInject.count > 0) { - NSMutableString *scriptWithInjections = [[NSMutableString alloc] initWithString:@"/* BEGIN NATIVELY INJECTED OBJECTS */\n"]; - [_objectsToInject enumerateKeysAndObjectsUsingBlock: - ^(NSString *objectName, NSString *blockScript, __unused BOOL *stop) { - [scriptWithInjections appendString:objectName]; - [scriptWithInjections appendString:@" = ("]; - [scriptWithInjections appendString:blockScript]; - [scriptWithInjections appendString:@");\n"]; - }]; - [_objectsToInject removeAllObjects]; - [scriptWithInjections appendString:@"/* END NATIVELY INJECTED OBJECTS */\n"]; - [scriptWithInjections appendString:scriptString]; - scriptString = scriptWithInjections; - } - - scriptString = [_commentsRegex stringByReplacingMatchesInString:scriptString - options:0 - range:NSMakeRange(0, script.length) - withTemplate:@""]; - scriptString = [_scriptTagsRegex stringByReplacingMatchesInString:scriptString - options:0 - range:NSMakeRange(0, script.length) - withTemplate:@"\\\\<$1\\\\>"]; - - NSString *runScript = - [NSString - stringWithFormat:@"", - scriptString - ]; - [_webView loadHTMLString:runScript baseURL:url]; -} - -- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block -{ - - if ([NSThread isMainThread]) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); - } -} - -- (void)executeAsyncBlockOnJavaScriptQueue:(dispatch_block_t)block -{ - dispatch_async(dispatch_get_main_queue(), block); -} - -/** - * `UIWebViewDelegate` methods. Handle application script load. - */ -- (void)webViewDidFinishLoad:(__unused UIWebView *)webView -{ - RCTAssertMainThread(); - if (_onApplicationScriptLoaded) { - _onApplicationScriptLoaded(nil); // TODO(frantic): how to fetch error from UIWebView? - } - _onApplicationScriptLoaded = nil; -} - -- (void)injectJSONText:(NSString *)script - asGlobalObjectNamed:(NSString *)objectName - callback:(RCTJavaScriptCompleteBlock)onComplete -{ - if (RCT_DEBUG) { - RCTAssert(!_objectsToInject[objectName], - @"already injected object named %@", _objectsToInject[objectName]); - } - _objectsToInject[objectName] = script; - onComplete(nil); -} - -@end - -#endif diff --git a/React/Modules/RCTDevMenu.m b/React/Modules/RCTDevMenu.m index 165237ce0..a57c4b643 100644 --- a/React/Modules/RCTDevMenu.m +++ b/React/Modules/RCTDevMenu.m @@ -415,13 +415,6 @@ RCT_EXPORT_MODULE() }]]; } - Class safariExecutorClass = NSClassFromString(@"RCTWebViewExecutor"); - BOOL isDebuggingInSafari = _executorClass && _executorClass == safariExecutorClass; - NSString *debugTitleSafari = isDebuggingInSafari ? @"Disable Safari Debugging" : @"Debug in Safari"; - [items addObject:[RCTDevMenuItem buttonItemWithTitle:debugTitleSafari handler:^{ - weakSelf.executorClass = isDebuggingInSafari ? Nil : safariExecutorClass; - }]]; - if (_liveReloadURL) { NSString *liveReloadTitle = _liveReloadEnabled ? @"Disable Live Reload" : @"Enable Live Reload"; [items addObject:[RCTDevMenuItem buttonItemWithTitle:liveReloadTitle handler:^{ @@ -552,8 +545,7 @@ RCT_EXPORT_METHOD(reload) // needed to prevent overriding a custom executor with the default if a // custom executor has been set directly on the bridge if (executorClass == Nil && - (_bridge.executorClass != NSClassFromString(@"RCTWebSocketExecutor") && - _bridge.executorClass != NSClassFromString(@"RCTWebViewExecutor"))) { + _bridge.executorClass != NSClassFromString(@"RCTWebSocketExecutor")) { return; } diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index d7383e604..6327931a8 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 13456E961ADAD482009F94A7 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 13456E951ADAD482009F94A7 /* RCTConvert+MapKit.m */; }; 134FCB361A6D42D900051CC8 /* RCTSparseArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BEE46D1A6D19BC00B5863B /* RCTSparseArray.m */; }; 134FCB3D1A6E7F0800051CC8 /* RCTContextExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */; }; - 134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */; }; 13513F3C1B1F43F400FCE529 /* RCTProgressViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13513F3B1B1F43F400FCE529 /* RCTProgressViewManager.m */; }; 13723B501A82FD3C00F88898 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; }; 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7091AB030C200659ED6 /* RCTAppState.m */; }; @@ -53,11 +52,11 @@ 142014191B32094000CC17BA /* RCTPerformanceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 142014171B32094000CC17BA /* RCTPerformanceLogger.m */; }; 14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 14435CE21AAC4AE100FC20F4 /* RCTMap.m */; }; 14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14435CE41AAC4AE100FC20F4 /* RCTMapManager.m */; }; - 1450FF861BCFF28A00208362 /* RCTProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF811BCFF28A00208362 /* RCTProfile.m */; settings = {ASSET_TAGS = (); }; }; - 1450FF871BCFF28A00208362 /* RCTProfileTrampoline-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF821BCFF28A00208362 /* RCTProfileTrampoline-arm.S */; settings = {ASSET_TAGS = (); }; }; - 1450FF881BCFF28A00208362 /* RCTProfileTrampoline-arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF831BCFF28A00208362 /* RCTProfileTrampoline-arm64.S */; settings = {ASSET_TAGS = (); }; }; - 1450FF891BCFF28A00208362 /* RCTProfileTrampoline-x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF841BCFF28A00208362 /* RCTProfileTrampoline-x86.S */; settings = {ASSET_TAGS = (); }; }; - 1450FF8A1BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF851BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S */; settings = {ASSET_TAGS = (); }; }; + 1450FF861BCFF28A00208362 /* RCTProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF811BCFF28A00208362 /* RCTProfile.m */; }; + 1450FF871BCFF28A00208362 /* RCTProfileTrampoline-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF821BCFF28A00208362 /* RCTProfileTrampoline-arm.S */; }; + 1450FF881BCFF28A00208362 /* RCTProfileTrampoline-arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF831BCFF28A00208362 /* RCTProfileTrampoline-arm64.S */; }; + 1450FF891BCFF28A00208362 /* RCTProfileTrampoline-x86.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF841BCFF28A00208362 /* RCTProfileTrampoline-x86.S */; }; + 1450FF8A1BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 1450FF851BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S */; }; 14C2CA711B3AC63800E6CBB2 /* RCTModuleMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA701B3AC63800E6CBB2 /* RCTModuleMethod.m */; }; 14C2CA741B3AC64300E6CBB2 /* RCTModuleData.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA731B3AC64300E6CBB2 /* RCTModuleData.m */; }; 14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */; }; @@ -65,8 +64,8 @@ 14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F362081AABD06A001CE568 /* RCTSwitch.m */; }; 14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */; }; 14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */; }; - 14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */; settings = {ASSET_TAGS = (); }; }; - 14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; settings = {ASSET_TAGS = (); }; }; + 14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */; }; + 14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; }; 58114A161AAE854800E7D092 /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A131AAE854800E7D092 /* RCTPicker.m */; }; 58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; }; 58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; }; @@ -121,8 +120,6 @@ 1345A83B1B265A0E00583190 /* RCTURLRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTURLRequestHandler.h; sourceTree = ""; }; 134FCB391A6E7F0800051CC8 /* RCTContextExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTContextExecutor.h; sourceTree = ""; }; 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutor.m; sourceTree = ""; }; - 134FCB3B1A6E7F0800051CC8 /* RCTWebViewExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewExecutor.h; sourceTree = ""; }; - 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewExecutor.m; sourceTree = ""; }; 13513F3A1B1F43F400FCE529 /* RCTProgressViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTProgressViewManager.h; sourceTree = ""; }; 13513F3B1B1F43F400FCE529 /* RCTProgressViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTProgressViewManager.m; sourceTree = ""; }; 13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStatusBarManager.h; sourceTree = ""; }; @@ -290,8 +287,6 @@ children = ( 134FCB391A6E7F0800051CC8 /* RCTContextExecutor.h */, 134FCB3A1A6E7F0800051CC8 /* RCTContextExecutor.m */, - 134FCB3B1A6E7F0800051CC8 /* RCTWebViewExecutor.h */, - 134FCB3C1A6E7F0800051CC8 /* RCTWebViewExecutor.m */, ); path = Executors; sourceTree = ""; @@ -686,7 +681,6 @@ 83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */, 14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */, 1450FF891BCFF28A00208362 /* RCTProfileTrampoline-x86.S in Sources */, - 134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */, 13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */, 1385D0341B665AAE000A309B /* RCTModuleMap.m in Sources */, 83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */,