@capgo/inappbrowser 7.10.0 → 7.10.3

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/Package.swift CHANGED
@@ -10,14 +10,14 @@ let package = Package(
10
10
  targets: ["InappbrowserPlugin"])
11
11
  ],
12
12
  dependencies: [
13
- .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.2.0"),
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.2.0")
14
14
  ],
15
15
  targets: [
16
16
  .target(
17
17
  name: "InappbrowserPlugin",
18
18
  dependencies: [
19
19
  .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
- .product(name: "Cordova", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
21
  ],
22
22
  path: "ios/Sources/InappbrowserPlugin"),
23
23
  .testTarget(
@@ -251,6 +251,7 @@ public class InAppBrowserPlugin
251
251
  String url = call.getString("url");
252
252
  if (url == null || TextUtils.isEmpty(url)) {
253
253
  call.reject("Invalid URL");
254
+ return;
254
255
  }
255
256
  currentUrl = url;
256
257
  this.getActivity()
@@ -258,11 +259,15 @@ public class InAppBrowserPlugin
258
259
  new Runnable() {
259
260
  @Override
260
261
  public void run() {
261
- webViewDialog.setUrl(url);
262
+ if (webViewDialog != null) {
263
+ webViewDialog.setUrl(url);
264
+ call.resolve();
265
+ } else {
266
+ call.reject("WebView is not initialized");
267
+ }
262
268
  }
263
269
  }
264
270
  );
265
- call.resolve();
266
271
  }
267
272
 
268
273
  @PluginMethod
@@ -396,12 +401,15 @@ public class InAppBrowserPlugin
396
401
  new Runnable() {
397
402
  @Override
398
403
  public void run() {
399
- webViewDialog.executeScript(scriptToRun.toString());
404
+ if (webViewDialog != null) {
405
+ webViewDialog.executeScript(scriptToRun.toString());
406
+ call.resolve();
407
+ } else {
408
+ call.reject("WebView is not initialized");
409
+ }
400
410
  }
401
411
  }
402
412
  );
403
-
404
- call.resolve();
405
413
  }
406
414
 
407
415
  @PluginMethod
@@ -409,22 +417,21 @@ public class InAppBrowserPlugin
409
417
  String url = call.getString("url");
410
418
  if (url == null || TextUtils.isEmpty(url)) {
411
419
  call.reject("Invalid URL");
412
- } else {
413
- CookieManager cookieManager = CookieManager.getInstance();
414
- String cookieString = cookieManager.getCookie(url);
415
- if (cookieString != null) {
416
- String[] cookiePairs = cookieString.split("; ");
417
- JSObject result = new JSObject();
418
- for (String cookie : cookiePairs) {
419
- String[] parts = cookie.split("=", 2);
420
- if (parts.length == 2) {
421
- result.put(parts[0], parts[1]);
422
- }
420
+ return;
421
+ }
422
+ CookieManager cookieManager = CookieManager.getInstance();
423
+ String cookieString = cookieManager.getCookie(url);
424
+ JSObject result = new JSObject();
425
+ if (cookieString != null) {
426
+ String[] cookiePairs = cookieString.split("; ");
427
+ for (String cookie : cookiePairs) {
428
+ String[] parts = cookie.split("=", 2);
429
+ if (parts.length == 2) {
430
+ result.put(parts[0], parts[1]);
423
431
  }
424
- call.resolve(result);
425
432
  }
426
- call.resolve(new JSObject());
427
433
  }
434
+ call.resolve(result);
428
435
  }
429
436
 
430
437
  @PluginMethod
@@ -753,8 +760,12 @@ public class InAppBrowserPlugin
753
760
  new Runnable() {
754
761
  @Override
755
762
  public void run() {
756
- webViewDialog.postMessageToJS(eventData);
757
- call.resolve();
763
+ if (webViewDialog != null) {
764
+ webViewDialog.postMessageToJS(eventData);
765
+ call.resolve();
766
+ } else {
767
+ call.reject("WebView is not initialized");
768
+ }
758
769
  }
759
770
  }
760
771
  );
@@ -765,37 +776,40 @@ public class InAppBrowserPlugin
765
776
  String script = call.getString("code");
766
777
  if (script == null || TextUtils.isEmpty(script)) {
767
778
  call.reject("No script to run");
779
+ return;
768
780
  }
