cordova-plugin-inappbrowser-patch 6.0.1 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +2 -2
- package/README.md +51 -24
- package/RELEASENOTES.md +4 -4
- package/eslint.config.js +45 -0
- package/licence_checker.yml +19 -0
- package/package.json +12 -7
- package/plugin.xml +20 -19
- package/src/android/InAppBrowser.java +20 -18
- package/src/android/InAppBrowserDialog.java +18 -17
- package/src/android/InAppChromeClient.java +18 -17
- package/src/browser/InAppBrowserProxy.js +24 -26
- package/src/ios/CDVInAppBrowserNavigationController.h +16 -20
- package/src/ios/CDVInAppBrowserNavigationController.m +23 -50
- package/src/ios/CDVInAppBrowserOptions.h +27 -27
- package/src/ios/CDVInAppBrowserOptions.m +25 -25
- package/src/ios/CDVWKInAppBrowser.h +56 -49
- package/src/ios/CDVWKInAppBrowser.m +492 -567
- package/src/ios/CDVWKInAppBrowserUIDelegate.h +20 -20
- package/src/ios/CDVWKInAppBrowserUIDelegate.m +43 -43
- package/types/index.d.ts +7 -5
- package/www/inappbrowser.js +18 -20
|
@@ -1,25 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
/**
|
|
2
|
+
Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
or more contributor license agreements. See the NOTICE file
|
|
4
|
+
distributed with this work for additional information
|
|
5
|
+
regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
to you under the Apache License, Version 2.0 (the
|
|
7
|
+
"License"); you may not use this file except in compliance
|
|
8
|
+
with the License. You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing,
|
|
13
|
+
software distributed under the License is distributed on an
|
|
14
|
+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
KIND, either express or implied. See the License for the
|
|
16
|
+
specific language governing permissions and limitations
|
|
17
|
+
under the License.
|
|
18
|
+
*/
|
|
19
19
|
|
|
20
20
|
#import "CDVWKInAppBrowser.h"
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
#if __has_include(<Cordova/CDVWebViewProcessPoolFactory.h>)
|
|
23
|
+
/*
|
|
24
|
+
CDVWebViewProcessPoolFactory is deprecated since cordova-ios 8.0.0
|
|
25
|
+
and will be removed in a future release.
|
|
26
|
+
*/
|
|
22
27
|
#import <Cordova/CDVWebViewProcessPoolFactory.h>
|
|
28
|
+
#endif
|
|
29
|
+
|
|
23
30
|
#import <Cordova/CDVPluginResult.h>
|
|
24
31
|
|
|
25
32
|
#define kInAppBrowserTargetSelf @"_self"
|
|
@@ -31,24 +38,12 @@
|
|
|
31
38
|
|
|
32
39
|
#define IAB_BRIDGE_NAME @"cordova_iab"
|
|
33
40
|
|
|
34
|
-
#define TOOLBAR_HEIGHT 44.0
|
|
35
|
-
#define LOCATIONBAR_HEIGHT 21.0
|
|
36
|
-
#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT))
|
|
37
|
-
|
|
38
41
|
#pragma mark CDVWKInAppBrowser
|
|
39
42
|
|
|
40
43
|
@implementation CDVWKInAppBrowser
|
|
41
44
|
|
|
42
|
-
static CDVWKInAppBrowser* instance = nil;
|
|
43
|
-
|
|
44
|
-
+ (id) getInstance{
|
|
45
|
-
return instance;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
45
|
- (void)pluginInitialize
|
|
49
46
|
{
|
|
50
|
-
instance = self;
|
|
51
|
-
_callbackIdPattern = nil;
|
|
52
47
|
_beforeload = @"";
|
|
53
48
|
_waitForBeforeload = NO;
|
|
54
49
|
}
|
|
@@ -58,44 +53,44 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
58
53
|
[self close:nil];
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
- (void)close:(CDVInvokedUrlCommand*)command
|
|
56
|
+
- (void)close:(CDVInvokedUrlCommand *)command
|
|
62
57
|
{
|
|
63
58
|
if (self.inAppBrowserViewController == nil) {
|
|
64
59
|
NSLog(@"IAB.close() called but it was already closed.");
|
|
65
60
|
return;
|
|
66
61
|
}
|
|
67
|
-
|
|
62
|
+
|
|
68
63
|
// Things are cleaned up in browserExit.
|
|
69
64
|
[self.inAppBrowserViewController close];
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
- (BOOL)
|
|
67
|
+
- (BOOL)isSystemUrl:(NSURL *)url
|
|
73
68
|
{
|
|
74
|
-
if ([
|
|
69
|
+
if ([url.host isEqualToString:@"itunes.apple.com"]) {
|
|
75
70
|
return YES;
|
|
76
71
|
}
|
|
77
|
-
|
|
72
|
+
|
|
78
73
|
return NO;
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
- (void)open:(CDVInvokedUrlCommand*)command
|
|
76
|
+
- (void)open:(CDVInvokedUrlCommand *)command
|
|
82
77
|
{
|
|
83
|
-
CDVPluginResult*
|
|
84
|
-
|
|
85
|
-
NSString*
|
|
86
|
-
NSString*
|
|
87
|
-
NSString*
|
|
88
|
-
|
|
78
|
+
CDVPluginResult *pluginResult;
|
|
79
|
+
|
|
80
|
+
NSString *url = [command argumentAtIndex:0];
|
|
81
|
+
NSString *target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf];
|
|
82
|
+
NSString *options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]];
|
|
83
|
+
|
|
89
84
|
self.callbackId = command.callbackId;
|
|
90
|
-
|
|
85
|
+
|
|
91
86
|
if (url != nil) {
|
|
92
|
-
NSURL*
|
|
93
|
-
NSURL*
|
|
94
|
-
|
|
87
|
+
NSURL *baseUrl = [self.webViewEngine URL];
|
|
88
|
+
NSURL *absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL];
|
|
89
|
+
|
|
95
90
|
if ([self isSystemUrl:absoluteUrl]) {
|
|
96
91
|
target = kInAppBrowserTargetSystem;
|
|
97
92
|
}
|
|
98
|
-
|
|
93
|
+
|
|
99
94
|
if ([target isEqualToString:kInAppBrowserTargetSelf]) {
|
|
100
95
|
[self openInCordovaWebView:absoluteUrl withOptions:options];
|
|
101
96
|
} else if ([target isEqualToString:kInAppBrowserTargetSystem]) {
|
|
@@ -103,48 +98,55 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
103
98
|
} else { // _blank or anything else
|
|
104
99
|
[self openInInAppBrowser:absoluteUrl withOptions:options];
|
|
105
100
|
}
|
|
106
|
-
|
|
101
|
+
|
|
107
102
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
|
|
108
103
|
} else {
|
|
109
104
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"incorrect number of arguments"];
|
|
110
105
|
}
|
|
111
|
-
|
|
112
|
-
[pluginResult
|
|
106
|
+
|
|
107
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
113
108
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
114
109
|
}
|
|
115
110
|
|
|
116
|
-
- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
|
|
111
|
+
- (void)openInInAppBrowser:(NSURL *)url withOptions:(NSString *)options
|
|
117
112
|
{
|
|
118
|
-
CDVInAppBrowserOptions*
|
|
119
|
-
|
|
120
|
-
|
|
113
|
+
CDVInAppBrowserOptions *browserOptions = [CDVInAppBrowserOptions parseOptions:options];
|
|
114
|
+
WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
|
|
115
|
+
|
|
121
116
|
if (browserOptions.cleardata) {
|
|
122
|
-
|
|
123
|
-
NSDate* dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
|
|
117
|
+
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
|
|
124
118
|
[dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:dateFrom completionHandler:^{
|
|
125
119
|
NSLog(@"Removed all WKWebView data");
|
|
126
|
-
|
|
120
|
+
if (@available(iOS 15.0, *)) {
|
|
121
|
+
// Since iOS 15 WKProcessPool is deprecated and has no effect
|
|
122
|
+
} else {
|
|
123
|
+
#pragma clang diagnostic push
|
|
124
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
125
|
+
// Set for iOS 14 and below a new process pool
|
|
126
|
+
self.inAppBrowserViewController.webView.configuration.processPool = [[WKProcessPool alloc] init]; // create new process pool to flush all data
|
|
127
|
+
#pragma clang diagnostic pop
|
|
128
|
+
}
|
|
127
129
|
}];
|
|
128
130
|
}
|
|
129
|
-
|
|
131
|
+
|
|
130
132
|
if (browserOptions.clearcache) {
|
|
131
133
|
// Deletes all cookies
|
|
132
|
-
WKHTTPCookieStore*
|
|
133
|
-
[cookieStore getAllCookies:^(NSArray*
|
|
134
|
-
NSHTTPCookie*
|
|
135
|
-
for(cookie in cookies){
|
|
134
|
+
WKHTTPCookieStore *cookieStore = dataStore.httpCookieStore;
|
|
135
|
+
[cookieStore getAllCookies:^(NSArray *cookies) {
|
|
136
|
+
NSHTTPCookie *cookie;
|
|
137
|
+
for (cookie in cookies) {
|
|
136
138
|
[cookieStore deleteCookie:cookie completionHandler:nil];
|
|
137
139
|
}
|
|
138
140
|
}];
|
|
139
141
|
}
|
|
140
|
-
|
|
142
|
+
|
|
141
143
|
if (browserOptions.clearsessioncache) {
|
|
142
144
|
// Deletes session cookies
|
|
143
|
-
WKHTTPCookieStore*
|
|
144
|
-
[cookieStore getAllCookies:^(NSArray*
|
|
145
|
-
NSHTTPCookie*
|
|
146
|
-
for(cookie in cookies){
|
|
147
|
-
if(cookie.sessionOnly){
|
|
145
|
+
WKHTTPCookieStore *cookieStore = dataStore.httpCookieStore;
|
|
146
|
+
[cookieStore getAllCookies:^(NSArray *cookies) {
|
|
147
|
+
NSHTTPCookie *cookie;
|
|
148
|
+
for (cookie in cookies) {
|
|
149
|
+
if (cookie.sessionOnly) {
|
|
148
150
|
[cookieStore deleteCookie:cookie completionHandler:nil];
|
|
149
151
|
}
|
|
150
152
|
}
|
|
@@ -154,17 +156,13 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
154
156
|
if (self.inAppBrowserViewController == nil) {
|
|
155
157
|
self.inAppBrowserViewController = [[CDVWKInAppBrowserViewController alloc] initWithBrowserOptions: browserOptions andSettings:self.commandDelegate.settings];
|
|
156
158
|
self.inAppBrowserViewController.navigationDelegate = self;
|
|
157
|
-
|
|
158
|
-
if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) {
|
|
159
|
-
self.inAppBrowserViewController.orientationDelegate = (UIViewController <CDVScreenOrientationDelegate>*)self.viewController;
|
|
160
|
-
}
|
|
161
159
|
}
|
|
162
|
-
|
|
160
|
+
|
|
163
161
|
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
|
|
164
|
-
[self.inAppBrowserViewController showToolBar:browserOptions.toolbar :browserOptions.toolbarposition];
|
|
162
|
+
[self.inAppBrowserViewController showToolBar:browserOptions.toolbar atPosition:browserOptions.toolbarposition];
|
|
165
163
|
if (browserOptions.closebuttoncaption != nil || browserOptions.closebuttoncolor != nil) {
|
|
166
164
|
int closeButtonIndex = browserOptions.lefttoright ? (browserOptions.hidenavigationbuttons ? 1 : 4) : 0;
|
|
167
|
-
[self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption :browserOptions.closebuttoncolor :closeButtonIndex];
|
|
165
|
+
[self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption withColor:browserOptions.closebuttoncolor atIndex:closeButtonIndex];
|
|
168
166
|
}
|
|
169
167
|
// Set Presentation Style
|
|
170
168
|
UIModalPresentationStyle presentationStyle = UIModalPresentationFullScreen; // default
|
|
@@ -176,7 +174,7 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
176
174
|
}
|
|
177
175
|
}
|
|
178
176
|
self.inAppBrowserViewController.modalPresentationStyle = presentationStyle;
|
|
179
|
-
|
|
177
|
+
|
|
180
178
|
// Set Transition Style
|
|
181
179
|
UIModalTransitionStyle transitionStyle = UIModalTransitionStyleCoverVertical; // default
|
|
182
180
|
if (browserOptions.transitionstyle != nil) {
|
|
@@ -187,76 +185,85 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
187
|
self.inAppBrowserViewController.modalTransitionStyle = transitionStyle;
|
|
190
|
-
|
|
191
|
-
//
|
|
188
|
+
|
|
189
|
+
// Prevent WebView from bouncing
|
|
192
190
|
if (browserOptions.disallowoverscroll) {
|
|
193
191
|
if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) {
|
|
194
|
-
((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO;
|
|
192
|
+
((UIScrollView *)[self.inAppBrowserViewController.webView scrollView]).bounces = NO;
|
|
195
193
|
} else {
|
|
196
194
|
for (id subview in self.inAppBrowserViewController.webView.subviews) {
|
|
197
195
|
if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
|
|
198
|
-
((UIScrollView*)subview).bounces = NO;
|
|
196
|
+
((UIScrollView *)subview).bounces = NO;
|
|
199
197
|
}
|
|
200
198
|
}
|
|
201
199
|
}
|
|
202
200
|
}
|
|
203
|
-
|
|
204
|
-
//
|
|
205
|
-
if([browserOptions.beforeload isKindOfClass:[NSString class]]){
|
|
201
|
+
|
|
202
|
+
// Use of beforeload event
|
|
203
|
+
if ([browserOptions.beforeload isKindOfClass:[NSString class]]) {
|
|
206
204
|
_beforeload = browserOptions.beforeload;
|
|
207
|
-
}else{
|
|
205
|
+
} else {
|
|
208
206
|
_beforeload = @"yes";
|
|
209
207
|
}
|
|
210
208
|
_waitForBeforeload = ![_beforeload isEqualToString:@""];
|
|
211
|
-
|
|
209
|
+
|
|
212
210
|
[self.inAppBrowserViewController navigateTo:url];
|
|
213
211
|
if (!browserOptions.hidden) {
|
|
214
212
|
[self show:nil withNoAnimate:browserOptions.hidden];
|
|
215
213
|
}
|
|
216
214
|
}
|
|
217
215
|
|
|
218
|
-
- (void)show:(CDVInvokedUrlCommand*)command
|
|
216
|
+
- (void)show:(CDVInvokedUrlCommand *)command
|
|
217
|
+
{
|
|
219
218
|
[self show:command withNoAnimate:NO];
|
|
220
219
|
}
|
|
221
220
|
|
|
222
|
-
- (void)show:(CDVInvokedUrlCommand*)command withNoAnimate:(BOOL)noAnimate
|
|
221
|
+
- (void)show:(CDVInvokedUrlCommand *)command withNoAnimate:(BOOL)noAnimate
|
|
223
222
|
{
|
|
224
223
|
BOOL initHidden = NO;
|
|
225
|
-
if(command == nil && noAnimate == YES){
|
|
224
|
+
if (command == nil && noAnimate == YES) {
|
|
226
225
|
initHidden = YES;
|
|
227
226
|
}
|
|
228
|
-
|
|
227
|
+
|
|
229
228
|
if (self.inAppBrowserViewController == nil) {
|
|
230
229
|
NSLog(@"Tried to show IAB after it was closed.");
|
|
231
230
|
return;
|
|
232
231
|
}
|
|
233
|
-
|
|
234
|
-
__block CDVInAppBrowserNavigationController*
|
|
232
|
+
|
|
233
|
+
__block CDVInAppBrowserNavigationController *nav = [[CDVInAppBrowserNavigationController alloc]
|
|
235
234
|
initWithRootViewController:self.inAppBrowserViewController];
|
|
236
|
-
nav.orientationDelegate = self.inAppBrowserViewController;
|
|
237
235
|
nav.navigationBarHidden = YES;
|
|
238
236
|
nav.modalPresentationStyle = self.inAppBrowserViewController.modalPresentationStyle;
|
|
239
237
|
nav.presentationController.delegate = self.inAppBrowserViewController;
|
|
240
|
-
|
|
241
|
-
__weak CDVWKInAppBrowser*
|
|
242
|
-
|
|
238
|
+
|
|
239
|
+
__weak CDVWKInAppBrowser *weakSelf = self;
|
|
240
|
+
|
|
243
241
|
// Run later to avoid the "took a long time" log message.
|
|
244
242
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
245
243
|
if (weakSelf.inAppBrowserViewController != nil) {
|
|
246
244
|
float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
|
|
247
245
|
__strong __typeof(weakSelf) strongSelf = weakSelf;
|
|
248
246
|
if (!strongSelf->tmpWindow) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
if (@available(iOS 13.0, *)) {
|
|
248
|
+
UIWindowScene *scene = strongSelf.viewController.view.window.windowScene;
|
|
249
|
+
if (scene) {
|
|
250
|
+
strongSelf->tmpWindow = [[UIWindow alloc] initWithWindowScene:scene];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (!strongSelf->tmpWindow) {
|
|
255
|
+
CGRect frame = [[UIScreen mainScreen] bounds];
|
|
256
|
+
if (initHidden && osVersion < 11) {
|
|
257
|
+
frame.origin.x = -10000;
|
|
258
|
+
}
|
|
259
|
+
strongSelf->tmpWindow = [[UIWindow alloc] initWithFrame:frame];
|
|
252
260
|
}
|
|
253
|
-
strongSelf->tmpWindow = [[UIWindow alloc] initWithFrame:frame];
|
|
254
261
|
}
|
|
255
262
|
UIViewController *tmpController = [[UIViewController alloc] init];
|
|
256
263
|
[strongSelf->tmpWindow setRootViewController:tmpController];
|
|
257
264
|
[strongSelf->tmpWindow setWindowLevel:UIWindowLevelNormal];
|
|
258
265
|
|
|
259
|
-
if(!initHidden || osVersion < 11){
|
|
266
|
+
if (!initHidden || osVersion < 11) {
|
|
260
267
|
[self->tmpWindow makeKeyAndVisible];
|
|
261
268
|
}
|
|
262
269
|
[tmpController presentViewController:nav animated:!noAnimate completion:nil];
|
|
@@ -264,9 +271,9 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
264
271
|
});
|
|
265
272
|
}
|
|
266
273
|
|
|
267
|
-
- (void)hide:(CDVInvokedUrlCommand*)command
|
|
274
|
+
- (void)hide:(CDVInvokedUrlCommand *)command
|
|
268
275
|
{
|
|
269
|
-
// Set tmpWindow to hidden to make main
|
|
276
|
+
// Set tmpWindow to hidden to make main WebView responsive to touch again
|
|
270
277
|
// https://stackoverflow.com/questions/4544489/how-to-remove-a-uiwindow
|
|
271
278
|
self->tmpWindow.hidden = YES;
|
|
272
279
|
self->tmpWindow = nil;
|
|
@@ -274,10 +281,8 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
274
281
|
if (self.inAppBrowserViewController == nil) {
|
|
275
282
|
NSLog(@"Tried to hide IAB after it was closed.");
|
|
276
283
|
return;
|
|
277
|
-
|
|
278
|
-
|
|
279
284
|
}
|
|
280
|
-
|
|
285
|
+
|
|
281
286
|
// Run later to avoid the "took a long time" log message.
|
|
282
287
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
283
288
|
if (self.inAppBrowserViewController != nil) {
|
|
@@ -286,15 +291,15 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
286
291
|
});
|
|
287
292
|
}
|
|
288
293
|
|
|
289
|
-
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
|
|
294
|
+
- (void)openInCordovaWebView:(NSURL *)url withOptions:(NSString *)options
|
|
290
295
|
{
|
|
291
|
-
NSURLRequest*
|
|
292
|
-
//
|
|
296
|
+
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
|
297
|
+
// The WebView engine itself will filter for this according to <allow-navigation> policy
|
|
293
298
|
// in config.xml
|
|
294
299
|
[self.webViewEngine loadRequest:request];
|
|
295
300
|
}
|
|
296
301
|
|
|
297
|
-
- (void)openInSystem:(NSURL*)url
|
|
302
|
+
- (void)openInSystem:(NSURL *)url
|
|
298
303
|
{
|
|
299
304
|
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
|
|
300
305
|
if (!success) {
|
|
@@ -303,9 +308,9 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
303
308
|
}];
|
|
304
309
|
}
|
|
305
310
|
|
|
306
|
-
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command
|
|
311
|
+
- (void)loadAfterBeforeload:(CDVInvokedUrlCommand *)command
|
|
307
312
|
{
|
|
308
|
-
NSString*
|
|
313
|
+
NSString *urlStr = [command argumentAtIndex:0];
|
|
309
314
|
|
|
310
315
|
if ([_beforeload isEqualToString:@""]) {
|
|
311
316
|
NSLog(@"unexpected loadAfterBeforeload called without feature beforeload=get|post");
|
|
@@ -319,8 +324,7 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
319
324
|
return;
|
|
320
325
|
}
|
|
321
326
|
|
|
322
|
-
NSURL*
|
|
323
|
-
//_beforeload = @"";
|
|
327
|
+
NSURL *url = [NSURL URLWithString:urlStr];
|
|
324
328
|
_waitForBeforeload = NO;
|
|
325
329
|
[self.inAppBrowserViewController navigateTo:url];
|
|
326
330
|
}
|
|
@@ -334,17 +338,17 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
334
338
|
//
|
|
335
339
|
// If no wrapper is supplied, then the source string is executed directly.
|
|
336
340
|
|
|
337
|
-
- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper
|
|
341
|
+
- (void)injectDeferredObject:(NSString *)source withWrapper:(NSString *)jsWrapper
|
|
338
342
|
{
|
|
339
343
|
// Ensure a message handler bridge is created to communicate with the CDVWKInAppBrowserViewController
|
|
340
|
-
[self evaluateJavaScript: [NSString stringWithFormat:@"(function(w){if(!w._cdvMessageHandler) {w._cdvMessageHandler = function(id,d){w.webkit.messageHandlers.%@.postMessage({d:d, id:id});}}})(window)", IAB_BRIDGE_NAME]];
|
|
341
|
-
|
|
344
|
+
[self evaluateJavaScript: [NSString stringWithFormat:@"(function(w){if (!w._cdvMessageHandler) {w._cdvMessageHandler = function(id,d){w.webkit.messageHandlers.%@.postMessage({d:d, id:id});}}})(window)", IAB_BRIDGE_NAME]];
|
|
345
|
+
|
|
342
346
|
if (jsWrapper != nil) {
|
|
343
|
-
NSData*
|
|
344
|
-
NSString*
|
|
347
|
+
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil];
|
|
348
|
+
NSString *sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
345
349
|
if (sourceArrayString) {
|
|
346
|
-
NSString*
|
|
347
|
-
NSString*
|
|
350
|
+
NSString *sourceString = [sourceArrayString substringWithRange:NSMakeRange(1, [sourceArrayString length] - 2)];
|
|
351
|
+
NSString *jsToInject = [NSString stringWithFormat:jsWrapper, sourceString];
|
|
348
352
|
[self evaluateJavaScript:jsToInject];
|
|
349
353
|
}
|
|
350
354
|
} else {
|
|
@@ -353,9 +357,10 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
353
357
|
}
|
|
354
358
|
|
|
355
359
|
|
|
356
|
-
//
|
|
357
|
-
- (void)evaluateJavaScript:(NSString *)script
|
|
358
|
-
|
|
360
|
+
// Synchronous helper for javascript evaluation
|
|
361
|
+
- (void)evaluateJavaScript:(NSString *)script
|
|
362
|
+
{
|
|
363
|
+
__block NSString *_script = script;
|
|
359
364
|
[self.inAppBrowserViewController.webView evaluateJavaScript:script completionHandler:^(id result, NSError *error) {
|
|
360
365
|
if (error == nil) {
|
|
361
366
|
if (result != nil) {
|
|
@@ -367,20 +372,20 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
367
372
|
}];
|
|
368
373
|
}
|
|
369
374
|
|
|
370
|
-
- (void)injectScriptCode:(CDVInvokedUrlCommand*)command
|
|
375
|
+
- (void)injectScriptCode:(CDVInvokedUrlCommand *)command
|
|
371
376
|
{
|
|
372
|
-
NSString*
|
|
373
|
-
|
|
377
|
+
NSString *jsWrapper = nil;
|
|
378
|
+
|
|
374
379
|
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
|
375
380
|
jsWrapper = [NSString stringWithFormat:@"_cdvMessageHandler('%@',JSON.stringify([eval(%%@)]));", command.callbackId];
|
|
376
381
|
}
|
|
377
382
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
|
378
383
|
}
|
|
379
384
|
|
|
380
|
-
- (void)injectScriptFile:(CDVInvokedUrlCommand*)command
|
|
385
|
+
- (void)injectScriptFile:(CDVInvokedUrlCommand *)command
|
|
381
386
|
{
|
|
382
|
-
NSString*
|
|
383
|
-
|
|
387
|
+
NSString *jsWrapper;
|
|
388
|
+
|
|
384
389
|
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
|
385
390
|
jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('script'); c.src = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
|
|
386
391
|
} else {
|
|
@@ -389,10 +394,10 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
389
394
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
|
390
395
|
}
|
|
391
396
|
|
|
392
|
-
- (void)injectStyleCode:(CDVInvokedUrlCommand*)command
|
|
397
|
+
- (void)injectStyleCode:(CDVInvokedUrlCommand *)command
|
|
393
398
|
{
|
|
394
|
-
NSString*
|
|
395
|
-
|
|
399
|
+
NSString *jsWrapper;
|
|
400
|
+
|
|
396
401
|
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
|
397
402
|
jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('style'); c.innerHTML = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
|
|
398
403
|
} else {
|
|
@@ -401,31 +406,29 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
401
406
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
|
402
407
|
}
|
|
403
408
|
|
|
404
|
-
- (void)injectStyleFile:(CDVInvokedUrlCommand*)command
|
|
409
|
+
- (void)injectStyleFile:(CDVInvokedUrlCommand *)command
|
|
405
410
|
{
|
|
406
|
-
NSString*
|
|
407
|
-
|
|
411
|
+
NSString *jsWrapper;
|
|
412
|
+
|
|
408
413
|
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
|
409
414
|
jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
|
|
410
415
|
} else {
|
|
411
|
-
jsWrapper = @"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'
|
|
416
|
+
jsWrapper = @"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)";
|
|
412
417
|
}
|
|
413
418
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
|
414
419
|
}
|
|
415
420
|
|
|
416
|
-
- (BOOL)
|
|
421
|
+
- (BOOL)isAllowedScheme:(NSString *)scheme
|
|
417
422
|
{
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (err != nil) {
|
|
423
|
-
// Couldn't initialize Regex; No is safer than Yes.
|
|
424
|
-
return NO;
|
|
425
|
-
}
|
|
423
|
+
NSString *allowedSchemesPreference = [self.commandDelegate.settings cordovaSettingForKey:@"AllowedSchemes"];
|
|
424
|
+
if (allowedSchemesPreference == nil || [allowedSchemesPreference isEqualToString:@""]) {
|
|
425
|
+
// Preference missing.
|
|
426
|
+
return NO;
|
|
426
427
|
}
|
|
427
|
-
|
|
428
|
-
|
|
428
|
+
for (NSString *allowedScheme in [allowedSchemesPreference componentsSeparatedByString:@","]) {
|
|
429
|
+
if ([allowedScheme isEqualToString:scheme]) {
|
|
430
|
+
return YES;
|
|
431
|
+
}
|
|
429
432
|
}
|
|
430
433
|
return NO;
|
|
431
434
|
}
|
|
@@ -435,97 +438,104 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
435
438
|
* to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no
|
|
436
439
|
* other code execution is possible.
|
|
437
440
|
*/
|
|
438
|
-
- (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
|
439
|
-
|
|
440
|
-
NSURL*
|
|
441
|
-
NSURL*
|
|
441
|
+
- (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
|
442
|
+
{
|
|
443
|
+
NSURL *url = navigationAction.request.URL;
|
|
444
|
+
NSURL *mainDocumentURL = navigationAction.request.mainDocumentURL;
|
|
442
445
|
BOOL isTopLevelNavigation = [url isEqual:mainDocumentURL];
|
|
443
446
|
BOOL shouldStart = YES;
|
|
444
447
|
BOOL useBeforeLoad = NO;
|
|
445
|
-
NSString*
|
|
446
|
-
NSString*
|
|
447
|
-
|
|
448
|
-
if([_beforeload isEqualToString:@"post"]){
|
|
449
|
-
//TODO
|
|
448
|
+
NSString *httpMethod = navigationAction.request.HTTPMethod;
|
|
449
|
+
NSString *errorMessage = nil;
|
|
450
|
+
|
|
451
|
+
if ([_beforeload isEqualToString:@"post"]) {
|
|
452
|
+
// TODO: Handle POST requests by preserving POST data then remove this condition.
|
|
450
453
|
errorMessage = @"beforeload doesn't yet support POST requests";
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
)){
|
|
454
|
+
} else if (isTopLevelNavigation && (
|
|
455
|
+
[_beforeload isEqualToString:@"yes"]
|
|
456
|
+
|| ([_beforeload isEqualToString:@"get"] && [httpMethod isEqualToString:@"GET"])
|
|
457
|
+
// TODO: Comment in when POST requests are handled.
|
|
458
|
+
// || ([_beforeload isEqualToString:@"post"] && [httpMethod isEqualToString:@"POST"])
|
|
459
|
+
)) {
|
|
458
460
|
useBeforeLoad = YES;
|
|
459
461
|
}
|
|
460
462
|
|
|
461
463
|
// When beforeload, on first URL change, initiate JS callback. Only after the beforeload event, continue.
|
|
462
464
|
if (_waitForBeforeload && useBeforeLoad) {
|
|
463
|
-
CDVPluginResult*
|
|
464
|
-
messageAsDictionary:@{@"type":@"beforeload", @"url":
|
|
465
|
-
[pluginResult
|
|
466
|
-
|
|
465
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
466
|
+
messageAsDictionary:@{@"type":@"beforeload", @"url":url.absoluteString}];
|
|
467
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
468
|
+
|
|
467
469
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
468
470
|
decisionHandler(WKNavigationActionPolicyCancel);
|
|
469
471
|
return;
|
|
470
472
|
}
|
|
471
|
-
|
|
472
|
-
if(errorMessage != nil){
|
|
473
|
-
NSLog(errorMessage);
|
|
474
|
-
CDVPluginResult*
|
|
475
|
-
messageAsDictionary:@{@"type":@"loaderror", @"url":
|
|
476
|
-
[pluginResult
|
|
473
|
+
|
|
474
|
+
if (errorMessage != nil) {
|
|
475
|
+
NSLog(@"%@", errorMessage);
|
|
476
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
|
|
477
|
+
messageAsDictionary:@{@"type":@"loaderror", @"url":url.absoluteString, @"code": @"-1", @"message": errorMessage}];
|
|
478
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
477
479
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
478
480
|
}
|
|
479
|
-
|
|
480
|
-
//
|
|
481
|
-
NSArray *
|
|
482
|
-
if ([allowedSchemes containsObject:
|
|
481
|
+
|
|
482
|
+
// If the URL is an app store, tel, sms, mailto or geo link, let the system handle it, otherwise it fails to load it.
|
|
483
|
+
NSArray *allowedSchemes = @[@"itms-appss", @"itms-apps", @"tel", @"sms", @"mailto", @"geo"];
|
|
484
|
+
if ([allowedSchemes containsObject:url.scheme]) {
|
|
483
485
|
[theWebView stopLoading];
|
|
484
486
|
[self openInSystem:url];
|
|
485
487
|
shouldStart = NO;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
+
} else if (self.callbackId != nil && ![url.scheme isEqualToString:@"http"] && ![url.scheme isEqualToString:@"https"] && [self isAllowedScheme:url.scheme]) {
|
|
489
|
+
// Send a customscheme event for allowed schemes that are not http/https.
|
|
490
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
491
|
+
messageAsDictionary:@{@"type":@"customscheme", @"url":url.absoluteString}];
|
|
492
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
493
|
+
|
|
494
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
495
|
+
|
|
496
|
+
shouldStart = NO;
|
|
497
|
+
} else if (self.callbackId != nil && isTopLevelNavigation) {
|
|
488
498
|
// Send a loadstart event for each top-level navigation (includes redirects).
|
|
489
|
-
CDVPluginResult*
|
|
490
|
-
messageAsDictionary:@{@"type":@"loadstart", @"url":
|
|
491
|
-
[pluginResult
|
|
492
|
-
|
|
499
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
500
|
+
messageAsDictionary:@{@"type":@"loadstart", @"url":url.absoluteString}];
|
|
501
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
502
|
+
|
|
493
503
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
494
504
|
}
|
|
495
505
|
|
|
496
506
|
if (useBeforeLoad) {
|
|
497
507
|
_waitForBeforeload = YES;
|
|
498
508
|
}
|
|
499
|
-
|
|
500
|
-
if(shouldStart){
|
|
509
|
+
|
|
510
|
+
if (shouldStart) {
|
|
501
511
|
// Fix GH-417 & GH-424: Handle non-default target attribute
|
|
502
512
|
// Based on https://stackoverflow.com/a/25713070/777265
|
|
503
|
-
if (!navigationAction.targetFrame){
|
|
513
|
+
if (!navigationAction.targetFrame) {
|
|
504
514
|
[theWebView loadRequest:navigationAction.request];
|
|
505
515
|
decisionHandler(WKNavigationActionPolicyCancel);
|
|
506
|
-
}else{
|
|
516
|
+
} else {
|
|
507
517
|
decisionHandler(WKNavigationActionPolicyAllow);
|
|
508
518
|
}
|
|
509
|
-
}else{
|
|
519
|
+
} else {
|
|
510
520
|
decisionHandler(WKNavigationActionPolicyCancel);
|
|
511
521
|
}
|
|
512
522
|
}
|
|
513
523
|
|
|
514
524
|
#pragma mark WKScriptMessageHandler delegate
|
|
515
|
-
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
|
516
|
-
|
|
517
|
-
CDVPluginResult*
|
|
518
|
-
|
|
519
|
-
if([message.body isKindOfClass:[NSDictionary class]]){
|
|
520
|
-
NSDictionary*
|
|
521
|
-
NSString*
|
|
522
|
-
|
|
523
|
-
if([messageContent objectForKey:@"d"]){
|
|
524
|
-
NSString*
|
|
525
|
-
NSError* __autoreleasing error = nil;
|
|
526
|
-
NSData*
|
|
525
|
+
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
|
526
|
+
{
|
|
527
|
+
CDVPluginResult *pluginResult = nil;
|
|
528
|
+
|
|
529
|
+
if ([message.body isKindOfClass:[NSDictionary class]]) {
|
|
530
|
+
NSDictionary *messageContent = (NSDictionary *) message.body;
|
|
531
|
+
NSString *scriptCallbackId = messageContent[@"id"];
|
|
532
|
+
|
|
533
|
+
if ([messageContent objectForKey:@"d"]) {
|
|
534
|
+
NSString *scriptResult = messageContent[@"d"];
|
|
535
|
+
NSError * __autoreleasing error = nil;
|
|
536
|
+
NSData *decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
|
|
527
537
|
if ((error == nil) && [decodedResult isKindOfClass:[NSArray class]]) {
|
|
528
|
-
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray*)decodedResult];
|
|
538
|
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray *)decodedResult];
|
|
529
539
|
} else {
|
|
530
540
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION];
|
|
531
541
|
}
|
|
@@ -533,62 +543,61 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
533
543
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:@[]];
|
|
534
544
|
}
|
|
535
545
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId];
|
|
536
|
-
}else if(self.callbackId != nil){
|
|
546
|
+
} else if (self.callbackId != nil) {
|
|
537
547
|
// Send a message event
|
|
538
|
-
NSString*
|
|
539
|
-
NSError* __autoreleasing error = nil;
|
|
540
|
-
NSData*
|
|
548
|
+
NSString *messageContent = (NSString *) message.body;
|
|
549
|
+
NSError * __autoreleasing error = nil;
|
|
550
|
+
NSData *decodedResult = [NSJSONSerialization JSONObjectWithData:[messageContent dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
|
|
541
551
|
if (error == nil) {
|
|
542
|
-
NSMutableDictionary*
|
|
552
|
+
NSMutableDictionary *dResult = [NSMutableDictionary new];
|
|
543
553
|
[dResult setValue:@"message" forKey:@"type"];
|
|
544
554
|
[dResult setObject:decodedResult forKey:@"data"];
|
|
545
|
-
CDVPluginResult*
|
|
546
|
-
[pluginResult
|
|
555
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dResult];
|
|
556
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
547
557
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
548
558
|
}
|
|
549
559
|
}
|
|
550
560
|
}
|
|
551
561
|
|
|
552
|
-
- (void)didStartProvisionalNavigation:(WKWebView*)theWebView
|
|
562
|
+
- (void)didStartProvisionalNavigation:(WKWebView *)theWebView
|
|
553
563
|
{
|
|
554
564
|
NSLog(@"didStartProvisionalNavigation");
|
|
555
|
-
// self.inAppBrowserViewController.currentURL = theWebView.URL;
|
|
556
565
|
}
|
|
557
566
|
|
|
558
|
-
- (void)didFinishNavigation:(WKWebView*)theWebView
|
|
567
|
+
- (void)didFinishNavigation:(WKWebView *)theWebView
|
|
559
568
|
{
|
|
560
569
|
if (self.callbackId != nil) {
|
|
561
|
-
NSString*
|
|
562
|
-
if(url == nil){
|
|
563
|
-
if(self.inAppBrowserViewController.currentURL != nil){
|
|
564
|
-
url =
|
|
565
|
-
}else{
|
|
570
|
+
NSString *url = theWebView.URL.absoluteString;
|
|
571
|
+
if (url == nil) {
|
|
572
|
+
if (self.inAppBrowserViewController.currentURL != nil) {
|
|
573
|
+
url = self.inAppBrowserViewController.currentURL.absoluteString;
|
|
574
|
+
} else {
|
|
566
575
|
url = @"";
|
|
567
576
|
}
|
|
568
577
|
}
|
|
569
|
-
CDVPluginResult*
|
|
578
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
570
579
|
messageAsDictionary:@{@"type":@"loadstop", @"url":url}];
|
|
571
|
-
[pluginResult
|
|
572
|
-
|
|
580
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
581
|
+
|
|
573
582
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
574
583
|
}
|
|
575
584
|
}
|
|
576
585
|
|
|
577
|
-
- (void)webView:(WKWebView*)theWebView didFailNavigation:(NSError*)error
|
|
586
|
+
- (void)webView:(WKWebView *)theWebView didFailNavigation:(NSError *)error
|
|
578
587
|
{
|
|
579
588
|
if (self.callbackId != nil) {
|
|
580
|
-
NSString*
|
|
581
|
-
if(url == nil){
|
|
582
|
-
if(self.inAppBrowserViewController.currentURL != nil){
|
|
583
|
-
url =
|
|
584
|
-
}else{
|
|
589
|
+
NSString *url = theWebView.URL.absoluteString;
|
|
590
|
+
if (url == nil) {
|
|
591
|
+
if (self.inAppBrowserViewController.currentURL != nil) {
|
|
592
|
+
url = self.inAppBrowserViewController.currentURL.absoluteString;
|
|
593
|
+
} else {
|
|
585
594
|
url = @"";
|
|
586
595
|
}
|
|
587
596
|
}
|
|
588
|
-
CDVPluginResult*
|
|
597
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
|
|
589
598
|
messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}];
|
|
590
|
-
[pluginResult
|
|
591
|
-
|
|
599
|
+
[pluginResult setKeepCallbackAsBool:YES];
|
|
600
|
+
|
|
592
601
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
593
602
|
}
|
|
594
603
|
}
|
|
@@ -596,32 +605,32 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
596
605
|
- (void)browserExit
|
|
597
606
|
{
|
|
598
607
|
if (self.callbackId != nil) {
|
|
599
|
-
CDVPluginResult*
|
|
608
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
600
609
|
messageAsDictionary:@{@"type":@"exit"}];
|
|
601
610
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
|
602
611
|
self.callbackId = nil;
|
|
603
612
|
}
|
|
604
|
-
|
|
613
|
+
|
|
605
614
|
[self.inAppBrowserViewController.configuration.userContentController removeScriptMessageHandlerForName:IAB_BRIDGE_NAME];
|
|
606
615
|
self.inAppBrowserViewController.configuration = nil;
|
|
607
|
-
|
|
616
|
+
|
|
608
617
|
[self.inAppBrowserViewController.webView stopLoading];
|
|
609
618
|
[self.inAppBrowserViewController.webView removeFromSuperview];
|
|
610
619
|
[self.inAppBrowserViewController.webView setUIDelegate:nil];
|
|
611
620
|
[self.inAppBrowserViewController.webView setNavigationDelegate:nil];
|
|
612
621
|
self.inAppBrowserViewController.webView = nil;
|
|
613
|
-
|
|
622
|
+
|
|
614
623
|
// Set navigationDelegate to nil to ensure no callbacks are received from it.
|
|
615
624
|
self.inAppBrowserViewController.navigationDelegate = nil;
|
|
616
625
|
self.inAppBrowserViewController = nil;
|
|
617
626
|
|
|
618
|
-
// Set tmpWindow to hidden to make main
|
|
627
|
+
// Set tmpWindow to hidden to make main WebView responsive to touch again
|
|
619
628
|
// Based on https://stackoverflow.com/questions/4544489/how-to-remove-a-uiwindow
|
|
620
629
|
self->tmpWindow.hidden = YES;
|
|
621
630
|
self->tmpWindow = nil;
|
|
622
631
|
}
|
|
623
632
|
|
|
624
|
-
@end //CDVWKInAppBrowser
|
|
633
|
+
@end // CDVWKInAppBrowser
|
|
625
634
|
|
|
626
635
|
#pragma mark CDVWKInAppBrowserViewController
|
|
627
636
|
|
|
@@ -630,9 +639,9 @@ static CDVWKInAppBrowser* instance = nil;
|
|
|
630
639
|
@synthesize currentURL;
|
|
631
640
|
|
|
632
641
|
CGFloat lastReducedStatusBarHeight = 0.0;
|
|
633
|
-
BOOL isExiting =
|
|
642
|
+
BOOL isExiting = NO;
|
|
634
643
|
|
|
635
|
-
- (id)initWithBrowserOptions:
|
|
644
|
+
- (id)initWithBrowserOptions:(CDVInAppBrowserOptions *)browserOptions andSettings:(CDVSettingsDictionary *)settings
|
|
636
645
|
{
|
|
637
646
|
self = [super init];
|
|
638
647
|
if (self != nil) {
|
|
@@ -640,68 +649,64 @@ BOOL isExiting = FALSE;
|
|
|
640
649
|
_settings = settings;
|
|
641
650
|
self.webViewUIDelegate = [[CDVWKInAppBrowserUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
|
|
642
651
|
[self.webViewUIDelegate setViewController:self];
|
|
643
|
-
|
|
644
652
|
[self createViews];
|
|
645
653
|
}
|
|
646
|
-
|
|
647
|
-
return self;
|
|
648
|
-
}
|
|
649
654
|
|
|
650
|
-
|
|
651
|
-
//NSLog(@"dealloc");
|
|
655
|
+
return self;
|
|
652
656
|
}
|
|
653
657
|
|
|
654
658
|
- (void)createViews
|
|
655
659
|
{
|
|
656
|
-
// We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
BOOL toolbarIsAtBottom = ![_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop];
|
|
660
|
-
webViewBounds.size.height -= _browserOptions.location ? FOOTER_HEIGHT : TOOLBAR_HEIGHT;
|
|
661
|
-
WKUserContentController* userContentController = [[WKUserContentController alloc] init];
|
|
662
|
-
|
|
663
|
-
WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
|
|
664
|
-
|
|
660
|
+
// We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included.
|
|
661
|
+
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
|
|
662
|
+
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
|
|
665
663
|
NSString *userAgent = configuration.applicationNameForUserAgent;
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
[
|
|
669
|
-
|
|
670
|
-
userAgent = [NSString stringWithFormat:@"%@ %@", userAgent, [self settingForKey:@"AppendUserAgent"]];
|
|
664
|
+
|
|
665
|
+
if ([_settings cordovaSettingForKey:@"OverrideUserAgent"] == nil &&
|
|
666
|
+
[_settings cordovaSettingForKey:@"AppendUserAgent"] != nil) {
|
|
667
|
+
userAgent = [NSString stringWithFormat:@"%@ %@", userAgent, [_settings cordovaSettingForKey:@"AppendUserAgent"]];
|
|
671
668
|
}
|
|
669
|
+
|
|
672
670
|
configuration.applicationNameForUserAgent = userAgent;
|
|
673
671
|
configuration.userContentController = userContentController;
|
|
674
672
|
#if __has_include(<Cordova/CDVWebViewProcessPoolFactory.h>)
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
673
|
+
if (@available(iOS 15.0, *)) {
|
|
674
|
+
// Since iOS 15 WKProcessPool is deprecated and has no effect
|
|
675
|
+
} else {
|
|
676
|
+
// Set for iOS 14 and 15 a shared process pool
|
|
677
|
+
// CDVWebViewProcessPoolFactory is deprecated since cordova-ios 8.0.0
|
|
678
|
+
#pragma clang diagnostic push
|
|
679
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
680
|
+
configuration.processPool = [[CDVWebViewProcessPoolFactory sharedFactory] sharedProcessPool];
|
|
681
|
+
#pragma clang diagnostic pop
|
|
682
|
+
}
|
|
678
683
|
#endif
|
|
679
684
|
[configuration.userContentController addScriptMessageHandler:self name:IAB_BRIDGE_NAME];
|
|
680
|
-
|
|
681
|
-
//WKWebView options
|
|
685
|
+
|
|
686
|
+
// WKWebView options
|
|
682
687
|
configuration.allowsInlineMediaPlayback = _browserOptions.allowinlinemediaplayback;
|
|
683
688
|
configuration.ignoresViewportScaleLimits = _browserOptions.enableviewportscale;
|
|
684
|
-
|
|
689
|
+
|
|
690
|
+
if (_browserOptions.mediaplaybackrequiresuseraction == YES) {
|
|
685
691
|
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
|
|
686
|
-
}else{
|
|
692
|
+
} else {
|
|
687
693
|
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
|
688
694
|
}
|
|
689
|
-
|
|
695
|
+
|
|
690
696
|
if (@available(iOS 13.0, *)) {
|
|
691
|
-
NSString *contentMode = [
|
|
697
|
+
NSString *contentMode = [_settings cordovaSettingForKey:@"PreferredContentMode"];
|
|
692
698
|
if ([contentMode isEqual: @"mobile"]) {
|
|
693
699
|
configuration.defaultWebpagePreferences.preferredContentMode = WKContentModeMobile;
|
|
694
700
|
} else if ([contentMode isEqual: @"desktop"]) {
|
|
695
701
|
configuration.defaultWebpagePreferences.preferredContentMode = WKContentModeDesktop;
|
|
696
702
|
}
|
|
697
|
-
|
|
703
|
+
|
|
698
704
|
}
|
|
699
|
-
|
|
700
705
|
|
|
701
|
-
self.webView = [[WKWebView alloc] initWithFrame:
|
|
706
|
+
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
|
|
702
707
|
|
|
703
708
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160400
|
|
704
|
-
// With the introduction of iOS 16.4 the
|
|
709
|
+
// With the introduction of iOS 16.4 the WebView is no longer inspectable by default.
|
|
705
710
|
// We'll honor that change for release builds, but will still allow inspection on debug builds by default.
|
|
706
711
|
// We also introduce an override option, so consumers can influence this decision in their own build.
|
|
707
712
|
if (@available(iOS 16.4, *)) {
|
|
@@ -714,62 +719,19 @@ BOOL isExiting = FALSE;
|
|
|
714
719
|
}
|
|
715
720
|
#endif
|
|
716
721
|
|
|
717
|
-
|
|
718
722
|
[self.view addSubview:self.webView];
|
|
723
|
+
// The WebView should be behind the other elements like toolbar, address label, spinner
|
|
724
|
+
// Since the WebView is added first, this is already the case.
|
|
725
|
+
// sendSubviewToBack is normally not necessary.
|
|
719
726
|
[self.view sendSubviewToBack:self.webView];
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
self.webView.
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
self.webView.customUserAgent = [self settingForKey:@"OverrideUserAgent"];
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
self.webView.clearsContextBeforeDrawing = YES;
|
|
730
|
-
self.webView.clipsToBounds = YES;
|
|
731
|
-
self.webView.contentMode = UIViewContentModeScaleToFill;
|
|
732
|
-
self.webView.multipleTouchEnabled = YES;
|
|
733
|
-
self.webView.opaque = YES;
|
|
734
|
-
self.webView.userInteractionEnabled = YES;
|
|
735
|
-
self.automaticallyAdjustsScrollViewInsets = YES ;
|
|
736
|
-
[self.webView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
|
|
737
|
-
self.webView.allowsLinkPreview = NO;
|
|
738
|
-
self.webView.allowsBackForwardNavigationGestures = NO;
|
|
739
|
-
|
|
740
|
-
[self.webView.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
|
|
741
|
-
|
|
742
|
-
self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
|
743
|
-
self.spinner.alpha = 1.000;
|
|
744
|
-
self.spinner.autoresizesSubviews = YES;
|
|
745
|
-
self.spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);
|
|
746
|
-
self.spinner.clearsContextBeforeDrawing = NO;
|
|
747
|
-
self.spinner.clipsToBounds = NO;
|
|
748
|
-
self.spinner.contentMode = UIViewContentModeScaleToFill;
|
|
749
|
-
self.spinner.frame = CGRectMake(CGRectGetMidX(self.webView.frame), CGRectGetMidY(self.webView.frame), 20.0, 20.0);
|
|
750
|
-
self.spinner.hidden = NO;
|
|
751
|
-
self.spinner.hidesWhenStopped = YES;
|
|
752
|
-
self.spinner.multipleTouchEnabled = NO;
|
|
753
|
-
self.spinner.opaque = NO;
|
|
754
|
-
self.spinner.userInteractionEnabled = NO;
|
|
755
|
-
[self.spinner stopAnimating];
|
|
756
|
-
|
|
757
|
-
self.closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];
|
|
758
|
-
self.closeButton.enabled = YES;
|
|
759
|
-
|
|
760
|
-
UIBarButtonItem* flexibleSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
|
|
761
|
-
|
|
762
|
-
UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
|
|
763
|
-
fixedSpaceButton.width = 20;
|
|
764
|
-
|
|
765
|
-
float toolbarY = toolbarIsAtBottom ? self.view.bounds.size.height - TOOLBAR_HEIGHT : 0.0;
|
|
766
|
-
CGRect toolbarFrame = CGRectMake(0.0, toolbarY, self.view.bounds.size.width, TOOLBAR_HEIGHT);
|
|
767
|
-
|
|
768
|
-
self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];
|
|
727
|
+
|
|
728
|
+
// We add our own constraints, they should not be determined from the frame.
|
|
729
|
+
self.webView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
730
|
+
|
|
731
|
+
// Toolbar init without frame
|
|
732
|
+
self.toolbar = [[UIToolbar alloc] init];
|
|
769
733
|
self.toolbar.alpha = 1.000;
|
|
770
|
-
self.toolbar.
|
|
771
|
-
self.toolbar.autoresizingMask = toolbarIsAtBottom ? (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin) : UIViewAutoresizingFlexibleWidth;
|
|
772
|
-
self.toolbar.barStyle = UIBarStyleBlackOpaque;
|
|
734
|
+
self.toolbar.barStyle = UIBarStyleBlack;
|
|
773
735
|
self.toolbar.clearsContextBeforeDrawing = NO;
|
|
774
736
|
self.toolbar.clipsToBounds = NO;
|
|
775
737
|
self.toolbar.contentMode = UIViewContentModeScaleToFill;
|
|
@@ -778,20 +740,18 @@ BOOL isExiting = FALSE;
|
|
|
778
740
|
self.toolbar.opaque = NO;
|
|
779
741
|
self.toolbar.userInteractionEnabled = YES;
|
|
780
742
|
if (_browserOptions.toolbarcolor != nil) { // Set toolbar color if user sets it in options
|
|
781
|
-
|
|
743
|
+
self.toolbar.barTintColor = [self colorFromHexString:_browserOptions.toolbarcolor];
|
|
782
744
|
}
|
|
783
745
|
if (!_browserOptions.toolbartranslucent) { // Set toolbar translucent to no if user sets it in options
|
|
784
|
-
|
|
746
|
+
self.toolbar.translucent = NO;
|
|
785
747
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
self.addressLabel = [[UILabel alloc]
|
|
748
|
+
[self.view addSubview:self.toolbar];
|
|
749
|
+
// We add our own constraints, they should not be determined from the frame.
|
|
750
|
+
self.toolbar.translatesAutoresizingMaskIntoConstraints = NO;
|
|
751
|
+
|
|
752
|
+
self.addressLabel = [[UILabel alloc] init];
|
|
791
753
|
self.addressLabel.adjustsFontSizeToFitWidth = NO;
|
|
792
754
|
self.addressLabel.alpha = 1.000;
|
|
793
|
-
self.addressLabel.autoresizesSubviews = YES;
|
|
794
|
-
self.addressLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;
|
|
795
755
|
self.addressLabel.backgroundColor = [UIColor clearColor];
|
|
796
756
|
self.addressLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
|
|
797
757
|
self.addressLabel.clearsContextBeforeDrawing = YES;
|
|
@@ -800,13 +760,13 @@ BOOL isExiting = FALSE;
|
|
|
800
760
|
self.addressLabel.enabled = YES;
|
|
801
761
|
self.addressLabel.hidden = NO;
|
|
802
762
|
self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
|
803
|
-
|
|
763
|
+
|
|
804
764
|
if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumScaleFactor:")]) {
|
|
805
765
|
[self.addressLabel setValue:@(10.0/[UIFont labelFontSize]) forKey:@"minimumScaleFactor"];
|
|
806
766
|
} else if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumFontSize:")]) {
|
|
807
767
|
[self.addressLabel setValue:@(10.0) forKey:@"minimumFontSize"];
|
|
808
768
|
}
|
|
809
|
-
|
|
769
|
+
|
|
810
770
|
self.addressLabel.multipleTouchEnabled = NO;
|
|
811
771
|
self.addressLabel.numberOfLines = 1;
|
|
812
772
|
self.addressLabel.opaque = NO;
|
|
@@ -815,21 +775,47 @@ BOOL isExiting = FALSE;
|
|
|
815
775
|
self.addressLabel.textAlignment = NSTextAlignmentLeft;
|
|
816
776
|
self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000];
|
|
817
777
|
self.addressLabel.userInteractionEnabled = NO;
|
|
818
|
-
|
|
819
|
-
|
|
778
|
+
[self.view addSubview:self.addressLabel];
|
|
779
|
+
// We add our own constraints, they should not be determined from the frame.
|
|
780
|
+
self.addressLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
781
|
+
|
|
782
|
+
self.spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero];
|
|
783
|
+
self.spinner.alpha = 1.000;
|
|
784
|
+
self.spinner.clearsContextBeforeDrawing = NO;
|
|
785
|
+
self.spinner.clipsToBounds = NO;
|
|
786
|
+
self.spinner.contentMode = UIViewContentModeScaleToFill;
|
|
787
|
+
self.spinner.hidden = NO;
|
|
788
|
+
self.spinner.hidesWhenStopped = YES;
|
|
789
|
+
self.spinner.multipleTouchEnabled = NO;
|
|
790
|
+
self.spinner.opaque = NO;
|
|
791
|
+
self.spinner.userInteractionEnabled = NO;
|
|
792
|
+
[self.spinner stopAnimating];
|
|
793
|
+
[self.view addSubview:self.spinner];
|
|
794
|
+
// We add our own constraints, they should not be determined from the frame.
|
|
795
|
+
self.spinner.translatesAutoresizingMaskIntoConstraints = NO;
|
|
796
|
+
|
|
797
|
+
self.closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];
|
|
798
|
+
self.closeButton.enabled = YES;
|
|
799
|
+
|
|
800
|
+
UIBarButtonItem *flexibleSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
|
|
801
|
+
|
|
802
|
+
UIBarButtonItem *fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
|
|
803
|
+
fixedSpaceButton.width = 20;
|
|
804
|
+
|
|
805
|
+
NSString *frontArrowString = NSLocalizedString(@"►", nil); // Create arrow from Unicode char
|
|
820
806
|
self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)];
|
|
821
807
|
self.forwardButton.enabled = YES;
|
|
822
808
|
self.forwardButton.imageInsets = UIEdgeInsetsZero;
|
|
823
809
|
if (_browserOptions.navigationbuttoncolor != nil) { // Set button color if user sets it in options
|
|
824
|
-
|
|
810
|
+
self.forwardButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
|
|
825
811
|
}
|
|
826
812
|
|
|
827
|
-
NSString*
|
|
813
|
+
NSString *backArrowString = NSLocalizedString(@"◄", nil); // Create arrow from Unicode char
|
|
828
814
|
self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)];
|
|
829
815
|
self.backButton.enabled = YES;
|
|
830
816
|
self.backButton.imageInsets = UIEdgeInsetsZero;
|
|
831
817
|
if (_browserOptions.navigationbuttoncolor != nil) { // Set button color if user sets it in options
|
|
832
|
-
|
|
818
|
+
self.backButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
|
|
833
819
|
}
|
|
834
820
|
|
|
835
821
|
// Filter out Navigation Buttons if user requests so
|
|
@@ -844,149 +830,159 @@ BOOL isExiting = FALSE;
|
|
|
844
830
|
} else {
|
|
845
831
|
[self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]];
|
|
846
832
|
}
|
|
847
|
-
|
|
848
|
-
self.view.backgroundColor = [UIColor clearColor];
|
|
849
|
-
[self.view addSubview:self.toolbar];
|
|
850
|
-
[self.view addSubview:self.addressLabel];
|
|
851
|
-
[self.view addSubview:self.spinner];
|
|
852
|
-
}
|
|
853
833
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
834
|
+
self.webView.navigationDelegate = self;
|
|
835
|
+
self.webView.UIDelegate = self.webViewUIDelegate;
|
|
836
|
+
self.webView.backgroundColor = [UIColor whiteColor];
|
|
837
|
+
if ([_settings cordovaSettingForKey:@"OverrideUserAgent"] != nil) {
|
|
838
|
+
self.webView.customUserAgent = [_settings cordovaSettingForKey:@"OverrideUserAgent"];
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
self.webView.clearsContextBeforeDrawing = YES;
|
|
842
|
+
self.webView.clipsToBounds = YES;
|
|
843
|
+
self.webView.contentMode = UIViewContentModeScaleToFill;
|
|
844
|
+
self.webView.multipleTouchEnabled = YES;
|
|
845
|
+
self.webView.opaque = YES;
|
|
846
|
+
self.webView.userInteractionEnabled = YES;
|
|
847
|
+
self.webView.allowsLinkPreview = NO;
|
|
848
|
+
self.webView.allowsBackForwardNavigationGestures = NO;
|
|
849
|
+
|
|
850
|
+
// Setup Auto Layout constraints
|
|
851
|
+
//
|
|
852
|
+
// Setup horizontal constraints
|
|
853
|
+
// WebView horizontal constraints
|
|
854
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
855
|
+
// Left
|
|
856
|
+
[self.webView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
857
|
+
// Right
|
|
858
|
+
[self.webView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
|
|
859
|
+
]];
|
|
860
|
+
|
|
861
|
+
// Toolbar horizontal constraints
|
|
862
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
863
|
+
// Left
|
|
864
|
+
[self.toolbar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
|
865
|
+
// Right
|
|
866
|
+
[self.toolbar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
|
|
867
|
+
]];
|
|
868
|
+
|
|
869
|
+
// Address label horizontal constraints
|
|
870
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
871
|
+
// Left
|
|
872
|
+
[self.addressLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:5.0],
|
|
873
|
+
// Right
|
|
874
|
+
[self.addressLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-5.0]
|
|
875
|
+
]];
|
|
876
|
+
|
|
877
|
+
// Define vertical constraints, in order from top to bottom
|
|
878
|
+
// The address label and toolbar are optional
|
|
879
|
+
BOOL toolbarIsAtTop = [_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop];
|
|
880
|
+
BOOL toolbarVisible = _browserOptions.toolbar;
|
|
881
|
+
BOOL addressLabelVisible = _browserOptions.location;
|
|
882
|
+
|
|
883
|
+
// Center spinner in WebView
|
|
884
|
+
[self.spinner.centerXAnchor constraintEqualToAnchor:self.webView.centerXAnchor].active = YES;
|
|
885
|
+
[self.spinner.centerYAnchor constraintEqualToAnchor:self.webView.centerYAnchor].active = YES;
|
|
886
|
+
|
|
887
|
+
// Toolbar can be at top
|
|
888
|
+
if (toolbarIsAtTop) {
|
|
889
|
+
// Toolbar visible
|
|
890
|
+
if (toolbarVisible) {
|
|
891
|
+
// Toolbar top to safe area top
|
|
892
|
+
[self.toolbar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
|
|
893
|
+
// Webview top to toolbar bottom
|
|
894
|
+
[self.webView.topAnchor constraintEqualToAnchor:self.toolbar.bottomAnchor].active = YES;
|
|
895
|
+
|
|
896
|
+
// Toolbar not visible
|
|
897
|
+
} else {
|
|
898
|
+
// Webview top to safe area top
|
|
899
|
+
[self.webView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
if (addressLabelVisible) {
|
|
903
|
+
// Address label top to WebView bottom
|
|
904
|
+
[self.addressLabel.topAnchor constraintEqualToAnchor:self.webView.bottomAnchor].active = YES;
|
|
905
|
+
// Address label bottom to safe area bottom
|
|
906
|
+
[self.addressLabel.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
|
|
907
|
+
|
|
908
|
+
// Address label hidden
|
|
909
|
+
} else {
|
|
910
|
+
// WebView to view bottom
|
|
911
|
+
[self.webView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// Toolbar can be at bottom
|
|
915
|
+
} else {
|
|
916
|
+
// WebView top to safe area top
|
|
917
|
+
[self.webView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
|
|
918
|
+
|
|
919
|
+
if (addressLabelVisible) {
|
|
920
|
+
// WebView bottom to address label top
|
|
921
|
+
[self.webView.bottomAnchor constraintEqualToAnchor:self.addressLabel.topAnchor].active = YES;
|
|
922
|
+
|
|
923
|
+
// Address label bottom to toolbar top
|
|
924
|
+
if (toolbarVisible) {
|
|
925
|
+
[self.addressLabel.bottomAnchor constraintEqualToAnchor:self.toolbar.topAnchor].active = YES;
|
|
926
|
+
|
|
927
|
+
// Address label bottom to safe area bottom
|
|
928
|
+
} else {
|
|
929
|
+
[self.addressLabel.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Address label hidden
|
|
933
|
+
} else {
|
|
934
|
+
// WebView bottom to toolbar top
|
|
935
|
+
if (toolbarVisible) {
|
|
936
|
+
[self.webView.bottomAnchor constraintEqualToAnchor:self.toolbar.topAnchor].active = YES;
|
|
937
|
+
|
|
938
|
+
// WebView bottom to view bottom
|
|
939
|
+
} else {
|
|
940
|
+
[self.webView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// Toolbar bottom to safe area bottom
|
|
945
|
+
if (toolbarVisible) {
|
|
946
|
+
[self.toolbar.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
857
949
|
}
|
|
858
950
|
|
|
859
|
-
- (void)
|
|
951
|
+
- (void)setWebViewFrame:(CGRect)frame
|
|
952
|
+
{
|
|
860
953
|
NSLog(@"Setting the WebView's frame to %@", NSStringFromCGRect(frame));
|
|
861
954
|
[self.webView setFrame:frame];
|
|
862
955
|
}
|
|
863
956
|
|
|
864
|
-
- (void)setCloseButtonTitle:(NSString*)title :
|
|
957
|
+
- (void)setCloseButtonTitle:(NSString *)title withColor:(NSString *)colorString atIndex:(int)buttonIndex
|
|
865
958
|
{
|
|
866
|
-
//
|
|
867
|
-
// but, if you want to set this yourself, knock yourself out (
|
|
959
|
+
// The advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically
|
|
960
|
+
// but, if you want to set this yourself, knock yourself out. (We can't set the title for a system Done button, so we have to create a new one.)
|
|
868
961
|
self.closeButton = nil;
|
|
869
|
-
// Initialize with title if title is set, otherwise the title will be 'Done' localized
|
|
962
|
+
// Initialize with title if title is set, otherwise the title will be 'Done' localized.
|
|
870
963
|
self.closeButton = title != nil ? [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:self action:@selector(close)] : [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];
|
|
871
964
|
self.closeButton.enabled = YES;
|
|
872
|
-
// If color on closebutton is requested then initialize with that that color, otherwise use initialize with default
|
|
965
|
+
// If color on closebutton is requested then initialize with that that color, otherwise use initialize with default.
|
|
873
966
|
self.closeButton.tintColor = colorString != nil ? [self colorFromHexString:colorString] : [UIColor colorWithRed:60.0 / 255.0 green:136.0 / 255.0 blue:230.0 / 255.0 alpha:1];
|
|
874
|
-
|
|
875
|
-
NSMutableArray*
|
|
967
|
+
|
|
968
|
+
NSMutableArray *items = [self.toolbar.items mutableCopy];
|
|
876
969
|
[items replaceObjectAtIndex:buttonIndex withObject:self.closeButton];
|
|
877
970
|
[self.toolbar setItems:items];
|
|
878
971
|
}
|
|
879
972
|
|
|
880
973
|
- (void)showLocationBar:(BOOL)show
|
|
881
974
|
{
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
// prevent double show/hide
|
|
887
|
-
if (show == !(self.addressLabel.hidden)) {
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
if (show) {
|
|
892
|
-
self.addressLabel.hidden = NO;
|
|
893
|
-
|
|
894
|
-
if (toolbarVisible) {
|
|
895
|
-
// toolBar at the bottom, leave as is
|
|
896
|
-
// put locationBar on top of the toolBar
|
|
897
|
-
|
|
898
|
-
CGRect webViewBounds = self.view.bounds;
|
|
899
|
-
webViewBounds.size.height -= FOOTER_HEIGHT;
|
|
900
|
-
[self setWebViewFrame:webViewBounds];
|
|
901
|
-
|
|
902
|
-
locationbarFrame.origin.y = webViewBounds.size.height;
|
|
903
|
-
self.addressLabel.frame = locationbarFrame;
|
|
904
|
-
} else {
|
|
905
|
-
// no toolBar, so put locationBar at the bottom
|
|
906
|
-
|
|
907
|
-
CGRect webViewBounds = self.view.bounds;
|
|
908
|
-
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
|
909
|
-
[self setWebViewFrame:webViewBounds];
|
|
910
|
-
|
|
911
|
-
locationbarFrame.origin.y = webViewBounds.size.height;
|
|
912
|
-
self.addressLabel.frame = locationbarFrame;
|
|
913
|
-
}
|
|
914
|
-
} else {
|
|
915
|
-
self.addressLabel.hidden = YES;
|
|
916
|
-
|
|
917
|
-
if (toolbarVisible) {
|
|
918
|
-
// locationBar is on top of toolBar, hide locationBar
|
|
919
|
-
|
|
920
|
-
// webView take up whole height less toolBar height
|
|
921
|
-
CGRect webViewBounds = self.view.bounds;
|
|
922
|
-
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
|
923
|
-
[self setWebViewFrame:webViewBounds];
|
|
924
|
-
} else {
|
|
925
|
-
// no toolBar, expand webView to screen dimensions
|
|
926
|
-
[self setWebViewFrame:self.view.bounds];
|
|
927
|
-
}
|
|
928
|
-
}
|
|
975
|
+
self.addressLabel.hidden = !show;
|
|
976
|
+
[self.view setNeedsLayout];
|
|
977
|
+
[self.view layoutIfNeeded];
|
|
929
978
|
}
|
|
930
979
|
|
|
931
|
-
- (void)showToolBar:(BOOL)show :
|
|
980
|
+
- (void)showToolBar:(BOOL)show atPosition:(NSString *)toolbarPosition
|
|
932
981
|
{
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
// prevent double show/hide
|
|
939
|
-
if (show == !(self.toolbar.hidden)) {
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
if (show) {
|
|
944
|
-
self.toolbar.hidden = NO;
|
|
945
|
-
CGRect webViewBounds = self.view.bounds;
|
|
946
|
-
|
|
947
|
-
if (locationbarVisible) {
|
|
948
|
-
// locationBar at the bottom, move locationBar up
|
|
949
|
-
// put toolBar at the bottom
|
|
950
|
-
webViewBounds.size.height -= FOOTER_HEIGHT;
|
|
951
|
-
locationbarFrame.origin.y = webViewBounds.size.height;
|
|
952
|
-
self.addressLabel.frame = locationbarFrame;
|
|
953
|
-
self.toolbar.frame = toolbarFrame;
|
|
954
|
-
} else {
|
|
955
|
-
// no locationBar, so put toolBar at the bottom
|
|
956
|
-
CGRect webViewBounds = self.view.bounds;
|
|
957
|
-
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
|
958
|
-
self.toolbar.frame = toolbarFrame;
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {
|
|
962
|
-
toolbarFrame.origin.y = 0;
|
|
963
|
-
webViewBounds.origin.y += toolbarFrame.size.height;
|
|
964
|
-
[self setWebViewFrame:webViewBounds];
|
|
965
|
-
} else {
|
|
966
|
-
toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT);
|
|
967
|
-
}
|
|
968
|
-
[self setWebViewFrame:webViewBounds];
|
|
969
|
-
|
|
970
|
-
} else {
|
|
971
|
-
self.toolbar.hidden = YES;
|
|
972
|
-
|
|
973
|
-
if (locationbarVisible) {
|
|
974
|
-
// locationBar is on top of toolBar, hide toolBar
|
|
975
|
-
// put locationBar at the bottom
|
|
976
|
-
|
|
977
|
-
// webView take up whole height less locationBar height
|
|
978
|
-
CGRect webViewBounds = self.view.bounds;
|
|
979
|
-
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
|
980
|
-
[self setWebViewFrame:webViewBounds];
|
|
981
|
-
|
|
982
|
-
// move locationBar down
|
|
983
|
-
locationbarFrame.origin.y = webViewBounds.size.height;
|
|
984
|
-
self.addressLabel.frame = locationbarFrame;
|
|
985
|
-
} else {
|
|
986
|
-
// no locationBar, expand webView to screen dimensions
|
|
987
|
-
[self setWebViewFrame:self.view.bounds];
|
|
988
|
-
}
|
|
989
|
-
}
|
|
982
|
+
self.toolbar.hidden = !show;
|
|
983
|
+
_browserOptions.toolbarposition = toolbarPosition; // Keep state consistent if needed
|
|
984
|
+
[self.view setNeedsLayout];
|
|
985
|
+
[self.view layoutIfNeeded];
|
|
990
986
|
}
|
|
991
987
|
|
|
992
988
|
- (void)viewDidLoad
|
|
@@ -999,13 +995,13 @@ BOOL isExiting = FALSE;
|
|
|
999
995
|
[super viewDidDisappear:animated];
|
|
1000
996
|
if (isExiting && (self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
|
|
1001
997
|
[self.navigationDelegate browserExit];
|
|
1002
|
-
isExiting =
|
|
998
|
+
isExiting = NO;
|
|
1003
999
|
}
|
|
1004
1000
|
}
|
|
1005
1001
|
|
|
1006
1002
|
- (UIStatusBarStyle)preferredStatusBarStyle
|
|
1007
1003
|
{
|
|
1008
|
-
NSString*
|
|
1004
|
+
NSString *statusBarStylePreference = [_settings cordovaSettingForKey:@"InAppBrowserStatusBarStyle"];
|
|
1009
1005
|
if (statusBarStylePreference && [statusBarStylePreference isEqualToString:@"lightcontent"]) {
|
|
1010
1006
|
return UIStatusBarStyleLightContent;
|
|
1011
1007
|
} else if (statusBarStylePreference && [statusBarStylePreference isEqualToString:@"darkcontent"]) {
|
|
@@ -1019,19 +1015,20 @@ BOOL isExiting = FALSE;
|
|
|
1019
1015
|
}
|
|
1020
1016
|
}
|
|
1021
1017
|
|
|
1022
|
-
- (BOOL)prefersStatusBarHidden
|
|
1018
|
+
- (BOOL)prefersStatusBarHidden
|
|
1019
|
+
{
|
|
1023
1020
|
return NO;
|
|
1024
1021
|
}
|
|
1025
1022
|
|
|
1026
1023
|
- (void)close
|
|
1027
1024
|
{
|
|
1028
1025
|
self.currentURL = nil;
|
|
1029
|
-
|
|
1030
|
-
__weak UIViewController*
|
|
1031
|
-
|
|
1026
|
+
|
|
1027
|
+
__weak UIViewController *weakSelf = self;
|
|
1028
|
+
|
|
1032
1029
|
// Run later to avoid the "took a long time" log message.
|
|
1033
1030
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1034
|
-
isExiting =
|
|
1031
|
+
isExiting = YES;
|
|
1035
1032
|
lastReducedStatusBarHeight = 0.0;
|
|
1036
1033
|
if ([weakSelf respondsToSelector:@selector(presentingViewController)]) {
|
|
1037
1034
|
[[weakSelf presentingViewController] dismissViewControllerAnimated:YES completion:nil];
|
|
@@ -1041,12 +1038,12 @@ BOOL isExiting = FALSE;
|
|
|
1041
1038
|
});
|
|
1042
1039
|
}
|
|
1043
1040
|
|
|
1044
|
-
- (void)navigateTo:(NSURL*)url
|
|
1041
|
+
- (void)navigateTo:(NSURL *)url
|
|
1045
1042
|
{
|
|
1046
1043
|
if ([url.scheme isEqualToString:@"file"]) {
|
|
1047
1044
|
[self.webView loadFileURL:url allowingReadAccessToURL:url];
|
|
1048
1045
|
} else {
|
|
1049
|
-
NSURLRequest*
|
|
1046
|
+
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
|
1050
1047
|
[self.webView loadRequest:request];
|
|
1051
1048
|
}
|
|
1052
1049
|
}
|
|
@@ -1061,42 +1058,11 @@ BOOL isExiting = FALSE;
|
|
|
1061
1058
|
[self.webView goForward];
|
|
1062
1059
|
}
|
|
1063
1060
|
|
|
1064
|
-
- (void)viewWillAppear:(BOOL)animated
|
|
1065
|
-
{
|
|
1066
|
-
[self rePositionViews];
|
|
1067
|
-
|
|
1068
|
-
[super viewWillAppear:animated];
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
- (float) getStatusBarOffset {
|
|
1072
|
-
return (float) [[UIApplication sharedApplication] statusBarFrame].size.height;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
- (void) rePositionViews {
|
|
1076
|
-
CGRect viewBounds = [self.webView bounds];
|
|
1077
|
-
CGFloat statusBarHeight = [self getStatusBarOffset];
|
|
1078
|
-
|
|
1079
|
-
// orientation portrait or portraitUpsideDown: status bar is on the top and web view is to be aligned to the bottom of the status bar
|
|
1080
|
-
// orientation landscapeLeft or landscapeRight: status bar height is 0 in but lets account for it in case things ever change in the future
|
|
1081
|
-
viewBounds.origin.y = statusBarHeight;
|
|
1082
|
-
|
|
1083
|
-
// account for web view height portion that may have been reduced by a previous call to this method
|
|
1084
|
-
viewBounds.size.height = viewBounds.size.height - statusBarHeight + lastReducedStatusBarHeight;
|
|
1085
|
-
lastReducedStatusBarHeight = statusBarHeight;
|
|
1086
|
-
|
|
1087
|
-
if ((_browserOptions.toolbar) && ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop])) {
|
|
1088
|
-
// if we have to display the toolbar on top of the web view, we need to account for its height
|
|
1089
|
-
viewBounds.origin.y += TOOLBAR_HEIGHT;
|
|
1090
|
-
self.toolbar.frame = CGRectMake(self.toolbar.frame.origin.x, statusBarHeight, self.toolbar.frame.size.width, self.toolbar.frame.size.height);
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
self.webView.frame = viewBounds;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
1061
|
// Helper function to convert hex color string to UIColor
|
|
1097
1062
|
// Assumes input like "#00FF00" (#RRGGBB).
|
|
1098
1063
|
// Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
|
|
1099
|
-
- (UIColor *)colorFromHexString:(NSString *)hexString
|
|
1064
|
+
- (UIColor *)colorFromHexString:(NSString *)hexString
|
|
1065
|
+
{
|
|
1100
1066
|
unsigned rgbValue = 0;
|
|
1101
1067
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
|
1102
1068
|
[scanner setScanLocation:1]; // bypass '#' character
|
|
@@ -1106,19 +1072,14 @@ BOOL isExiting = FALSE;
|
|
|
1106
1072
|
|
|
1107
1073
|
#pragma mark WKNavigationDelegate
|
|
1108
1074
|
|
|
1109
|
-
- (void)webView:(WKWebView *)theWebView didStartProvisionalNavigation:(WKNavigation *)navigation
|
|
1110
|
-
|
|
1111
|
-
//
|
|
1112
|
-
|
|
1075
|
+
- (void)webView:(WKWebView *)theWebView didStartProvisionalNavigation:(WKNavigation *)navigation
|
|
1076
|
+
{
|
|
1077
|
+
// Loading URL, start spinner, update back/forward
|
|
1113
1078
|
self.addressLabel.text = NSLocalizedString(@"Loading...", nil);
|
|
1114
1079
|
self.backButton.enabled = theWebView.canGoBack;
|
|
1115
1080
|
self.forwardButton.enabled = theWebView.canGoForward;
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
if(!_browserOptions.hidespinner) {
|
|
1119
|
-
[self.spinner startAnimating];
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1081
|
+
|
|
1082
|
+
if (!_browserOptions.hidespinner) [self.spinner startAnimating];
|
|
1122
1083
|
return [self.navigationDelegate didStartProvisionalNavigation:theWebView];
|
|
1123
1084
|
}
|
|
1124
1085
|
|
|
@@ -1126,98 +1087,62 @@ BOOL isExiting = FALSE;
|
|
|
1126
1087
|
{
|
|
1127
1088
|
NSURL *url = navigationAction.request.URL;
|
|
1128
1089
|
NSURL *mainDocumentURL = navigationAction.request.mainDocumentURL;
|
|
1129
|
-
|
|
1090
|
+
|
|
1130
1091
|
BOOL isTopLevelNavigation = [url isEqual:mainDocumentURL];
|
|
1131
|
-
|
|
1092
|
+
|
|
1132
1093
|
if (isTopLevelNavigation) {
|
|
1133
1094
|
self.currentURL = url;
|
|
1134
1095
|
}
|
|
1135
|
-
|
|
1096
|
+
|
|
1136
1097
|
[self.navigationDelegate webView:theWebView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
|
|
1137
1098
|
}
|
|
1138
1099
|
|
|
1139
1100
|
- (void)webView:(WKWebView *)theWebView didFinishNavigation:(WKNavigation *)navigation
|
|
1140
1101
|
{
|
|
1141
|
-
//
|
|
1142
|
-
|
|
1143
|
-
self.addressLabel.text = [self.currentURL absoluteString];
|
|
1102
|
+
// Update URL, stop spinner, update back/forward
|
|
1103
|
+
self.addressLabel.text = self.currentURL.absoluteString;
|
|
1144
1104
|
self.backButton.enabled = theWebView.canGoBack;
|
|
1145
1105
|
self.forwardButton.enabled = theWebView.canGoForward;
|
|
1146
1106
|
theWebView.scrollView.contentInset = UIEdgeInsetsZero;
|
|
1147
|
-
|
|
1148
1107
|
[self.spinner stopAnimating];
|
|
1149
|
-
|
|
1150
1108
|
[self.navigationDelegate didFinishNavigation:theWebView];
|
|
1151
1109
|
}
|
|
1152
|
-
|
|
1153
|
-
- (void)webView:(WKWebView*)theWebView failedNavigation:(NSString*) delegateName withError:(nonnull NSError *)error
|
|
1154
|
-
|
|
1110
|
+
|
|
1111
|
+
- (void)webView:(WKWebView *)theWebView failedNavigation:(NSString *) delegateName withError:(nonnull NSError *)error
|
|
1112
|
+
{
|
|
1113
|
+
// Log fail message, stop spinner, update back/forward
|
|
1155
1114
|
NSLog(@"webView:%@ - %ld: %@", delegateName, (long)error.code, [error localizedDescription]);
|
|
1156
|
-
|
|
1157
1115
|
self.backButton.enabled = theWebView.canGoBack;
|
|
1158
1116
|
self.forwardButton.enabled = theWebView.canGoForward;
|
|
1159
1117
|
[self.spinner stopAnimating];
|
|
1160
|
-
|
|
1161
1118
|
self.addressLabel.text = NSLocalizedString(@"Load Error", nil);
|
|
1162
|
-
|
|
1163
1119
|
[self.navigationDelegate webView:theWebView didFailNavigation:error];
|
|
1164
1120
|
}
|
|
1165
1121
|
|
|
1166
|
-
- (void)webView:(WKWebView*)theWebView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
|
|
1122
|
+
- (void)webView:(WKWebView *)theWebView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
|
|
1167
1123
|
{
|
|
1168
1124
|
[self webView:theWebView failedNavigation:@"didFailNavigation" withError:error];
|
|
1169
1125
|
}
|
|
1170
|
-
|
|
1171
|
-
- (void)webView:(WKWebView*)theWebView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
|
|
1126
|
+
|
|
1127
|
+
- (void)webView:(WKWebView *)theWebView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
|
|
1172
1128
|
{
|
|
1173
1129
|
[self webView:theWebView failedNavigation:@"didFailProvisionalNavigation" withError:error];
|
|
1174
1130
|
}
|
|
1175
1131
|
|
|
1176
1132
|
#pragma mark WKScriptMessageHandler delegate
|
|
1177
|
-
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
|
1133
|
+
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
|
1134
|
+
{
|
|
1178
1135
|
if (![message.name isEqualToString:IAB_BRIDGE_NAME]) {
|
|
1179
1136
|
return;
|
|
1180
1137
|
}
|
|
1181
|
-
//NSLog(@"Received script message %@", message.body);
|
|
1182
1138
|
[self.navigationDelegate userContentController:userContentController didReceiveScriptMessage:message];
|
|
1183
1139
|
}
|
|
1184
1140
|
|
|
1185
|
-
#pragma mark CDVScreenOrientationDelegate
|
|
1186
|
-
|
|
1187
|
-
- (BOOL)shouldAutorotate
|
|
1188
|
-
{
|
|
1189
|
-
if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) {
|
|
1190
|
-
return [self.orientationDelegate shouldAutorotate];
|
|
1191
|
-
}
|
|
1192
|
-
return YES;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
|
1196
|
-
{
|
|
1197
|
-
if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {
|
|
1198
|
-
return [self.orientationDelegate supportedInterfaceOrientations];
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
return 1 << UIInterfaceOrientationPortrait;
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
|
1205
|
-
{
|
|
1206
|
-
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
|
|
1207
|
-
{
|
|
1208
|
-
[self rePositionViews];
|
|
1209
|
-
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
|
|
1210
|
-
{
|
|
1211
|
-
|
|
1212
|
-
}];
|
|
1213
|
-
|
|
1214
|
-
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
1141
|
#pragma mark UIAdaptivePresentationControllerDelegate
|
|
1218
1142
|
|
|
1219
|
-
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
|
|
1220
|
-
|
|
1143
|
+
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
|
|
1144
|
+
{
|
|
1145
|
+
isExiting = YES;
|
|
1221
1146
|
}
|
|
1222
1147
|
|
|
1223
|
-
@end //CDVWKInAppBrowserViewController
|
|
1148
|
+
@end // CDVWKInAppBrowserViewController
|