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.
@@ -1,25 +1,32 @@
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
- */
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
- #import <Cordova/NSDictionary+CordovaPreferences.h>
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) isSystemUrl:(NSURL*)url
67
+ - (BOOL)isSystemUrl:(NSURL *)url
73
68
  {
74
- if ([[url host] isEqualToString:@"itunes.apple.com"]) {
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* pluginResult;
84
-
85
- NSString* url = [command argumentAtIndex:0];
86
- NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf];
87
- NSString* options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]];
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* baseUrl = [self.webViewEngine URL];
93
- NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL];
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 setKeepCallback:[NSNumber numberWithBool:YES]];
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* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
119
-
120
- WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
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
- self.inAppBrowserViewController.webView.configuration.processPool = [[WKProcessPool alloc] init]; // create new process pool to flush all data
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* cookieStore = dataStore.httpCookieStore;
133
- [cookieStore getAllCookies:^(NSArray* cookies) {
134
- NSHTTPCookie* cookie;
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* cookieStore = dataStore.httpCookieStore;
144
- [cookieStore getAllCookies:^(NSArray* cookies) {
145
- NSHTTPCookie* cookie;
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
- //prevent webView from bouncing
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
- // use of beforeload event
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* nav = [[CDVInAppBrowserNavigationController alloc]
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* weakSelf = self;
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
- CGRect frame = [[UIScreen mainScreen] bounds];
250
- if(initHidden && osVersion < 11){
251
- frame.origin.x = -10000;
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 webview responsive to touch again
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* request = [NSURLRequest requestWithURL:url];
292
- // the webview engine itself will filter for this according to <allow-navigation> policy
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* urlStr = [command argumentAtIndex:0];
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* url = [NSURL URLWithString:urlStr];
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* jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil];
344
- NSString* sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
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* sourceString = [sourceArrayString substringWithRange:NSMakeRange(1, [sourceArrayString length] - 2)];
347
- NSString* jsToInject = [NSString stringWithFormat:jsWrapper, sourceString];
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
- //Synchronus helper for javascript evaluation
357
- - (void)evaluateJavaScript:(NSString *)script {
358
- __block NSString* _script = script;
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* jsWrapper = nil;
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* jsWrapper;
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* jsWrapper;
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* jsWrapper;
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', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)";
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)isValidCallbackId:(NSString *)callbackId
421
+ - (BOOL)isAllowedScheme:(NSString *)scheme
417
422
  {
418
- NSError *err = nil;
419
- // Initialize on first use
420
- if (self.callbackIdPattern == nil) {
421
- self.callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@"^InAppBrowser[0-9]{1,10}$" options:0 error:&err];
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
- if ([self.callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) {
428
- return YES;
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* url = navigationAction.request.URL;
441
- NSURL* mainDocumentURL = navigationAction.request.mainDocumentURL;
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* httpMethod = navigationAction.request.HTTPMethod;
446
- NSString* errorMessage = nil;
447
-
448
- if([_beforeload isEqualToString:@"post"]){
449
- //TODO handle POST requests by preserving POST data then remove this condition
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
- else if(isTopLevelNavigation && (
453
- [_beforeload isEqualToString:@"yes"]
454
- || ([_beforeload isEqualToString:@"get"] && [httpMethod isEqualToString:@"GET"])
455
- // TODO comment in when POST requests are handled
456
- // || ([_beforeload isEqualToString:@"post"] && [httpMethod isEqualToString:@"POST"])
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
464
- messageAsDictionary:@{@"type":@"beforeload", @"url":[url absoluteString]}];
465
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
475
- messageAsDictionary:@{@"type":@"loaderror", @"url":[url absoluteString], @"code": @"-1", @"message": errorMessage}];
476
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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
- //if is an app store, tel, sms, mailto or geo link, let the system handle it, otherwise it fails to load it
481
- NSArray * allowedSchemes = @[@"itms-appss", @"itms-apps", @"tel", @"sms", @"mailto", @"geo"];
482
- if ([allowedSchemes containsObject:[url scheme]]) {
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
- else if ((self.callbackId != nil) && isTopLevelNavigation) {
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
490
- messageAsDictionary:@{@"type":@"loadstart", @"url":[url absoluteString]}];
491
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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* pluginResult = nil;
518
-
519
- if([message.body isKindOfClass:[NSDictionary class]]){
520
- NSDictionary* messageContent = (NSDictionary*) message.body;
521
- NSString* scriptCallbackId = messageContent[@"id"];
522
-
523
- if([messageContent objectForKey:@"d"]){
524
- NSString* scriptResult = messageContent[@"d"];
525
- NSError* __autoreleasing error = nil;
526
- NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
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* messageContent = (NSString*) message.body;
539
- NSError* __autoreleasing error = nil;
540
- NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[messageContent dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
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* dResult = [NSMutableDictionary new];
552
+ NSMutableDictionary *dResult = [NSMutableDictionary new];
543
553
  [dResult setValue:@"message" forKey:@"type"];
544
554
  [dResult setObject:decodedResult forKey:@"data"];
545
- CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dResult];
546
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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* url = [theWebView.URL absoluteString];
562
- if(url == nil){
563
- if(self.inAppBrowserViewController.currentURL != nil){
564
- url = [self.inAppBrowserViewController.currentURL absoluteString];
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
578
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
570
579
  messageAsDictionary:@{@"type":@"loadstop", @"url":url}];
571
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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* url = [theWebView.URL absoluteString];
581
- if(url == nil){
582
- if(self.inAppBrowserViewController.currentURL != nil){
583
- url = [self.inAppBrowserViewController.currentURL absoluteString];
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
597
+ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
589
598
  messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}];
590
- [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
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* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
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 webview responsive to touch again
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 = FALSE;
642
+ BOOL isExiting = NO;
634
643
 
635
- - (id)initWithBrowserOptions: (CDVInAppBrowserOptions*) browserOptions andSettings:(NSDictionary *)settings
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
- -(void)dealloc {
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
- CGRect webViewBounds = self.view.bounds;
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
- if (
667
- [self settingForKey:@"OverrideUserAgent"] == nil &&
668
- [self settingForKey:@"AppendUserAgent"] != nil
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
- configuration.processPool = [[CDVWebViewProcessPoolFactory sharedFactory] sharedProcessPool];
676
- #elif __has_include("CDVWKProcessPoolFactory.h")
677
- configuration.processPool = [[CDVWKProcessPoolFactory sharedFactory] sharedProcessPool];
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
- if(_browserOptions.mediaplaybackrequiresuseraction == YES){
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 = [self settingForKey:@"PreferredContentMode"];
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:webViewBounds configuration:configuration];
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 webview is no longer inspectable by default.
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.navigationDelegate = self;
723
- self.webView.UIDelegate = self.webViewUIDelegate;
724
- self.webView.backgroundColor = [UIColor whiteColor];
725
- if ([self settingForKey:@"OverrideUserAgent"] != nil) {
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.autoresizesSubviews = YES;
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
- self.toolbar.barTintColor = [self colorFromHexString:_browserOptions.toolbarcolor];
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
- self.toolbar.translucent = NO;
746
+ self.toolbar.translucent = NO;
785
747
  }
786
-
787
- CGFloat labelInset = 5.0;
788
- float locationBarY = toolbarIsAtBottom ? self.view.bounds.size.height - FOOTER_HEIGHT : self.view.bounds.size.height - LOCATIONBAR_HEIGHT;
789
-
790
- self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, locationBarY, self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)];
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
- NSString* frontArrowString = NSLocalizedString(@"►", nil); // create arrow from Unicode char
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
- self.forwardButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
810
+ self.forwardButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
825
811
  }
826
812
 
827
- NSString* backArrowString = NSLocalizedString(@"◄", nil); // create arrow from Unicode char
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
- self.backButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
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
- - (id)settingForKey:(NSString*)key
855
- {
856
- return [_settings objectForKey:[key lowercaseString]];
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) setWebViewFrame : (CGRect) frame {
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 : (NSString*) colorString : (int) buttonIndex
957
+ - (void)setCloseButtonTitle:(NSString *)title withColor:(NSString *)colorString atIndex:(int)buttonIndex
865
958
  {
866
- // the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically
867
- // 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)
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* items = [self.toolbar.items mutableCopy];
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
- CGRect locationbarFrame = self.addressLabel.frame;
883
-
884
- BOOL toolbarVisible = !self.toolbar.hidden;
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 : (NSString *) toolbarPosition
980
+ - (void)showToolBar:(BOOL)show atPosition:(NSString *)toolbarPosition
932
981
  {
933
- CGRect toolbarFrame = self.toolbar.frame;
934
- CGRect locationbarFrame = self.addressLabel.frame;
935
-
936
- BOOL locationbarVisible = !self.addressLabel.hidden;
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 = FALSE;
998
+ isExiting = NO;
1003
999
  }
1004
1000
  }
1005
1001
 
1006
1002
  - (UIStatusBarStyle)preferredStatusBarStyle
1007
1003
  {
1008
- NSString* statusBarStylePreference = [self settingForKey:@"InAppBrowserStatusBarStyle"];
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* weakSelf = self;
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 = TRUE;
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* request = [NSURLRequest requestWithURL:url];
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
- // loading url, start spinner, update back/forward
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
- NSLog(_browserOptions.hidespinner ? @"Yes" : @"No");
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
- // update url, stop spinner, update back/forward
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
- // log fail message, stop spinner, update back/forward
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
- isExiting = TRUE;
1143
+ - (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
1144
+ {
1145
+ isExiting = YES;
1221
1146
  }
1222
1147
 
1223
- @end //CDVWKInAppBrowserViewController
1148
+ @end // CDVWKInAppBrowserViewController