You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2014/11/01 00:44:04 UTC

[44/50] ios commit: WKWebView - squashed commit.

WKWebView - squashed commit.

commit da7a3546f809c331cf230af180b3e6f1fb99cb2b
Author: Shazron Abdullah <sh...@apache.org>
Date:   Thu Jul 10 17:48:15 2014 -0700

    Support alert/confirm/prompt in WKWebView

commit 63552fd3f2548f407aec1bbfda997809d1f2a89d
Author: Shazron Abdullah <sh...@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 <sh...@apache.org>
Date:   Wed Jul 9 18:44:03 2014 -0700

    Use weakSelf in block

commit fc83f068388f3402935819f7891906ffa9029cc1
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jul 9 18:38:30 2014 -0700

    Support config.xml preferences for WKWebView

commit 4eeaf0c8730a30b8709d0d98aba4b2996e34d9f4
Author: Shazron Abdullah <sh...@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 <sh...@apache.org>
Date:   Wed Jul 9 17:51:11 2014 -0700

    Re-add pragma message for iOS 8

commit 2e17db94a87da80a7d50f202eef40178c0a688c0
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jul 9 17:46:00 2014 -0700

    Removed unused WKWebView+Private header

commit 601eea1c8784e1acf00b0a39ca4a3ea5085b2098
Author: Shazron Abdullah <sh...@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 <sh...@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 <sh...@gmail.com>
Date:   Sat Jun 21 22:14:26 2014 -0700

    Removed WebKit.framework from templates.

commit b4832d132e6628a7ae0ef681eab54554ed913b77
Author: Shazron Abdullah <sh...@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 <sh...@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 <sh...@apache.org>
Date:   Fri Jun 20 16:59:48 2014 -0700

    Re-add deprecated CDVPlugin functions

commit e16e914c3ba2f30324f25da27fbbc0efa9cde727
Merge: f3af6f2 2e1b00c
Author: Shazron Abdullah <sh...@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 <sh...@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 <sh...@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 <sh...@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 <sh...@apache.org>
Date:   Thu Jun 19 16:08:30 2014 -0700

    Implemented the WKWebView Cordova bridge.

commit 6eb29c716b8308a7f4824a313a232c7c16f421b8
Author: Shazron Abdullah <sh...@apache.org>
Date:   Thu Jun 19 13:42:49 2014 -0700

    Moved WKScriptMessageHandler to CDVCommandDelegateImpl

commit 374763daf13f73df872a64caa83a7371a0c58542
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jun 18 17:51:51 2014 -0700

    Updated templates for WebKit.framework use

commit be7fd66f708587bee48b9dbbc7c0b57b03002eb2
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jun 18 17:50:28 2014 -0700

    Updated AppDelegate.m to use WKWebView evaluateJavascript (private)

commit 05b5c5912e339d29623de75127c2f162e0c875ed
Author: Shazron Abdullah <sh...@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 <sh...@apache.org>
Date:   Wed Jun 18 17:49:00 2014 -0700

    Added WKWebView private functions.

commit 2e1b00cbb92164114db2f30df10b7f0ec918c9bc
Author: Shazron Abdullah <sh...@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 <sh...@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 <sh...@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 <sh...@apache.org>
Date:   Thu Jun 19 16:08:30 2014 -0700

    Implemented the WKWebView Cordova bridge.

commit c1c39086ab220fcdc5a796b27d38a5d32f7f5f37
Author: Shazron Abdullah <sh...@apache.org>
Date:   Thu Jun 19 13:42:49 2014 -0700

    Moved WKScriptMessageHandler to CDVCommandDelegateImpl

commit 5d2b137645e5fffb460c8e84d16dc8f5d104d085
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jun 18 17:51:51 2014 -0700

    Updated templates for WebKit.framework use

commit 63bf9a7ca03f92f263a3a3d7226512aee784a171
Author: Shazron Abdullah <sh...@apache.org>
Date:   Wed Jun 18 17:50:28 2014 -0700

    Updated AppDelegate.m to use WKWebView evaluateJavascript (private)

commit 23c05db85e57f82a4c6fe03fc5faf49abaf947b8
Author: Shazron Abdullah <sh...@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 <sh...@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/wkwebview
Commit: 1a759ac7fd7fa24aa658f868dbf413ef8ca34396
Parents: 5769d58
Author: Shazron Abdullah <sh...@apache.org>
Authored: Mon Jul 14 12:03:19 2014 -0700
Committer: Shazron Abdullah <sh...@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-76@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76@2x.png"; sourceTree = "<group>"; };
 		7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; };
 		7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@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-76@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76@2x.png"; sourceTree = "<group>"; };
 		7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; };
 		7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@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-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org