WKWebView - squashed commit. commit da7a3546f809c331cf230af180b3e6f1fb99cb2b Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jul 10 17:48:15 2014 -0700
Support alert/confirm/prompt in WKWebView commit 63552fd3f2548f407aec1bbfda997809d1f2a89d Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jul 10 14:52:44 2014 -0700 Support config.xml preferences for WKWebView, and style fixups commit e67e6bf2577c776c887453801af05f973fb90094 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jul 9 18:44:03 2014 -0700 Use weakSelf in block commit fc83f068388f3402935819f7891906ffa9029cc1 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jul 9 18:38:30 2014 -0700 Support config.xml preferences for WKWebView commit 4eeaf0c8730a30b8709d0d98aba4b2996e34d9f4 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jul 9 18:27:51 2014 -0700 Break out config.xml preferences for UIWebView (related to WKWebView prefs support) commit 9ba496297116f20a4ea0d7b83a9f142ceec2bc84 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jul 9 17:51:11 2014 -0700 Re-add pragma message for iOS 8 commit 2e17db94a87da80a7d50f202eef40178c0a688c0 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jul 9 17:46:00 2014 -0700 Removed unused WKWebView+Private header commit 601eea1c8784e1acf00b0a39ca4a3ea5085b2098 Author: Shazron Abdullah <shaz...@apache.org> Date: Mon Jul 7 15:59:30 2014 -0700 Removed WKWebView+Private category since the functions it covers are already now in iOS 8 beta 3 commit 69c86d641c8a14e23843566ff2024ce77238fd79 Author: Shazron Abdullah <shaz...@apache.org> Date: Mon Jun 23 11:59:51 2014 -0700 Changed @import WebKit back to the old #import (for supporting older IPHONE_OS_DEPLOYMENT_TARGET reasons, bug in Xcode), add #pragma message to add WebKit.framework for iOS 8 commit c133640d264eba5456b3ffd2d3be83e3fd90bf42 Author: Shazron Abdullah <shaz...@gmail.com> Date: Sat Jun 21 22:14:26 2014 -0700 Removed WebKit.framework from templates. commit b4832d132e6628a7ae0ef681eab54554ed913b77 Author: Shazron Abdullah <shaz...@gmail.com> Date: Sat Jun 21 21:45:10 2014 -0700 Using @import instead of #import for WebKit, which doesn't require us to list the framework in the project explicitly. This gives us a true Xcode 5 / 6 compile solution. HOWEVER there is a bug in Xcode (was there since 5) where if you do an @import for a framework, it won't link if your Deployment Target OS version does not also include the framework itself, when compiling for the Simulator. For example, if you @import WebKit, and build for the Simulator, your Deployment Target MUST be iOS 8. The workaround is, this bug does not appear if you build for a device. To make it work for the Simulator, you will have to explicitly add the framework in Build Phases -> Link Binary with Libraries. commit df3d8391546b2bb6da659ca2102609beb7038f7d Author: Shazron Abdullah <shaz...@gmail.com> Date: Sat Jun 21 00:20:36 2014 -0700 Unified the implementations to switch to WKWebView when available and fall back to UIWebView. The implementation even compiles under Xcode 5.1 -- however, the linker will complain under Xcode 5.1 that WebKit.framework is not available. Just remove the framework in "Link Binary With Libraries" Build Phase and it should run. commit 52e27adcd4227621d329fea4743be73bfcb7f4bf Author: Shazron Abdullah <shaz...@apache.org> Date: Fri Jun 20 16:59:48 2014 -0700 Re-add deprecated CDVPlugin functions commit e16e914c3ba2f30324f25da27fbbc0efa9cde727 Merge: f3af6f2 2e1b00c Author: Shazron Abdullah <shaz...@apache.org> Date: Fri Jun 20 16:51:54 2014 -0700 Merge branch 'wkwebview-only' of github.com:shazron/cordova-ios into wkwebview-only Conflicts: CordovaLib/Classes/CDVPlugin.h commit f3af6f2636dad50412da329ce7c21dfaf3717254 Author: Shazron Abdullah <shaz...@apache.org> Date: Fri Jun 20 16:22:08 2014 -0700 Changed webView property of CDVPlugin to UIView. Plugins need to coerce this into a UIWebView or WKWebView. commit c33497742cfe9c7f0e2c7c8902b56cf6fba09ad9 Author: Shazron Abdullah <shaz...@gmail.com> Date: Thu Jun 19 21:39:07 2014 -0700 Fixed native commands not being called when called in a exec callback commit b155b5d9e120a1b7ec2d4a8c3950073792281df5 Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 16:22:04 2014 -0700 Added new cordova.js to support WKWebView Cordova bridge commit 6a96341da8d0f455ed9f977e6329af6d98c357fe Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 16:08:30 2014 -0700 Implemented the WKWebView Cordova bridge. commit 6eb29c716b8308a7f4824a313a232c7c16f421b8 Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 13:42:49 2014 -0700 Moved WKScriptMessageHandler to CDVCommandDelegateImpl commit 374763daf13f73df872a64caa83a7371a0c58542 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:51:51 2014 -0700 Updated templates for WebKit.framework use commit be7fd66f708587bee48b9dbbc7c0b57b03002eb2 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:50:28 2014 -0700 Updated AppDelegate.m to use WKWebView evaluateJavascript (private) commit 05b5c5912e339d29623de75127c2f162e0c875ed Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:49:54 2014 -0700 Added WKWebView support (not unified, stripped out UIWebView use) commit a6ebfb01a7dbad504928b871783f75bbc95e0d85 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:49:00 2014 -0700 Added WKWebView private functions. commit 2e1b00cbb92164114db2f30df10b7f0ec918c9bc Author: Shazron Abdullah <shaz...@apache.org> Date: Fri Jun 20 16:22:08 2014 -0700 Changed webView property of CDVPlugin to UIView. Plugins need to coerce this into a UIWebView or WKWebView. commit 867647075c837c3782333eb6b4c865cb70451aa3 Author: Shazron Abdullah <shaz...@gmail.com> Date: Thu Jun 19 21:39:07 2014 -0700 Fixed native commands not being called when called in a exec callback commit ad3ec2937633995309b77bc663ee22e0b07ac667 Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 16:22:04 2014 -0700 Added new cordova.js to support WKWebView Cordova bridge commit ede3ad5cef804c67e777c0f2c750712df50883f5 Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 16:08:30 2014 -0700 Implemented the WKWebView Cordova bridge. commit c1c39086ab220fcdc5a796b27d38a5d32f7f5f37 Author: Shazron Abdullah <shaz...@apache.org> Date: Thu Jun 19 13:42:49 2014 -0700 Moved WKScriptMessageHandler to CDVCommandDelegateImpl commit 5d2b137645e5fffb460c8e84d16dc8f5d104d085 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:51:51 2014 -0700 Updated templates for WebKit.framework use commit 63bf9a7ca03f92f263a3a3d7226512aee784a171 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:50:28 2014 -0700 Updated AppDelegate.m to use WKWebView evaluateJavascript (private) commit 23c05db85e57f82a4c6fe03fc5faf49abaf947b8 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:49:54 2014 -0700 Added WKWebView support (not unified, stripped out UIWebView use) commit 74a0f4e678e4349849596f23f7f0714aaa574532 Author: Shazron Abdullah <shaz...@apache.org> Date: Wed Jun 18 17:49:00 2014 -0700 Added WKWebView private functions. Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/1a759ac7 Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/1a759ac7 Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/1a759ac7 Branch: refs/heads/4.0.x Commit: 1a759ac7fd7fa24aa658f868dbf413ef8ca34396 Parents: 5769d58 Author: Shazron Abdullah <shaz...@apache.org> Authored: Mon Jul 14 12:03:19 2014 -0700 Committer: Shazron Abdullah <shaz...@apache.org> Committed: Fri Oct 31 15:37:43 2014 -0700 ---------------------------------------------------------------------- CordovaLib/CDVWebViewUIDelegate.h | 35 +++ CordovaLib/CDVWebViewUIDelegate.m | 126 +++++++++ CordovaLib/Classes/CDV.h | 2 + CordovaLib/Classes/CDVCommandDelegateImpl.h | 6 +- CordovaLib/Classes/CDVCommandDelegateImpl.m | 37 +-- CordovaLib/Classes/CDVCommandQueue.m | 17 +- CordovaLib/Classes/CDVPlugin.h | 7 +- CordovaLib/Classes/CDVPlugin.m | 9 +- CordovaLib/Classes/CDVViewController.h | 18 +- CordovaLib/Classes/CDVViewController.m | 250 ++++++------------ .../Classes/CDVWebViewOperationsDelegate.h | 39 +++ .../Classes/CDVWebViewOperationsDelegate.m | 83 ++++++ CordovaLib/Classes/CDVWebViewPreferences.h | 32 +++ CordovaLib/Classes/CDVWebViewPreferences.m | 261 +++++++++++++++++++ CordovaLib/CordovaLib.xcodeproj/project.pbxproj | 26 ++ CordovaLib/cordova.js | 8 +- .../project/__CLI__.xcodeproj/project.pbxproj | 6 + .../__NON-CLI__.xcodeproj/project.pbxproj | 6 + .../project/__PROJECT_NAME__/config.xml | 1 + tests/CordovaLibTests/CordovaLibApp/config.xml | 1 + 20 files changed, 767 insertions(+), 203 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/CDVWebViewUIDelegate.h ---------------------------------------------------------------------- diff --git a/CordovaLib/CDVWebViewUIDelegate.h b/CordovaLib/CDVWebViewUIDelegate.h new file mode 100644 index 0000000..9ff2ac1 --- /dev/null +++ b/CordovaLib/CDVWebViewUIDelegate.h @@ -0,0 +1,35 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <Foundation/Foundation.h> + +#ifdef __IPHONE_8_0 + #import <WebKit/WebKit.h> +#endif + +@interface CDVWebViewUIDelegate : NSObject +#ifdef __IPHONE_8_0 + <WKUIDelegate> +#endif + +@property (nonatomic, copy) NSString* title; + +- (instancetype)initWithTitle:(NSString*)title; + +@end http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/CDVWebViewUIDelegate.m ---------------------------------------------------------------------- diff --git a/CordovaLib/CDVWebViewUIDelegate.m b/CordovaLib/CDVWebViewUIDelegate.m new file mode 100644 index 0000000..6f98327 --- /dev/null +++ b/CordovaLib/CDVWebViewUIDelegate.m @@ -0,0 +1,126 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#ifdef __IPHONE_8_0 + +#import "CDVWebViewUIDelegate.h" + + @implementation CDVWebViewUIDelegate + + - (instancetype)initWithTitle:(NSString*)title + { + self = [super init]; + if (self) { + self.title = title; + } + + return self; + } + + - (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message + initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)())completionHandler + { + UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title + message:message + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) + { + completionHandler(); + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + + [alert addAction:ok]; + + UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController; + + [rootController presentViewController:alert animated:YES completion:nil]; + } + + - (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message + initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(BOOL result))completionHandler + { + UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title + message:message + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) + { + completionHandler(YES); + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + + [alert addAction:ok]; + + UIAlertAction* cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) + { + completionHandler(NO); + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + [alert addAction:cancel]; + + UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController; + + [rootController presentViewController:alert animated:YES completion:nil]; + } + + - (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt + defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame + completionHandler:(void (^)(NSString* result))completionHandler + { + UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title + message:prompt + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) + { + completionHandler(((UITextField*)alert.textFields[0]).text); + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + + [alert addAction:ok]; + + UIAlertAction* cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction* action) + { + completionHandler(nil); + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + [alert addAction:cancel]; + + [alert addTextFieldWithConfigurationHandler:^(UITextField* textField) { + textField.text = defaultText; + }]; + + UIViewController* rootController = [UIApplication sharedApplication].delegate.window.rootViewController; + + [rootController presentViewController:alert animated:YES completion:nil]; + } + + @end +#endif /* ifdef __IPHONE_8_0 */ http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDV.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDV.h b/CordovaLib/Classes/CDV.h index 6cf592a..d368961 100644 --- a/CordovaLib/Classes/CDV.h +++ b/CordovaLib/Classes/CDV.h @@ -31,6 +31,8 @@ #import "CDVLocalStorage.h" #import "CDVScreenOrientationDelegate.h" #import "CDVTimer.h" +#import "CDVWebViewPreferences.h" +#import "CDVWebViewOperationsDelegate.h" #import "NSArray+Comparisons.h" #import "NSData+Base64.h" http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVCommandDelegateImpl.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandDelegateImpl.h b/CordovaLib/Classes/CDVCommandDelegateImpl.h index 0531134..4a74d55 100644 --- a/CordovaLib/Classes/CDVCommandDelegateImpl.h +++ b/CordovaLib/Classes/CDVCommandDelegateImpl.h @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,7 +24,7 @@ @class CDVCommandQueue; @interface CDVCommandDelegateImpl : NSObject <CDVCommandDelegate>{ - @private +@private __weak CDVViewController* _viewController; NSRegularExpression* _callbackIdPattern; @protected http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVCommandDelegateImpl.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandDelegateImpl.m b/CordovaLib/Classes/CDVCommandDelegateImpl.m index fc3346d..02e3064 100644 --- a/CordovaLib/Classes/CDVCommandDelegateImpl.m +++ b/CordovaLib/Classes/CDVCommandDelegateImpl.m @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -48,16 +48,16 @@ NSBundle* mainBundle = [NSBundle mainBundle]; NSMutableArray* directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]]; NSString* filename = [directoryParts lastObject]; - + [directoryParts removeLastObject]; - + NSString* directoryPartsJoined = [directoryParts componentsJoinedByString:@"/"]; NSString* directoryStr = _viewController.wwwFolderName; - + if ([directoryPartsJoined length] > 0) { directoryStr = [NSString stringWithFormat:@"%@/%@", _viewController.wwwFolderName, [directoryParts componentsJoinedByString:@"/"]]; } - + return [mainBundle pathForResource:filename ofType:@"" inDirectory:directoryStr]; } @@ -71,13 +71,18 @@ - (void)evalJsHelper2:(NSString*)js { CDV_EXEC_LOG(@"Exec: evalling: %@", [js substringToIndex:MIN([js length], 160)]); - NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js]; - if ([commandsJSON length] > 0) { - CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining."); - } - - [_commandQueue enqueueCommandBatch:commandsJSON]; - [_commandQueue executePending]; + [_viewController.webViewOperationsDelegate evaluateJavaScript:js completionHandler:^(id obj, NSError* error) { + // TODO: obj can be something other than string + if ([obj isKindOfClass:[NSString class]]) { + NSString* commandsJSON = (NSString*)obj; + if ([commandsJSON length] > 0) { + CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining."); + } + + [_commandQueue enqueueCommandBatch:commandsJSON]; + [_commandQueue executePending]; + } + }]; } - (void)evalJsHelper:(NSString*)js @@ -131,9 +136,9 @@ int status = [result.status intValue]; BOOL keepCallback = [result.keepCallback boolValue]; NSString* argumentsAsJSON = [result argumentsAsJSON]; - + NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)", callbackId, status, argumentsAsJSON, keepCallback]; - + [self evalJsHelper:js]; } @@ -170,7 +175,7 @@ - (BOOL)URLIsWhitelisted:(NSURL*)url { return ![_viewController.whitelist schemeIsAllowed:[url scheme]] || - [_viewController.whitelist URLIsAllowed:url logFailure:NO]; + [_viewController.whitelist URLIsAllowed:url logFailure:NO]; } - (NSDictionary*)settings http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVCommandQueue.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandQueue.m b/CordovaLib/Classes/CDVCommandQueue.m index 1eddfe3..b4f1fa6 100644 --- a/CordovaLib/Classes/CDVCommandQueue.m +++ b/CordovaLib/Classes/CDVCommandQueue.m @@ -109,9 +109,22 @@ static const double MAX_EXECUTION_TIME = .008; // Half of a 60fps frame. - (void)fetchCommandsFromJs { + NSString* js = @"cordova.require('cordova/exec').nativeFetchMessages()"; + SEL ui_selector = NSSelectorFromString(@"stringByEvaluatingJavaScriptFromString:"); + // Grab all the queued commands from the JS side. - NSString* queuedCommandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString: - @"cordova.require('cordova/exec').nativeFetchMessages()"]; + NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: + [[_viewController.webView class] instanceMethodSignatureForSelector:ui_selector]]; + + [invocation setSelector:ui_selector]; + [invocation setTarget:_viewController.webView]; + // arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation + [invocation setArgument:&(js) atIndex:2]; + + [invocation invoke]; + + NSString* queuedCommandsJSON; + [invocation getReturnValue:&(queuedCommandsJSON)]; CDV_EXEC_LOG(@"Exec: Flushed JS->native queue (hadCommands=%d).", [queuedCommandsJSON length] > 0); [self enqueueCommandBatch:queuedCommandsJSON]; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVPlugin.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVPlugin.h b/CordovaLib/Classes/CDVPlugin.h index 5e8b283..35d4cc2 100644 --- a/CordovaLib/Classes/CDVPlugin.h +++ b/CordovaLib/Classes/CDVPlugin.h @@ -22,6 +22,9 @@ #import "CDVPluginResult.h" #import "NSMutableArray+QueueAdditions.h" #import "CDVCommandDelegate.h" +#ifdef __IPHONE_8_0 + #import <WebKit/WebKit.h> +#endif extern NSString* const CDVPageDidLoadNotification; extern NSString* const CDVPluginHandleOpenURLNotification; @@ -32,13 +35,13 @@ extern NSString* const CDVRemoteNotificationError; @interface CDVPlugin : NSObject {} -@property (nonatomic, weak) UIWebView* webView; +@property (nonatomic, weak) UIView* webView; @property (nonatomic, weak) UIViewController* viewController; @property (nonatomic, weak) id <CDVCommandDelegate> commandDelegate; @property (readonly, assign) BOOL hasPendingOperation; -- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView; +- (instancetype)initWithWebView:(UIView*)theWebView; - (void)pluginInitialize; - (void)handleOpenURL:(NSNotification*)notification; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVPlugin.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVPlugin.m b/CordovaLib/Classes/CDVPlugin.m index ea81ddd..5f90311 100644 --- a/CordovaLib/Classes/CDVPlugin.m +++ b/CordovaLib/Classes/CDVPlugin.m @@ -18,6 +18,7 @@ */ #import "CDVPlugin.h" +#import "CDVViewController.h" NSString* const CDVPageDidLoadNotification = @"CDVPageDidLoadNotification"; NSString* const CDVPluginHandleOpenURLNotification = @"CDVPluginHandleOpenURLNotification"; @@ -36,12 +37,12 @@ NSString* const CDVRemoteNotificationError = @"CDVRemoteNotificationError"; @synthesize webView, viewController, commandDelegate, hasPendingOperation; // Do not override these methods. Use pluginInitialize instead. -- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings +- (instancetype)initWithWebView:(UIView*)theWebView settings:(NSDictionary*)classSettings { return [self initWithWebView:theWebView]; } -- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView +- (instancetype)initWithWebView:(UIView*)theWebView { self = [super init]; if (self) { @@ -130,7 +131,9 @@ NSString* const CDVRemoteNotificationError = @"CDVRemoteNotificationError"; - (NSString*)writeJavascript:(NSString*)javascript { - return [self.webView stringByEvaluatingJavaScriptFromString:javascript]; + // TODO: although deprecated, should have some solution here instead of removing it + [((CDVViewController*)self.viewController).webViewOperationsDelegate evaluateJavaScript : javascript completionHandler : nil]; // bad cast, but ok for now + return @""; } - (NSString*)success:(CDVPluginResult*)pluginResult callbackId:(NSString*)callbackId http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVViewController.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.h b/CordovaLib/Classes/CDVViewController.h index 51863a5..7bc005a 100644 --- a/CordovaLib/Classes/CDVViewController.h +++ b/CordovaLib/Classes/CDVViewController.h @@ -26,8 +26,19 @@ #import "CDVWhitelist.h" #import "CDVScreenOrientationDelegate.h" #import "CDVPlugin.h" +#import "CDVWebViewOperationsDelegate.h" +#ifdef __IPHONE_8_0 + #import <WebKit/WebKit.h> +#else + @protocol WKScriptMessageHandler + @end +#endif -@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{ +@protocol WKScriptMessageHandler; + +@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate, WKScriptMessageHandler>{ + @protected + CDVWebViewOperationsDelegate* _webViewOperationsDelegate; @protected id <CDVCommandDelegate> _commandDelegate; @protected @@ -35,7 +46,7 @@ NSString* _userAgent; } -@property (nonatomic, strong) IBOutlet UIWebView* webView; +@property (nonatomic, strong) IBOutlet UIView* webView; @property (nonatomic, readonly, strong) NSMutableDictionary* pluginObjects; @property (nonatomic, readonly, strong) NSDictionary* pluginsMap; @@ -47,6 +58,7 @@ @property (nonatomic, readwrite, copy) NSString* wwwFolderName; @property (nonatomic, readwrite, copy) NSString* startPage; @property (nonatomic, readonly, strong) CDVCommandQueue* commandQueue; +@property (nonatomic, readonly, strong) CDVWebViewOperationsDelegate* webViewOperationsDelegate; @property (nonatomic, readonly, strong) id <CDVCommandDelegate> commandDelegate; /** @@ -66,7 +78,7 @@ - (void)printMultitaskingInfo; - (void)createGapView; -- (UIWebView*)newCordovaViewWithFrame:(CGRect)bounds; +- (UIView*)newCordovaViewWithFrame:(CGRect)bounds; - (void)javascriptAlert:(NSString*)text; - (NSString*)appURLScheme; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVViewController.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.m b/CordovaLib/Classes/CDVViewController.m index eb056ce..6730239 100644 --- a/CordovaLib/Classes/CDVViewController.m +++ b/CordovaLib/Classes/CDVViewController.m @@ -23,6 +23,7 @@ #import "CDVConfigParser.h" #import "CDVUserAgentUtil.h" #import "CDVWebViewDelegate.h" +#import "CDVWebViewUIDelegate.h" #import <AVFoundation/AVFoundation.h> #define degreesToRadian(x) (M_PI * (x) / 180.0) @@ -30,6 +31,7 @@ @interface CDVViewController () { NSInteger _userAgentLockToken; CDVWebViewDelegate* _webViewDelegate; + CDVWebViewUIDelegate* _webViewUIDelegate; } @property (nonatomic, readwrite, strong) NSXMLParser* configParser; @@ -55,6 +57,7 @@ @synthesize wwwFolderName, startPage, initialized, openURL, baseUserAgent; @synthesize commandDelegate = _commandDelegate; @synthesize commandQueue = _commandQueue; +@synthesize webViewOperationsDelegate = _webViewOperationsDelegate; - (void)__init { @@ -279,22 +282,15 @@ // Configure WebView _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self]; - self.webView.delegate = _webViewDelegate; + if ([webView respondsToSelector:@selector(setDelegate:)]) { + [webView setValue:_webViewDelegate forKey:@"delegate"]; + } // register this viewcontroller with the NSURLProtocol, only after the User-Agent is set [CDVURLProtocol registerViewController:self]; // ///////////////// - NSString* enableViewportScale = [self settingForKey:@"EnableViewportScale"]; - NSNumber* allowInlineMediaPlayback = [self settingForKey:@"AllowInlineMediaPlayback"]; - BOOL mediaPlaybackRequiresUserAction = YES; // default value - if ([self settingForKey:@"MediaPlaybackRequiresUserAction"]) { - mediaPlaybackRequiresUserAction = [(NSNumber*)[self settingForKey:@"MediaPlaybackRequiresUserAction"] boolValue]; - } - - self.webView.scalesPageToFit = [enableViewportScale boolValue]; - /* * Fire up CDVLocalStorage to work-around WebKit storage limitations: on all iOS 5.1+ versions for local-only backups, but only needed on iOS 5.1 for cloud backup. */ @@ -303,150 +299,8 @@ [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])]; } - /* - * This is for iOS 4.x, where you can allow inline <video> and <audio>, and also autoplay them - */ - if ([allowInlineMediaPlayback boolValue] && [self.webView respondsToSelector:@selector(allowsInlineMediaPlayback)]) { - self.webView.allowsInlineMediaPlayback = YES; - } - if ((mediaPlaybackRequiresUserAction == NO) && [self.webView respondsToSelector:@selector(mediaPlaybackRequiresUserAction)]) { - self.webView.mediaPlaybackRequiresUserAction = NO; - } - - // By default, overscroll bouncing is allowed. - // UIWebViewBounce has been renamed to DisallowOverscroll, but both are checked. - BOOL bounceAllowed = YES; - NSNumber* disallowOverscroll = [self settingForKey:@"DisallowOverscroll"]; - if (disallowOverscroll == nil) { - NSNumber* bouncePreference = [self settingForKey:@"UIWebViewBounce"]; - bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]); - } else { - bounceAllowed = ![disallowOverscroll boolValue]; - } - - // prevent webView from bouncing - // based on the DisallowOverscroll/UIWebViewBounce key in config.xml - if (!bounceAllowed) { - if ([self.webView respondsToSelector:@selector(scrollView)]) { - ((UIScrollView*)[self.webView scrollView]).bounces = NO; - } else { - for (id subview in self.webView.subviews) { - if ([[subview class] isSubclassOfClass:[UIScrollView class]]) { - ((UIScrollView*)subview).bounces = NO; - } - } - } - } - - NSString* decelerationSetting = [self settingForKey:@"UIWebViewDecelerationSpeed"]; - if (![@"fast" isEqualToString:decelerationSetting]) { - [self.webView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal]; - } - - /* - * iOS 6.0 UIWebView properties - */ - if (IsAtLeastiOSVersion(@"6.0")) { - BOOL keyboardDisplayRequiresUserAction = YES; // KeyboardDisplayRequiresUserAction - defaults to YES - if ([self settingForKey:@"KeyboardDisplayRequiresUserAction"] != nil) { - if ([self settingForKey:@"KeyboardDisplayRequiresUserAction"]) { - keyboardDisplayRequiresUserAction = [(NSNumber*)[self settingForKey:@"KeyboardDisplayRequiresUserAction"] boolValue]; - } - } - - // property check for compiling under iOS < 6 - if ([self.webView respondsToSelector:@selector(setKeyboardDisplayRequiresUserAction:)]) { - [self.webView setValue:[NSNumber numberWithBool:keyboardDisplayRequiresUserAction] forKey:@"keyboardDisplayRequiresUserAction"]; - } - - BOOL suppressesIncrementalRendering = NO; // SuppressesIncrementalRendering - defaults to NO - if ([self settingForKey:@"SuppressesIncrementalRendering"] != nil) { - if ([self settingForKey:@"SuppressesIncrementalRendering"]) { - suppressesIncrementalRendering = [(NSNumber*)[self settingForKey:@"SuppressesIncrementalRendering"] boolValue]; - } - } - - // property check for compiling under iOS < 6 - if ([self.webView respondsToSelector:@selector(setSuppressesIncrementalRendering:)]) { - [self.webView setValue:[NSNumber numberWithBool:suppressesIncrementalRendering] forKey:@"suppressesIncrementalRendering"]; - } - } - - /* - * iOS 7.0 UIWebView properties - */ - if (IsAtLeastiOSVersion(@"7.0")) { - SEL ios7sel = nil; - id prefObj = nil; - - CGFloat gapBetweenPages = 0.0; // default - prefObj = [self settingForKey:@"GapBetweenPages"]; - if (prefObj != nil) { - gapBetweenPages = [prefObj floatValue]; - } - - // property check for compiling under iOS < 7 - ios7sel = NSSelectorFromString(@"setGapBetweenPages:"); - if ([self.webView respondsToSelector:ios7sel]) { - [self.webView setValue:[NSNumber numberWithFloat:gapBetweenPages] forKey:@"gapBetweenPages"]; - } - - CGFloat pageLength = 0.0; // default - prefObj = [self settingForKey:@"PageLength"]; - if (prefObj != nil) { - pageLength = [[self settingForKey:@"PageLength"] floatValue]; - } - - // property check for compiling under iOS < 7 - ios7sel = NSSelectorFromString(@"setPageLength:"); - if ([self.webView respondsToSelector:ios7sel]) { - [self.webView setValue:[NSNumber numberWithBool:pageLength] forKey:@"pageLength"]; - } - - NSInteger paginationBreakingMode = 0; // default - UIWebPaginationBreakingModePage - prefObj = [self settingForKey:@"PaginationBreakingMode"]; - if (prefObj != nil) { - NSArray* validValues = @[@"page", @"column"]; - NSString* prefValue = [validValues objectAtIndex:0]; - - if ([prefObj isKindOfClass:[NSString class]]) { - prefValue = prefObj; - } - - paginationBreakingMode = [validValues indexOfObject:[prefValue lowercaseString]]; - if (paginationBreakingMode == NSNotFound) { - paginationBreakingMode = 0; - } - } - - // property check for compiling under iOS < 7 - ios7sel = NSSelectorFromString(@"setPaginationBreakingMode:"); - if ([self.webView respondsToSelector:ios7sel]) { - [self.webView setValue:[NSNumber numberWithInteger:paginationBreakingMode] forKey:@"paginationBreakingMode"]; - } - - NSInteger paginationMode = 0; // default - UIWebPaginationModeUnpaginated - prefObj = [self settingForKey:@"PaginationMode"]; - if (prefObj != nil) { - NSArray* validValues = @[@"unpaginated", @"lefttoright", @"toptobottom", @"bottomtotop", @"righttoleft"]; - NSString* prefValue = [validValues objectAtIndex:0]; - - if ([prefObj isKindOfClass:[NSString class]]) { - prefValue = prefObj; - } - - paginationMode = [validValues indexOfObject:[prefValue lowercaseString]]; - if (paginationMode == NSNotFound) { - paginationMode = 0; - } - } - - // property check for compiling under iOS < 7 - ios7sel = NSSelectorFromString(@"setPaginationMode:"); - if ([self.webView respondsToSelector:ios7sel]) { - [self.webView setValue:[NSNumber numberWithInteger:paginationMode] forKey:@"paginationMode"]; - } - } + CDVWebViewPreferences* prefs = [[CDVWebViewPreferences alloc] initWithWebView:webView]; + [prefs updateSettings:self.settings]; if ([self.startupPluginNames count] > 0) { [CDVTimer start:@"TotalPluginStartup"]; @@ -468,7 +322,7 @@ [CDVUserAgentUtil setUserAgent:self.userAgent lockToken:lockToken]; if (appURL) { NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0]; - [self.webView loadRequest:appReq]; + [_webViewOperationsDelegate loadRequest:appReq]; } else { NSString* loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage]; NSLog(@"%@", loadErr); @@ -479,8 +333,8 @@ NSLog(@"%@", [errorUrl absoluteString]); [self.webView loadRequest:[NSURLRequest requestWithURL:errorUrl]]; } else { - NSString* html = [NSString stringWithFormat:@"<html><body> %@ </body></html>", loadErr]; - [self.webView loadHTMLString:html baseURL:nil]; + NSString* html = [NSString stringWithFormat:@"<html><body> %@ </body></html>", loadErr]; + [_webViewOperationsDelegate loadHTMLString:html baseURL:nil]; } } }]; @@ -545,20 +399,22 @@ } } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +- (void)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation completionHandler:(void (^)(BOOL))completionHandler { // First, ask the webview via JS if it supports the new orientation NSString* jsCall = [NSString stringWithFormat: @"window.shouldRotateToOrientation && window.shouldRotateToOrientation(%ld);" , (long)[self mapIosOrientationToJsOrientation:interfaceOrientation]]; - NSString* res = [webView stringByEvaluatingJavaScriptFromString:jsCall]; + __weak CDVViewController* weakSelf = self; - if ([res length] > 0) { - return [res boolValue]; - } - - // if js did not handle the new orientation (no return value), use values from the plist (via supportedOrientations) - return [self supportsOrientation:interfaceOrientation]; + [_webViewOperationsDelegate evaluateJavaScript:jsCall completionHandler:^(NSString* obj, NSError* error) { + if ([obj length] > 0) { + completionHandler([obj boolValue]); + } else { + // if js did not handle the new orientation (no return value), use values from the plist (via supportedOrientations) + completionHandler([weakSelf supportsOrientation:interfaceOrientation]); + } + }]; } - (BOOL)shouldAutorotate @@ -591,9 +447,37 @@ return [self.supportedOrientations containsObject:[NSNumber numberWithInt:orientation]]; } -- (UIWebView*)newCordovaViewWithFrame:(CGRect)bounds +- (UIView*)newCordovaViewWithFrame:(CGRect)bounds { - return [[UIWebView alloc] initWithFrame:bounds]; + UIView* cordovaView = nil; + BOOL useWKWebView = NO; // default value + + if ([self settingForKey:@"UseWKWebView"]) { + useWKWebView = [(NSNumber*)[self settingForKey:@"UseWKWebView"] boolValue]; + } + + if (NSClassFromString(@"WKWebView") && useWKWebView) { +#ifdef __IPHONE_8_0 + WKUserContentController* userContentController = [[WKUserContentController alloc] init]; + + // scriptMessageHandler is the object that conforms to the WKScriptMessageHandler protocol + // see https://developer.apple.com/library/prerelease/ios/documentation/WebKit/Reference/WKScriptMessageHandler_Ref/index.html#//apple_ref/swift/intf/WKScriptMessageHandler + if ([_commandDelegate conformsToProtocol:@protocol(WKScriptMessageHandler)]) { + [userContentController addScriptMessageHandler:self name:@"cordova"]; + } + + WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init]; + configuration.userContentController = userContentController; + + cordovaView = [[WKWebView alloc] initWithFrame:bounds configuration:configuration]; + _webViewUIDelegate = [[CDVWebViewUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]]; + ((WKWebView*)cordovaView).UIDelegate = _webViewUIDelegate; +#endif + } else { + cordovaView = [[UIWebView alloc] initWithFrame:bounds]; + } + + return cordovaView; } - (NSString*)userAgent @@ -619,6 +503,7 @@ self.webView = [self newCordovaViewWithFrame:webViewBounds]; self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); + _webViewOperationsDelegate = [[CDVWebViewOperationsDelegate alloc] initWithWebView:self.webView]; [self.view addSubview:self.webView]; [self.view sendSubviewToBack:self.webView]; @@ -654,7 +539,9 @@ // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; - self.webView.delegate = nil; + if ([webView respondsToSelector:@selector(setDelegate:)]) { + [webView setValue:nil forKey:@"delegate"]; + } self.webView = nil; [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; @@ -1002,10 +889,25 @@ { if (self.openURL) { [self processOpenUrl:self.openURL pageLoaded:YES]; + NSString* jsString = [NSString stringWithFormat:@"handleOpenURL(\"%@\");", [self.openURL description]]; + [_webViewOperationsDelegate evaluateJavaScript:jsString completionHandler:nil]; self.openURL = nil; } } +#pragma mark WKScriptMessageHandler implementation + +#ifdef __IPHONE_8_0 + - (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message + { + if (![message.name isEqualToString:@"cordova"]) { + return; + } + + NSArray* jsonEntry = message.body; // NSString:callbackId, NSString:service, NSString:action, NSArray:args + CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry]; + CDV_EXEC_LOG(@"Exec(%@): Calling %@.%@", command.callbackId, command.className, command.methodName); + - (void)processOpenUrl:(NSURL*)url pageLoaded:(BOOL)pageLoaded { if (!pageLoaded) { @@ -1015,16 +917,17 @@ } if (pageLoaded) { - // calls into javascript global function 'handleOpenURL' + DLog(@"FAILED pluginJSON = %@", commandString); NSString* jsString = [NSString stringWithFormat:@"if (typeof handleOpenURL === 'function') { handleOpenURL(\"%@\");}", url]; - [self.webView stringByEvaluatingJavaScriptFromString:jsString]; + #endif + } } else { // save for when page has loaded self.openURL = url; } } -- (void)processOpenUrl:(NSURL*)url +#endif /* ifdef __IPHONE_8_0 */ { [self processOpenUrl:url pageLoaded:NO]; } @@ -1036,7 +939,10 @@ [CDVURLProtocol unregisterViewController:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; - self.webView.delegate = nil; + if ([webView respondsToSelector:@selector(setDelegate:)]) { + [webView setValue:nil forKey:@"delegate"]; + } + self.webView = nil; [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; [_commandQueue dispose]; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVWebViewOperationsDelegate.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVWebViewOperationsDelegate.h b/CordovaLib/Classes/CDVWebViewOperationsDelegate.h new file mode 100644 index 0000000..34330a1 --- /dev/null +++ b/CordovaLib/Classes/CDVWebViewOperationsDelegate.h @@ -0,0 +1,39 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#ifdef __IPHONE_8_0 +#pragma message("For iOS 8 - Please add WebKit.framework into your 'Link Binary with Libraries' Build Phase Project Setting. This will be baked in once Xcode 6 is required.") +#endif /* ifdef __IPHONE_8_0 */ + + +@interface CDVWebViewOperationsDelegate : NSObject { + @private + __weak UIView* _webView; +} + +- (instancetype) initWithWebView:(UIView*)webView; + +- (void)loadRequest:(NSURLRequest*)request; +- (void)loadHTMLString:(NSString*)string baseURL:(NSURL*)baseURL; +- (void)evaluateJavaScript:(NSString*)javaScriptString completionHandler:(void (^)(id, NSError*))completionHandler; + +@end http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVWebViewOperationsDelegate.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVWebViewOperationsDelegate.m b/CordovaLib/Classes/CDVWebViewOperationsDelegate.m new file mode 100644 index 0000000..d243aba --- /dev/null +++ b/CordovaLib/Classes/CDVWebViewOperationsDelegate.m @@ -0,0 +1,83 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <objc/message.h> +#import "CDVWebViewOperationsDelegate.h" + +@implementation CDVWebViewOperationsDelegate + +- (instancetype) initWithWebView:(UIView*)webView +{ + self = [super init]; + if (self) { + Class wk_class = NSClassFromString(@"WKWebView"); + if ( !([webView isKindOfClass:wk_class] || [webView isKindOfClass:[UIWebView class]] )) { + return nil; + } + _webView = webView; + } + + return self; +} + +- (void)loadRequest:(NSURLRequest*)request +{ + SEL selector = NSSelectorFromString(@"loadRequest:"); + if ([_webView respondsToSelector:selector]) { + // UIKit operations have to be on the main thread. and this method is synchronous + [_webView performSelectorOnMainThread:selector withObject:request waitUntilDone:YES]; + } +} + +- (void)loadHTMLString:(NSString*)string baseURL:(NSURL*)baseURL +{ + SEL selector = NSSelectorFromString(@"loadHTMLString:baseURL:"); + + dispatch_block_t invoke = ^(void) { + ((void (*)(id, SEL, id, id))objc_msgSend)(_webView, selector, string, baseURL); + }; + + if ([_webView respondsToSelector:selector]) { + // UIKit operations have to be on the main thread. + // perform a synchronous invoke on the main thread without deadlocking + if ([NSThread isMainThread]) { + invoke(); + } else { + dispatch_sync(dispatch_get_main_queue(), invoke); + } + } +} + +- (void)evaluateJavaScript:(NSString*)javaScriptString completionHandler:(void (^)(id, NSError*))completionHandler +{ + SEL ui_sel = NSSelectorFromString(@"stringByEvaluatingJavaScriptFromString:"); + SEL wk_sel = NSSelectorFromString(@"evaluateJavaScript:completionHandler:"); + + // UIKit operations have to be on the main thread. This method does not need to be synchronous + dispatch_async(dispatch_get_main_queue(), ^{ + if ([_webView respondsToSelector:ui_sel]) { + NSString* ret = ((NSString* (*)(id, SEL, id))objc_msgSend)(_webView, ui_sel, javaScriptString); + completionHandler(ret, nil); + } else if ([_webView respondsToSelector:wk_sel]) { + ((void (*)(id, SEL, id, id))objc_msgSend)(_webView, wk_sel, javaScriptString, completionHandler); + } + }); +} + +@end http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVWebViewPreferences.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVWebViewPreferences.h b/CordovaLib/Classes/CDVWebViewPreferences.h new file mode 100644 index 0000000..5058eef --- /dev/null +++ b/CordovaLib/Classes/CDVWebViewPreferences.h @@ -0,0 +1,32 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +@interface CDVWebViewPreferences: NSObject { + @private + __weak UIView* _webView; +} + +- (instancetype) initWithWebView:(UIView*)webView; +- (void) updateSettings:(NSDictionary*)settings; + + +@end http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/Classes/CDVWebViewPreferences.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVWebViewPreferences.m b/CordovaLib/Classes/CDVWebViewPreferences.m new file mode 100644 index 0000000..a42b3aa --- /dev/null +++ b/CordovaLib/Classes/CDVWebViewPreferences.m @@ -0,0 +1,261 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +#import "CDVWebViewPreferences.h" +#import "CDVAvailability.h" +#import <objc/message.h> + +#ifdef __IPHONE_8_0 + #import <WebKit/WebKit.h> +#endif /* ifdef __IPHONE_8_0 */ + +@implementation CDVWebViewPreferences + +- (instancetype)initWithWebView:(UIView*)webView +{ + self = [super init]; + if (self) { + Class wk_class = NSClassFromString(@"WKWebView"); + if (!([webView isKindOfClass:wk_class] || [webView isKindOfClass:[UIWebView class]])) { + return nil; + } + _webView = webView; + } + + return self; +} + +- (void)updateSettings:(NSDictionary*)settings +{ + Class wk_class = NSClassFromString(@"WKWebView"); + SEL ui_sel = NSSelectorFromString(@"updateUIWebView:settings:"); + SEL wk_sel = NSSelectorFromString(@"updateWKWebView:settings:"); + + __weak id weakSelf = self; + + dispatch_block_t invoke = ^(void) { + if ([_webView isKindOfClass:[UIWebView class]] && [weakSelf respondsToSelector:ui_sel]) { + ((void (*)(id, SEL, id, id))objc_msgSend)(weakSelf, ui_sel, _webView, settings); + } else if ([_webView isKindOfClass:wk_class] && [weakSelf respondsToSelector:wk_sel]) { + ((void (*)(id, SEL, id, id))objc_msgSend)(weakSelf, wk_sel, _webView, settings); + } + }; + + // UIKit operations have to be on the main thread. + // perform a synchronous invoke on the main thread without deadlocking + if ([NSThread isMainThread]) { + invoke(); + } else { + dispatch_sync(dispatch_get_main_queue(), invoke); + } +} + +- (id)cordovaSettings:(NSDictionary*)settings forKey:(NSString*)key +{ + return [settings objectForKey:[key lowercaseString]]; +} + +- (void)updateUIWebView:(UIWebView*)theWebView settings:(NSDictionary*)settings +{ + NSString* enableViewportScale = [self cordovaSettings:settings forKey:@"EnableViewportScale"]; + NSNumber* allowInlineMediaPlayback = [self cordovaSettings:settings forKey:@"AllowInlineMediaPlayback"]; + BOOL mediaPlaybackRequiresUserAction = YES; // default value + + if ([self cordovaSettings:settings forKey:@"MediaPlaybackRequiresUserAction"]) { + mediaPlaybackRequiresUserAction = [(NSNumber*)[self cordovaSettings:settings forKey:@"MediaPlaybackRequiresUserAction"] boolValue]; + } + + theWebView.scalesPageToFit = [enableViewportScale boolValue]; + + /* + * This is for iOS 4.x, where you can allow inline <video> and <audio>, and also autoplay them + */ + if ([allowInlineMediaPlayback boolValue] && [theWebView respondsToSelector:@selector(allowsInlineMediaPlayback)]) { + theWebView.allowsInlineMediaPlayback = YES; + } + if ((mediaPlaybackRequiresUserAction == NO) && [theWebView respondsToSelector:@selector(mediaPlaybackRequiresUserAction)]) { + theWebView.mediaPlaybackRequiresUserAction = NO; + } + + // By default, overscroll bouncing is allowed. + // UIWebViewBounce has been renamed to DisallowOverscroll, but both are checked. + BOOL bounceAllowed = YES; + NSNumber* disallowOverscroll = [self cordovaSettings:settings forKey:@"DisallowOverscroll"]; + if (disallowOverscroll == nil) { + NSNumber* bouncePreference = [self cordovaSettings:settings forKey:@"UIWebViewBounce"]; + bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]); + } else { + bounceAllowed = ![disallowOverscroll boolValue]; + } + + // prevent webView from bouncing + // based on the DisallowOverscroll/UIWebViewBounce key in config.xml + if (!bounceAllowed) { + if ([theWebView respondsToSelector:@selector(scrollView)]) { + ((UIScrollView*)[theWebView scrollView]).bounces = NO; + } else { + for (id subview in theWebView.subviews) { + if ([[subview class] isSubclassOfClass:[UIScrollView class]]) { + ((UIScrollView*)subview).bounces = NO; + } + } + } + } + + NSString* decelerationSetting = [self cordovaSettings:settings forKey:@"UIWebViewDecelerationSpeed"]; + if (![@"fast" isEqualToString : decelerationSetting]) { + [theWebView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal]; + } + + /* + * iOS 6.0 UIWebView properties + */ + if (IsAtLeastiOSVersion(@"6.0")) { + BOOL keyboardDisplayRequiresUserAction = YES; // KeyboardDisplayRequiresUserAction - defaults to YES + if ([self cordovaSettings:settings forKey:@"KeyboardDisplayRequiresUserAction"] != nil) { + if ([self cordovaSettings:settings forKey:@"KeyboardDisplayRequiresUserAction"]) { + keyboardDisplayRequiresUserAction = [(NSNumber*)[self cordovaSettings:settings forKey:@"KeyboardDisplayRequiresUserAction"] boolValue]; + } + } + + // property check for compiling under iOS < 6 + if ([theWebView respondsToSelector:@selector(setKeyboardDisplayRequiresUserAction:)]) { + [theWebView setValue:[NSNumber numberWithBool:keyboardDisplayRequiresUserAction] forKey:@"keyboardDisplayRequiresUserAction"]; + } + + BOOL suppressesIncrementalRendering = NO; // SuppressesIncrementalRendering - defaults to NO + if ([self cordovaSettings:settings forKey:@"SuppressesIncrementalRendering"] != nil) { + if ([self cordovaSettings:settings forKey:@"SuppressesIncrementalRendering"]) { + suppressesIncrementalRendering = [(NSNumber*)[self cordovaSettings:settings forKey:@"SuppressesIncrementalRendering"] boolValue]; + } + } + + // property check for compiling under iOS < 6 + if ([theWebView respondsToSelector:@selector(setSuppressesIncrementalRendering:)]) { + [theWebView setValue:[NSNumber numberWithBool:suppressesIncrementalRendering] forKey:@"suppressesIncrementalRendering"]; + } + } + + /* + * iOS 7.0 UIWebView properties + */ + if (IsAtLeastiOSVersion(@"7.0")) { + SEL ios7sel = nil; + id prefObj = nil; + + CGFloat gapBetweenPages = 0.0; // default + prefObj = [self cordovaSettings:settings forKey:@"GapBetweenPages"]; + if (prefObj != nil) { + gapBetweenPages = [prefObj floatValue]; + } + + // property check for compiling under iOS < 7 + ios7sel = NSSelectorFromString(@"setGapBetweenPages:"); + if ([theWebView respondsToSelector:ios7sel]) { + [theWebView setValue:[NSNumber numberWithFloat:gapBetweenPages] forKey:@"gapBetweenPages"]; + } + + CGFloat pageLength = 0.0; // default + prefObj = [self cordovaSettings:settings forKey:@"PageLength"]; + if (prefObj != nil) { + pageLength = [[self cordovaSettings:settings forKey:@"PageLength"] floatValue]; + } + + // property check for compiling under iOS < 7 + ios7sel = NSSelectorFromString(@"setPageLength:"); + if ([theWebView respondsToSelector:ios7sel]) { + [theWebView setValue:[NSNumber numberWithBool:pageLength] forKey:@"pageLength"]; + } + + NSInteger paginationBreakingMode = 0; // default - UIWebPaginationBreakingModePage + prefObj = [self cordovaSettings:settings forKey:@"PaginationBreakingMode"]; + if (prefObj != nil) { + NSArray* validValues = @[@"page", @"column"]; + NSString* prefValue = [validValues objectAtIndex:0]; + + if ([prefObj isKindOfClass:[NSString class]]) { + prefValue = prefObj; + } + + paginationBreakingMode = [validValues indexOfObject:[prefValue lowercaseString]]; + if (paginationBreakingMode == NSNotFound) { + paginationBreakingMode = 0; + } + } + + // property check for compiling under iOS < 7 + ios7sel = NSSelectorFromString(@"setPaginationBreakingMode:"); + if ([theWebView respondsToSelector:ios7sel]) { + [theWebView setValue:[NSNumber numberWithInteger:paginationBreakingMode] forKey:@"paginationBreakingMode"]; + } + + NSInteger paginationMode = 0; // default - UIWebPaginationModeUnpaginated + prefObj = [self cordovaSettings:settings forKey:@"PaginationMode"]; + if (prefObj != nil) { + NSArray* validValues = @[@"unpaginated", @"lefttoright", @"toptobottom", @"bottomtotop", @"righttoleft"]; + NSString* prefValue = [validValues objectAtIndex:0]; + + if ([prefObj isKindOfClass:[NSString class]]) { + prefValue = prefObj; + } + + paginationMode = [validValues indexOfObject:[prefValue lowercaseString]]; + if (paginationMode == NSNotFound) { + paginationMode = 0; + } + } + + // property check for compiling under iOS < 7 + ios7sel = NSSelectorFromString(@"setPaginationMode:"); + if ([theWebView respondsToSelector:ios7sel]) { + [theWebView setValue:[NSNumber numberWithInteger:paginationMode] forKey:@"paginationMode"]; + } + } +} + +#ifdef __IPHONE_8_0 + + - (void)updateWKWebView:(WKWebView*)theWebView settings:(NSDictionary*)settings + { + id prefObj = nil; + + CGFloat minimumFontSize = 0.0; // default + + prefObj = [self cordovaSettings:settings forKey:@"MinimumFontSize"]; + if (prefObj != nil) { + minimumFontSize = [[self cordovaSettings:settings forKey:@"MinimumFontSize"] floatValue]; + } + theWebView.configuration.preferences.minimumFontSize = minimumFontSize; + + /* + BOOL javaScriptEnabled = YES; // default value + if ([self cordovaSettings:settings forKey:@"JavaScriptEnabled"]) { + javaScriptEnabled = [(NSNumber*)[self cordovaSettings:settings forKey:@"JavaScriptEnabled"] boolValue]; + } + theWebView.configuration.preferences.javaScriptEnabled = javaScriptEnabled; + + BOOL javaScriptCanOpenWindowsAutomatically = NO; // default value + if ([self cordovaSettings:settings forKey:@"JavaScriptEnabled"]) { + javaScriptCanOpenWindowsAutomatically = [(NSNumber*)[self cordovaSettings:settings forKey:@"JavaScriptEnabled"] boolValue]; + } + theWebView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = javaScriptCanOpenWindowsAutomatically; + */ + } +#endif /* ifdef __IPHONE_8_0 */ + +@end http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/CordovaLib.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index 63c294c..941fa15 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -12,8 +12,10 @@ 1F92F4A11314023E0046367C /* CDVPluginResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F92F49F1314023E0046367C /* CDVPluginResult.m */; }; 301F2F2A14F3C9CA003FE9FC /* CDV.h in Headers */ = {isa = PBXBuildFile; fileRef = 301F2F2914F3C9CA003FE9FC /* CDV.h */; settings = {ATTRIBUTES = (Public, ); }; }; 302965BC13A94E9D007046C5 /* CDVDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 302965BB13A94E9D007046C5 /* CDVDebug.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 302D72FC19554BFC0028C99F /* CDVWebViewOperationsDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D72FA19554BFC0028C99F /* CDVWebViewOperationsDelegate.m */; }; 3034979C1513D56A0090E688 /* CDVLocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 3034979A1513D56A0090E688 /* CDVLocalStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3034979E1513D56A0090E688 /* CDVLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 3034979B1513D56A0090E688 /* CDVLocalStorage.m */; }; + 303820731955603600C91592 /* CDVWebViewOperationsDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 302D72F919554BFC0028C99F /* CDVWebViewOperationsDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30392E4E14F4FCAB00B9E0B8 /* CDVAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 30392E4D14F4FCAB00B9E0B8 /* CDVAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3062D120151D0EDB000D9128 /* UIDevice+Extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3062D11E151D0EDB000D9128 /* UIDevice+Extensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3062D122151D0EDB000D9128 /* UIDevice+Extensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3062D11F151D0EDB000D9128 /* UIDevice+Extensions.m */; }; @@ -31,7 +33,11 @@ 30F5EBAB14CA26E700987760 /* CDVCommandDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 30F5EBA914CA26E700987760 /* CDVCommandDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7E14B5A81705050A0032169E /* CDVTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E14B5A61705050A0032169E /* CDVTimer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7E14B5A91705050A0032169E /* CDVTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E14B5A71705050A0032169E /* CDVTimer.m */; }; + 7E785B9A196F508900ABBDC8 /* CDVWebViewUIDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E785B98196F508900ABBDC8 /* CDVWebViewUIDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7E785B9B196F508900ABBDC8 /* CDVWebViewUIDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E785B99196F508900ABBDC8 /* CDVWebViewUIDelegate.m */; }; + 7EE9ECF819525D24004CA6B9 /* CDVWebViewPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EE9ECF619525D24004CA6B9 /* CDVWebViewPreferences.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7E22B88519E4C0210026F95E /* CDVAvailabilityDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E22B88419E4C0210026F95E /* CDVAvailabilityDeprecated.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7EE9ECF919525D24004CA6B9 /* CDVWebViewPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE9ECF719525D24004CA6B9 /* CDVWebViewPreferences.m */; }; 8852C43A14B65FD800F0E735 /* CDVViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 8852C43614B65FD800F0E735 /* CDVViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8852C43C14B65FD800F0E735 /* CDVViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8852C43714B65FD800F0E735 /* CDVViewController.m */; }; 8887FD681090FBE7009987E8 /* NSDictionary+Extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8887FD281090FBE7009987E8 /* NSDictionary+Extensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -60,6 +66,8 @@ 1F92F49F1314023E0046367C /* CDVPluginResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVPluginResult.m; path = Classes/CDVPluginResult.m; sourceTree = "<group>"; }; 301F2F2914F3C9CA003FE9FC /* CDV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDV.h; path = Classes/CDV.h; sourceTree = "<group>"; }; 302965BB13A94E9D007046C5 /* CDVDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVDebug.h; path = Classes/CDVDebug.h; sourceTree = "<group>"; }; + 302D72F919554BFC0028C99F /* CDVWebViewOperationsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVWebViewOperationsDelegate.h; path = Classes/CDVWebViewOperationsDelegate.h; sourceTree = "<group>"; }; + 302D72FA19554BFC0028C99F /* CDVWebViewOperationsDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVWebViewOperationsDelegate.m; path = Classes/CDVWebViewOperationsDelegate.m; sourceTree = "<group>"; }; 30325A0B136B343700982B63 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; }; 3034979A1513D56A0090E688 /* CDVLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVLocalStorage.h; path = Classes/CDVLocalStorage.h; sourceTree = "<group>"; }; 3034979B1513D56A0090E688 /* CDVLocalStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVLocalStorage.m; path = Classes/CDVLocalStorage.m; sourceTree = "<group>"; }; @@ -92,7 +100,11 @@ 68A32D7414103017006B237C /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; 7E14B5A61705050A0032169E /* CDVTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVTimer.h; path = Classes/CDVTimer.h; sourceTree = "<group>"; }; 7E14B5A71705050A0032169E /* CDVTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVTimer.m; path = Classes/CDVTimer.m; sourceTree = "<group>"; }; + 7E785B98196F508900ABBDC8 /* CDVWebViewUIDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVWebViewUIDelegate.h; sourceTree = "<group>"; }; + 7E785B99196F508900ABBDC8 /* CDVWebViewUIDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVWebViewUIDelegate.m; sourceTree = "<group>"; }; + 7EE9ECF619525D24004CA6B9 /* CDVWebViewPreferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVWebViewPreferences.h; path = Classes/CDVWebViewPreferences.h; sourceTree = "<group>"; }; 7E22B88419E4C0210026F95E /* CDVAvailabilityDeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVAvailabilityDeprecated.h; path = Classes/CDVAvailabilityDeprecated.h; sourceTree = "<group>"; }; + 7EE9ECF719525D24004CA6B9 /* CDVWebViewPreferences.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVWebViewPreferences.m; path = Classes/CDVWebViewPreferences.m; sourceTree = "<group>"; }; 8220B5C316D5427E00EC3921 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 8852C43614B65FD800F0E735 /* CDVViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVViewController.h; path = Classes/CDVViewController.h; sourceTree = "<group>"; }; 8852C43714B65FD800F0E735 /* CDVViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVViewController.m; path = Classes/CDVViewController.m; sourceTree = "<group>"; }; @@ -176,6 +188,12 @@ 8852C43714B65FD800F0E735 /* CDVViewController.m */, EB3B3545161CB44D003DBE7D /* CDVCommandQueue.h */, EB3B3546161CB44D003DBE7D /* CDVCommandQueue.m */, + 7EE9ECF619525D24004CA6B9 /* CDVWebViewPreferences.h */, + 7EE9ECF719525D24004CA6B9 /* CDVWebViewPreferences.m */, + 302D72F919554BFC0028C99F /* CDVWebViewOperationsDelegate.h */, + 302D72FA19554BFC0028C99F /* CDVWebViewOperationsDelegate.m */, + 7E785B98196F508900ABBDC8 /* CDVWebViewUIDelegate.h */, + 7E785B99196F508900ABBDC8 /* CDVWebViewUIDelegate.m */, ); name = Cleaver; sourceTree = "<group>"; @@ -282,8 +300,11 @@ F858FBC6166009A8007DA594 /* CDVConfigParser.h in Headers */, 30F3930B169F839700B22307 /* CDVJSON.h in Headers */, EBFF4DBD16D3FE2E008F452B /* CDVWebViewDelegate.h in Headers */, + 7EE9ECF819525D24004CA6B9 /* CDVWebViewPreferences.h in Headers */, EB96673B16A8970A00D86CDF /* CDVUserAgentUtil.h in Headers */, 7E14B5A81705050A0032169E /* CDVTimer.h in Headers */, + 7E785B9A196F508900ABBDC8 /* CDVWebViewUIDelegate.h in Headers */, + 303820731955603600C91592 /* CDVWebViewOperationsDelegate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -345,6 +366,7 @@ 8887FD751090FBE7009987E8 /* CDVInvokedUrlCommand.m in Sources */, 8887FD901090FBE7009987E8 /* NSData+Base64.m in Sources */, 1F92F4A11314023E0046367C /* CDVPluginResult.m in Sources */, + 7EE9ECF919525D24004CA6B9 /* CDVWebViewPreferences.m in Sources */, 30E33AF313A7E24B00594D64 /* CDVPlugin.m in Sources */, 30E563D013E217EC00C949AA /* NSMutableArray+QueueAdditions.m in Sources */, 30C684821406CB38004C1A8E /* CDVWhitelist.m in Sources */, @@ -357,9 +379,11 @@ EB3B357D161F2A45003DBE7D /* CDVCommandDelegateImpl.m in Sources */, F858FBC7166009A8007DA594 /* CDVConfigParser.m in Sources */, 30F3930C169F839700B22307 /* CDVJSON.m in Sources */, + 7E785B9B196F508900ABBDC8 /* CDVWebViewUIDelegate.m in Sources */, EB96673C16A8970A00D86CDF /* CDVUserAgentUtil.m in Sources */, EBFF4DBC16D3FE2E008F452B /* CDVWebViewDelegate.m in Sources */, 7E14B5A91705050A0032169E /* CDVTimer.m in Sources */, + 302D72FC19554BFC0028C99F /* CDVWebViewOperationsDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -370,6 +394,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; DSTROOT = "/tmp/$(PROJECT_NAME).dst"; @@ -393,6 +418,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; DSTROOT = "/tmp/$(PROJECT_NAME).dst"; GCC_MODEL_TUNING = G5; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/CordovaLib/cordova.js ---------------------------------------------------------------------- diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js index 75729c1..36dfa1b 100644 --- a/CordovaLib/cordova.js +++ b/CordovaLib/cordova.js @@ -925,13 +925,17 @@ function convertMessageToArgsNativeToJs(message) { function iOSExec() { if (bridgeMode === undefined) { + if (navigator.userAgent) { + bridgeMode = navigator.userAgent.indexOf(' 5_') == -1 ? jsToNativeModes.IFRAME_NAV: jsToNativeModes.XHR_NO_PAYLOAD; + } else { bridgeMode = jsToNativeModes.IFRAME_NAV; + } } if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) { bridgeMode = jsToNativeModes.WK_WEBVIEW_BINDING; } - + var successCallback, failCallback, service, action, actionArgs, splitCommand; var callbackId = null; if (typeof arguments[0] !== "string") { @@ -1802,4 +1806,4 @@ window.cordova = require('cordova'); require('cordova/init'); -})(); \ No newline at end of file +})(); http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/bin/templates/project/__CLI__.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/bin/templates/project/__CLI__.xcodeproj/project.pbxproj b/bin/templates/project/__CLI__.xcodeproj/project.pbxproj index 9edef21..100a9ea 100755 --- a/bin/templates/project/__CLI__.xcodeproj/project.pbxproj +++ b/bin/templates/project/__CLI__.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ 7E7966DB1810823500FA85AD /* icon...@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon...@2x.png"; sourceTree = "<group>"; }; 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; }; 7E7966DD1810823500FA85AD /* icon-sm...@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-sm...@2x.png"; sourceTree = "<group>"; }; + 7ED68E4519526A5A00B0A8AF /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 8D1107310486CEB800E47090 /* __PROJECT_NAME__-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "__PROJECT_NAME__-Info.plist"; path = "../__PROJECT_NAME__-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; }; D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; }; EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = "<group>"; }; @@ -185,6 +186,7 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + 7ED68E4519526A5A00B0A8AF /* WebKit.framework */, 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */, 288765FC0DF74451002DB57D /* CoreGraphics.framework */, 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, @@ -405,6 +407,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -436,6 +439,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -464,6 +468,7 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -508,6 +513,7 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj b/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj index 47db3a2..c48f3ed 100755 --- a/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj +++ b/bin/templates/project/__NON-CLI__.xcodeproj/project.pbxproj @@ -97,6 +97,7 @@ 7E7966DB1810823500FA85AD /* icon...@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon...@2x.png"; sourceTree = "<group>"; }; 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; }; 7E7966DD1810823500FA85AD /* icon-sm...@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-sm...@2x.png"; sourceTree = "<group>"; }; + 7EFADAF51952687D00F28308 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 8D1107310486CEB800E47090 /* __PROJECT_NAME__-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "__PROJECT_NAME__-Info.plist"; path = "../__PROJECT_NAME__-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; }; D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; }; F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = "__PROJECT_NAME__/config.xml"; sourceTree = "<group>"; }; @@ -178,6 +179,7 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + 7EFADAF51952687D00F28308 /* WebKit.framework */, 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */, 288765FC0DF74451002DB57D /* CoreGraphics.framework */, 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, @@ -389,6 +391,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -420,6 +423,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -448,6 +452,7 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -492,6 +497,7 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/bin/templates/project/__PROJECT_NAME__/config.xml ---------------------------------------------------------------------- diff --git a/bin/templates/project/__PROJECT_NAME__/config.xml b/bin/templates/project/__PROJECT_NAME__/config.xml index 1fcc8d7..da6c067 100644 --- a/bin/templates/project/__PROJECT_NAME__/config.xml +++ b/bin/templates/project/__PROJECT_NAME__/config.xml @@ -36,6 +36,7 @@ <content src="index.html" /> <!-- Preferences for iOS --> + <preference name="UseWKWebView" value="false" /> <preference name="AllowInlineMediaPlayback" value="false" /> <preference name="BackupWebStorage" value="cloud" /> <preference name="DisallowOverscroll" value="false" /> http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/1a759ac7/tests/CordovaLibTests/CordovaLibApp/config.xml ---------------------------------------------------------------------- diff --git a/tests/CordovaLibTests/CordovaLibApp/config.xml b/tests/CordovaLibTests/CordovaLibApp/config.xml index 1fcc8d7..da6c067 100644 --- a/tests/CordovaLibTests/CordovaLibApp/config.xml +++ b/tests/CordovaLibTests/CordovaLibApp/config.xml @@ -36,6 +36,7 @@ <content src="index.html" /> <!-- Preferences for iOS --> + <preference name="UseWKWebView" value="false" /> <preference name="AllowInlineMediaPlayback" value="false" /> <preference name="BackupWebStorage" value="cloud" /> <preference name="DisallowOverscroll" value="false" /> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org For additional commands, e-mail: commits-h...@cordova.apache.org