@calvingoh-hexa/capacitor-inappbrowser 6.9.36

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.
Files changed (55) hide show
  1. package/CapgoInappbrowser.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +690 -0
  4. package/android/build.gradle +64 -0
  5. package/android/src/main/AndroidManifest.xml +12 -0
  6. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +741 -0
  7. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +340 -0
  8. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +15 -0
  9. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +1177 -0
  10. package/android/src/main/res/.gitkeep +0 -0
  11. package/android/src/main/res/drawable/arrow_back_disabled.xml +9 -0
  12. package/android/src/main/res/drawable/arrow_back_enabled.xml +9 -0
  13. package/android/src/main/res/drawable/arrow_forward_disabled.xml +9 -0
  14. package/android/src/main/res/drawable/arrow_forward_enabled.xml +9 -0
  15. package/android/src/main/res/drawable/ic_clear_24px.xml +9 -0
  16. package/android/src/main/res/drawable/ic_refresh.xml +9 -0
  17. package/android/src/main/res/layout/activity_browser.xml +22 -0
  18. package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
  19. package/android/src/main/res/layout/content_browser.xml +16 -0
  20. package/android/src/main/res/layout/tool_bar.xml +72 -0
  21. package/android/src/main/res/values/browser_theme.xml +3 -0
  22. package/android/src/main/res/values/colors.xml +5 -0
  23. package/android/src/main/res/values/dimens.xml +3 -0
  24. package/android/src/main/res/values/strings.xml +11 -0
  25. package/android/src/main/res/values/styles.xml +4 -0
  26. package/dist/docs.json +1865 -0
  27. package/dist/esm/definitions.d.ts +361 -0
  28. package/dist/esm/definitions.js +13 -0
  29. package/dist/esm/definitions.js.map +1 -0
  30. package/dist/esm/index.d.ts +4 -0
  31. package/dist/esm/index.js +7 -0
  32. package/dist/esm/index.js.map +1 -0
  33. package/dist/esm/web.d.ts +19 -0
  34. package/dist/esm/web.js +48 -0
  35. package/dist/esm/web.js.map +1 -0
  36. package/dist/plugin.cjs.js +75 -0
  37. package/dist/plugin.cjs.js.map +1 -0
  38. package/dist/plugin.js +78 -0
  39. package/dist/plugin.js.map +1 -0
  40. package/ios/Plugin/Assets.xcassets/Back.imageset/Back.png +0 -0
  41. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@2x.png +0 -0
  42. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@3x.png +0 -0
  43. package/ios/Plugin/Assets.xcassets/Back.imageset/Contents.json +26 -0
  44. package/ios/Plugin/Assets.xcassets/Contents.json +6 -0
  45. package/ios/Plugin/Assets.xcassets/Forward.imageset/Contents.json +26 -0
  46. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward.png +0 -0
  47. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@2x.png +0 -0
  48. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@3x.png +0 -0
  49. package/ios/Plugin/Enums.swift +65 -0
  50. package/ios/Plugin/InAppBrowserPlugin.h +10 -0
  51. package/ios/Plugin/InAppBrowserPlugin.m +21 -0
  52. package/ios/Plugin/InAppBrowserPlugin.swift +434 -0
  53. package/ios/Plugin/Info.plist +24 -0
  54. package/ios/Plugin/WKWebViewController.swift +1021 -0
  55. package/package.json +83 -0
