Repository: cordova-plugin-wkwebview-engine
Updated Branches:
  refs/heads/master [created] 0cda51fe9


Added wkwebview-engine plugin.


Project: 
http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/commit/40f6b453
Tree: 
http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/tree/40f6b453
Diff: 
http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/diff/40f6b453

Branch: refs/heads/master
Commit: 40f6b4538cb063a7de9a454190d652247c5dadee
Parents: 
Author: Shazron Abdullah <[email protected]>
Authored: Thu Nov 6 16:08:59 2014 -0800
Committer: Shazron Abdullah <[email protected]>
Committed: Thu Nov 6 16:08:59 2014 -0800

----------------------------------------------------------------------
 README.md                        |  20 ++++
 plugin.xml                       |  38 +++++++
 src/ios/CDVWKWebViewEngine.h     |  27 +++++
 src/ios/CDVWKWebViewEngine.m     | 189 ++++++++++++++++++++++++++++++++++
 src/ios/CDVWKWebViewUIDelegate.h |  28 +++++
 src/ios/CDVWKWebViewUIDelegate.m | 123 ++++++++++++++++++++++
 6 files changed, 425 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a3f7931
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+Cordova WKWebView Engine
+======
+
+This plugin makes Cordova use the WKWebView component (new in iOS 8.0) instead 
of the default UIWebView component.
+
+This will also install the Cordova Local Web Server plugin (TODO: move this 
into Labs)
+
+Permissions
+-----------
+
+#### config.xml
+
+            <feature name="CDVWKWebViewEngine">
+                <param name="ios-package" value="CDVWKWebViewEngine" />
+            </feature>
+
+Supported Platforms
+-------------------
+
+- iOS

