aboutsummaryrefslogtreecommitdiff
path: root/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m
diff options
context:
space:
mode:
Diffstat (limited to 'CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m')
-rw-r--r--CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m202
1 files changed, 202 insertions, 0 deletions
diff --git a/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m
new file mode 100644
index 0000000..f571d80
--- /dev/null
+++ b/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewEngine.m
@@ -0,0 +1,202 @@
+/*
+ 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 "CDVUIWebViewEngine.h"
+#import "CDVUIWebViewDelegate.h"
+#import "CDVUIWebViewNavigationDelegate.h"
+#import "NSDictionary+CordovaPreferences.h"
+
+#import <objc/message.h>
+
+@interface CDVUIWebViewEngine ()
+
+@property (nonatomic, strong, readwrite) UIView* engineWebView;
+@property (nonatomic, strong, readwrite) id <UIWebViewDelegate> uiWebViewDelegate;
+@property (nonatomic, strong, readwrite) CDVUIWebViewNavigationDelegate* navWebViewDelegate;
+
+@end
+
+@implementation CDVUIWebViewEngine
+
+@synthesize engineWebView = _engineWebView;
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ self = [super init];
+ if (self) {
+ self.engineWebView = [[UIWebView alloc] initWithFrame:frame];
+ NSLog(@"Using UIWebView");
+ }
+
+ return self;
+}
+
+- (void)pluginInitialize
+{
+ // viewController would be available now. we attempt to set all possible delegates to it, by default
+
+ UIWebView* uiWebView = (UIWebView*)_engineWebView;
+
+ if ([self.viewController conformsToProtocol:@protocol(UIWebViewDelegate)]) {
+ self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:(id <UIWebViewDelegate>)self.viewController];
+ uiWebView.delegate = self.uiWebViewDelegate;
+ } else {
+ self.navWebViewDelegate = [[CDVUIWebViewNavigationDelegate alloc] initWithEnginePlugin:self];
+ self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:self.navWebViewDelegate];
+ uiWebView.delegate = self.uiWebViewDelegate;
+ }
+
+ [self updateSettings:self.commandDelegate.settings];
+}
+
+- (void)evaluateJavaScript:(NSString*)javaScriptString completionHandler:(void (^)(id, NSError*))completionHandler
+{
+ NSString* ret = [(UIWebView*)_engineWebView stringByEvaluatingJavaScriptFromString:javaScriptString];
+
+ if (completionHandler) {
+ completionHandler(ret, nil);
+ }
+}
+
+- (id)loadRequest:(NSURLRequest*)request
+{
+ [(UIWebView*)_engineWebView loadRequest:request];
+ return nil;
+}
+
+- (id)loadHTMLString:(NSString*)string baseURL:(NSURL*)baseURL
+{
+ [(UIWebView*)_engineWebView loadHTMLString:string baseURL:baseURL];
+ return nil;
+}
+
+- (NSURL*)URL
+{
+ return [[(UIWebView*)_engineWebView request] URL];
+}
+
+- (BOOL) canLoadRequest:(NSURLRequest*)request
+{
+ return (request != nil);
+}
+
+- (void)updateSettings:(NSDictionary*)settings
+{
+ UIWebView* uiWebView = (UIWebView*)_engineWebView;
+
+ uiWebView.scalesPageToFit = [settings cordovaBoolSettingForKey:@"EnableViewportScale" defaultValue:NO];
+ uiWebView.allowsInlineMediaPlayback = [settings cordovaBoolSettingForKey:@"AllowInlineMediaPlayback" defaultValue:NO];
+ uiWebView.mediaPlaybackRequiresUserAction = [settings cordovaBoolSettingForKey:@"MediaPlaybackRequiresUserAction" defaultValue:YES];
+ uiWebView.mediaPlaybackAllowsAirPlay = [settings cordovaBoolSettingForKey:@"MediaPlaybackAllowsAirPlay" defaultValue:YES];
+ uiWebView.keyboardDisplayRequiresUserAction = [settings cordovaBoolSettingForKey:@"KeyboardDisplayRequiresUserAction" defaultValue:YES];
+ uiWebView.suppressesIncrementalRendering = [settings cordovaBoolSettingForKey:@"SuppressesIncrementalRendering" defaultValue:NO];
+ uiWebView.gapBetweenPages = [settings cordovaFloatSettingForKey:@"GapBetweenPages" defaultValue:0.0];
+ uiWebView.pageLength = [settings cordovaFloatSettingForKey:@"PageLength" defaultValue:0.0];
+
+ id prefObj = nil;
+
+ // By default, DisallowOverscroll is false (thus bounce is allowed)
+ BOOL bounceAllowed = !([settings cordovaBoolSettingForKey:@"DisallowOverscroll" defaultValue:NO]);
+
+ // prevent webView from bouncing
+ if (!bounceAllowed) {
+ if ([uiWebView respondsToSelector:@selector(scrollView)]) {
+ ((UIScrollView*)[uiWebView scrollView]).bounces = NO;
+ } else {
+ for (id subview in self.webView.subviews) {
+ if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
+ ((UIScrollView*)subview).bounces = NO;
+ }
+ }
+ }
+ }
+
+ NSString* decelerationSetting = [settings cordovaSettingForKey:@"UIWebViewDecelerationSpeed"];
+ if (![@"fast" isEqualToString:decelerationSetting]) {
+ [uiWebView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal];
+ }
+
+ NSInteger paginationBreakingMode = 0; // default - UIWebPaginationBreakingModePage
+ prefObj = [settings cordovaSettingForKey:@"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;
+ }
+ }
+ uiWebView.paginationBreakingMode = paginationBreakingMode;
+
+ NSInteger paginationMode = 0; // default - UIWebPaginationModeUnpaginated
+ prefObj = [settings cordovaSettingForKey:@"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;
+ }
+ }
+ uiWebView.paginationMode = paginationMode;
+}
+
+- (void)updateWithInfo:(NSDictionary*)info
+{
+ UIWebView* uiWebView = (UIWebView*)_engineWebView;
+
+ id <UIWebViewDelegate> uiWebViewDelegate = [info objectForKey:kCDVWebViewEngineUIWebViewDelegate];
+ NSDictionary* settings = [info objectForKey:kCDVWebViewEngineWebViewPreferences];
+
+ if (uiWebViewDelegate &&
+ [uiWebViewDelegate conformsToProtocol:@protocol(UIWebViewDelegate)]) {
+ self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:(id <UIWebViewDelegate>)self.viewController];
+ uiWebView.delegate = self.uiWebViewDelegate;
+ }
+
+ 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;
+}
+
+- (UIView*)webView
+{
+ return self.engineWebView;
+}
+
+@end