769
-
770
- if (webViewDialog != null) {
771
- this.getActivity()
772
- .runOnUiThread(
773
- new Runnable() {
774
- @Override
775
- public void run() {
781
+ this.getActivity()
782
+ .runOnUiThread(
783
+ new Runnable() {
784
+ @Override
785
+ public void run() {
786
+ if (webViewDialog != null) {
776
787
  webViewDialog.executeScript(script);
788
+ call.resolve();
789
+ } else {
790
+ call.reject("WebView is not initialized");
777
791
  }
778
792
  }
779
- );
780
- }
781
-
782
- call.resolve();
793
+ }
794
+ );
783
795
  }
784
796
 
785
797
  @PluginMethod
786
798
  public void reload(PluginCall call) {
787
- if (webViewDialog != null) {
788
- this.getActivity()
789
- .runOnUiThread(
790
- new Runnable() {
791
- @Override
792
- public void run() {
799
+ this.getActivity()
800
+ .runOnUiThread(
801
+ new Runnable() {
802
+ @Override
803
+ public void run() {
804
+ if (webViewDialog != null) {
793
805
  webViewDialog.reload();
806
+ call.resolve();
807
+ } else {
808
+ call.reject("WebView is not initialized");
794
809
  }
795
810
  }
796
- );
797
- }
798
- call.resolve();
811
+ }
812
+ );
799
813
  }
800
814
 
801
815
  @PluginMethod
@@ -826,9 +840,10 @@ public class InAppBrowserPlugin
826
840
  @Override
827
841
  public void run() {
828
842
  if (webViewDialog != null) {
843
+ String currentUrl = webViewDialog.getUrl();
829
844
  notifyListeners(
830
845
  "closeEvent",
831
- new JSObject().put("url", webViewDialog.getUrl())
846
+ new JSObject().put("url", currentUrl)
832
847
  );
833
848
  webViewDialog.dismiss();
834
849
  webViewDialog = null;
@@ -948,7 +948,7 @@ public class WebViewDialog extends Dialog {
948
948
  }
949
949
  }
950
950
 
951
- // Apply system insets to WebView (compatible with all Android versions)
951
+ // Apply system insets to WebView content view (compatible with all Android versions)
952
952
  ViewCompat.setOnApplyWindowInsetsListener(_webView, (v, windowInsets) -> {
953
953
  Insets insets = windowInsets.getInsets(
954
954
  WindowInsetsCompat.Type.systemBars()
@@ -971,9 +971,13 @@ public class WebViewDialog extends Dialog {
971
971
  // On Android 15+, don't add top margin as it's handled by AppBarLayout
972
972
  mlp.topMargin = 0;
973
973
  } else {
974
- // Original behavior for older Android versions
975
- mlp.topMargin = insets.top;
976
- mlp.bottomMargin = insets.bottom;
974
+ // For all other Android versions, ensure bottom margin respects navigation bar
975
+ mlp.topMargin = 0; // Top is handled by toolbar
976
+ if (keyboardVisible) {
977
+ mlp.bottomMargin = 0;
978
+ } else {
979
+ mlp.bottomMargin = insets.bottom;
980
+ }
977
981
  }
978
982
 
979
983
  // These stay the same for all Android versions
@@ -984,41 +988,44 @@ public class WebViewDialog extends Dialog {
984
988
  return WindowInsetsCompat.CONSUMED;
985
989
  });
986
990
 
987
- // Handle window decoration - version-specific window settings
991
+ // Handle window decoration - version-specific handling
988
992
  if (getWindow() != null) {
989
993
  if (isAndroid15Plus) {
990
- // Only for Android 15+: Set window to draw behind status bar
994
+ // Android 15+: Use edge-to-edge with proper insets handling
991
995
  getWindow().setDecorFitsSystemWindows(false);
992
996
  getWindow().setStatusBarColor(Color.TRANSPARENT);
997
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
998
+
999
+ WindowInsetsControllerCompat controller =
1000
+ new WindowInsetsControllerCompat(
1001
+ getWindow(),
1002
+ getWindow().getDecorView()
1003
+ );
993
1004
 
994
1005
  // Set status bar text color
995
- int backgroundColor;
996
1006
  if (
997
1007
  _options.getToolbarColor() != null &&
998
1008
  !_options.getToolbarColor().isEmpty()
999
1009
  ) {
1000
1010
  try {
1001
- backgroundColor = Color.parseColor(_options.getToolbarColor());
1011
+ int backgroundColor = Color.parseColor(_options.getToolbarColor());
1002
1012
  boolean isDarkBackground = isDarkColor(backgroundColor);
1003
- WindowInsetsControllerCompat controller =
1004
- new WindowInsetsControllerCompat(
1005
- getWindow(),
1006
- getWindow().getDecorView()
1007
- );
1008
1013
  controller.setAppearanceLightStatusBars(!isDarkBackground);
1009
1014
  } catch (IllegalArgumentException e) {
1010
1015
  // Ignore color parsing errors
1011
1016
  }
1012
1017
  }
1013
1018
  } else if (Build.VERSION.SDK_INT >= 30) {
1014
- // Android 11-14: Use original behavior
1019
+ // Android 11-14: Keep navigation bar transparent but respect status bar
1020
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
1021
+
1015
1022
  WindowInsetsControllerCompat controller =
1016
1023
  new WindowInsetsControllerCompat(
1017
1024
  getWindow(),
1018
1025
  getWindow().getDecorView()
1019
1026
  );
1020
1027
 
1021
- // Original behavior for status bar color
1028
+ // Set status bar color to match toolbar or use system default
1022
1029
  if (
1023
1030
  _options.getToolbarColor() != null &&
1024
1031
  !_options.getToolbarColor().isEmpty()
@@ -1026,23 +1033,34 @@ public class WebViewDialog extends Dialog {
1026
1033
  try {
1027
1034
  int toolbarColor = Color.parseColor(_options.getToolbarColor());
1028
1035
  getWindow().setStatusBarColor(toolbarColor);
1029
-
1030
1036
  boolean isDarkBackground = isDarkColor(toolbarColor);
1031
1037
  controller.setAppearanceLightStatusBars(!isDarkBackground);
1032
1038
  } catch (IllegalArgumentException e) {
1033
- // Ignore color parsing errors
1039
+ // Follow system theme if color parsing fails
1040
+ boolean isDarkTheme = isDarkThemeEnabled();
1041
+ int statusBarColor = isDarkTheme ? Color.BLACK : Color.WHITE;
1042
+ getWindow().setStatusBarColor(statusBarColor);
1043
+ controller.setAppearanceLightStatusBars(!isDarkTheme);
1034
1044
  }
1045
+ } else {
1046
+ // Follow system theme if no toolbar color provided
1047
+ boolean isDarkTheme = isDarkThemeEnabled();
1048
+ int statusBarColor = isDarkTheme ? Color.BLACK : Color.WHITE;
1049
+ getWindow().setStatusBarColor(statusBarColor);
1050
+ controller.setAppearanceLightStatusBars(!isDarkTheme);
1035
1051
  }
1036
1052
  } else {
1037
- // Pre-Android 11: Original behavior with deprecated flags
1053
+ // Pre-Android 11: Use deprecated flags for edge-to-edge navigation bar only
1038
1054
  getWindow()
1039
1055
  .getDecorView()
1040
1056
  .setSystemUiVisibility(
1041
1057
  View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
1042
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1058
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
1043
1059
  );
1044
1060
 
1045
- // Apply original status bar color logic
1061
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
1062
+
1063
+ // Set status bar color to match toolbar
1046
1064
  if (
1047
1065
  _options.getToolbarColor() != null &&
1048
1066
  !_options.getToolbarColor().isEmpty()
@@ -1051,7 +1069,7 @@ public class WebViewDialog extends Dialog {
1051
1069
  int toolbarColor = Color.parseColor(_options.getToolbarColor());
1052
1070
  getWindow().setStatusBarColor(toolbarColor);
1053
1071
  } catch (IllegalArgumentException e) {
1054
- // Ignore color parsing errors
1072
+ // Use system default
1055
1073
  }
1056
1074
  }
1057
1075
  }
@@ -1068,7 +1086,11 @@ public class WebViewDialog extends Dialog {
1068
1086
  "window.dispatchEvent(new CustomEvent('messageFromNative', " +
1069
1087
  jsonDetail +
1070
1088
  "));";
1071
- _webView.post(() -> _webView.evaluateJavascript(script, null));
1089
+ _webView.post(() -> {
1090
+ if (_webView != null) {
1091
+ _webView.evaluateJavascript(script, null);
1092
+ }
1093
+ });
1072
1094
  } catch (Exception e) {
1073
1095
  Log.e(
1074
1096
  "postMessageToJS",
@@ -1079,6 +1101,9 @@ public class WebViewDialog extends Dialog {
1079
1101
  }
1080
1102
 
1081
1103
  private void injectJavaScriptInterface() {
1104
+ if (_webView == null) {
1105
+ return;
1106
+ }
1082
1107
  String script =
1083
1108
  "if (!window.mobileApp) { " +
1084
1109
  " window.mobileApp = { " +
@@ -1126,7 +1151,14 @@ public class WebViewDialog extends Dialog {
1126
1151
  new Runnable() {
1127
1152
  @Override
1128
1153
  public void run() {
1129
- _webView.evaluateJavascript(script, null);
1154
+ if (_webView != null) {
1155
+ _webView.evaluateJavascript(script, null);
1156
+ } else {
1157
+ // If WebView is null, release semaphore to prevent deadlock
1158
+ if (preShowSemaphore != null) {
1159
+ preShowSemaphore.release();
1160
+ }
1161
+ }
1130
1162
  }
1131
1163
  }
1132
1164
  );
@@ -1317,36 +1349,45 @@ public class WebViewDialog extends Dialog {
1317
1349
  }
1318
1350
 
1319
1351
  public void reload() {
1320
- if (_webView != null) {
1321
- // First stop any ongoing loading
1322
- _webView.stopLoading();
1323
-
1324
- // Check if there's a URL to reload
1325
- if (_webView.getUrl() != null) {
1326
- // Reload the current page
1327
- _webView.reload();
1328
- Log.d("InAppBrowser", "Reloading page: " + _webView.getUrl());
1329
- } else if (_options != null && _options.getUrl() != null) {
1330
- // If webView URL is null but we have an initial URL, load that
1331
- setUrl(_options.getUrl());
1332
- Log.d("InAppBrowser", "Loading initial URL: " + _options.getUrl());
1333
- }
1352
+ if (_webView == null) {
1353
+ return;
1354
+ }
1355
+ // First stop any ongoing loading
1356
+ _webView.stopLoading();
1357
+
1358
+ // Check if there's a URL to reload
1359
+ String currentUrl = _webView.getUrl();
1360
+ if (currentUrl != null) {
1361
+ // Reload the current page
1362
+ _webView.reload();
1363
+ Log.d("InAppBrowser", "Reloading page: " + currentUrl);
1364
+ } else if (_options != null && _options.getUrl() != null) {
1365
+ // If webView URL is null but we have an initial URL, load that
1366
+ setUrl(_options.getUrl());
1367
+ Log.d("InAppBrowser", "Loading initial URL: " + _options.getUrl());
1334
1368
  }
1335
1369
  }
1336
1370
 
1337
1371
  public void destroy() {
1338
- _webView.destroy();
1372
+ if (_webView != null) {
1373
+ _webView.destroy();
1374
+ }
1339
1375
  }
1340
1376
 
1341
1377
  public String getUrl() {
1342
- return _webView.getUrl();
1378
+ return _webView != null ? _webView.getUrl() : "";
1343
1379
  }
1344
1380
 
1345
1381
  public void executeScript(String script) {
1346
- _webView.evaluateJavascript(script, null);
1382
+ if (_webView != null) {
1383
+ _webView.evaluateJavascript(script, null);
1384
+ }
1347
1385
  }
1348
1386
 
1349
1387
  public void setUrl(String url) {
1388
+ if (_webView == null) {
1389
+ return;
1390
+ }
1350
1391
  Map<String, String> requestHeaders = new HashMap<>();
1351
1392
  if (_options.getHeaders() != null) {
1352
1393
  Iterator<String> keys = _options.getHeaders().keys();
@@ -1496,10 +1537,11 @@ public class WebViewDialog extends Dialog {
1496
1537
  _webView.stopLoading();
1497
1538
 
1498
1539
  // Check if there's a URL to reload
1499
- if (_webView.getUrl() != null) {
1540
+ String currentUrl = _webView.getUrl();
1541
+ if (currentUrl != null) {
1500
1542
  // Reload the current page
1501
1543
  _webView.reload();
1502
- Log.d("InAppBrowser", "Reloading page: " + _webView.getUrl());
1544
+ Log.d("InAppBrowser", "Reloading page: " + currentUrl);
1503
1545
  } else if (_options.getUrl() != null) {
1504
1546
  // If webView URL is null but we have an initial URL, load that
1505
1547
  setUrl(_options.getUrl());
@@ -1944,6 +1986,9 @@ public class WebViewDialog extends Dialog {
1944
1986
  WebView view,
1945
1987
  WebResourceRequest request
1946
1988
  ) {
1989
+ if (view == null || _webView == null) {
1990
+ return false;
1991
+ }
1947
1992
  Context context = view.getContext();
1948
1993
  String url = request.getUrl().toString();
1949
1994
  Log.d("InAppBrowser", "shouldOverrideUrlLoading: " + url);
@@ -1997,6 +2042,9 @@ public class WebViewDialog extends Dialog {
1997
2042
  WebView view,
1998
2043
  WebResourceRequest request
1999
2044
  ) {
2045
+ if (view == null || _webView == null) {
2046
+ return null;
2047
+ }
2000
2048
  Pattern pattern = _options.getProxyRequestsPattern();
2001
2049
  if (pattern == null) {
2002
2050
  return null;
@@ -2078,6 +2126,12 @@ public class WebViewDialog extends Dialog {
2078
2126
  String host,
2079
2127
  String realm
2080
2128
  ) {
2129
+ if (view == null || _webView == null) {
2130
+ if (handler != null) {
2131
+ handler.cancel();
2132
+ }
2133
+ return;
2134
+ }
2081
2135
  final String sourceUrl = _options.getUrl();
2082
2136
  final String url = view.getUrl();
2083
2137
  final JSObject credentials = _options.getCredentials();
@@ -2141,12 +2195,18 @@ public class WebViewDialog extends Dialog {
2141
2195
 
2142
2196
  @Override
2143
2197
  public void onLoadResource(WebView view, String url) {
2198
+ if (view == null || _webView == null) {
2199
+ return;
2200
+ }
2144
2201
  super.onLoadResource(view, url);
2145
2202
  }
2146
2203
 
2147
2204
  @Override
2148
2205
  public void onPageStarted(WebView view, String url, Bitmap favicon) {
2149
2206
  super.onPageStarted(view, url, favicon);
2207
+ if (view == null || _webView == null) {
2208
+ return;
2209
+ }
2150
2210
  try {
2151
2211
  URI uri = new URI(url);
2152
2212
  if (TextUtils.isEmpty(_options.getTitle())) {
@@ -2162,6 +2222,9 @@ public class WebViewDialog extends Dialog {
2162
2222
  String url,
2163
2223
  boolean isReload
2164
2224
  ) {
2225
+ if (view == null || _webView == null) {
2226
+ return;
2227
+ }
2165
2228
  if (!isReload) {
2166
2229
  _options.getCallbacks().urlChangeEvent(url);
2167
2230
  }
@@ -2172,6 +2235,9 @@ public class WebViewDialog extends Dialog {
2172
2235
  @Override
2173
2236
  public void onPageFinished(WebView view, String url) {
2174
2237
  super.onPageFinished(view, url);
2238
+ if (view == null || _webView == null) {
2239
+ return;
2240
+ }
2175
2241
  if (!isInitialized) {
2176
2242
  isInitialized = true;
2177
2243
  _webView.clearHistory();
@@ -2223,10 +2289,20 @@ public class WebViewDialog extends Dialog {
2223
2289
  }
2224
2290
 
2225
2291
  ImageButton backButton = _toolbar.findViewById(R.id.backButton);
2226
- if (_webView.canGoBack()) {
2292
+ if (_webView != null && _webView.canGoBack()) {
2227
2293
  backButton.setImageResource(R.drawable.arrow_back_enabled);
2228
2294
  backButton.setEnabled(true);
2229
2295
  backButton.setColorFilter(iconColor);
2296
+ backButton.setOnClickListener(
2297
+ new View.OnClickListener() {
2298
+ @Override
2299
+ public void onClick(View view) {
2300
+ if (_webView != null && _webView.canGoBack()) {
2301
+ _webView.goBack();
2302
+ }
2303
+ }
2304
+ }
2305
+ );
2230
2306
  } else {
2231
2307
  backButton.setImageResource(R.drawable.arrow_back_disabled);
2232
2308
  backButton.setEnabled(false);
@@ -2241,10 +2317,20 @@ public class WebViewDialog extends Dialog {
2241
2317
  }
2242
2318
 
2243
2319
  ImageButton forwardButton = _toolbar.findViewById(R.id.forwardButton);
2244
- if (_webView.canGoForward()) {
2320
+ if (_webView != null && _webView.canGoForward()) {
2245
2321
  forwardButton.setImageResource(R.drawable.arrow_forward_enabled);
2246
2322
  forwardButton.setEnabled(true);
2247
2323
  forwardButton.setColorFilter(iconColor);
2324
+ forwardButton.setOnClickListener(
2325
+ new View.OnClickListener() {
2326
+ @Override
2327
+ public void onClick(View view) {
2328
+ if (_webView != null && _webView.canGoForward()) {
2329
+ _webView.goForward();
2330
+ }
2331
+ }
2332
+ }
2333
+ );
2248
2334
  } else {
2249
2335
  forwardButton.setImageResource(R.drawable.arrow_forward_disabled);
2250
2336
  forwardButton.setEnabled(false);
@@ -2269,6 +2355,9 @@ public class WebViewDialog extends Dialog {
2269
2355
  WebResourceError error
2270
2356
  ) {
2271
2357
  super.onReceivedError(view, request, error);
2358
+ if (view == null || _webView == null) {
2359
+ return;
2360
+ }
2272
2361
  _options.getCallbacks().pageLoadError();
2273
2362
  }
2274
2363
 
@@ -2279,6 +2368,12 @@ public class WebViewDialog extends Dialog {
2279
2368
  SslErrorHandler handler,
2280
2369
  SslError error
2281
2370
  ) {
2371
+ if (view == null || _webView == null) {
2372
+ if (handler != null) {
2373
+ handler.cancel();
2374
+ }
2375
+ return;
2376
+ }
2282
2377
  boolean ignoreSSLUntrustedError = _options.ignoreUntrustedSSLError();
2283
2378
  if (
2284
2379
  ignoreSSLUntrustedError &&
@@ -2295,14 +2390,18 @@ public class WebViewDialog extends Dialog {
2295
2390
  @Override
2296
2391
  public void onBackPressed() {
2297
2392
  if (
2393
+ _webView != null &&
2298
2394
  _webView.canGoBack() &&
2299
2395
  (TextUtils.equals(_options.getToolbarType(), "navigation") ||
2300
2396
  _options.getActiveNativeNavigationForWebview())
2301
2397
  ) {
2302
2398
  _webView.goBack();
2303
2399
  } else if (!_options.getDisableGoBackOnNativeApplication()) {
2304
- _options.getCallbacks().closeEvent(_webView.getUrl());
2305
- _webView.destroy();
2400
+ String currentUrl = _webView != null ? _webView.getUrl() : "";
2401
+ _options.getCallbacks().closeEvent(currentUrl);
2402
+ if (_webView != null) {
2403
+ _webView.destroy();
2404
+ }
2306
2405
  super.onBackPressed();
2307
2406
  }
2308
2407
  }
@@ -2488,7 +2587,11 @@ public class WebViewDialog extends Dialog {
2488
2587
  })();""";
2489
2588
 
2490
2589
  // Execute the script in the WebView
2491
- _webView.post(() -> _webView.evaluateJavascript(script, null));
2590
+ _webView.post(() -> {
2591
+ if (_webView != null) {
2592
+ _webView.evaluateJavascript(script, null);
2593
+ }
2594
+ });
2492
2595
 
2493
2596
  Log.d("InAppBrowser", "Applied minimal date picker fixes");
2494
2597
  }
@@ -369,14 +369,14 @@ public class InAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
369
369
  }
370
370
 
371
371
  if self.bridge?.statusBarVisible == true {
372
- let subviews = self.bridge?.webView?.superview?.subviews
373
- if let emptyStatusBarIndex = subviews?.firstIndex(where: { $0.subviews.isEmpty }) {
374
- if let emptyStatusBar = subviews?[emptyStatusBarIndex] {
375
- webViewController.capacitorStatusBar = emptyStatusBar
376
- emptyStatusBar.removeFromSuperview()
377
- }
378
- }
379
- }
372
+ let subviews = self.bridge?.webView?.superview?.subviews
373
+ if let emptyStatusBarIndex = subviews?.firstIndex(where: { $0.subviews.isEmpty }) {
374
+ if let emptyStatusBar = subviews?[emptyStatusBarIndex] {
375
+ webViewController.capacitorStatusBar = emptyStatusBar
376
+ emptyStatusBar.removeFromSuperview()
377
+ }
378
+ }
379
+ }
380
380
 
381
381
  webViewController.source = .remote(url)
382
382
  webViewController.leftNavigationBarItemTypes = []
@@ -697,14 +697,14 @@ public class InAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
697
697
  }
698
698
 
699
699
  if self.bridge?.statusBarVisible == true {
700
- let subviews = self.bridge?.webView?.superview?.subviews
701
- if let emptyStatusBarIndex = subviews?.firstIndex(where: { $0.subviews.isEmpty }) {
702
- if let emptyStatusBar = subviews?[emptyStatusBarIndex] {
703
- webViewController.capacitorStatusBar = emptyStatusBar
704
- emptyStatusBar.removeFromSuperview()
705
- }
706
- }
707
- }
700
+ let subviews = self.bridge?.webView?.superview?.subviews
701
+ if let emptyStatusBarIndex = subviews?.firstIndex(where: { $0.subviews.isEmpty }) {
702
+ if let emptyStatusBar = subviews?[emptyStatusBarIndex] {
703
+ webViewController.capacitorStatusBar = emptyStatusBar
704
+ emptyStatusBar.removeFromSuperview()
705
+ }
706
+ }
707
+ }
708
708
 
709
709
  webViewController.source = .remote(url)
710
710
  webViewController.leftNavigationBarItemTypes = [.back, .forward, .reload]
@@ -277,9 +277,9 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
277
277
  // Check if custom image is provided
278
278
  if let image = activityBarButtonItemImage {
279
279
  let button = UIBarButtonItem(image: image.withRenderingMode(.alwaysTemplate),
280
- style: .plain,
281
- target: self,
282
- action: #selector(activityDidClick(sender:)))
280
+ style: .plain,
281
+ target: self,
282
+ action: #selector(activityDidClick(sender:)))
283
283
 
284
284
  // Apply tint from navigation bar or from tintColor property
285
285
  if let tintColor = self.tintColor ?? self.navigationController?.navigationBar.tintColor {
@@ -291,8 +291,8 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
291
291
  } else {
292
292
  // Use system share icon
293
293
  let button = UIBarButtonItem(barButtonSystemItem: .action,
294
- target: self,
295
- action: #selector(activityDidClick(sender:)))
294
+ target: self,
295
+ action: #selector(activityDidClick(sender:)))
296
296
 
297
297
  // Apply tint from navigation bar or from tintColor property
298
298
  if let tintColor = self.tintColor ?? self.navigationController?.navigationBar.tintColor {
@@ -404,9 +404,9 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
404
404
 
405
405
  // Create a properly tinted button
406
406
  let buttonItem = UIBarButtonItem(image: buttonNearDoneIcon?.withRenderingMode(.alwaysTemplate),
407
- style: .plain,
408
- target: self,
409
- action: #selector(buttonNearDoneDidClick))
407
+ style: .plain,
408
+ target: self,
409
+ action: #selector(buttonNearDoneDidClick))
410
410
  buttonItem.tintColor = tintColor
411
411
 
412
412
  // Add it to right items
@@ -444,7 +444,7 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
444
444
  // Method to send a message from Swift to JavaScript
445
445
  open func postMessageToJS(message: [String: Any]) {
446
446
  if let jsonData = try? JSONSerialization.data(withJSONObject: message, options: []),
447
- let jsonString = String(data: jsonData, encoding: .utf8) {
447
+ let jsonString = String(data: jsonData, encoding: .utf8) {
448
448
  let script = "window.dispatchEvent(new CustomEvent('messageFromNative', { detail: \(jsonString) }));"
449
449
  DispatchQueue.main.async {
450
450
  self.webView?.evaluateJavaScript(script, completionHandler: nil)
@@ -478,20 +478,20 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
478
478
  semaphore.signal()
479
479
  } else if message.name == "close" {
480
480
  closeView()
481
- } else if message.name == "magicPrint" {
482
- if let webView = self.webView {
483
- let printController = UIPrintInteractionController.shared
481
+ } else if message.name == "magicPrint" {
482
+ if let webView = self.webView {
483
+ let printController = UIPrintInteractionController.shared
484
484
 
485
- let printInfo = UIPrintInfo(dictionary: nil)
486
- printInfo.outputType = .general
487
- printInfo.jobName = "Print Job"
485
+ let printInfo = UIPrintInfo(dictionary: nil)
486
+ printInfo.outputType = .general
487
+ printInfo.jobName = "Print Job"
488
488
 
489
- printController.printInfo = printInfo
490
- printController.printFormatter = webView.viewPrintFormatter()
489
+ printController.printInfo = printInfo
490
+ printController.printFormatter = webView.viewPrintFormatter()
491
491
 
492
- printController.present(animated: true, completionHandler: nil)
493
- }
494
- }
492
+ printController.present(animated: true, completionHandler: nil)
493
+ }
494
+ }
495
495
  }
496
496
 
497
497
  func injectJavaScriptInterface() {
@@ -509,17 +509,17 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
509
509
  };
510
510
  }
511
511
  """
512
- DispatchQueue.main.async {
513
- self.webView?.evaluateJavaScript(script) { result, error in
514
- if let error = error {
515
- print("JavaScript evaluation error: \(error)")
516
- } else if let result = result {
517
- print("JavaScript result: \(result)")
518
- } else {
519
- print("JavaScript executed with no result")
520
- }
521
- }
522
- }
512
+ DispatchQueue.main.async {
513
+ self.webView?.evaluateJavaScript(script) { result, error in
514
+ if let error = error {
515
+ print("JavaScript evaluation error: \(error)")
516
+ } else if let result = result {
517
+ print("JavaScript result: \(result)")
518
+ } else {
519
+ print("JavaScript executed with no result")
520
+ }
521
+ }
522
+ }
523
523
  }
524
524
 
525
525
  open func initWebview(isInspectable: Bool = true) {
@@ -534,35 +534,35 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
534
534
  userContentController.add(self, name: "preShowScriptError")
535
535
  userContentController.add(self, name: "preShowScriptSuccess")
536
536
  userContentController.add(self, name: "close")
537
- userContentController.add(self, name: "magicPrint")
538
-
539
- // Inject JavaScript to override window.print
540
- let script = WKUserScript(
541
- source: """
542
- window.print = function() {
543
- window.webkit.messageHandlers.magicPrint.postMessage('magicPrint');
544
- };
545
- """,
546
- injectionTime: .atDocumentStart,
547
- forMainFrameOnly: false
548
- )
549
- userContentController.addUserScript(script)
537
+ userContentController.add(self, name: "magicPrint")
538
+
539
+ // Inject JavaScript to override window.print
540
+ let script = WKUserScript(
541
+ source: """
542
+ window.print = function() {
543
+ window.webkit.messageHandlers.magicPrint.postMessage('magicPrint');
544
+ };
545
+ """,
546
+ injectionTime: .atDocumentStart,
547
+ forMainFrameOnly: false
548
+ )
549
+ userContentController.addUserScript(script)
550
550
 
551
551
  webConfiguration.allowsInlineMediaPlayback = true
552
552
  webConfiguration.userContentController = userContentController
553
553
 
554
554
  let webView = WKWebView(frame: .zero, configuration: webConfiguration)
555
555
 
556
- // if webView.responds(to: Selector(("setInspectable:"))) {
557
- // // Fix: https://stackoverflow.com/questions/76216183/how-to-debug-wkwebview-in-ios-16-4-1-using-xcode-14-2/76603043#76603043
558
- // webView.perform(Selector(("setInspectable:")), with: isInspectable)
559
- // }
556
+ // if webView.responds(to: Selector(("setInspectable:"))) {
557
+ // // Fix: https://stackoverflow.com/questions/76216183/how-to-debug-wkwebview-in-ios-16-4-1-using-xcode-14-2/76603043#76603043
558
+ // webView.perform(Selector(("setInspectable:")), with: isInspectable)
559
+ // }
560
560
 
561
- if #available(iOS 16.4, *) {
562
- webView.isInspectable = true
563
- } else {
564
- // Fallback on earlier versions
565
- }
561
+ if #available(iOS 16.4, *) {
562
+ webView.isInspectable = true
563
+ } else {
564
+ // Fallback on earlier versions
565
+ }
566
566
 
567
567
  if self.blankNavigationTab {
568
568
  // First add the webView to view hierarchy
@@ -1438,8 +1438,8 @@ extension WKWebViewController: WKNavigationDelegate {
1438
1438
 
1439
1439
  public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
1440
1440
  if let credentials = credentials,
1441
- challenge.protectionSpace.receivesCredentialSecurely,
1442
- let url = webView.url, challenge.protectionSpace.host == url.host, challenge.protectionSpace.protocol == url.scheme, challenge.protectionSpace.port == url.port ?? (url.scheme == "https" ? 443 : url.scheme == "http" ? 80 : nil) {
1441
+ challenge.protectionSpace.receivesCredentialSecurely,
1442
+ let url = webView.url, challenge.protectionSpace.host == url.host, challenge.protectionSpace.protocol == url.scheme, challenge.protectionSpace.port == url.port ?? (url.scheme == "https" ? 443 : url.scheme == "http" ? 80 : nil) {
1443
1443
  let urlCredential = URLCredential(user: credentials.username, password: credentials.password, persistence: .none)
1444
1444
  completionHandler(.useCredential, urlCredential)
1445
1445
  } else if let bypassedSSLHosts = bypassedSSLHosts, bypassedSSLHosts.contains(challenge.protectionSpace.host) {
@@ -1451,8 +1451,8 @@ extension WKWebViewController: WKNavigationDelegate {
1451
1451
  return
1452
1452
  }
1453
1453
  /* allows to open links with self-signed certificates
1454
- Follow Apple's guidelines https://developer.apple.com/documentation/foundation/url_loading_system/handling_an_authentication_challenge/performing_manual_server_trust_authentication
1455
- */
1454
+ Follow Apple's guidelines https://developer.apple.com/documentation/foundation/url_loading_system/handling_an_authentication_challenge/performing_manual_server_trust_authentication
1455
+ */
1456
1456
  guard let serverTrust = challenge.protectionSpace.serverTrust else {
1457
1457
  completionHandler(.useCredential, nil)
1458
1458
  return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/inappbrowser",
3
- "version": "7.10.0",
3
+ "version": "7.10.3",
4
4
  "description": "Capacitor plugin in app browser",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",