http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..2643b94
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0";
+    xmlns:rim="http://www.blackberry.com/ns/widgets";
+    xmlns:android="http://schemas.android.com/apk/res/android";
+    id="org.apache.cordova.labs.wkwebviewengine"
+    version="0.1.0">
+    <name>Cordova WKWebView Engine</name>
+    <description>Cordova WKWebView Engine Plugin</description>
+    <license>Apache 2.0</license>
+    <keywords>cordova,wkwebview,webview</keywords>
+
+       <engines>
+               <engine name="cordova" version=">3.7.0" />
+       </engines>
+    
+    <!-- this plugin will be moved to labs soon -->
+    <dependency id="io.shaz.plugin.cordova-local-webserver" 
url="https://github.com/shazron/CordovaLocalWebServer.git"; version=">=2.1.0" />
+
+    <!-- ios -->
+    <platform name="ios">
+        <config-file target="config.xml" parent="/*">
+            <feature name="CDVWKWebViewEngine">
+                <param name="ios-package" value="CDVWKWebViewEngine" />
+            </feature>
+            <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" 
/>
+        </config-file>
+
+        <framework src="WebKit.framework" weak="true" />
+
+        <header-file src="src/ios/CDVWKWebViewEngine.h" />
+        <source-file src="src/ios/CDVWKWebViewEngine.m" />
+        <header-file src="src/ios/CDVWKWebViewUIDelegate.h" />
+        <source-file src="src/ios/CDVWKWebViewUIDelegate.m" />
+        
+    </platform>
+
+</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/src/ios/CDVWKWebViewEngine.h
----------------------------------------------------------------------
diff --git a/src/ios/CDVWKWebViewEngine.h b/src/ios/CDVWKWebViewEngine.h
new file mode 100644
index 0000000..753a07f
--- /dev/null
+++ b/src/ios/CDVWKWebViewEngine.h
@@ -0,0 +1,27 @@
+/*
+ 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 <WebKit/WebKit.h>
+#import <Cordova/CDV.h>
+
+@interface CDVWKWebViewEngine : CDVPlugin <CDVWebViewEngineProtocol, 
WKScriptMessageHandler>
+
+@property (nonatomic, strong, readonly) id <WKUIDelegate> uiDelegate;
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/src/ios/CDVWKWebViewEngine.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVWKWebViewEngine.m b/src/ios/CDVWKWebViewEngine.m
new file mode 100644
index 0000000..94ef0b2
--- /dev/null
+++ b/src/ios/CDVWKWebViewEngine.m
@@ -0,0 +1,189 @@
+/*
+ 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 "CDVWKWebViewEngine.h"
+#import "CDVWKWebViewUIDelegate.h"
+
+#import <objc/message.h>
+
+#define CDV_BRIDGE_NAME @"cordova"
+
+@interface CDVWKWebViewEngine ()
+
+@property (nonatomic, strong, readwrite) UIView* engineWebView;
+@property (nonatomic, strong, readwrite) id <WKUIDelegate> uiDelegate;
+
+@end
+
+// see forwardingTargetForSelector: selector comment for the reason for this 
pragma
+#pragma clang diagnostic ignored "-Wprotocol"
+
+@implementation CDVWKWebViewEngine
+
+@synthesize engineWebView = _engineWebView;
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    self = [super init];
+    if (self) {
+        self.uiDelegate = [[CDVWKWebViewUIDelegate alloc] 
initWithTitle:[[NSBundle mainBundle] 
objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
+
+        WKUserContentController* userContentController = 
[[WKUserContentController alloc] init];
+        [userContentController addScriptMessageHandler:self 
name:CDV_BRIDGE_NAME];
+
+        WKWebViewConfiguration* configuration = [[WKWebViewConfiguration 
alloc] init];
+        configuration.userContentController = userContentController;
+
+        WKWebView* wkWebView = [[WKWebView alloc] initWithFrame:frame 
configuration:configuration];
+
+        wkWebView.UIDelegate = self.uiDelegate;
+
+        self.engineWebView = wkWebView;
+
+        NSLog(@"Using WKWebView");
+    }
+
+    return self;
+}
+
+- (void)pluginInitialize
+{
+    // viewController would be available now. we attempt to set all possible 
delegates to it, by default
+
+    WKWebView* wkWebView = (WKWebView*)_engineWebView;
+
+    if ([self.viewController conformsToProtocol:@protocol(WKUIDelegate)]) {
+        wkWebView.UIDelegate = (id <WKUIDelegate>)self.viewController;
+    }
+
+    if ([self.viewController 
conformsToProtocol:@protocol(WKNavigationDelegate)]) {
+        wkWebView.navigationDelegate = (id 
<WKNavigationDelegate>)self.viewController;
+    }
+
+    if ([self.viewController 
conformsToProtocol:@protocol(WKScriptMessageHandler)]) {
+        [wkWebView.configuration.userContentController 
addScriptMessageHandler:(id < WKScriptMessageHandler >)self.viewController 
name:@"cordova"];
+    }
+
+    [self updateSettings:self.commandDelegate.settings];
+}
+
+// We implement this here because certain versions of iOS 8 do not implement 
this
+// in WKWebView, so we need to test for this during runtime.
+// It is speculated that this selector will be available in iOS 8.2 for 
WKWebView
+- (void)loadFileURL:(NSURL*)url allowingReadAccessToURL:(NSURL*)readAccessURL
+{
+    SEL wk_sel = @selector(loadFileURL:allowingReadAccessToURL:);
+    __weak CDVWKWebViewEngine* weakSelf = self;
+
+    // UIKit operations have to be on the main thread. This method does not 
need to be synchronous
+    dispatch_async(dispatch_get_main_queue(), ^{
+        if ([_engineWebView respondsToSelector:wk_sel] && [[url scheme] 
isEqualToString:@"file"]) {
+            ((id (*)(id, SEL, id, id))objc_msgSend)(_engineWebView, wk_sel, 
url, readAccessURL);
+        } else {
+            [weakSelf loadRequest:[NSURLRequest requestWithURL:url]];
+        }
+    });
+}
+
+- (void)updateSettings:(NSDictionary*)settings
+{
+    WKWebView* wkWebView = (WKWebView*)_engineWebView;
+
+    wkWebView.configuration.preferences.minimumFontSize = [settings 
cordovaFloatSettingForKey:@"MinimumFontSize" defaultValue:0.0];
+    wkWebView.configuration.allowsInlineMediaPlayback = [settings 
cordovaBoolSettingForKey:@"AllowInlineMediaPlayback" defaultValue:NO];
+    wkWebView.configuration.mediaPlaybackRequiresUserAction = [settings 
cordovaBoolSettingForKey:@"MediaPlaybackRequiresUserAction" defaultValue:YES];
+    wkWebView.configuration.suppressesIncrementalRendering = [settings 
cordovaBoolSettingForKey:@"SuppressesIncrementalRendering" defaultValue:NO];
+    wkWebView.configuration.mediaPlaybackAllowsAirPlay = [settings 
cordovaBoolSettingForKey:@"MediaPlaybackAllowsAirPlay" defaultValue:YES];
+
+    /*
+     wkWebView.configuration.preferences.javaScriptEnabled = [settings 
cordovaBoolSettingForKey:@"JavaScriptEnabled" default:YES];
+     wkWebView.configuration.preferences.javaScriptCanOpenWindowsAutomatically 
= [settings cordovaBoolSettingForKey:@"JavaScriptCanOpenWindowsAutomatically" 
default:NO];
+     */
+}
+
+- (void)updateWithInfo:(NSDictionary*)info
+{
+    NSDictionary* scriptMessageHandlers = [info 
objectForKey:kCDVWebViewEngineScriptMessageHandlers];
+    NSDictionary* settings = [info 
objectForKey:kCDVWebViewEngineWebViewPreferences];
+    id navigationDelegate = [info 
objectForKey:kCDVWebViewEngineWKNavigationDelegate];
+    id uiDelegate = [info objectForKey:kCDVWebViewEngineWKUIDelegate];
+
+    WKWebView* wkWebView = (WKWebView*)_engineWebView;
+
+    if (scriptMessageHandlers && [scriptMessageHandlers 
isKindOfClass:[NSDictionary class]]) {
+        NSArray* allKeys = [scriptMessageHandlers allKeys];
+
+        for (NSString* key in allKeys) {
+            id object = [scriptMessageHandlers objectForKey:key];
+            if ([object conformsToProtocol:@protocol(WKScriptMessageHandler)]) 
{
+                [wkWebView.configuration.userContentController 
addScriptMessageHandler:object name:key];
+            }
+        }
+    }
+
+    if (navigationDelegate && [navigationDelegate 
conformsToProtocol:@protocol(WKNavigationDelegate)]) {
+        wkWebView.navigationDelegate = navigationDelegate;
+    }
+
+    if (uiDelegate && [uiDelegate conformsToProtocol:@protocol(WKUIDelegate)]) 
{
+        wkWebView.UIDelegate = uiDelegate;
+    }
+
+    if (settings && [settings isKindOfClass:[NSDictionary class]]) {
+        [self updateSettings:settings];
+    }
+}
+
+// This forwards the methods that are in the header that are not implemented 
here.
+// Both WKWebView and UIWebView implement the below:
+//     loadHTMLString:baseURL:
+//     loadRequest:
+- (id)forwardingTargetForSelector:(SEL)aSelector
+{
+    return _engineWebView;
+}
+
+#pragma mark WKScriptMessageHandler implementation
+
+- (void)userContentController:(WKUserContentController*)userContentController 
didReceiveScriptMessage:(WKScriptMessage*)message
+{
+    if (![message.name isEqualToString:CDV_BRIDGE_NAME]) {
+        return;
+    }
+
+    CDVViewController* vc = (CDVViewController*)self.viewController;
+
+    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);
+
+    if (![vc.commandQueue execute:command]) {
+#ifdef DEBUG
+            NSString* commandJson = [jsonEntry JSONString];
+            static NSUInteger maxLogLength = 1024;
+            NSString* commandString = ([commandJson length] > maxLogLength) ?
+                [NSString stringWithFormat : @"%@[...]", [commandJson 
substringToIndex:maxLogLength]] :
+                commandJson;
+
+            DLog(@"FAILED pluginJSON = %@", commandString);
+#endif
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/src/ios/CDVWKWebViewUIDelegate.h
----------------------------------------------------------------------
diff --git a/src/ios/CDVWKWebViewUIDelegate.h b/src/ios/CDVWKWebViewUIDelegate.h
new file mode 100644
index 0000000..33a179b
--- /dev/null
+++ b/src/ios/CDVWKWebViewUIDelegate.h
@@ -0,0 +1,28 @@
+/*
+ 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 <WebKit/WebKit.h>
+
+@interface CDVWKWebViewUIDelegate : NSObject <WKUIDelegate>
+
+@property (nonatomic, copy) NSString* title;
+
+- (instancetype)initWithTitle:(NSString*)title;
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugin-wkwebview-engine/blob/40f6b453/src/ios/CDVWKWebViewUIDelegate.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVWKWebViewUIDelegate.m b/src/ios/CDVWKWebViewUIDelegate.m
new file mode 100644
index 0000000..c9e5ce9
--- /dev/null
+++ b/src/ios/CDVWKWebViewUIDelegate.m
@@ -0,0 +1,123 @@
+/*
+ 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 "CDVWKWebViewUIDelegate.h"
+
+@implementation CDVWKWebViewUIDelegate
+
+- (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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to