Skip to content

Commit

Permalink
using the webview based on WebKit instead of UIKit (apache#663)
Browse files Browse the repository at this point in the history
  • Loading branch information
braginxv authored and braginxv committed Jan 22, 2020
1 parent 266d339 commit a9a94a9
Show file tree
Hide file tree
Showing 13 changed files with 800 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
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 <Cordova/CDVAvailability.h>
#import <WebKit/WebKit.h>
#import "CDVWebViewEngineProtocol.h"

@class CDVViewController;

/**
* Distinguishes top-level navigations from sub-frame navigations.
* shouldStartLoadWithRequest is called for every request, but didStartLoad
* and didFinishLoad is called only for top-level navigations.
* Relevant bug: CB-2389
*/

#define CDV_WEB_HANDLER @"cordova"

@interface CDVWKWebViewDelegate : NSObject <WKUIDelegate, WKScriptMessageHandler>

- (id)initWithTitle:(NSString *)title;
- (BOOL)request:(NSURLRequest *)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest *)originalRequest;

@property (nonatomic, weak) CDVViewController *viewController;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
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 "CDVWKWebViewDelegate.h"
#import "CDVInvokedUrlCommand.h"
#import "CDVViewController.h"

@implementation CDVWKWebViewDelegate {
NSString *_title;
}

static NSString *stripFragment(NSString *url) {
NSRange range = [url rangeOfString:@"#"];

if (range.location == NSNotFound) {
return url;
}
return [url substringToIndex:range.location];
}

- (id)initWithTitle:(NSString *)title {
self = [super init];
if (self != nil) {
_title = title;
}
return self;
}

- (BOOL)request:(NSURLRequest *)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest *)originalRequest {
if (originalRequest.URL && newRequest.URL) {
NSString *originalRequestUrl = [originalRequest.URL absoluteString];
NSString *newRequestUrl = [newRequest.URL absoluteString];

NSString *baseOriginalRequestUrl = stripFragment(originalRequestUrl);
NSString *baseNewRequestUrl = stripFragment(newRequestUrl);
return [baseOriginalRequestUrl isEqualToString:baseNewRequestUrl];
}

return NO;
}

- (void) webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message
initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:_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:_title
message:message
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(YES);
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(NO);
[alert dismissViewControllerAnimated:YES completion:nil];
}];

[alert addAction:ok];
[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:_title
message:prompt
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(alert.textFields.firstObject.text);
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(nil);
[alert dismissViewControllerAnimated:YES completion:nil];
}];

[alert addAction:ok];
[alert addAction:cancel];

[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.text = defaultText;
}];

UIViewController *rootController = [UIApplication sharedApplication].delegate.window.rootViewController;

[rootController presentViewController:alert animated:YES completion:nil];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if (![message.name isEqualToString:CDV_WEB_HANDLER]) {
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);

if (![self.viewController.commandQueue execute:command]) {
#ifdef DEBUG
NSError *error = nil;
NSString *commandJson = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonEntry
options:0
error:&error];

if (error == nil) {
commandJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

static NSUInteger maxLogLength = 1024;
NSString *commandString = ([commandJson length] > maxLogLength) ?
[NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] :
commandJson;

NSLog(@"FAILED pluginJSON = %@", commandString);
#endif
}
}

@end
Original file line number Diff line number Diff line change
@@ -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 <Cordova/CDVPlugin.h>
#import <Cordova/CDVWebViewEngineProtocol.h>

@protocol WKScriptMessageHandler;
@protocol WKNavigationDelegate;

@interface CDVWKWebViewEngine : CDVPlugin <CDVWebViewEngineProtocol>
- (void)allowsBackForwardNavigationGestures:(CDVInvokedUrlCommand*)command;
@end
Loading

0 comments on commit a9a94a9

Please sign in to comment.