@capgo/inappbrowser 7.10.4 → 7.10.5

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.
@@ -253,17 +253,28 @@ public class InAppBrowserPlugin
253
253
  call.reject("Invalid URL");
254
254
  return;
255
255
  }
256
+
257
+ if (webViewDialog == null) {
258
+ call.reject("WebView is not initialized");
259
+ return;
260
+ }
261
+
256
262
  currentUrl = url;
257
263
  this.getActivity()
258
264
  .runOnUiThread(
259
265
  new Runnable() {
260
266
  @Override
261
267
  public void run() {
262
- if (webViewDialog != null) {
263
- webViewDialog.setUrl(url);
264
- call.resolve();
265
- } else {
266
- call.reject("WebView is not initialized");
268
+ try {
269
+ if (webViewDialog != null) {
270
+ webViewDialog.setUrl(url);
271
+ call.resolve();
272
+ } else {
273
+ call.reject("WebView is not initialized");
274
+ }
275
+ } catch (Exception e) {
276
+ Log.e("InAppBrowser", "Error setting URL: " + e.getMessage());
277
+ call.reject("Failed to set URL: " + e.getMessage());
267
278
  }
268
279
  }
269
280
  }
@@ -401,11 +412,19 @@ public class InAppBrowserPlugin
401
412
  new Runnable() {
402
413
  @Override
403
414
  public void run() {
404
- if (webViewDialog != null) {
405
- webViewDialog.executeScript(scriptToRun.toString());
406
- call.resolve();
407
- } else {
408
- call.reject("WebView is not initialized");
415
+ try {
416
+ if (webViewDialog != null) {
417
+ webViewDialog.executeScript(scriptToRun.toString());
418
+ call.resolve();
419
+ } else {
420
+ call.reject("WebView is not initialized");
421
+ }
422
+ } catch (Exception e) {
423
+ Log.e(
424
+ "InAppBrowser",
425
+ "Error clearing cookies: " + e.getMessage()
426
+ );
427
+ call.reject("Failed to clear cookies: " + e.getMessage());
409
428
  }
410
429
  }
411
430
  }
@@ -774,20 +793,34 @@ public class InAppBrowserPlugin
774
793
  @PluginMethod
775
794
  public void executeScript(PluginCall call) {
776
795
  String script = call.getString("code");
777
- if (script == null || TextUtils.isEmpty(script)) {
778
- call.reject("No script to run");
796
+ if (script == null || script.trim().isEmpty()) {
797
+ call.reject("Script is required");
798
+ return;
799
+ }
800
+
801
+ if (webViewDialog == null) {
802
+ call.reject("WebView is not initialized");
779
803
  return;
780
804
  }
805
+
781
806
  this.getActivity()
782
807
  .runOnUiThread(
783
808
  new Runnable() {
784
809
  @Override
785
810
  public void run() {
786
- if (webViewDialog != null) {
787
- webViewDialog.executeScript(script);
788
- call.resolve();
789
- } else {
790
- call.reject("WebView is not initialized");
811
+ try {
812
+ if (webViewDialog != null) {
813
+ webViewDialog.executeScript(script);
814
+ call.resolve();
815
+ } else {
816
+ call.reject("WebView is not initialized");
817
+ }
818
+ } catch (Exception e) {
819
+ Log.e(
820
+ "InAppBrowser",
821
+ "Error executing script: " + e.getMessage()
822
+ );
823
+ call.reject("Failed to execute script: " + e.getMessage());
791
824
  }
792
825
  }
793
826
  }
@@ -834,28 +867,80 @@ public class InAppBrowserPlugin
834
867
 
835
868
  @PluginMethod
836
869
  public void close(PluginCall call) {
870
+ if (webViewDialog == null) {
871
+ // Fallback: try to bring main activity to foreground
872
+ try {
873
+ Intent intent = new Intent(
874
+ getContext(),
875
+ getBridge().getActivity().getClass()
876
+ );
877
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
878
+ getContext().startActivity(intent);
879
+ call.resolve();
880
+ } catch (Exception e) {
881
+ Log.e(
882
+ "InAppBrowser",
883
+ "Error bringing main activity to foreground: " + e.getMessage()
884
+ );
885
+ call.reject(
886
+ "WebView is not initialized and failed to restore main activity"
887
+ );
888
+ }
889
+ return;
890
+ }
891
+
837
892
  this.getActivity()
838
893
  .runOnUiThread(
839
894
  new Runnable() {
840
895
  @Override
841
896
  public void run() {
842
- if (webViewDialog != null) {
843
- String currentUrl = webViewDialog.getUrl();
844
- notifyListeners(
845
- "closeEvent",
846
- new JSObject().put("url", currentUrl)
847
- );
848
- webViewDialog.dismiss();
849
- webViewDialog = null;
850
- } else {
851
- Intent intent = new Intent(
852
- getContext(),
853
- getBridge().getActivity().getClass()
854
- );
855
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
856
- getContext().startActivity(intent);
897
+ try {
898
+ if (webViewDialog != null) {
899
+ String currentUrl = "";
900
+ try {
901
+ currentUrl = webViewDialog.getUrl();
902
+ if (currentUrl == null) {
903
+ currentUrl = "";
904
+ }
905
+ } catch (Exception e) {
906
+ Log.e(
907
+ "InAppBrowser",
908
+ "Error getting URL before close: " + e.getMessage()
909
+ );
910
+ currentUrl = "";
911
+ }
912
+
913
+ // Notify listeners about the close event
914
+ notifyListeners(
915
+ "closeEvent",
916
+ new JSObject().put("url", currentUrl)
917
+ );
918
+
919
+ webViewDialog.dismiss();
920
+ webViewDialog = null;
921
+ call.resolve();
922
+ } else {
923
+ // Secondary fallback inside UI thread
924
+ try {
925
+ Intent intent = new Intent(
926
+ getContext(),
927
+ getBridge().getActivity().getClass()
928
+ );
929
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
930
+ getContext().startActivity(intent);
931
+ call.resolve();
932
+ } catch (Exception e) {
933
+ Log.e(
934
+ "InAppBrowser",
935
+ "Error in secondary fallback: " + e.getMessage()
936
+ );
937
+ call.reject("WebView is not initialized");
938
+ }
939
+ }
940
+ } catch (Exception e) {
941
+ Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
942
+ call.reject("Failed to close WebView: " + e.getMessage());
857
943
  }
858
- call.resolve();
859
944
  }
860
945
  }
861
946
  );
@@ -160,6 +160,15 @@ public class WebViewDialog extends Dialog {
160
160
  Log.e("InAppBrowser", "Received empty message from WebView");
161
161
  return;
162
162
  }
163
+
164
+ if (_options == null || _options.getCallbacks() == null) {
165
+ Log.e(
166
+ "InAppBrowser",
167
+ "Cannot handle postMessage - options or callbacks are null"
168
+ );
169
+ return;
170
+ }
171
+
163
172
  _options.getCallbacks().javascriptCallback(message);
164
173
  } catch (Exception e) {
165
174
  Log.e("InAppBrowser", "Error in postMessage: " + e.getMessage());
@@ -170,19 +179,35 @@ public class WebViewDialog extends Dialog {
170
179
  public void close() {
171
180
  try {
172
181
  // close webview safely
173
- if (activity != null) {
174
- activity.runOnUiThread(() -> {
175
- try {
176
- String currentUrl = _webView != null ? _webView.getUrl() : "";
177
- dismiss();
178
- if (_options != null && _options.getCallbacks() != null) {
179
- _options.getCallbacks().closeEvent(currentUrl);
182
+ if (activity == null) {
183
+ Log.e("InAppBrowser", "Cannot close - activity is null");
184
+ return;
185
+ }
186
+
187
+ activity.runOnUiThread(() -> {
188
+ try {
189
+ String currentUrl = "";
190
+ if (_webView != null) {
191
+ try {
192
+ currentUrl = _webView.getUrl();
193
+ if (currentUrl == null) {
194
+ currentUrl = "";
195
+ }
196
+ } catch (Exception e) {
197
+ Log.e("InAppBrowser", "Error getting URL: " + e.getMessage());
198
+ currentUrl = "";
180
199
  }
181
- } catch (Exception e) {
182
- Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
183
200
  }
184
- });
185
- }
201
+
202
+ dismiss();
203
+
204
+ if (_options != null && _options.getCallbacks() != null) {
205
+ _options.getCallbacks().closeEvent(currentUrl);
206
+ }
207
+ } catch (Exception e) {
208
+ Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
209
+ }
210
+ });
186
211
  } catch (Exception e) {
187
212
  Log.e("InAppBrowser", "Error in close: " + e.getMessage());
188
213
  }
@@ -1102,28 +1127,53 @@ public class WebViewDialog extends Dialog {
1102
1127
 
1103
1128
  private void injectJavaScriptInterface() {
1104
1129
  if (_webView == null) {
1130
+ Log.w(
1131
+ "InAppBrowser",
1132
+ "Cannot inject JavaScript interface - WebView is null"
1133
+ );
1105
1134
  return;
1106
1135
  }
1107
- String script =
1108
- "if (!window.mobileApp) { " +
1109
- " window.mobileApp = { " +
1110
- " postMessage: function(message) { " +
1111
- " if (window.AndroidInterface) { " +
1112
- " window.AndroidInterface.postMessage(JSON.stringify(message)); " +
1113
- " } " +
1114
- " }, " +
1115
- " close: function() { " +
1116
- " window.AndroidInterface.close(); " +
1117
- " } " +
1118
- " }; " +
1119
- "} " +
1120
- // Override the window.print function to use our PrintInterface
1121
- "window.print = function() { " +
1122
- " if (window.PrintInterface) { " +
1123
- " window.PrintInterface.print(); " +
1124
- " } " +
1125
- "};";
1126
- _webView.evaluateJavascript(script, null);
1136
+
1137
+ try {
1138
+ String script =
1139
+ "(function() {" +
1140
+ " if (window.AndroidInterface) {" +
1141
+ " window.postMessage = function(data) {" +
1142
+ " try {" +
1143
+ " var message = typeof data === 'string' ? data : JSON.stringify(data);" +
1144
+ " window.AndroidInterface.postMessage(message);" +
1145
+ " } catch(e) {" +
1146
+ " console.error('Error in postMessage:', e);" +
1147
+ " }" +
1148
+ " };" +
1149
+ " window.close = function() {" +
1150
+ " try {" +
1151
+ " window.AndroidInterface.close();" +
1152
+ " } catch(e) {" +
1153
+ " console.error('Error in close:', e);" +
1154
+ " }" +
1155
+ " };" +
1156
+ " }" +
1157
+ "})();";
1158
+
1159
+ _webView.post(() -> {
1160
+ if (_webView != null) {
1161
+ try {
1162
+ _webView.evaluateJavascript(script, null);
1163
+ } catch (Exception e) {
1164
+ Log.e(
1165
+ "InAppBrowser",
1166
+ "Error injecting JavaScript interface: " + e.getMessage()
1167
+ );
1168
+ }
1169
+ }
1170
+ });
1171
+ } catch (Exception e) {
1172
+ Log.e(
1173
+ "InAppBrowser",
1174
+ "Error preparing JavaScript interface: " + e.getMessage()
1175
+ );
1176
+ }
1127
1177
  }
1128
1178
 
1129
1179
  private void injectPreShowScript() {
@@ -1350,21 +1400,29 @@ public class WebViewDialog extends Dialog {
1350
1400
 
1351
1401
  public void reload() {
1352
1402
  if (_webView == null) {
1403
+ Log.w("InAppBrowser", "Cannot reload - WebView is null");
1353
1404
  return;
1354
1405
  }
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());
1406
+
1407
+ try {
1408
+ // First stop any ongoing loading
1409
+ _webView.stopLoading();
1410
+
1411
+ // Check if there's a URL to reload
1412
+ String currentUrl = _webView.getUrl();
1413
+ if (currentUrl != null && !currentUrl.equals("about:blank")) {
1414
+ // Reload the current page
1415
+ _webView.reload();
1416
+ Log.d("InAppBrowser", "Reloading page: " + currentUrl);
1417
+ } else if (_options != null && _options.getUrl() != null) {
1418
+ // If webView URL is null but we have an initial URL, load that
1419
+ setUrl(_options.getUrl());
1420
+ Log.d("InAppBrowser", "Loading initial URL: " + _options.getUrl());
1421
+ } else {
1422
+ Log.w("InAppBrowser", "Cannot reload - no valid URL available");
1423
+ }
1424
+ } catch (Exception e) {
1425
+ Log.e("InAppBrowser", "Error during reload: " + e.getMessage());
1368
1426
  }
1369
1427
  }
1370
1428
 
@@ -1379,30 +1437,53 @@ public class WebViewDialog extends Dialog {
1379
1437
  }
1380
1438
 
1381
1439
  public void executeScript(String script) {
1382
- if (_webView != null) {
1440
+ if (_webView == null) {
1441
+ Log.w("InAppBrowser", "Cannot execute script - WebView is null");
1442
+ return;
1443
+ }
1444
+
1445
+ if (script == null || script.trim().isEmpty()) {
1446
+ Log.w("InAppBrowser", "Cannot execute empty script");
1447
+ return;
1448
+ }
1449
+
1450
+ try {
1383
1451
  _webView.evaluateJavascript(script, null);
1452
+ } catch (Exception e) {
1453
+ Log.e("InAppBrowser", "Error executing script: " + e.getMessage());
1384
1454
  }
1385
1455
  }
1386
1456
 
1387
1457
  public void setUrl(String url) {
1388
1458
  if (_webView == null) {
1459
+ Log.w("InAppBrowser", "Cannot set URL - WebView is null");
1389
1460
  return;
1390
1461
  }
1391
- Map<String, String> requestHeaders = new HashMap<>();
1392
- if (_options.getHeaders() != null) {
1393
- Iterator<String> keys = _options.getHeaders().keys();
1394
- while (keys.hasNext()) {
1395
- String key = keys.next();
1396
- if (TextUtils.equals(key.toLowerCase(), "user-agent")) {
1397
- _webView
1398
- .getSettings()
1399
- .setUserAgentString(_options.getHeaders().getString(key));
1400
- } else {
1401
- requestHeaders.put(key, _options.getHeaders().getString(key));
1462
+
1463
+ if (url == null || url.trim().isEmpty()) {
1464
+ Log.w("InAppBrowser", "Cannot set empty URL");
1465
+ return;
1466
+ }
1467
+
1468
+ try {
1469
+ Map<String, String> requestHeaders = new HashMap<>();
1470
+ if (_options.getHeaders() != null) {
1471
+ Iterator<String> keys = _options.getHeaders().keys();
1472
+ while (keys.hasNext()) {
1473
+ String key = keys.next();
1474
+ if (TextUtils.equals(key.toLowerCase(), "user-agent")) {
1475
+ _webView
1476
+ .getSettings()
1477
+ .setUserAgentString(_options.getHeaders().getString(key));
1478
+ } else {
1479
+ requestHeaders.put(key, _options.getHeaders().getString(key));
1480
+ }
1402
1481
  }
1403
1482
  }
1483
+ _webView.loadUrl(url, requestHeaders);
1484
+ } catch (Exception e) {
1485
+ Log.e("InAppBrowser", "Error setting URL: " + e.getMessage());
1404
1486
  }
1405
- _webView.loadUrl(url, requestHeaders);
1406
1487
  }
1407
1488
 
1408
1489
  private void setTitle(String newTitleText) {
@@ -2459,38 +2540,93 @@ public class WebViewDialog extends Dialog {
2459
2540
 
2460
2541
  @Override
2461
2542
  public void dismiss() {
2543
+ // First, stop any ongoing operations and disable further interactions
2462
2544
  if (_webView != null) {
2463
- // Reset file inputs to prevent WebView from caching them
2464
- _webView.evaluateJavascript(
2465
- "(function() {" +
2466
- " var inputs = document.querySelectorAll('input[type=\"file\"]');" +
2467
- " for (var i = 0; i < inputs.length; i++) {" +
2468
- " inputs[i].value = '';" +
2469
- " }" +
2470
- " return true;" +
2471
- "})();",
2472
- null
2473
- );
2545
+ try {
2546
+ // Stop loading first to prevent any ongoing operations
2547
+ _webView.stopLoading();
2474
2548
 
2475
- _webView.loadUrl("about:blank");
2476
- _webView.onPause();
2477
- _webView.removeAllViews();
2478
- _webView.destroy();
2479
- _webView = null;
2549
+ // Clear any pending callbacks to prevent memory leaks
2550
+ if (mFilePathCallback != null) {
2551
+ mFilePathCallback.onReceiveValue(null);
2552
+ mFilePathCallback = null;
2553
+ }
2554
+ tempCameraUri = null;
2555
+
2556
+ // Clear file inputs for security/privacy before destroying WebView
2557
+ try {
2558
+ _webView.evaluateJavascript(
2559
+ "(function() {" +
2560
+ " try {" +
2561
+ " var inputs = document.querySelectorAll('input[type=\"file\"]');" +
2562
+ " for (var i = 0; i < inputs.length; i++) {" +
2563
+ " inputs[i].value = '';" +
2564
+ " }" +
2565
+ " return true;" +
2566
+ " } catch(e) {" +
2567
+ " console.log('Error clearing file inputs:', e);" +
2568
+ " return false;" +
2569
+ " }" +
2570
+ "})();",
2571
+ null
2572
+ );
2573
+ } catch (Exception e) {
2574
+ Log.w(
2575
+ "InAppBrowser",
2576
+ "Could not clear file inputs (WebView may be in invalid state): " +
2577
+ e.getMessage()
2578
+ );
2579
+ }
2580
+
2581
+ // Remove JavaScript interfaces before destroying
2582
+ _webView.removeJavascriptInterface("AndroidInterface");
2583
+ _webView.removeJavascriptInterface("PreShowScriptInterface");
2584
+ _webView.removeJavascriptInterface("PrintInterface");
2585
+
2586
+ // Load blank page and cleanup
2587
+ _webView.loadUrl("about:blank");
2588
+ _webView.onPause();
2589
+ _webView.removeAllViews();
2590
+ _webView.destroy();
2591
+ _webView = null;
2592
+ } catch (Exception e) {
2593
+ Log.e(
2594
+ "InAppBrowser",
2595
+ "Error during WebView cleanup: " + e.getMessage()
2596
+ );
2597
+ // Force set to null even if cleanup failed
2598
+ _webView = null;
2599
+ }
2480
2600
  }
2481
2601
 
2602
+ // Shutdown executor service safely
2482
2603
  if (executorService != null && !executorService.isShutdown()) {
2483
- executorService.shutdown();
2484
2604
  try {
2605
+ executorService.shutdown();
2485
2606
  if (!executorService.awaitTermination(500, TimeUnit.MILLISECONDS)) {
2486
2607
  executorService.shutdownNow();
2487
2608
  }
2488
2609
  } catch (InterruptedException e) {
2610
+ Thread.currentThread().interrupt();
2489
2611
  executorService.shutdownNow();
2612
+ } catch (Exception e) {
2613
+ Log.e(
2614
+ "InAppBrowser",
2615
+ "Error shutting down executor: " + e.getMessage()
2616
+ );
2490
2617
  }
2491
2618
  }
2492
2619
 
2493
- super.dismiss();
2620
+ // Clear any remaining proxied requests
2621
+ synchronized (proxiedRequestsHashmap) {
2622
+ proxiedRequestsHashmap.clear();
2623
+ }
2624
+
2625
+ try {
2626
+ super.dismiss();
2627
+ } catch (Exception e) {
2628
+ Log.e("InAppBrowser", "Error dismissing dialog: " + e.getMessage());
2629
+ }
2494
2630
  }
2495
2631
 
2496
2632
  public void addProxiedRequest(String key, ProxiedRequest request) {
@@ -2561,7 +2697,15 @@ public class WebViewDialog extends Dialog {
2561
2697
  }
2562
2698
 
2563
2699
  private void injectDatePickerFixes() {
2564
- if (_webView == null || datePickerInjected) {
2700
+ if (_webView == null) {
2701
+ Log.w(
2702
+ "InAppBrowser",
2703
+ "Cannot inject date picker fixes - WebView is null"
2704
+ );
2705
+ return;
2706
+ }
2707
+
2708
+ if (datePickerInjected) {
2565
2709
  return;
2566
2710
  }
2567
2711
 
@@ -2571,29 +2715,43 @@ public class WebViewDialog extends Dialog {
2571
2715
  String script =
2572
2716
  """
2573
2717
  (function() {
2574
- // Find all date inputs
2575
- const dateInputs = document.querySelectorAll('input[type="date"]');
2576
- dateInputs.forEach(input => {
2577
- // Ensure change events propagate correctly
2578
- let lastValue = input.value;
2579
- input.addEventListener('change', () => {
2580
- if (input.value !== lastValue) {
2581
- lastValue = input.value;
2582
- // Dispatch an input event to ensure frameworks detect the change
2583
- input.dispatchEvent(new Event('input', { bubbles: true }));
2584
- }
2718
+ try {
2719
+ // Find all date inputs
2720
+ const dateInputs = document.querySelectorAll('input[type="date"]');
2721
+ dateInputs.forEach(input => {
2722
+ // Ensure change events propagate correctly
2723
+ let lastValue = input.value;
2724
+ input.addEventListener('change', () => {
2725
+ try {
2726
+ if (input.value !== lastValue) {
2727
+ lastValue = input.value;
2728
+ // Dispatch an input event to ensure frameworks detect the change
2729
+ input.dispatchEvent(new Event('input', { bubbles: true }));
2730
+ }
2731
+ } catch(e) {
2732
+ console.error('Error in date input change handler:', e);
2733
+ }
2734
+ });
2585
2735
  });
2586
- });
2736
+ } catch(e) {
2737
+ console.error('Error applying date picker fixes:', e);
2738
+ }
2587
2739
  })();""";
2588
2740
 
2589
2741
  // Execute the script in the WebView
2590
2742
  _webView.post(() -> {
2591
2743
  if (_webView != null) {
2592
- _webView.evaluateJavascript(script, null);
2744
+ try {
2745
+ _webView.evaluateJavascript(script, null);
2746
+ Log.d("InAppBrowser", "Applied minimal date picker fixes");
2747
+ } catch (Exception e) {
2748
+ Log.e(
2749
+ "InAppBrowser",
2750
+ "Error injecting date picker fixes: " + e.getMessage()
2751
+ );
2752
+ }
2593
2753
  }
2594
2754
  });
2595
-
2596
- Log.d("InAppBrowser", "Applied minimal date picker fixes");
2597
2755
  }
2598
2756
 
2599
2757
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/inappbrowser",
3
- "version": "7.10.4",
3
+ "version": "7.10.5",
4
4
  "description": "Capacitor plugin in app browser",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",