@@ -0,0 +1,741 @@
1
+ package ee.forgr.capacitor_inappbrowser;
2
+
3
+ import android.Manifest;
4
+ import android.app.Activity;
5
+ import android.content.ComponentName;
6
+ import android.content.Intent;
7
+ import android.content.pm.PackageManager;
8
+ import android.content.pm.ResolveInfo;
9
+ import android.net.Uri;
10
+ import android.os.Bundle;
11
+ import android.text.TextUtils;
12
+ import android.util.Log;
13
+ import android.webkit.CookieManager;
14
+ import android.webkit.PermissionRequest;
15
+ import androidx.annotation.NonNull;
16
+ import androidx.browser.customtabs.CustomTabsCallback;
17
+ import androidx.browser.customtabs.CustomTabsClient;
18
+ import androidx.browser.customtabs.CustomTabsIntent;
19
+ import androidx.browser.customtabs.CustomTabsServiceConnection;
20
+ import androidx.browser.customtabs.CustomTabsSession;
21
+ import com.getcapacitor.JSObject;
22
+ import com.getcapacitor.PermissionState;
23
+ import com.getcapacitor.Plugin;
24
+ import com.getcapacitor.PluginCall;
25
+ import com.getcapacitor.PluginMethod;
26
+ import com.getcapacitor.annotation.CapacitorPlugin;
27
+ import com.getcapacitor.annotation.Permission;
28
+ import com.getcapacitor.annotation.PermissionCallback;
29
+ import java.util.ArrayList;
30
+ import java.util.Iterator;
31
+ import java.util.regex.Pattern;
32
+ import java.util.regex.PatternSyntaxException;
33
+ import org.json.JSONException;
34
+ import org.json.JSONObject;
35
+
36
+ @CapacitorPlugin(
37
+ name = "InAppBrowser",
38
+ permissions = {
39
+ @Permission(alias = "camera", strings = { Manifest.permission.CAMERA }),
40
+ @Permission(
41
+ alias = "microphone",
42
+ strings = { Manifest.permission.RECORD_AUDIO }
43
+ ),
44
+ @Permission(
45
+ alias = "storage",
46
+ strings = { Manifest.permission.READ_EXTERNAL_STORAGE }
47
+ ),
48
+ @Permission(
49
+ alias = "storage",
50
+ strings = { Manifest.permission.READ_MEDIA_IMAGES }
51
+ ),
52
+ },
53
+ requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
54
+ )
55
+ public class InAppBrowserPlugin
56
+ extends Plugin
57
+ implements WebViewDialog.PermissionHandler {
58
+
59
+ public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
60
+ private CustomTabsClient customTabsClient;
61
+ private CustomTabsSession currentSession;
62
+ private WebViewDialog webViewDialog = null;
63
+ private String currentUrl = "";
64
+
65
+ private PermissionRequest currentPermissionRequest;
66
+
67
+ public void handleMicrophonePermissionRequest(PermissionRequest request) {
68
+ this.currentPermissionRequest = request;
69
+ if (getPermissionState("microphone") != PermissionState.GRANTED) {
70
+ requestPermissionForAlias(
71
+ "microphone",
72
+ null,
73
+ "microphonePermissionCallback"
74
+ );
75
+ } else {
76
+ grantMicrophonePermission();
77
+ }
78
+ }
79
+
80
+ private void grantMicrophonePermission() {
81
+ if (currentPermissionRequest != null) {
82
+ currentPermissionRequest.grant(
83
+ new String[] { PermissionRequest.RESOURCE_AUDIO_CAPTURE }
84
+ );
85
+ currentPermissionRequest = null;
86
+ }
87
+ }
88
+
89
+ @PermissionCallback
90
+ private void microphonePermissionCallback(PluginCall call) {
91
+ if (getPermissionState("microphone") == PermissionState.GRANTED) {
92
+ grantCameraAndMicrophonePermission();
93
+ } else {
94
+ if (currentPermissionRequest != null) {
95
+ currentPermissionRequest.deny();
96
+ currentPermissionRequest = null;
97
+ }
98
+ call.reject("Microphone permission is required");
99
+ }
100
+ }
101
+
102
+ private void grantCameraAndMicrophonePermission() {
103
+ if (currentPermissionRequest != null) {
104
+ currentPermissionRequest.grant(
105
+ new String[] {
106
+ PermissionRequest.RESOURCE_VIDEO_CAPTURE,
107
+ PermissionRequest.RESOURCE_AUDIO_CAPTURE,
108
+ }
109
+ );
110
+ currentPermissionRequest = null;
111
+ }
112
+ }
113
+
114
+ public void handleCameraPermissionRequest(PermissionRequest request) {
115
+ this.currentPermissionRequest = request;
116
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
117
+ requestPermissionForAlias("camera", null, "cameraPermissionCallback");
118
+ } else if (getPermissionState("microphone") != PermissionState.GRANTED) {
119
+ requestPermissionForAlias(
120
+ "microphone",
121
+ null,
122
+ "microphonePermissionCallback"
123
+ );
124
+ } else {
125
+ grantCameraAndMicrophonePermission();
126
+ }
127
+ }
128
+
129
+ @Override
130
+ protected void handleOnActivityResult(
131
+ int requestCode,
132
+ int resultCode,
133
+ Intent data
134
+ ) {
135
+ super.handleOnActivityResult(requestCode, resultCode, data);
136
+
137
+ // Check if the request code matches the file chooser request code
138
+ if (requestCode == WebViewDialog.FILE_CHOOSER_REQUEST_CODE) {
139
+ if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
140
+ Uri[] results = null;
141
+
142
+ if (resultCode == Activity.RESULT_OK) {
143
+ if (data != null) {
144
+ String dataString = data.getDataString();
145
+ if (data.getClipData() != null) { // If multiple file selected
146
+ int count = data.getClipData().getItemCount();
147
+ results = new Uri[count];
148
+ for (int i = 0; i < count; i++) {
149
+ results[i] = data.getClipData().getItemAt(i).getUri();
150
+ }
151
+ } else if (dataString != null) { //if single file selected
152
+ results = new Uri[] { Uri.parse(dataString) };
153
+ }
154
+ }
155
+ }
156
+
157
+ // Pass the results back to the WebView
158
+ try {
159
+ webViewDialog.mFilePathCallback.onReceiveValue(results);
160
+ webViewDialog.mFilePathCallback = null;
161
+ } catch (Exception e) {
162
+ Log.e("ACTIVITYRESULT", e.getMessage());
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ @PermissionCallback
169
+ private void cameraPermissionCallback() {
170
+ if (getPermissionState("camera") == PermissionState.GRANTED) {
171
+ grantCameraPermission();
172
+ } else {
173
+ if (currentPermissionRequest != null) {
174
+ currentPermissionRequest.deny();
175
+ currentPermissionRequest = null;
176
+ }
177
+ // Handle the case where permission was not granted
178
+ }
179
+ }
180
+
181
+ @PermissionCallback
182
+ private void cameraPermissionCallback(PluginCall call) {
183
+ if (getPermissionState("camera") == PermissionState.GRANTED) {
184
+ if (getPermissionState("microphone") != PermissionState.GRANTED) {
185
+ requestPermissionForAlias(
186
+ "microphone",
187
+ null,
188
+ "microphonePermissionCallback"
189
+ );
190
+ } else {
191
+ grantCameraAndMicrophonePermission();
192
+ }
193
+ } else {
194
+ if (currentPermissionRequest != null) {
195
+ currentPermissionRequest.deny();
196
+ currentPermissionRequest = null;
197
+ }
198
+ call.reject("Camera permission is required");
199
+ }
200
+ }
201
+
202
+ private void grantCameraPermission() {
203
+ if (currentPermissionRequest != null) {
204
+ currentPermissionRequest.grant(
205
+ new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE }
206
+ );
207
+ currentPermissionRequest = null;
208
+ }
209
+ }
210
+
211
+ CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
212
+ @Override
213
+ public void onCustomTabsServiceConnected(
214
+ @NonNull ComponentName name,
215
+ CustomTabsClient client
216
+ ) {
217
+ customTabsClient = client;
218
+ client.warmup(0);
219
+ }
220
+
221
+ @Override
222
+ public void onServiceDisconnected(ComponentName name) {}
223
+ };
224
+
225
+ @PluginMethod
226
+ public void requestCameraPermission(PluginCall call) {
227
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
228
+ requestPermissionForAlias("camera", call, "cameraPermissionCallback");
229
+ } else {
230
+ call.resolve();
231
+ }
232
+ }
233
+
234
+ @PluginMethod
235
+ public void setUrl(PluginCall call) {
236
+ String url = call.getString("url");
237
+ if (url == null || TextUtils.isEmpty(url)) {
238
+ call.reject("Invalid URL");
239
+ }
240
+ currentUrl = url;
241
+ this.getActivity()
242
+ .runOnUiThread(
243
+ new Runnable() {
244
+ @Override
245
+ public void run() {
246
+ webViewDialog.setUrl(url);
247
+ }
248
+ }
249
+ );
250
+ call.resolve();
251
+ }
252
+
253
+ @PluginMethod
254
+ public void open(PluginCall call) {
255
+ String url = call.getString("url");
256
+
257
+ // get the deeplink prevention, if provided
258
+ Boolean preventDeeplink = call.getBoolean("preventDeeplink", null);
259
+
260
+ if (url == null || TextUtils.isEmpty(url)) {
261
+ call.reject("Invalid URL");
262
+ }
263
+ currentUrl = url;
264
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
265
+ getCustomTabsSession()
266
+ );
267
+ CustomTabsIntent tabsIntent = builder.build();
268
+ tabsIntent.intent.putExtra(
269
+ Intent.EXTRA_REFERRER,
270
+ Uri.parse(
271
+ Intent.URI_ANDROID_APP_SCHEME + "//" + getContext().getPackageName()
272
+ )
273
+ );
274
+ tabsIntent.intent.putExtra(
275
+ android.provider.Browser.EXTRA_HEADERS,
276
+ this.getHeaders(call)
277
+ );
278
+
279
+ if (preventDeeplink != null) {
280
+ String browserPackageName = "";
281
+ Intent browserIntent = new Intent(
282
+ Intent.ACTION_VIEW,
283
+ Uri.parse("http://")
284
+ );
285
+ ResolveInfo resolveInfo = getContext()
286
+ .getPackageManager()
287
+ .resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
288
+
289
+ if (resolveInfo != null) {
290
+ browserPackageName = resolveInfo.activityInfo.packageName;
291
+
292
+ if (!browserPackageName.isEmpty()) {
293
+ tabsIntent.intent.setPackage(browserPackageName);
294
+ }
295
+ }
296
+ }
297
+
298
+ tabsIntent.launchUrl(getContext(), Uri.parse(url));
299
+
300
+ call.resolve();
301
+ }
302
+
303
+ @PluginMethod
304
+ public void clearCache(PluginCall call) {
305
+ CookieManager cookieManager = CookieManager.getInstance();
306
+ cookieManager.removeAllCookies(null);
307
+ cookieManager.flush();
308
+ call.resolve();
309
+ }
310
+
311
+ @PluginMethod
312
+ public void clearAllCookies(PluginCall call) {
313
+ CookieManager cookieManager = CookieManager.getInstance();
314
+ cookieManager.removeAllCookies(null);
315
+ cookieManager.flush();
316
+ call.resolve();
317
+ }
318
+
319
+ @PluginMethod
320
+ public void clearCookies(PluginCall call) {
321
+ String url = call.getString("url", currentUrl);
322
+ if (url == null || TextUtils.isEmpty(url)) {
323
+ call.reject("Invalid URL");
324
+ return;
325
+ }
326
+
327
+ Uri uri = Uri.parse(url);
328
+ String host = uri.getHost();
329
+ if (host == null || TextUtils.isEmpty(host)) {
330
+ call.reject("Invalid URL (Host is null)");
331
+ return;
332
+ }
333
+
334
+ CookieManager cookieManager = CookieManager.getInstance();
335
+ String cookieString = cookieManager.getCookie(url);
336
+ ArrayList<String> cookiesToRemove = new ArrayList<>();
337
+
338
+ if (cookieString != null) {
339
+ String[] cookies = cookieString.split("; ");
340
+
341
+ String domain = uri.getHost();
342
+
343
+ for (String cookie : cookies) {
344
+ String[] parts = cookie.split("=");
345
+ if (parts.length > 0) {
346
+ cookiesToRemove.add(parts[0].trim());
347
+ CookieManager.getInstance()
348
+ .setCookie(url, String.format("%s=del;", parts[0].trim()));
349
+ }
350
+ }
351
+ }
352
+
353
+ StringBuilder scriptToRun = new StringBuilder();
354
+ for (String cookieToRemove : cookiesToRemove) {
355
+ scriptToRun.append(
356
+ String.format(
357
+ "window.cookieStore.delete('%s', {name: '%s', domain: '%s'});",
358
+ cookieToRemove,
359
+ cookieToRemove,
360
+ url
361
+ )
362
+ );
363
+ }
364
+
365
+ Log.i("DelCookies", String.format("Script to run:\n%s", scriptToRun));
366
+
367
+ this.getActivity()
368
+ .runOnUiThread(
369
+ new Runnable() {
370
+ @Override
371
+ public void run() {
372
+ webViewDialog.executeScript(scriptToRun.toString());
373
+ }
374
+ }
375
+ );
376
+
377
+ call.resolve();
378
+ }
379
+
380
+ @PluginMethod
381
+ public void getCookies(PluginCall call) {
382
+ String url = call.getString("url");
383
+ if (url == null || TextUtils.isEmpty(url)) {
384
+ call.reject("Invalid URL");
385
+ } else {
386
+ CookieManager cookieManager = CookieManager.getInstance();
387
+ String cookieString = cookieManager.getCookie(url);
388
+ if (cookieString != null) {
389
+ String[] cookiePairs = cookieString.split("; ");
390
+ JSObject result = new JSObject();
391
+ for (String cookie : cookiePairs) {
392
+ String[] parts = cookie.split("=", 2);
393
+ if (parts.length == 2) {
394
+ result.put(parts[0], parts[1]);
395
+ }
396
+ }
397
+ call.resolve(result);
398
+ }
399
+ call.resolve(new JSObject());
400
+ }
401
+ }
402
+
403
+ @PluginMethod
404
+ public void openWebView(PluginCall call) {
405
+ String url = call.getString("url");
406
+ if (url == null || TextUtils.isEmpty(url)) {
407
+ call.reject("Invalid URL");
408
+ }
409
+ currentUrl = url;
410
+ final Options options = new Options();
411
+ options.setUrl(url);
412
+ options.setHeaders(call.getObject("headers"));
413
+ options.setCredentials(call.getObject("credentials"));
414
+ options.setShowReloadButton(
415
+ Boolean.TRUE.equals(call.getBoolean("showReloadButton", false))
416
+ );
417
+ options.setVisibleTitle(
418
+ Boolean.TRUE.equals(call.getBoolean("visibleTitle", true))
419
+ );
420
+ if (Boolean.TRUE.equals(options.getVisibleTitle())) {
421
+ options.setTitle(call.getString("title", "New Window"));
422
+ } else {
423
+ options.setTitle(call.getString("title", ""));
424
+ }
425
+ options.setToolbarColor(call.getString("toolbarColor", "#ffffff"));
426
+ options.setArrow(Boolean.TRUE.equals(call.getBoolean("showArrow", false)));
427
+ options.setIgnoreUntrustedSSLError(
428
+ Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false))
429
+ );
430
+
431
+ String proxyRequestsStr = call.getString("proxyRequests");
432
+ if (proxyRequestsStr != null) {
433
+ try {
434
+ options.setProxyRequestsPattern(Pattern.compile(proxyRequestsStr));
435
+ } catch (PatternSyntaxException e) {
436
+ Log.e(
437
+ "WebViewDialog",
438
+ String.format("Pattern '%s' is not a valid pattern", proxyRequestsStr)
439
+ );
440
+ }
441
+ }
442
+
443
+ try {
444
+ Options.ButtonNearDone buttonNearDone =
445
+ Options.ButtonNearDone.generateFromPluginCall(
446
+ call,
447
+ getActivity().getAssets()
448
+ );
449
+ options.setButtonNearDone(buttonNearDone);
450
+ } catch (IllegalArgumentException illegalArgumentException) {
451
+ call.reject(
452
+ String.format(
453
+ "ButtonNearDone rejected: %s",
454
+ illegalArgumentException.getMessage()
455
+ )
456
+ );
457
+ } catch (RuntimeException e) {
458
+ Log.e(
459
+ "WebViewDialog",
460
+ String.format("ButtonNearDone runtime error: %s", e)
461
+ );
462
+ call.reject(String.format("ButtonNearDone RuntimeException: %s", e));
463
+ }
464
+
465
+ options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
466
+ options.setPreShowScript(call.getString("preShowScript", null));
467
+ options.setShareSubject(call.getString("shareSubject", null));
468
+ options.setToolbarType(call.getString("toolbarType", ""));
469
+ options.setActiveNativeNavigationForWebview(
470
+ Boolean.TRUE.equals(
471
+ call.getBoolean("activeNativeNavigationForWebview", false)
472
+ )
473
+ );
474
+ options.setDisableGoBackOnNativeApplication(
475
+ Boolean.TRUE.equals(
476
+ call.getBoolean("disableGoBackOnNativeApplication", false)
477
+ )
478
+ );
479
+ options.setPresentAfterPageLoad(
480
+ Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false))
481
+ );
482
+ if (Boolean.TRUE.equals(call.getBoolean("closeModal", false))) {
483
+ options.setCloseModal(true);
484
+ options.setCloseModalTitle(call.getString("closeModalTitle", "Close"));
485
+ options.setCloseModalDescription(
486
+ call.getString("closeModalDescription", "Are you sure ?")
487
+ );
488
+ options.setCloseModalOk(call.getString("closeModalOk", "Ok"));
489
+ options.setCloseModalCancel(call.getString("closeModalCancel", "Cancel"));
490
+ } else {
491
+ options.setCloseModal(false);
492
+ }
493
+ options.setPluginCall(call);
494
+ // options.getToolbarItemTypes().add(ToolbarItemType.RELOAD); TODO: fix this
495
+ options.setCallbacks(
496
+ new WebViewCallbacks() {
497
+ @Override
498
+ public void urlChangeEvent(String url) {
499
+ notifyListeners("urlChangeEvent", new JSObject().put("url", url));
500
+ }
501
+
502
+ @Override
503
+ public void closeEvent(String url) {
504
+ notifyListeners("closeEvent", new JSObject().put("url", url));
505
+ }
506
+
507
+ @Override
508
+ public void pageLoaded() {
509
+ notifyListeners("browserPageLoaded", new JSObject());
510
+ }
511
+
512
+ @Override
513
+ public void pageLoadError() {
514
+ notifyListeners("pageLoadError", new JSObject());
515
+ }
516
+
517
+ @Override
518
+ public void buttonNearDoneClicked() {
519
+ notifyListeners("buttonNearDoneClick", new JSObject());
520
+ }
521
+
522
+ @Override
523
+ public void javascriptCallback(String message) {
524
+ // Handle the message received from JavaScript
525
+ Log.d(
526
+ "WebViewDialog",
527
+ "Received message from JavaScript: " + message
528
+ );
529
+ // Process the message as needed
530
+ try {
531
+ // Parse the received message as a JSON object
532
+ JSONObject jsonMessage = new JSONObject(message);
533
+
534
+ // Create a new JSObject to send to the Capacitor plugin
535
+ JSObject jsObject = new JSObject();
536
+
537
+ // Iterate through the keys in the JSON object and add them to the JSObject
538
+ Iterator<String> keys = jsonMessage.keys();
539
+ while (keys.hasNext()) {
540
+ String key = keys.next();
541
+ jsObject.put(key, jsonMessage.get(key));
542
+ }
543
+
544
+ // Notify listeners with the parsed message
545
+ notifyListeners("messageFromWebview", jsObject);
546
+ } catch (JSONException e) {
547
+ Log.e(
548
+ "WebViewDialog",
549
+ "Error parsing JSON message: " + e.getMessage()
550
+ );
551
+
552
+ // If JSON parsing fails, send the raw message as a string
553
+ JSObject jsObject = new JSObject();
554
+ jsObject.put("rawMessage", message);
555
+ notifyListeners("messageFromWebview", jsObject);
556
+ }
557
+ }
558
+ }
559
+ );
560
+ this.getActivity()
561
+ .runOnUiThread(
562
+ new Runnable() {
563
+ @Override
564
+ public void run() {
565
+ webViewDialog = new WebViewDialog(
566
+ getContext(),
567
+ android.R.style.Theme_NoTitleBar,
568
+ options,
569
+ InAppBrowserPlugin.this,
570
+ getBridge().getWebView()
571
+ );
572
+ webViewDialog.activity = InAppBrowserPlugin.this.getActivity();
573
+ webViewDialog.presentWebView();
574
+ }
575
+ }
576
+ );
577
+ }
578
+
579
+ @PluginMethod
580
+ public void postMessage(PluginCall call) {
581
+ if (webViewDialog == null) {
582
+ call.reject("WebView is not initialized");
583
+ return;
584
+ }
585
+ JSObject eventData = call.getObject("detail");
586
+ // Log event data
587
+ if (eventData == null) {
588
+ call.reject("No event data provided");
589
+ return;
590
+ }
591
+
592
+ Log.d("InAppBrowserPlugin", "Event data: " + eventData.toString());
593
+ this.getActivity()
594
+ .runOnUiThread(
595
+ new Runnable() {
596
+ @Override
597
+ public void run() {
598
+ webViewDialog.postMessageToJS(eventData);
599
+ call.resolve();
600
+ }
601
+ }
602
+ );
603
+ }
604
+
605
+ @PluginMethod
606
+ public void executeScript(PluginCall call) {
607
+ String script = call.getString("code");
608
+ if (script == null || TextUtils.isEmpty(script)) {
609
+ call.reject("No script to run");
610
+ }
611
+
612
+ if (webViewDialog != null) {
613
+ this.getActivity()
614
+ .runOnUiThread(
615
+ new Runnable() {
616
+ @Override
617
+ public void run() {
618
+ webViewDialog.executeScript(script);
619
+ }
620
+ }
621
+ );
622
+ }
623
+
624
+ call.resolve();
625
+ }
626
+
627
+ @PluginMethod
628
+ public void reload(PluginCall call) {
629
+ if (webViewDialog != null) {
630
+ this.getActivity()
631
+ .runOnUiThread(
632
+ new Runnable() {
633
+ @Override
634
+ public void run() {
635
+ webViewDialog.reload();
636
+ }
637
+ }
638
+ );
639
+ }
640
+ call.resolve();
641
+ }
642
+
643
+ @PluginMethod
644
+ public void lsuakdchgbbaHandleProxiedRequest(PluginCall call) {
645
+ if (webViewDialog != null) {
646
+ Boolean ok = call.getBoolean("ok", false);
647
+ String id = call.getString("id");
648
+ if (id == null) {
649
+ Log.e("InAppBrowserProxy", "CRITICAL ERROR, proxy id = null");
650
+ return;
651
+ }
652
+ if (Boolean.FALSE.equals(ok)) {
653
+ String result = call.getString("result", "");
654
+ webViewDialog.handleProxyResultError(result, id);
655
+ } else {
656
+ JSONObject object = call.getObject("result");
657
+ webViewDialog.handleProxyResultOk(object, id);
658
+ }
659
+ }
660
+ call.resolve();
661
+ }
662
+
663
+ @PluginMethod
664
+ public void close(PluginCall call) {
665
+ this.getActivity()
666
+ .runOnUiThread(
667
+ new Runnable() {
668
+ @Override
669
+ public void run() {
670
+ if (webViewDialog != null) {
671
+ notifyListeners(
672
+ "closeEvent",
673
+ new JSObject().put("url", webViewDialog.getUrl())
674
+ );
675
+ webViewDialog.dismiss();
676
+ webViewDialog.destroy();
677
+ webViewDialog = null;
678
+ } else {
679
+ Intent intent = new Intent(
680
+ getContext(),
681
+ getBridge().getActivity().getClass()
682
+ );
683
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
684
+ getContext().startActivity(intent);
685
+ }
686
+ call.resolve();
687
+ }
688
+ }
689
+ );
690
+ }
691
+
692
+ private Bundle getHeaders(PluginCall pluginCall) {
693
+ JSObject headersProvided = pluginCall.getObject("headers");
694
+ Bundle headers = new Bundle();
695
+ if (headersProvided != null) {
696
+ Iterator<String> keys = headersProvided.keys();
697
+ while (keys.hasNext()) {
698
+ String key = keys.next();
699
+ headers.putString(key, headersProvided.getString(key));
700
+ }
701
+ }
702
+ return headers;
703
+ }
704
+
705
+ protected void handleOnResume() {
706
+ boolean ok = CustomTabsClient.bindCustomTabsService(
707
+ getContext(),
708
+ CUSTOM_TAB_PACKAGE_NAME,
709
+ connection
710
+ );
711
+ if (!ok) {
712
+ Log.e(getLogTag(), "Error binding to custom tabs service");
713
+ }
714
+ }
715
+
716
+ protected void handleOnPause() {
717
+ getContext().unbindService(connection);
718
+ }
719
+
720
+ public CustomTabsSession getCustomTabsSession() {
721
+ if (customTabsClient == null) {
722
+ return null;
723
+ }
724
+
725
+ if (currentSession == null) {
726
+ currentSession = customTabsClient.newSession(
727
+ new CustomTabsCallback() {
728
+ @Override
729
+ public void onNavigationEvent(int navigationEvent, Bundle extras) {
730
+ switch (navigationEvent) {
731
+ case NAVIGATION_FINISHED:
732
+ notifyListeners("browserPageLoaded", new JSObject());
733
+ break;
734
+ }
735
+ }
736
+ }
737
+ );
738
+ }
739
+ return currentSession;
740
+ }
741
+ }